From 87d5686151bcb2ab94bd1c962e94d7e41203e31a Mon Sep 17 00:00:00 2001 From: Jan Sebechlebsky Date: Thu, 28 Jul 2016 18:18:13 +0200 Subject: [PATCH 1/7] avcodec/bsf: Add ff_bsf_get_packet_ref() function Use of this function can save unnecessary malloc operation in bitstream filter. Signed-off-by: Jan Sebechlebsky Signed-off-by: Michael Niedermayer Signed-off-by: Luca Barbato --- libavcodec/bsf.c | 16 ++++++++++++++++ libavcodec/bsf.h | 11 +++++++++++ 2 files changed, 27 insertions(+) diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c index 05cad546de..f6f894b50a 100644 --- a/libavcodec/bsf.c +++ b/libavcodec/bsf.c @@ -227,3 +227,19 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) return 0; } + +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) +{ + AVBSFInternal *in = ctx->internal; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(pkt, ctx->internal->buffer_pkt); + + return 0; +} diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h index cf35fc8e01..39301a286f 100644 --- a/libavcodec/bsf.h +++ b/libavcodec/bsf.h @@ -28,6 +28,17 @@ */ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt); +/** + * Called by bitstream filters to get packet for filtering. + * The reference to packet is moved to provided packet structure. + * + * @param ctx pointer to AVBSFContext of filter + * @param pkt pointer to packet to move reference to + * + * @return 0>= on success, negative AVERROR in case of failure + */ +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt); + const AVClass *ff_bsf_child_class_next(const AVClass *prev); #endif /* AVCODEC_BSF_H */ From aaf7fd168050212c1a9b9c2080805c5095e86d20 Mon Sep 17 00:00:00 2001 From: Nikolas Bowe Date: Tue, 5 Dec 2017 15:11:26 -0800 Subject: [PATCH 2/7] avcodec/extract_extradata_bsf: Fix leak discovered via fuzzing Signed-off-by: Michael Niedermayer Signed-off-by: Luca Barbato --- libavcodec/extract_extradata_bsf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 100c60d063..10d108054a 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -78,7 +78,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, ret = ff_h2645_packet_split(&h2645_pkt, pkt->data, pkt->size, ctx, 0, 0, ctx->par_in->codec_id); if (ret < 0) - return ret; + goto fail; for (i = 0; i < h2645_pkt.nb_nals; i++) { H2645NAL *nal = &h2645_pkt.nals[i]; From be65995d23c94064df9ab15246c16c757adcd0c4 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 9 Mar 2018 13:00:55 -0300 Subject: [PATCH 3/7] avcodec/extract_extradata: Zero-initialize the padding bytes in all allocated buffers Reviewed-by: Derek Buitenhuis Signed-off-by: James Almer Signed-off-by: Luca Barbato --- libavcodec/extract_extradata_bsf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 10d108054a..0f1a4e0bcc 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -114,6 +114,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, ret = AVERROR(ENOMEM); goto fail; } + memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); *data = extradata; *size = extradata_size; @@ -137,6 +138,8 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, pkt->buf = filtered_buf; pkt->data = filtered_buf->data; pkt->size = filtered_data - filtered_buf->data; + + memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } } @@ -171,6 +174,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) { @@ -202,6 +206,7 @@ static int extract_extradata_mpeg124(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; From 70f11ee9981fce6145795b9c970343eb9237812d Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 9 Mar 2018 14:31:30 -0300 Subject: [PATCH 4/7] avcodec/extract_extradata: Do not allocate more space than needed when removing NALUs in h264/hevc Signed-off-by: James Almer Signed-off-by: Luca Barbato --- libavcodec/extract_extradata_bsf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 0f1a4e0bcc..90ff8c852b 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -62,7 +62,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; @@ -90,6 +90,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,11 +102,13 @@ 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; } + memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + filtered_data = filtered_buf->data; } @@ -137,9 +141,7 @@ 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; - - memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + pkt->size = filtered_size; } } From 6442d8bad68052a1d42565fbbad85695fadd26c1 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sun, 11 Mar 2018 13:45:05 -0300 Subject: [PATCH 5/7] avcodec/extract_extradata: Move the reference in the bsf internal buffer There is no need to allocate a new packet for it. Reviewed-by: Mark Thompson Signed-off-by: James Almer Signed-off-by: Luca Barbato --- libavcodec/extract_extradata_bsf.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 90ff8c852b..d2773ce87a 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -252,24 +252,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); @@ -277,10 +276,10 @@ 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; } From 3365e91b1ed82f225aaa15c5c27504873f4b8c7a Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 10 Mar 2018 19:57:35 -0300 Subject: [PATCH 6/7] avcodec/extract_extradata: don't uninitialize the H2645Packet on every processed packet Based on hevc_parser code. This prevents repeated unnecessary allocations and frees on every packet processed by the bsf. Reviewed-by: Jun Zhao Signed-off-by: James Almer Signed-off-by: Luca Barbato --- libavcodec/extract_extradata_bsf.c | 33 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index d2773ce87a..f631331766 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,7 +64,6 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, ExtractExtradataContext *s = ctx->priv_data; - H2645Packet h2645_pkt = { 0 }; int extradata_size = 0, filtered_size = 0; const int *extradata_nal_types; int nb_extradata_nal_types; @@ -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); 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) { @@ -104,8 +106,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, if (s->remove) { 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); @@ -115,16 +116,15 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, 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 @@ -145,9 +145,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, } } -fail: - ff_h2645_packet_uninit(&h2645_pkt); - return ret; + return 0; } static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, @@ -283,6 +281,12 @@ fail: 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,4 +319,5 @@ const AVBitStreamFilter ff_extract_extradata_bsf = { .priv_class = &extract_extradata_class, .init = extract_extradata_init, .filter = extract_extradata_filter, + .close = extract_extradata_close, }; From 97c9a5084479eeb66f4beb100cc7589a2c8bfe81 Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 12 Sep 2018 11:44:56 -0300 Subject: [PATCH 7/7] avcodec/libaomenc: remove AVOption related to frame partitions Support for it was apparently never in the codebase, and the enum value was recently removed from the public headers [1] [1] https://aomedia.googlesource.com/aom/+/df4ffb73140fe31bebdabd17c1a7b53721e74838 Signed-off-by: James Almer Signed-off-by: Luca Barbato --- libavcodec/libaomenc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index 9807bd5adb..dfa0d28c71 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -540,10 +540,6 @@ static const AVOption options[] = { "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, - { "partitions", "The frame partitions are independently decodable " - "by the bool decoder, meaning that partitions can be decoded even " - "though earlier partitions have been lost. Note that intra predicition" - " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, { "crf", "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE }, { "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { "drop-threshold", "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },