Patches attached. - Andreas
From 84c03ef85ef01a9109e99d915e1b2b1cab30cfd8 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 21:14:32 +0200 Subject: [PATCH 01/11] avcodec/vulkan_encode_h264: Fix memleak on error
Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/vulkan_encode_h264.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vulkan_encode_h264.c b/libavcodec/vulkan_encode_h264.c index ecbb125420..f31b6d4069 100644 --- a/libavcodec/vulkan_encode_h264.c +++ b/libavcodec/vulkan_encode_h264.c @@ -1065,7 +1065,7 @@ static int parse_feedback_units(AVCodecContext *avctx, if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n", av_err2str(err)); - return err; + goto fail; } /* If PPS has an override, just copy it entirely. */ @@ -1079,10 +1079,12 @@ static int parse_feedback_units(AVCodecContext *avctx, } } + err = 0; +fail: ff_cbs_fragment_free(&au); ff_cbs_close(&cbs); - return 0; + return err; } static int init_base_units(AVCodecContext *avctx) -- 2.45.2
From a225b6bc5afd70ca0f9bea793a20acdef6686116 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 22:16:13 +0200 Subject: [PATCH 02/11] avcodec/vulkan_encode_hevc: Fix memleak on error Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/vulkan_encode_h265.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vulkan_encode_h265.c b/libavcodec/vulkan_encode_h265.c index a1f9528ac3..d81d2de95a 100644 --- a/libavcodec/vulkan_encode_h265.c +++ b/libavcodec/vulkan_encode_h265.c @@ -1218,7 +1218,7 @@ static int parse_feedback_units(AVCodecContext *avctx, if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n", av_err2str(err)); - return err; + goto fail; } if (sps_override) { @@ -1246,10 +1246,12 @@ static int parse_feedback_units(AVCodecContext *avctx, } } + err = 0; +fail: ff_cbs_fragment_free(&au); ff_cbs_close(&cbs); - return 0; + return err; } static int init_base_units(AVCodecContext *avctx) -- 2.45.2
From 73fc5e8ffe793a45f1727479d470122b7a88b4bf Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:23:23 +0200 Subject: [PATCH 03/11] avcodec/apv_parser: Mark close as av_cold Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/apv_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/apv_parser.c b/libavcodec/apv_parser.c index e5c468f675..fdd575339b 100644 --- a/libavcodec/apv_parser.c +++ b/libavcodec/apv_parser.c @@ -132,7 +132,7 @@ static av_cold int init(AVCodecParserContext *s) return 0; } -static void close(AVCodecParserContext *s) +static av_cold void close(AVCodecParserContext *s) { APVParseContext *p = s->priv_data; -- 2.45.2
From 40deeb4ae0055b7bcd932a92a6afadfd378e1e0e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 18:22:37 +0200 Subject: [PATCH 04/11] avcodec/cbs: Avoid branch Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/cbs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 2b4445ddb8..6b2ebe597d 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -783,15 +783,13 @@ static int cbs_insert_unit(CodedBitstreamFragment *frag, if (position < frag->nb_units) memcpy(units + position + 1, frag->units + position, (frag->nb_units - position) * sizeof(*units)); - } - - memset(units + position, 0, sizeof(*units)); - if (units != frag->units) { av_free(frag->units); frag->units = units; } + memset(units + position, 0, sizeof(*units)); + ++frag->nb_units; return 0; -- 2.45.2
From 6cab1dcb098aa15e4d6d646584b32a8fd5bad473 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 18:40:28 +0200 Subject: [PATCH 05/11] avcodec/cbs,cbs_jpeg: Split ff_cbs_append_unit_data() It currently has two modes: One where the caller supplies an AVBufferRef* from which a new reference is created and one where it only provides a naked buffer ownership of which passed to the unit (by wrapping it into an AVBuffer). Split these two modes into two separate functions. (One of which is only used by cbs_jpeg which has been adapted to use it.) Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/cbs.c | 34 +++++++++++++++++++--------------- libavcodec/cbs.h | 21 +++++++++++++++------ libavcodec/cbs_jpeg.c | 17 ++++++++--------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 6b2ebe597d..39411d4cf5 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -828,25 +828,14 @@ int CBS_FUNC(insert_unit_content)(CodedBitstreamFragment *frag, static int cbs_insert_unit_data(CodedBitstreamFragment *frag, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, - AVBufferRef *data_buf, + AVBufferRef *data_ref, int position) { CodedBitstreamUnit *unit; - AVBufferRef *data_ref; int err; av_assert0(position >= 0 && position <= frag->nb_units); - if (data_buf) - data_ref = av_buffer_ref(data_buf); - else - data_ref = av_buffer_create(data, data_size, NULL, NULL, 0); - if (!data_ref) { - if (!data_buf) - av_free(data); - return AVERROR(ENOMEM); - } - err = cbs_insert_unit(frag, position); if (err < 0) { av_buffer_unref(&data_ref); @@ -863,10 +852,25 @@ static int cbs_insert_unit_data(CodedBitstreamFragment *frag, } int CBS_FUNC(append_unit_data)(CodedBitstreamFragment *frag, - CodedBitstreamUnitType type, - uint8_t *data, size_t data_size, - AVBufferRef *data_buf) + CodedBitstreamUnitType type, + uint8_t *data, size_t data_size, + const AVBufferRef *data_buf) +{ + AVBufferRef *data_ref = av_buffer_ref(data_buf); + if (!data_ref) + return AVERROR(ENOMEM); + + return cbs_insert_unit_data(frag, type, + data, data_size, data_ref, + frag->nb_units); +} + +int CBS_FUNC(append_unit_data_move_ref)(CodedBitstreamFragment *frag, + CodedBitstreamUnitType type, + uint8_t *data, size_t data_size, + AVBufferRef *data_buf) { + av_assert1(data_buf); return cbs_insert_unit_data(frag, type, data, data_size, data_buf, frag->nb_units); diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index 67f2ec9e50..958b00cc05 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -460,14 +460,23 @@ int CBS_FUNC(insert_unit_content)(CodedBitstreamFragment *frag, /** * Add a new unit to a fragment with the given data bitstream. * - * If data_buf is not supplied then data must have been allocated with - * av_malloc() and will on success become owned by the unit after this - * call or freed on error. + * data must be owned by data_buf (which must be provided); + * ownership of the reference stays with the caller. */ int CBS_FUNC(append_unit_data)(CodedBitstreamFragment *frag, - CodedBitstreamUnitType type, - uint8_t *data, size_t data_size, - AVBufferRef *data_buf); + CodedBitstreamUnitType type, + uint8_t *data, size_t data_size, + const AVBufferRef *data_buf); +/** + * Add a new unit to a fragment with the given data bitstream. + * + * data_buf must be supplied and ownership of it will be transferred + * to the new unit; in case of error, it is unreferenced. + */ +int CBS_FUNC(append_unit_data_move_ref)(CodedBitstreamFragment *frag, + CodedBitstreamUnitType type, + uint8_t *data, size_t data_size, + AVBufferRef *data_buf); /** * Delete a unit from a fragment and free all memory it uses. diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c index 406147c082..281606e7af 100644 --- a/libavcodec/cbs_jpeg.c +++ b/libavcodec/cbs_jpeg.c @@ -87,7 +87,6 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header) { - AVBufferRef *data_ref; uint8_t *data; size_t data_size; int start, end, marker, next_start, next_marker; @@ -180,11 +179,11 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, if (length > end - start) return AVERROR_INVALIDDATA; - data_ref = NULL; - data = av_malloc(end - start + - AV_INPUT_BUFFER_PADDING_SIZE); - if (!data) + AVBufferRef *data_ref = av_buffer_alloc(end - start + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!data_ref) return AVERROR(ENOMEM); + data = data_ref->data; memcpy(data, frag->data + start, length); for (i = start + length, j = length; i < end; i++, j++) { @@ -200,14 +199,14 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, memset(data + data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + err = ff_cbs_append_unit_data_move_ref(frag, marker, data, + data_size, data_ref); } else { data = frag->data + start; data_size = end - start; - data_ref = frag->data_ref; + err = ff_cbs_append_unit_data(frag, marker, + data, data_size, frag->data_ref); } - - err = ff_cbs_append_unit_data(frag, marker, - data, data_size, data_ref); if (err < 0) return err; -- 2.45.2
From 721a5e228983707d98611e29bdc3b49539be958a Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:03:18 +0200 Subject: [PATCH 06/11] avcodec/cbs: Allow to avoid refcounting/data copying This will make it possible to avoid copying data when using CBS with e.g. a parser. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/cbs.c | 26 ++++++++++++++++---------- libavcodec/cbs.h | 22 +++++++++++++++++++--- libavcodec/cbs_apv.c | 14 ++++++++------ libavcodec/cbs_av1.c | 8 +++++--- libavcodec/cbs_h2645.c | 24 +++++++++++++++--------- libavcodec/cbs_jpeg.c | 8 +++++--- libavcodec/cbs_mpeg2.c | 8 +++++--- libavcodec/cbs_vp8.c | 8 +++++--- libavcodec/cbs_vp9.c | 8 +++++--- 9 files changed, 83 insertions(+), 43 deletions(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 39411d4cf5..b9c9284f3d 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -114,6 +114,7 @@ av_cold int CBS_FUNC(init)(CodedBitstreamContext **ctx_ptr, ctx->log_ctx = log_ctx; ctx->codec = type; /* Must be before any error */ + ctx->force_refcounting = 1; if (type->priv_data_size) { ctx->priv_data = av_mallocz(ctx->codec->priv_data_size); @@ -216,7 +217,7 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx, av_refstruct_unref(&unit->content_ref); unit->content = NULL; - av_assert0(unit->data && unit->data_ref); + av_assert0(unit->data); err = ctx->codec->read_unit(ctx, unit); if (err == AVERROR(ENOSYS)) { @@ -267,7 +268,10 @@ static int cbs_read_data(CodedBitstreamContext *ctx, { int err; - if (buf) { + if (!ctx->force_refcounting) { + frag->data = (uint8_t*)data; + frag->data_size = size; + } else if (buf) { frag->data_ref = av_buffer_ref(buf); if (!frag->data_ref) return AVERROR(ENOMEM); @@ -856,9 +860,13 @@ int CBS_FUNC(append_unit_data)(CodedBitstreamFragment *frag, uint8_t *data, size_t data_size, const AVBufferRef *data_buf) { - AVBufferRef *data_ref = av_buffer_ref(data_buf); - if (!data_ref) - return AVERROR(ENOMEM); + AVBufferRef *data_ref = NULL; + + if (data_buf) { + data_ref = av_buffer_ref(data_buf); + if (!data_ref) + return AVERROR(ENOMEM); + } return cbs_insert_unit_data(frag, type, data, data_size, data_ref, @@ -990,11 +998,9 @@ static int cbs_clone_noncomplex_unit_content(void **clonep, continue; } if (!src_buf) { - // We can't handle a non-refcounted pointer here - we don't - // have enough information to handle whatever structure lies - // at the other end of it. - err = AVERROR(EINVAL); - goto fail; + // Both original and copy point to the same data and + // neither are refcounted. + continue; } *copy_buf = av_buffer_ref(src_buf); diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index 958b00cc05..40159d3c6d 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -100,7 +100,7 @@ typedef struct CodedBitstreamUnit { /** * A reference to the buffer containing data. * - * Must be set if data is not NULL. + * If unset, it is the user's responsibility to ensure that data stays valid. */ AVBufferRef *data_ref; @@ -147,7 +147,7 @@ typedef struct CodedBitstreamFragment { /** * A reference to the buffer containing data. * - * Must be set if data is not NULL. + * If unset, it is the user's responsibility to ensure that data stays valid. */ AVBufferRef *data_ref; @@ -258,6 +258,22 @@ typedef struct CodedBitstreamContext { */ int nb_decompose_unit_types; + /** + * If set (the default), CBS will ensure that CodedBitstreamUnit.data + * and CodedBitstreamFragment.data are valid indefinitely by setting + * the corresponding data_ref (this involves copying non-refcounted data + * to newly allocated buffers). + * If unset, it is the user's responsibility to ensure that CodedBitstreamUnit.data + * and CodedBitstreamFragment.data stays valid long enough. CBS will try + * to avoid creating references and copying data. + * + * This flag does not influence whether buffers allocated by CBS are + * refcounted (they always are). Also, CBS will still ensure that + * non-transient data (kept in the codec-specific private data) is always + * valid indefinitely. + */ + int force_refcounting; + /** * Enable trace output during read/write operations. */ @@ -460,7 +476,7 @@ int CBS_FUNC(insert_unit_content)(CodedBitstreamFragment *frag, /** * Add a new unit to a fragment with the given data bitstream. * - * data must be owned by data_buf (which must be provided); + * If data_buf is provided, data must be owned by data_buf; * ownership of the reference stays with the caller. */ int CBS_FUNC(append_unit_data)(CodedBitstreamFragment *frag, diff --git a/libavcodec/cbs_apv.c b/libavcodec/cbs_apv.c index ebf57d3bbb..ddc363fbf3 100644 --- a/libavcodec/cbs_apv.c +++ b/libavcodec/cbs_apv.c @@ -276,12 +276,14 @@ static int cbs_apv_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - // Each tile inside the frame has pointers into the unit - // data buffer; make a single reference here for all of - // them together. - frame->tile_data_ref = av_buffer_ref(unit->data_ref); - if (!frame->tile_data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + // Each tile inside the frame has pointers into the unit + // data buffer; make a single reference here for all of + // them together. + frame->tile_data_ref = av_buffer_ref(unit->data_ref); + if (!frame->tile_data_ref) + return AVERROR(ENOMEM); + } } break; case APV_PBU_ACCESS_UNIT_INFORMATION: diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c index 4edb6ecd50..40c3cc8167 100644 --- a/libavcodec/cbs_av1.c +++ b/libavcodec/cbs_av1.c @@ -824,9 +824,11 @@ static int cbs_av1_ref_tile_data(CodedBitstreamContext *ctx, // Must be byte-aligned at this point. av_assert0(pos % 8 == 0); - *data_ref = av_buffer_ref(unit->data_ref); - if (!*data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + *data_ref = av_buffer_ref(unit->data_ref); + if (!*data_ref) + return AVERROR(ENOMEM); + } *data = unit->data + pos / 8; *data_size = unit->data_size - pos / 8; diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 369e3ac876..45b0c2ce87 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -902,9 +902,11 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, len = unit->data_size; slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if (!slice->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + slice->data_ref = av_buffer_ref(unit->data_ref); + if (!slice->data_ref) + return AVERROR(ENOMEM); + } slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; } @@ -1039,9 +1041,11 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, len = unit->data_size; slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if (!slice->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + slice->data_ref = av_buffer_ref(unit->data_ref); + if (!slice->data_ref) + return AVERROR(ENOMEM); + } slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; } @@ -1205,9 +1209,11 @@ static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx, slice->header_size = pos / 8; slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if (!slice->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + slice->data_ref = av_buffer_ref(unit->data_ref); + if (!slice->data_ref) + return AVERROR(ENOMEM); + } slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; } diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c index 281606e7af..cfb9b6d46c 100644 --- a/libavcodec/cbs_jpeg.c +++ b/libavcodec/cbs_jpeg.c @@ -255,9 +255,11 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, av_assert0(pos % 8 == 0); if (pos > 0) { scan->data_size = unit->data_size - pos / 8; - scan->data_ref = av_buffer_ref(unit->data_ref); - if (!scan->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + scan->data_ref = av_buffer_ref(unit->data_ref); + if (!scan->data_ref) + return AVERROR(ENOMEM); + } scan->data = unit->data + pos / 8; } diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c index 37fc28a4e6..4b51647b13 100644 --- a/libavcodec/cbs_mpeg2.c +++ b/libavcodec/cbs_mpeg2.c @@ -234,9 +234,11 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, len = unit->data_size; slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if (!slice->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + slice->data_ref = av_buffer_ref(unit->data_ref); + if (!slice->data_ref) + return AVERROR(ENOMEM); + } slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; diff --git a/libavcodec/cbs_vp8.c b/libavcodec/cbs_vp8.c index 1f80f34faf..9bfba71d9e 100644 --- a/libavcodec/cbs_vp8.c +++ b/libavcodec/cbs_vp8.c @@ -344,9 +344,11 @@ static int cbs_vp8_read_unit(CodedBitstreamContext *ctx, pos = (pos + 7) / 8; av_assert0(pos <= unit->data_size); - frame->data_ref = av_buffer_ref(unit->data_ref); - if (!frame->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + frame->data_ref = av_buffer_ref(unit->data_ref); + if (!frame->data_ref) + return AVERROR(ENOMEM); + } frame->data = unit->data + pos; frame->data_size = unit->data_size - pos; diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c index ff99fe32fb..3ca52770f3 100644 --- a/libavcodec/cbs_vp9.c +++ b/libavcodec/cbs_vp9.c @@ -460,9 +460,11 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, if (pos == unit->data_size) { // No data (e.g. a show-existing-frame frame). } else { - frame->data_ref = av_buffer_ref(unit->data_ref); - if (!frame->data_ref) - return AVERROR(ENOMEM); + if (unit->data_ref) { + frame->data_ref = av_buffer_ref(unit->data_ref); + if (!frame->data_ref) + return AVERROR(ENOMEM); + } frame->data = unit->data + pos; frame->data_size = unit->data_size - pos; -- 2.45.2
From 62e5f78289f53ed14aa55fdc593b3cdffa6b369b Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:11:56 +0200 Subject: [PATCH 07/11] avcodec/apv_parser: Don't use dummy AVBufferRef* Use the new CodedBitstreamContext.force_refcounting instead. This achieves the same aim as 0cabfdc8bc324891e4301c96940bca39d504cfbf, but in a cleaner way. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/apv_parser.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/libavcodec/apv_parser.c b/libavcodec/apv_parser.c index fdd575339b..f3cc9dd669 100644 --- a/libavcodec/apv_parser.c +++ b/libavcodec/apv_parser.c @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/avassert.h" -#include "libavutil/buffer.h" - #include "avcodec.h" #include "apv.h" #include "cbs.h" @@ -37,11 +34,6 @@ static const enum AVPixelFormat apv_format_table[5][5] = { { AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_YUVA444P16 }, }; -static void dummy_free(void *opaque, uint8_t *data) -{ - av_assert0(opaque == data); -} - static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -49,20 +41,14 @@ static int parse(AVCodecParserContext *s, { APVParseContext *p = s->priv_data; CodedBitstreamFragment *au = &p->au; - AVBufferRef *ref = NULL; int ret; *poutbuf = buf; *poutbuf_size = buf_size; - ref = av_buffer_create((uint8_t *)buf, buf_size, dummy_free, - (void *)buf, AV_BUFFER_FLAG_READONLY); - if (!ref) - return buf_size; - p->cbc->log_ctx = avctx; - ret = ff_cbs_read(p->cbc, au, ref, buf, buf_size); + ret = ff_cbs_read(p->cbc, au, NULL, buf, buf_size); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to parse access unit.\n"); goto end; @@ -106,8 +92,6 @@ static int parse(AVCodecParserContext *s, end: ff_cbs_fragment_reset(au); - av_assert1(av_buffer_get_ref_count(ref) == 1); - av_buffer_unref(&ref); p->cbc->log_ctx = NULL; return buf_size; @@ -128,6 +112,7 @@ static av_cold int init(AVCodecParserContext *s) p->cbc->decompose_unit_types = decompose_unit_types; p->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types); + p->cbc->force_refcounting = 0; return 0; } -- 2.45.2
From fd131ce99ecaaf3881d11ce7478b5be66cb059d5 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:14:29 +0200 Subject: [PATCH 08/11] Revert "avcodec/cbs: add an AVBufferRef input argument to ff_cbs_read()" This reverts commit 4bfe9c56632a3ccdcd5c1d0c415cda0111639bf1. It is no longer necessary, as the only user (the APV parser) no longer makes use of this facility. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/apv_parser.c | 2 +- libavcodec/av1_parser.c | 2 +- libavcodec/cbs.c | 5 ++--- libavcodec/cbs.h | 1 - libavcodec/vulkan_encode_h264.c | 2 +- libavcodec/vulkan_encode_h265.c | 2 +- libavcodec/vvc_parser.c | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/libavcodec/apv_parser.c b/libavcodec/apv_parser.c index f3cc9dd669..c940ebe9c1 100644 --- a/libavcodec/apv_parser.c +++ b/libavcodec/apv_parser.c @@ -48,7 +48,7 @@ static int parse(AVCodecParserContext *s, p->cbc->log_ctx = avctx; - ret = ff_cbs_read(p->cbc, au, NULL, buf, buf_size); + ret = ff_cbs_read(p->cbc, au, buf, buf_size); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to parse access unit.\n"); goto end; diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c index 1792e813f4..2b79493bf8 100644 --- a/libavcodec/av1_parser.c +++ b/libavcodec/av1_parser.c @@ -82,7 +82,7 @@ static int av1_parser_parse(AVCodecParserContext *ctx, ff_cbs_fragment_reset(td); } - ret = ff_cbs_read(s->cbc, td, NULL, data, size); + ret = ff_cbs_read(s->cbc, td, data, size); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n"); goto end; diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index b9c9284f3d..a43d938a54 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -262,7 +262,7 @@ static int cbs_fill_fragment_data(CodedBitstreamFragment *frag, static int cbs_read_data(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, - const AVBufferRef *buf, + AVBufferRef *buf, const uint8_t *data, size_t size, int header) { @@ -333,10 +333,9 @@ int CBS_FUNC(read_packet_side_data)(CodedBitstreamContext *ctx, int CBS_FUNC(read)(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, - const AVBufferRef *buf, const uint8_t *data, size_t size) { - return cbs_read_data(ctx, frag, buf, + return cbs_read_data(ctx, frag, NULL, data, size, 0); } #endif diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index 40159d3c6d..a2651cb43a 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -395,7 +395,6 @@ int CBS_FUNC(read_packet)(CodedBitstreamContext *ctx, */ int CBS_FUNC(read)(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, - const AVBufferRef *buf, const uint8_t *data, size_t size); diff --git a/libavcodec/vulkan_encode_h264.c b/libavcodec/vulkan_encode_h264.c index f31b6d4069..0f2b23a908 100644 --- a/libavcodec/vulkan_encode_h264.c +++ b/libavcodec/vulkan_encode_h264.c @@ -1061,7 +1061,7 @@ static int parse_feedback_units(AVCodecContext *avctx, if (err < 0) return err; - err = ff_cbs_read(cbs, &au, NULL, data, size); + err = ff_cbs_read(cbs, &au, data, size); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n", av_err2str(err)); diff --git a/libavcodec/vulkan_encode_h265.c b/libavcodec/vulkan_encode_h265.c index d81d2de95a..77d4f7101d 100644 --- a/libavcodec/vulkan_encode_h265.c +++ b/libavcodec/vulkan_encode_h265.c @@ -1214,7 +1214,7 @@ static int parse_feedback_units(AVCodecContext *avctx, if (err < 0) return err; - err = ff_cbs_read(cbs, &au, NULL, data, size); + err = ff_cbs_read(cbs, &au, data, size); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Unable to parse feedback units, bad drivers: %s\n", av_err2str(err)); diff --git a/libavcodec/vvc_parser.c b/libavcodec/vvc_parser.c index c9c3a3949f..8d32d66573 100644 --- a/libavcodec/vvc_parser.c +++ b/libavcodec/vvc_parser.c @@ -357,7 +357,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, return 1; } - if ((ret = ff_cbs_read(ctx->cbc, pu, NULL, buf, buf_size)) < 0) { + if ((ret = ff_cbs_read(ctx->cbc, pu, buf, buf_size)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to parse picture unit.\n"); goto end; } -- 2.45.2
From 820583769749e3af48e62fe98674267e37a68ca8 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:36:51 +0200 Subject: [PATCH 09/11] avcodec/av1_parser: Avoid copying data Disable forcing refcounting; this is possible because the data's lifetime is known to include the whole lifetime of the fragment (which is contained in one call to the parser). Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/av1_parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c index 2b79493bf8..77e1b161b6 100644 --- a/libavcodec/av1_parser.c +++ b/libavcodec/av1_parser.c @@ -196,6 +196,7 @@ static av_cold int av1_parser_init(AVCodecParserContext *ctx) s->cbc->decompose_unit_types = decompose_unit_types; s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types); + s->cbc->force_refcounting = 0; return 0; } -- 2.45.2
From 5d83793cb5754e4589c287f948d6fd592cc5beb9 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Mon, 5 May 2025 20:54:21 +0200 Subject: [PATCH 10/11] avcodec/cbs_bsf: Avoid creating unnecessary references Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/cbs_bsf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/cbs_bsf.c b/libavcodec/cbs_bsf.c index b25285483b..784114c475 100644 --- a/libavcodec/cbs_bsf.c +++ b/libavcodec/cbs_bsf.c @@ -119,6 +119,8 @@ int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type) if (err < 0) return err; + ctx->input->force_refcounting = 0; + err = ff_cbs_init(&ctx->output, type->codec_id, bsf); if (err < 0) return err; -- 2.45.2
From 98156827df040a885d274f0ea89973e14d3aa210 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Tue, 6 May 2025 01:30:41 +0200 Subject: [PATCH 11/11] avcodec/bsf/trace_headers: Avoid creating unnecessary references Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/bsf/trace_headers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/bsf/trace_headers.c b/libavcodec/bsf/trace_headers.c index 8781f5f100..9b967007a6 100644 --- a/libavcodec/bsf/trace_headers.c +++ b/libavcodec/bsf/trace_headers.c @@ -46,6 +46,7 @@ static int trace_headers_init(AVBSFContext *bsf) ctx->cbc->trace_level = AV_LOG_INFO; ctx->cbc->trace_context = ctx->cbc; ctx->cbc->trace_read_callback = ff_cbs_trace_read_log; + ctx->cbc->force_refcounting = 0; if (bsf->par_in->extradata) { CodedBitstreamFragment *frag = &ctx->fragment; -- 2.45.2
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".