X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fextract_extradata_bsf.c;h=082b3e749bc80d99a13486b25654080dd5e74552;hb=0c7bc7eb4789f4ee27296c0ff85c6d973c157531;hp=d40907a675c55b0b83614e46de34679346df8c54;hpb=e9dfc6f9006f81d6267d183b00616053b514df8f;p=ffmpeg diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index d40907a675c..082b3e749bc 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -36,6 +36,9 @@ typedef struct ExtractExtradataContext { int (*extract)(AVBSFContext *ctx, AVPacket *pkt, uint8_t **data, int *size); + /* H264/HEVC specifc fields */ + H2645Packet h2645_pkt; + /* AVOptions */ int remove; } ExtractExtradataContext; @@ -61,8 +64,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, ExtractExtradataContext *s = ctx->priv_data; - H2645Packet h2645_pkt = { 0 }; - int extradata_size = 0; + int extradata_size = 0, filtered_size = 0; const int *extradata_nal_types; int nb_extradata_nal_types; int i, has_sps = 0, has_vps = 0, ret = 0; @@ -75,13 +77,13 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264); } - ret = ff_h2645_packet_split(&h2645_pkt, pkt->data, pkt->size, + ret = ff_h2645_packet_split(&s->h2645_pkt, pkt->data, pkt->size, ctx, 0, 0, ctx->par_in->codec_id, 1); if (ret < 0) - goto fail; + return ret; - for (i = 0; i < h2645_pkt.nb_nals; i++) { - H2645NAL *nal = &h2645_pkt.nals[i]; + for (i = 0; i < s->h2645_pkt.nb_nals; i++) { + H2645NAL *nal = &s->h2645_pkt.nals[i]; if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) { extradata_size += nal->raw_size + 3; if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { @@ -90,6 +92,8 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, } else { if (nal->type == H264_NAL_SPS) has_sps = 1; } + } else if (s->remove) { + filtered_size += nal->raw_size + 3; } } @@ -100,26 +104,27 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, uint8_t *extradata, *filtered_data; if (s->remove) { - filtered_buf = av_buffer_alloc(pkt->size + AV_INPUT_BUFFER_PADDING_SIZE); + filtered_buf = av_buffer_alloc(filtered_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!filtered_buf) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } + memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + filtered_data = filtered_buf->data; } extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!extradata) { av_buffer_unref(&filtered_buf); - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } + memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *data = extradata; *size = extradata_size; - for (i = 0; i < h2645_pkt.nb_nals; i++) { - H2645NAL *nal = &h2645_pkt.nals[i]; + for (i = 0; i < s->h2645_pkt.nb_nals; i++) { + H2645NAL *nal = &s->h2645_pkt.nals[i]; if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) { AV_WB24(extradata, 1); // startcode @@ -136,13 +141,11 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, av_buffer_unref(&pkt->buf); pkt->buf = filtered_buf; pkt->data = filtered_buf->data; - pkt->size = filtered_data - filtered_buf->data; + pkt->size = filtered_size; } } -fail: - ff_h2645_packet_uninit(&h2645_pkt); - return ret; + return 0; } static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, @@ -169,6 +172,7 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, return AVERROR(ENOMEM); memcpy(*data, pkt->data, extradata_size); + memset(*data + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *size = extradata_size; if (s->remove) { @@ -199,6 +203,7 @@ static int extract_extradata_mpeg12(AVBSFContext *ctx, AVPacket *pkt, return AVERROR(ENOMEM); memcpy(*data, pkt->data, *size); + memset(*data + *size, 0, AV_INPUT_BUFFER_PADDING_SIZE); if (s->remove) { pkt->data += *size; @@ -228,6 +233,7 @@ static int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, return AVERROR(ENOMEM); memcpy(*data, pkt->data, *size); + memset(*data + *size, 0, AV_INPUT_BUFFER_PADDING_SIZE); if (s->remove) { pkt->data += *size; @@ -271,24 +277,23 @@ static int extract_extradata_init(AVBSFContext *ctx) return 0; } -static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *out) +static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *pkt) { ExtractExtradataContext *s = ctx->priv_data; - AVPacket *in; uint8_t *extradata = NULL; int extradata_size; int ret = 0; - ret = ff_bsf_get_packet(ctx, &in); + ret = ff_bsf_get_packet_ref(ctx, pkt); if (ret < 0) return ret; - ret = s->extract(ctx, in, &extradata, &extradata_size); + ret = s->extract(ctx, pkt, &extradata, &extradata_size); if (ret < 0) goto fail; if (extradata) { - ret = av_packet_add_side_data(in, AV_PKT_DATA_NEW_EXTRADATA, + ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, extradata, extradata_size); if (ret < 0) { av_freep(&extradata); @@ -296,13 +301,19 @@ static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *out) } } - av_packet_move_ref(out, in); + return 0; fail: - av_packet_free(&in); + av_packet_unref(pkt); return ret; } +static void extract_extradata_close(AVBSFContext *ctx) +{ + ExtractExtradataContext *s = ctx->priv_data; + ff_h2645_packet_uninit(&s->h2645_pkt); +} + static const enum AVCodecID codec_ids[] = { AV_CODEC_ID_CAVS, AV_CODEC_ID_H264, @@ -315,9 +326,10 @@ static const enum AVCodecID codec_ids[] = { }; #define OFFSET(x) offsetof(ExtractExtradataContext, x) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) static const AVOption options[] = { { "remove", "remove the extradata from the bitstream", OFFSET(remove), AV_OPT_TYPE_INT, - { .i64 = 0 }, 0, 1 }, + { .i64 = 0 }, 0, 1, FLAGS }, { NULL }, }; @@ -335,4 +347,5 @@ const AVBitStreamFilter ff_extract_extradata_bsf = { .priv_class = &extract_extradata_class, .init = extract_extradata_init, .filter = extract_extradata_filter, + .close = extract_extradata_close, };