@@ -611,7 +611,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
err = ff_h2645_packet_split(&priv->read_packet,
frag->data + start, end - start,
- ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1);
+ ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, NULL);
if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n");
return err;
@@ -635,7 +635,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
err = ff_h2645_packet_split(&priv->read_packet,
frag->data + start, end - start,
- ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1);
+ ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, NULL);
if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n");
return err;
@@ -689,7 +689,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
err = ff_h2645_packet_split(&priv->read_packet,
frag->data + start, end - start,
- ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1);
+ ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1, NULL);
if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split "
"HVCC array %d (%d NAL units of type %d).\n",
@@ -708,7 +708,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
frag->data, frag->data_size,
ctx->log_ctx,
priv->mp4, priv->nal_length_size,
- codec_id, 1);
+ codec_id, 1, NULL);
if (err < 0)
return err;
@@ -1510,7 +1510,7 @@ static void cbs_h264_close(CodedBitstreamContext *ctx)
CodedBitstreamH264Context *h264 = ctx->priv_data;
int i;
- ff_h2645_packet_uninit(&h264->common.read_packet);
+ ff_h2645_packet_uninit(&h264->common.read_packet, NULL);
av_freep(&h264->common.write_buffer);
@@ -1525,7 +1525,7 @@ static void cbs_h265_close(CodedBitstreamContext *ctx)
CodedBitstreamH265Context *h265 = ctx->priv_data;
int i;
- ff_h2645_packet_uninit(&h265->common.read_packet);
+ ff_h2645_packet_uninit(&h265->common.read_packet, NULL);
av_freep(&h265->common.write_buffer);
@@ -157,7 +157,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
}
ret = ff_h2645_packet_split(&s->h2645_pkt, pkt->data, pkt->size,
- ctx, 0, 0, ctx->par_in->codec_id, 1);
+ ctx, 0, 0, ctx->par_in->codec_id, 1, NULL);
if (ret < 0)
return ret;
@@ -393,7 +393,7 @@ static void extract_extradata_close(AVBSFContext *ctx)
{
ExtractExtradataContext *s = ctx->priv_data;
ff_av1_packet_uninit(&s->av1_pkt);
- ff_h2645_packet_uninit(&s->h2645_pkt);
+ ff_h2645_packet_uninit(&s->h2645_pkt, NULL);
}
static const enum AVCodecID codec_ids[] = {
@@ -345,7 +345,7 @@ static int find_next_start_code(const uint8_t *buf, const uint8_t *next_avc)
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
void *logctx, int is_nalff, int nal_length_size,
- enum AVCodecID codec_id, int small_padding)
+ enum AVCodecID codec_id, int small_padding, AVBufferRef **ref)
{
GetByteContext bc;
int consumed, ret = 0;
@@ -353,9 +353,22 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
int64_t padding = small_padding ? 0 : MAX_MBPAIR_SIZE;
bytestream2_init(&bc, buf, length);
- av_fast_padded_malloc(&pkt->rbsp.rbsp_buffer, &pkt->rbsp.rbsp_buffer_alloc_size, length + padding);
- if (!pkt->rbsp.rbsp_buffer)
- return AVERROR(ENOMEM);
+ if (!ref) {
+ av_fast_padded_malloc(&pkt->rbsp.rbsp_buffer, &pkt->rbsp.rbsp_buffer_alloc_size, length + padding);
+ if (!pkt->rbsp.rbsp_buffer)
+ return AVERROR(ENOMEM);
+ } else {
+ int err;
+ err = avpriv_buffer_fast_alloc(ref, length + padding + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (err < 0) {
+ pkt->rbsp.rbsp_buffer = NULL;
+ pkt->rbsp.rbsp_buffer_alloc_size = 0;
+ return err;
+ }
+
+ pkt->rbsp.rbsp_buffer = (*ref)->data;
+ pkt->rbsp.rbsp_buffer_alloc_size = (*ref)->size;
+ }
pkt->rbsp.rbsp_buffer_size = 0;
pkt->nb_nals = 0;
@@ -466,7 +479,7 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
return 0;
}
-void ff_h2645_packet_uninit(H2645Packet *pkt)
+void ff_h2645_packet_uninit(H2645Packet *pkt, AVBufferRef *ref)
{
int i;
for (i = 0; i < pkt->nals_allocated; i++) {
@@ -474,6 +487,9 @@ void ff_h2645_packet_uninit(H2645Packet *pkt)
}
av_freep(&pkt->nals);
pkt->nals_allocated = 0;
- av_freep(&pkt->rbsp.rbsp_buffer);
+ if (!ref)
+ av_freep(&pkt->rbsp.rbsp_buffer);
+ else
+ pkt->rbsp.rbsp_buffer = NULL;
pkt->rbsp.rbsp_buffer_alloc_size = pkt->rbsp.rbsp_buffer_size = 0;
}
@@ -23,6 +23,7 @@
#include <stdint.h>
+#include "libavutil/buffer.h"
#include "avcodec.h"
#include "get_bits.h"
@@ -91,15 +92,19 @@ int ff_h2645_extract_rbsp(const uint8_t *src, int length, H2645RBSP *rbsp,
* the data is contained in the input buffer pointed to by buf.
* Otherwise, the unescaped data is part of the rbsp_buffer described by the
* packet's H2645RBSP.
+ * If ref is not NULL, *ref must either be NULL in which case pkt's underlying
+ * rbsp_buffer must be NULL, too, or (*ref)->buffer owns rbsp_buffer. In both
+ * cases, rbsp_buffer will be owned by **ref afterwards.
*/
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
void *logctx, int is_nalff, int nal_length_size,
- enum AVCodecID codec_id, int small_padding);
+ enum AVCodecID codec_id, int small_padding, AVBufferRef **ref);
/**
* Free all the allocated memory in the packet.
+ * If ref is supplied, the underlying AVBuffer is supposed to own the rbsp_buffer.
*/
-void ff_h2645_packet_uninit(H2645Packet *pkt);
+void ff_h2645_packet_uninit(H2645Packet *pkt, AVBufferRef *ref);
static inline int get_nalsize(int nal_length_size, const uint8_t *buf,
int buf_size, int *buf_index, void *logctx)
@@ -359,7 +359,7 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps,
H2645Packet pkt = { 0 };
int i, ret = 0;
- ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1);
+ ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1, NULL);
if (ret < 0) {
ret = 0;
goto fail;
@@ -387,7 +387,7 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps,
}
fail:
- ff_h2645_packet_uninit(&pkt);
+ ff_h2645_packet_uninit(&pkt, NULL);
return ret;
}
@@ -377,7 +377,7 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
ff_h264_sei_uninit(&h->sei);
ff_h264_ps_uninit(&h->ps);
- ff_h2645_packet_uninit(&h->pkt);
+ ff_h2645_packet_uninit(&h->pkt, NULL);
ff_h264_unref_picture(h, &h->cur_pic);
av_frame_free(&h->cur_pic.f);
@@ -622,8 +622,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
h->is_avc = 1;
}
- ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc,
- h->nal_length_size, avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST);
+ ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, h->nal_length_size,
+ avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST, NULL);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR,
"Error splitting the input into NAL units.\n");
@@ -29,7 +29,8 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets
int ret = 0;
H2645Packet pkt = { 0 };
- ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff, nal_length_size, AV_CODEC_ID_HEVC, 1);
+ ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff,
+ nal_length_size, AV_CODEC_ID_HEVC, 1, NULL);
if (ret < 0) {
goto done;
}
@@ -67,7 +68,7 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets
}
done:
- ff_h2645_packet_uninit(&pkt);
+ ff_h2645_packet_uninit(&pkt, NULL);
if (err_recognition & AV_EF_EXPLODE)
return ret;
@@ -194,7 +194,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
ff_hevc_reset_sei(sei);
ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, ctx->is_avc,
- ctx->nal_length_size, AV_CODEC_ID_HEVC, 1);
+ ctx->nal_length_size, AV_CODEC_ID_HEVC, 1, NULL);
if (ret < 0)
return ret;
@@ -363,7 +363,7 @@ static void hevc_parser_close(AVCodecParserContext *s)
HEVCParserContext *ctx = s->priv_data;
ff_hevc_ps_uninit(&ctx->ps);
- ff_h2645_packet_uninit(&ctx->pkt);
+ ff_h2645_packet_uninit(&ctx->pkt, NULL);
ff_hevc_reset_sei(&ctx->sei);
av_freep(&ctx->pc.buffer);
@@ -3024,7 +3024,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length)
/* split the input packet into NAL units, so we know the upper bound on the
* number of slices in the frame */
ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff,
- s->nal_length_size, s->avctx->codec_id, 1);
+ s->nal_length_size, s->avctx->codec_id, 1, NULL);
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"Error splitting the input into NAL units.\n");
@@ -3305,7 +3305,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
s->HEVClc = NULL;
av_freep(&s->HEVClcList[0]);
- ff_h2645_packet_uninit(&s->pkt);
+ ff_h2645_packet_uninit(&s->pkt, NULL);
return 0;
}
This is in preparation for a patch for cbs_h2645. Now the packet's rbsp_buffer can be owned by an AVBuffer. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com> --- libavcodec/cbs_h2645.c | 12 ++++++------ libavcodec/extract_extradata_bsf.c | 4 ++-- libavcodec/h2645_parse.c | 28 ++++++++++++++++++++++------ libavcodec/h2645_parse.h | 9 +++++++-- libavcodec/h264_parse.c | 4 ++-- libavcodec/h264dec.c | 6 +++--- libavcodec/hevc_parse.c | 5 +++-- libavcodec/hevc_parser.c | 4 ++-- libavcodec/hevcdec.c | 4 ++-- 9 files changed, 49 insertions(+), 27 deletions(-)