PR #25134 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25134 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25134.patch
>From 79bf5a7c6942fc0dfb9e3c29699536a63d4a4932 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:06:47 +0200 Subject: [PATCH 01/38] ffplay: avoid signed overflow of the chapter shuffle seed Volunteer for testing welcome Fixes: Qc9DRRq5X1KU Fixes: signed integer overflow Signed integer overflow Replicated through Modified FFmpeg with UBSAN Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24589 --- fftools/ffplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/ffplay.c b/fftools/ffplay.c index a280ed3abe..712931f69d 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -1159,7 +1159,7 @@ static void chapter_sort_by(int key, int seed_step) while (chapter_sort[i].key != key) i++; if (key == CHAPTER_SORT_SHUFFLE) - chapter_shuffle_seed += seed_step; + chapter_shuffle_seed = (unsigned)chapter_shuffle_seed + seed_step; else if (i == 0) chapter_sort[0].descending ^= 1; if (i == 0) -- 2.54.0 >From f2fd14ec17e68770b3975e26f676147ae8727921 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 03:33:38 +0200 Subject: [PATCH 02/38] avcodec/dvbsubenc: reject rects wider or higher than 65535 Region width and height are 16 bit fields (ETSI EN 300 743, 7.2.3); Fixes: tOTDK93gpiC1 Fixes: out of array write Fixes: signed integer overflow Out of array write Replicated through API with ASAN Signed integer overflow Replicated through API with UBSAN Region width truncated to 16 bits Replicated through API with plain output check Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24913 --- libavcodec/dvbsubenc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c index b6e31ab933..062f93412b 100644 --- a/libavcodec/dvbsubenc.c +++ b/libavcodec/dvbsubenc.c @@ -302,6 +302,10 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, if (h->num_rects >= 256) return AVERROR(EINVAL); + for (i = 0; i < h->num_rects; i++) + if (h->rects[i]->w > 0xFFFF || h->rects[i]->h > 0xFFFF) + return AVERROR(EINVAL); + if (avctx->width > 0 && avctx->height > 0) { if (buf_size < 11) return AVERROR_BUFFER_TOO_SMALL; -- 2.54.0 >From 5d9d93a8d11c72ee20888b186e2f232099d7f02b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 03:33:38 +0200 Subject: [PATCH 03/38] avcodec/dvbsubenc: assert that the rect dimensions and nb_colors are in range A negative width, height or nb_colors, or more colors than the 256 entry palette holds, is caller misuse. Fixes: tOTDK93gpiC1 Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24913 --- libavcodec/dvbsubenc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c index 062f93412b..b4d4c8d14f 100644 --- a/libavcodec/dvbsubenc.c +++ b/libavcodec/dvbsubenc.c @@ -21,6 +21,7 @@ #include "avcodec.h" #include "bytestream.h" #include "codec_internal.h" +#include "libavutil/avassert.h" #include "libavutil/colorspace.h" #include "libavutil/opt.h" @@ -302,9 +303,12 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, if (h->num_rects >= 256) return AVERROR(EINVAL); - for (i = 0; i < h->num_rects; i++) + for (i = 0; i < h->num_rects; i++) { + av_assert0(h->rects[i]->w >= 0 && h->rects[i]->h >= 0 && + h->rects[i]->nb_colors >= 0 && h->rects[i]->nb_colors <= 256); if (h->rects[i]->w > 0xFFFF || h->rects[i]->h > 0xFFFF) return AVERROR(EINVAL); + } if (avctx->width > 0 && avctx->height > 0) { if (buf_size < 11) -- 2.54.0 >From 29747427f1ebe6498d1b98af823336b80f36a17e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Fri, 16 Oct 2026 19:49:04 +0200 Subject: [PATCH 04/38] avcodec/dvbsubenc: compute the line budget of the RLE coders in 64 bit Fixes: tOTDK93gpiC1 Fixes: signed integer overflow Signed integer overflow Replicated through API with UBSAN Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24913 --- libavcodec/dvbsubenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c index b4d4c8d14f..e40199472b 100644 --- a/libavcodec/dvbsubenc.c +++ b/libavcodec/dvbsubenc.c @@ -55,7 +55,7 @@ static int dvb_encode_rle2(uint8_t **pq, int buf_size, for(y = 0; y < h; y++) { // Worst case line is 3 bits per value + 4 bytes overhead - if (buf_size * 8 < w * 3 + 32) + if (buf_size * 8LL < w * 3 + 32) return AVERROR_BUFFER_TOO_SMALL; line_begin = q; *q++ = 0x10; @@ -150,7 +150,7 @@ static int dvb_encode_rle4(uint8_t **pq, int buf_size, for(y = 0; y < h; y++) { // Worst case line is 6 bits per value, + 4 bytes overhead - if (buf_size * 8 < w * 6 + 32) + if (buf_size * 8LL < w * 6 + 32) return AVERROR_BUFFER_TOO_SMALL; line_begin = q; *q++ = 0x11; @@ -223,7 +223,7 @@ static int dvb_encode_rle8(uint8_t **pq, int buf_size, for (y = 0; y < h; y++) { // Worst case line is 12 bits per value, + 4 bytes overhead - if (buf_size * 8 < w * 12 + 32) + if (buf_size * 8LL < w * 12 + 32) return AVERROR_BUFFER_TOO_SMALL; line_begin = q; *q++ = 0x12; -- 2.54.0 >From d121d521345504a1039b74fbf86e5162dde0fd90 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:06:48 +0200 Subject: [PATCH 05/38] avcodec/encode: assert that the subtitle buffer size is not negative A negative size is caller misuse. Fixes: 1JEyyg9rrIOc Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24913 --- libavcodec/encode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 6fbbe86d8f..c690505ec1 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -209,6 +209,7 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); return -1; } + av_assert0(buf_size >= 0); ret = ffcodec(avctx->codec)->cb.encode_sub(avctx, buf, buf_size, sub); avctx->frame_num++; -- 2.54.0 >From b2cd7df2056ca2fe035ec4d73abf5e85446e8613 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:06:59 +0200 Subject: [PATCH 06/38] swscale/graph: copy the palette of a PAL8 frame as a whole Fixes: NwCWHv3RIJff Fixes: missing palette Missing palette Replicated through API with a plain output check Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24851 --- libswscale/graph.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libswscale/graph.c b/libswscale/graph.c index 5a5d469a51..3468087d50 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -290,6 +290,12 @@ static void run_copy(const SwsFrame *out, const SwsFrame *in, int y, int h, const int lines = h >> ff_fmt_vshift(in->format, i); av_assert1(in_data[i]); + if (i == 1 && av_pix_fmt_desc_get(in->format)->flags & AV_PIX_FMT_FLAG_PAL) { + if (!y && in->data[1] != out->data[1]) + memcpy(out->data[1], in->data[1], AVPALETTE_SIZE); + break; + } + if (in_data[i] == out_data[i]) { av_assert0(in->linesize[i] == out->linesize[i]); } else if (in->linesize[i] == out->linesize[i]) { -- 2.54.0 >From 2139efdd89ca9de17eef7dd336333ceab0c7101c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:06:59 +0200 Subject: [PATCH 07/38] swscale: allocate every plane the frame pool provides Fixes: NwCWHv3RIJff Fixes: missing palette Missing palette Replicated through API with a plain output check Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24851 --- libswscale/swscale.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 070b0f5939..8e10061199 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1282,8 +1282,7 @@ static int frame_alloc_buffers(SwsContext *sws, AVFrame *frame) buf_start++; int nb_bufs = 0; - const int nb_planes = av_pix_fmt_count_planes(frame->format); - for (int i = 0; i < nb_planes; i++) { + for (int i = 0; i < 4 && pool->pools[i]; i++) { if (frame->data[i]) continue; /* already ref'd by frame_ref */ -- 2.54.0 >From f08ba2df4f69f9ecac5cef1c1582c61169cfa085 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:24:19 +0200 Subject: [PATCH 08/38] avfilter/vf_showinfo: free the frame when av_image_get_linesize() fails Fixes: lJDYwsOtMQXY Fixes: memleak Memleak Replicated through UnModified FFmpeg with LSan Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/vf_showinfo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 9aec0b6004..d81bd0fede 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -779,8 +779,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) int linesize = av_image_get_linesize(frame->format, frame->width, plane); int width = linesize >> (bitdepth > 8); - if (linesize < 0) + if (linesize < 0) { + av_frame_free(&frame); return linesize; + } for (i = 0; i < h; i++) { plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize); -- 2.54.0 >From 81a98cde6a7475a279c85ddc683f5c4d348e9a40 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:24:19 +0200 Subject: [PATCH 09/38] avfilter/vf_showinfo: do not checksum hardware frames Fixes: lJDYwsOtMQXY Fixes: EINVAL on every hardware frame EINVAL on every hardware frame Replicated through UnModified FFmpeg with plain output Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/vf_showinfo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index d81bd0fede..ecd3459e0d 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -772,8 +772,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) int bitdepth = desc->comp[0].depth; int be = desc->flags & AV_PIX_FMT_FLAG_BE; int i, plane, vsub = desc->log2_chroma_h; + int calculate_checksums = s->calculate_checksums && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL); - for (plane = 0; plane < 4 && s->calculate_checksums && frame->data[plane] && frame->linesize[plane]; plane++) { + for (plane = 0; plane < 4 && calculate_checksums && frame->data[plane] && frame->linesize[plane]; plane++) { uint8_t *data = frame->data[plane]; int h = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(frame->height, vsub) : frame->height; int linesize = av_image_get_linesize(frame->format, frame->width, plane); @@ -809,7 +810,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) !!(frame->flags & AV_FRAME_FLAG_KEY), av_get_picture_type_char(frame->pict_type)); - if (s->calculate_checksums) { + if (calculate_checksums) { av_log(ctx, AV_LOG_INFO, "checksum:%08"PRIX32" plane_checksum:[%08"PRIX32, checksum, plane_checksum[0]); -- 2.54.0 >From e70d82bb9dfaeeff63d2114eb6ded3a8fc0d3333 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:31:14 +0200 Subject: [PATCH 10/38] avfilter/vf_lcevc: free the input frame when sending it to the decoder fails Fixes: qchet66gqCBs Fixes: memleak Memleak Replicated through UnModified FFmpeg with LSan, LCEVC_SendDecoderBase() failing through an LD_PRELOAD shim Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/vf_lcevc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_lcevc.c b/libavfilter/vf_lcevc.c index 4ccd5ba659..01e5ded900 100644 --- a/libavfilter/vf_lcevc.c +++ b/libavfilter/vf_lcevc.c @@ -350,8 +350,10 @@ static int activate(AVFilterContext *ctx) } ret = send_frame(inlink, in); - if (ret < 0) + if (ret < 0) { + av_frame_free(&in); return ret; + } } out = ff_get_video_buffer(outlink, lcevc->w, lcevc->h); -- 2.54.0 >From 52ada082017045138b7b969ddc29837d189cb4a2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:32:26 +0200 Subject: [PATCH 11/38] avfilter/vf_libopencv: stop at the end of the shape file without stepping past it Fixes: XPtsDsDMo2NW Fixes: pointer formed two past the mapping Pointer formed two past the mapping Replicated through Modified FFmpeg with an assertion Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24753 --- libavfilter/vf_libopencv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index cdfa678860..c94a1ac48f 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -180,7 +180,9 @@ static int read_shape_from_file(int *cols, int *rows, int **values, const char * pend = buf + size-1; for (i = 0; i < *rows; i++) { for (j = 0;; j++) { - if (p > pend || *p == '\n') { + if (p > pend) + break; + if (*p == '\n') { p++; break; } else -- 2.54.0 >From 6e269ecf72f546557590e00cc0cdf7ebc9ee77c0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:50 +0200 Subject: [PATCH 12/38] avfilter/dnn_backend_openvino: do not free the input layouts twice Fixes: o7gnt6oof6Qd Fixes: use after free Heap use after free after an allocation failure Replicated through UnModified FFmpeg with ASAN, the allocation failure injected through an LD_PRELOAD shim Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_openvino.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index a5c3be835d..633a419040 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -802,7 +802,9 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * ov_preprocess_input_model_info_free(input_model_info); input_model_info = NULL; ov_layout_free(NCHW_layout); + NCHW_layout = NULL; ov_layout_free(NHWC_layout); + NHWC_layout = NULL; #else if (ctx->batch_size > 1) { input_shapes_t input_shapes; -- 2.54.0 >From 751932118e1d78d17a18942759040169f514597e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:50 +0200 Subject: [PATCH 13/38] avfilter/dnn_backend_openvino: return an error when creating an inference request fails Fixes: cE2BMN6svM0X Fixes: success reported after a failure Success reported after a failure Replicated through UnModified FFmpeg with LSan Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_openvino.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 633a419040..b7a5a93f61 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -917,6 +917,7 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * status = ov_compiled_model_create_infer_request(ov_model->compiled_model, &item->infer_request); if (status != OK) { av_log(ctx, AV_LOG_ERROR, "Failed to Creates an inference request object.\n"); + ret = ov2_map_error(status, NULL); goto err; } #else -- 2.54.0 >From ff08385704c011aa6d16107a6640e7e5d9e2c054 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:50 +0200 Subject: [PATCH 14/38] avfilter/dnn_backend_openvino: wait only for the inference requests that were created Fixes: nC3u8khGyx61 Fixes: hang on teardown Hang on teardown Replicated through UnModified FFmpeg with gdb Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_openvino.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index b7a5a93f61..ed6552667b 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -62,6 +62,7 @@ typedef struct OVModel{ Queue *task_queue; // holds TaskItem Queue *lltask_queue; // holds LastLevelTaskItem int nb_outputs; + int nb_requests; } OVModel; // one request for one call to openvino @@ -516,7 +517,7 @@ static void dnn_free_model_ov(DNNModel **model) return; ov_model = (OVModel *)(*model); - ff_dnn_wait_requests(ov_model->request_queue, ov_model->ctx->nireq); + ff_dnn_wait_requests(ov_model->request_queue, ov_model->nb_requests); while (ff_safe_queue_size(ov_model->request_queue) != 0) { OVRequestItem *item = ff_safe_queue_pop_front(ov_model->request_queue); if (item && item->infer_request) { @@ -912,6 +913,7 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * ret = AVERROR(ENOMEM); goto err; } + ov_model->nb_requests++; #if HAVE_OPENVINO2 status = ov_compiled_model_create_infer_request(ov_model->compiled_model, &item->infer_request); -- 2.54.0 >From 86d85cbcb38c537aadedb810910d7af5079af82a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:51 +0200 Subject: [PATCH 15/38] avfilter/dnn_backend_openvino: do not dereference output_names when the ports are looked up by index Fixes: O0Cm42dvrP4l Fixes: NULL pointer dereference NULL pointer dereference Replicated through UnModified FFmpeg with UBSAN and gdb Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_openvino.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index ed6552667b..d195ee14f8 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -780,7 +780,7 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * status = ov_model_const_output_by_index(ov_model->ov_model, i, &ov_model->output_ports[i]); if (status != OK) { - av_log(ctx, AV_LOG_ERROR, "Failed to get output port %s.\n", output_names[i]); + av_log(ctx, AV_LOG_ERROR, "Failed to get output port %d.\n", i); ret = ov2_map_error(status, NULL); goto err; } -- 2.54.0 >From f92b0141dfabea1a723a170445039c9545023c0d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:51 +0200 Subject: [PATCH 16/38] avfilter/dnn_backend_openvino: free the frames when execution fails before the task is queued This is not a security issue. Fixes: 6HSeekmc6mV7 Fixes: 8YwigyLd85Gn Fixes: swarm-Memory-leak-of-input-output-frames-on-ff_dnn_execute_model-failure-3a5cbe Fixes: memleak Memory leak Replicated through UnModified FFmpeg with LSan Found-by: zhang xingxing <[email protected]> --- libavfilter/dnn/dnn_backend_openvino.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index d195ee14f8..e9c0e8571a 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -1504,26 +1504,28 @@ static int dnn_execute_model_ov(const DNNModel *model, DNNExecBaseParams *exec_p exec_params->output_names, exec_params->nb_output); if (ret != 0) { av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO executable network or inference request\n"); - return ret; + goto fail; } } task = av_malloc(sizeof(*task)); if (!task) { av_log(ctx, AV_LOG_ERROR, "unable to alloc memory for task item.\n"); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } ret = ff_dnn_fill_task(task, exec_params, ov_model, ctx->async, 1); if (ret != 0) { av_freep(&task); - return ret; + goto fail; } if (ff_queue_push_back(ov_model->task_queue, task) < 0) { av_freep(&task); av_log(ctx, AV_LOG_ERROR, "unable to push back task_queue.\n"); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } ret = extract_lltask_from_task(model->func_type, task, ov_model->lltask_queue, exec_params); @@ -1568,6 +1570,10 @@ static int dnn_execute_model_ov(const DNNModel *model, DNNExecBaseParams *exec_p } return execute_model_ov(request, ov_model->lltask_queue); } +fail: + av_frame_free(&exec_params->in_frame); + av_frame_free(&exec_params->out_frame); + return ret; } static DNNAsyncStatusType dnn_get_result_ov(const DNNModel *model, AVFrame **in, AVFrame **out) -- 2.54.0 >From 32680f1cb28a8b78ed7a38f7b761c9fc37a9f920 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:51 +0200 Subject: [PATCH 17/38] avfilter/dnn_backend_tf: wait only for the inference requests that were created Fixes: nC3u8khGyx61 Fixes: hang on teardown Hang on teardown Replicated through UnModified FFmpeg with gdb Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_tf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c index 110ae2c509..c292a14efe 100644 --- a/libavfilter/dnn/dnn_backend_tf.c +++ b/libavfilter/dnn/dnn_backend_tf.c @@ -44,6 +44,7 @@ typedef struct TFModel { SafeQueue *request_queue; Queue *lltask_queue; Queue *task_queue; + int nb_requests; } TFModel; /** @@ -486,7 +487,7 @@ static void dnn_free_model_tf(DNNModel **model) return; tf_model = (TFModel *)(*model); - ff_dnn_wait_requests(tf_model->request_queue, tf_model->ctx->nireq); + ff_dnn_wait_requests(tf_model->request_queue, tf_model->nb_requests); while (ff_safe_queue_size(tf_model->request_queue) != 0) { TFRequestItem *item = ff_safe_queue_pop_front(tf_model->request_queue); destroy_request_item(&item); @@ -567,6 +568,7 @@ static DNNModel *dnn_load_model_tf(DnnContext *ctx, DNNFunctionType func_type, A destroy_request_item(&item); goto err; } + tf_model->nb_requests++; } tf_model->lltask_queue = ff_queue_create(); -- 2.54.0 >From c244b2092b4176f7f22e4e0e6b61baaf9cd27d8f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:10:51 +0200 Subject: [PATCH 18/38] avfilter/dnn_backend_torch: wait only for the inference requests that were created Fixes: nC3u8khGyx61 Fixes: hang on teardown Hang on teardown Replicated through UnModified FFmpeg with gdb Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617 --- libavfilter/dnn/dnn_backend_torch.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/dnn/dnn_backend_torch.cpp b/libavfilter/dnn/dnn_backend_torch.cpp index 1ecf95e938..59ab0a9c72 100644 --- a/libavfilter/dnn/dnn_backend_torch.cpp +++ b/libavfilter/dnn/dnn_backend_torch.cpp @@ -50,6 +50,7 @@ typedef struct THModel { SafeQueue *request_queue; Queue *task_queue; Queue *lltask_queue; + int nb_requests; } THModel; typedef struct THInferRequest { @@ -130,7 +131,7 @@ static void dnn_free_model_th(DNNModel **model) th_model = (THModel *)(*model); if (th_model->request_queue) { - ff_dnn_wait_requests(th_model->request_queue, th_model->ctx->nireq); + ff_dnn_wait_requests(th_model->request_queue, th_model->nb_requests); while (ff_safe_queue_size(th_model->request_queue) != 0) { THRequestItem *item = (THRequestItem *)ff_safe_queue_pop_front(th_model->request_queue); destroy_request_item(&item); @@ -676,6 +677,7 @@ static DNNModel *dnn_load_model_th(DnnContext *ctx, DNNFunctionType func_type, A if (ff_safe_queue_push_back(th_model->request_queue, item) < 0) { goto fail; } + th_model->nb_requests++; item = NULL; } -- 2.54.0 >From 41e028f8d76bab2d32f4b76d855ceb36f588fa5c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:52:20 +0200 Subject: [PATCH 19/38] avformat/assenc: do not read the event beyond the packet Fixes: FJdNqUYeEkPS Fixes: wrong event text Wrong event text Replicated through UnModified FFmpeg with plain output diff Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24659 --- libavformat/assenc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavformat/assenc.c b/libavformat/assenc.c index b948203885..e121ceb632 100644 --- a/libavformat/assenc.c +++ b/libavformat/assenc.c @@ -155,15 +155,19 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) long int layer; int text_len; - char *p = pkt->data; + char *text = av_strndup(pkt->data, pkt->size); + char *p = text; int64_t start = pkt->pts; int64_t end = start + pkt->duration; int hh1, mm1, ss1, ms1; int hh2, mm2, ss2, ms2; DialogueLine *dialogue = av_mallocz(sizeof(*dialogue)); - if (!dialogue) + if (!text || !dialogue) { + av_free(text); + av_free(dialogue); return AVERROR(ENOMEM); + } dialogue->readorder = strtol(p, &p, 10); if (dialogue->readorder < ass->expected_readorder) @@ -192,6 +196,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) dialogue->line = av_asprintf("%s%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%.*s", ass->ssa_mode ? "Marked=" : "", layer, hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, text_len, p); + av_free(text); if (!dialogue->line) { av_free(dialogue); return AVERROR(ENOMEM); -- 2.54.0 >From 1feedcb163ae11710f150e7fe8f23519faf40550 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:52:20 +0200 Subject: [PATCH 20/38] avcodec/assdec: do not copy the event beyond the packet av_strdup() reads up to the first NUL, which for a laced Matroska block lies in the next event. Fixes: hVJyTegWPmu6 Fixes: wrong event text Wrong event text Replicated through UnModified FFmpeg with plain output diff Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24659 --- libavcodec/assdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c index 89d7b51894..28aebd4d0e 100644 --- a/libavcodec/assdec.c +++ b/libavcodec/assdec.c @@ -54,7 +54,7 @@ static int ass_decode_frame(AVCodecContext *avctx, AVSubtitle *sub, return AVERROR(ENOMEM); sub->num_rects = 1; sub->rects[0]->type = SUBTITLE_ASS; - sub->rects[0]->ass = av_strdup(avpkt->data); + sub->rects[0]->ass = av_strndup(avpkt->data, avpkt->size); if (!sub->rects[0]->ass) return AVERROR(ENOMEM); *got_sub_ptr = 1; -- 2.54.0 >From fc652a7fb0a653c82b67e9ad6231ab72837567c7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:52:20 +0200 Subject: [PATCH 21/38] avformat/aviobuf: retry the read after AVERROR(EAGAIN) Fixes: 3Fn44aM2tqIx Fixes: infinite loop Infinite loop Replicated through UnModified FFmpeg with a nonblocking pipe and timeout Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24909 --- libavformat/aviobuf.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index edbbc5ffd6..43431381b9 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -520,6 +520,11 @@ static void fill_buffer(AVIOContext *s) s->buf_end : s->buffer; int len = s->buffer_size - (dst - s->buffer); + if (s->error == AVERROR(EAGAIN)) { + s->error = 0; + s->eof_reached = 0; + } + /* can't fill the buffer without read_packet, just set EOF if appropriate */ if (!s->read_packet && s->buf_ptr >= s->buf_end) s->eof_reached = 1; @@ -622,6 +627,10 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size) if (len == 0 || s->write_flag) { if((s->direct || size > s->buffer_size) && !s->update_checksum && s->read_packet) { // bypass the buffer and read data directly into buf + if (s->error == AVERROR(EAGAIN)) { + s->error = 0; + s->eof_reached = 0; + } len = read_packet_wrapper(s, buf, size); if (len == AVERROR_EOF) { /* do not modify buffer if EOF reached so that a seek back can -- 2.54.0 >From 0710fe7f2ff5ae9d1ec3549c9329b3e38b382222 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:52:20 +0200 Subject: [PATCH 22/38] avformat/rtpenc_h263_rfc2190: check the return of init_get_bits8() Fixes: OEXYJTpBYJPS Fixes: NULL pointer dereference NULL pointer dereference Replicated through API with ASAN Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24916 --- libavformat/rtpenc_h263_rfc2190.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/rtpenc_h263_rfc2190.c b/libavformat/rtpenc_h263_rfc2190.c index 590cbc75b6..9ba865cd7e 100644 --- a/libavformat/rtpenc_h263_rfc2190.c +++ b/libavformat/rtpenc_h263_rfc2190.c @@ -111,8 +111,8 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, s->timestamp = s->cur_timestamp; - init_get_bits8(&gb, buf, FFMIN(size, 6)); - if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */ + if (init_get_bits8(&gb, buf, FFMIN(size, 6)) >= 0 && + get_bits(&gb, 22) == 0x20) { /* Picture Start Code */ info.tr = get_bits(&gb, 8); skip_bits(&gb, 2); /* PTYPE start, H.261 disambiguation */ skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */ -- 2.54.0 >From b462aaaa0ef370a1406412ba53f7855471db03b7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:52:21 +0200 Subject: [PATCH 23/38] avdevice/v4l2: copy compressed frames out of the mmap buffers A packet referencing a driver buffer has no AV_INPUT_BUFFER_PADDING_SIZE Fixes: 7ZY4JenXTFy4 Fixes: out of array read Out of array read Replicated through UnModified FFmpeg with v4l2loopback and an LD_PRELOAD guard page behind the mmap buffers Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24659 --- libavdevice/v4l2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 2ca093b7b0..4d42a3f5de 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -604,7 +604,8 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) } /* Image is at s->buf_data[buf.index].start */ - if (atomic_load(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) { + if (atomic_load(&s->buffers_queued) == FFMAX(s->buffers / 8, 1) || + ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { /* when we start getting low on queued buffers, fall back on copying data */ res = av_new_packet(pkt, bytesused); if (res < 0) { -- 2.54.0 >From 4221157bec0b58f022d44f9dc596c0bb16fa1f9c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:35:56 +0200 Subject: [PATCH 24/38] avcodec/tdsc: store the cursor hotspot only after the cursor header is accepted A rejected cursor header moved the retained cursor sprite to its hotspot. Fixes: 18O8mbD0uiX8 Fixes: wrong cursor position Wrong cursor position Replicated through UnModified FFmpeg with output diff Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24682 --- libavcodec/tdsc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c index 976b67b8f9..cc075bf9b2 100644 --- a/libavcodec/tdsc.c +++ b/libavcodec/tdsc.c @@ -199,11 +199,11 @@ static void tdsc_paint_cursor(AVCodecContext *avctx, uint8_t *dst, int stride) static int tdsc_load_cursor(AVCodecContext *avctx) { TDSCContext *ctx = avctx->priv_data; - int i, j, k, ret, cursor_fmt, w, h; + int i, j, k, ret, cursor_fmt, w, h, hot_x, hot_y; uint8_t *dst; - ctx->cursor_hot_x = bytestream2_get_le16(&ctx->gbc); - ctx->cursor_hot_y = bytestream2_get_le16(&ctx->gbc); + hot_x = bytestream2_get_le16(&ctx->gbc); + hot_y = bytestream2_get_le16(&ctx->gbc); w = bytestream2_get_le16(&ctx->gbc); h = bytestream2_get_le16(&ctx->gbc); @@ -221,6 +221,8 @@ static int tdsc_load_cursor(AVCodecContext *avctx) ctx->cursor_w = w; ctx->cursor_h = h; ctx->cursor_stride = FFALIGN(w, 32) * 4; + ctx->cursor_hot_x = hot_x; + ctx->cursor_hot_y = hot_y; if (ctx->cursor_hot_x > ctx->cursor_w || ctx->cursor_hot_y > ctx->cursor_h) { av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d.%d.\n", -- 2.54.0 >From 44e52c0832653b1887be89cf0b91255315291dce Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:35:56 +0200 Subject: [PATCH 25/38] avcodec/mpegvideo_enc: return the error code of encode_picture() The error was replaced by -1, shown to the user as EPERM. Fixes: PUUZOCCqIPbY Fixes: wrong error code Wrong error code Replicated through UnModified FFmpeg with ffmpeg command line Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24758 --- libavcodec/mpegvideo_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 08d7aa59b7..4ea5064a6a 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1969,7 +1969,7 @@ vbv_retry: pkt->size = avctx->internal->byte_buffer_size; } if (ret < 0) - return -1; + return ret; frame_end(m); -- 2.54.0 >From 2a9ffa09d205270e0107ae4a0df666c754b5ca63 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:36:47 +0200 Subject: [PATCH 26/38] avcodec/flicvideo: byte swap FLI_BRUN pixels of 15/16 bpp FLX as they are decoded on big endian Fixes: 7jy6fSNHGagi Fixes: wrong output on big endian Wrong output on big endian Replicated through UnModified FFmpeg with qemu-s390x output diff Found during triage of the security report bQcit4JdHaHN Found again by the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24901 --- libavcodec/flicvideo.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index b8157c0e51..21f861dd3a 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -850,7 +850,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { - pixels[pixel_ptr++] = palette_idx1; + pixels[pixel_ptr++ ^ HAVE_BIGENDIAN] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n", @@ -863,7 +863,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { palette_idx1 = bytestream2_get_byte(&g2); - pixels[pixel_ptr++] = palette_idx1; + pixels[pixel_ptr++ ^ HAVE_BIGENDIAN] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", @@ -871,21 +871,6 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } } - - /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. - * This does not give us any good opportunity to perform word endian conversion - * during decompression. So if it is required (i.e., this is not a LE target, we do - * a second pass over the line here, swapping the bytes. - */ -#if HAVE_BIGENDIAN - pixel_ptr = y_ptr; - pixel_countdown = s->avctx->width; - while (pixel_countdown > 0) { - *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&pixels[pixel_ptr]); - pixel_ptr += 2; - pixel_countdown--; - } -#endif y_ptr += s->frame->linesize[0]; } break; -- 2.54.0 >From 784c9447c1ea194c10f700428f8ab70df779e793 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:41:32 +0200 Subject: [PATCH 27/38] avcodec/targa: clear the palette entries the colormap does not cover Fixes: p05Q9unwy6Vp Fixes: use of uninitialized palette entries Use of uninitialized palette entries Replicated through UnModified FFmpeg (--enable-memory-poisoning) with valgrind Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24597 --- libavcodec/targa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 10092ab3cb..22bd225f34 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -200,6 +200,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p, return ret; p->pict_type = AV_PICTURE_TYPE_I; + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) + memset(p->data[1], 0, AVPALETTE_SIZE); + if (flags & TGA_TOPTOBOTTOM) { dst = p->data[0]; stride = p->linesize[0]; -- 2.54.0 >From 2d04b4fe52630dfd002a9816100b83dc68f014c2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:42:36 +0200 Subject: [PATCH 28/38] avcodec/xan: start each frame from the previous one Fixes: jL900fW1VfPh Fixes: use of uninitialized pixels Use of uninitialized pixels Replicated through UnModified FFmpeg (--enable-memory-poisoning) with valgrind Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24626 --- libavcodec/xan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 416e33c420..cb6cac03e4 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -617,6 +617,12 @@ static int xan_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (!s->frame_size) s->frame_size = frame->linesize[0] * s->avctx->height; + if (s->last_frame->data[0]) { + if ((ret = av_frame_copy(frame, s->last_frame)) < 0) + return ret; + } else + memset(frame->data[0], 0, s->frame_size); + memcpy(frame->data[1], s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE); -- 2.54.0 >From 82656cf9896d23d981786677c1a0256abb584d64 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:23:33 +0200 Subject: [PATCH 29/38] avfilter/vf_cropdetect: scan the edge map inside the motion bounding box The fate-filter-metadata-cropdetect1/2 references change as the scans now stop at the edge free lines next to the box. Fixes: s7zfKOCXo4MJ Fixes: wrong crop area with mode=mvedges Wrong crop area with mode=mvedges Replicated through UnModified FFmpeg with a plain output diff Found during triage of the security report VoiiaDYyhdfz Found again by the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24623 --- libavfilter/vf_cropdetect.c | 14 ++++++++------ tests/ref/fate/filter-metadata-cropdetect1 | 6 +++--- tests/ref/fate/filter-metadata-cropdetect2 | 14 +++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 3aa0c1477d..f85a7690fd 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -337,9 +337,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) scan_w = s->x2 - s->x1; scan_h = s->y2 - s->y1; -#define FIND_EDGE(DST, FROM, NOEND, INC, STEP0, STEP1, LEN) \ +#define FIND_EDGE(DST, FROM, NOEND, INC, BASE, STEP0, STEP1, LEN) \ for (last_y = y = FROM; NOEND; y = y INC) { \ - if (checkline_edge(ctx, tmpbuf + STEP0 * y, STEP1, LEN)) { \ + if (checkline_edge(ctx, BASE + STEP0 * y, STEP1, LEN)) { \ if (last_y INC == y) { \ DST = y; \ break; \ @@ -351,10 +351,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) DST = y -(INC); \ } - FIND_EDGE(s->y1, s->y1, y >= 0, -1, inw, 1, scan_w); - FIND_EDGE(s->y2, s->y2, y < inh, +1, inw, 1, scan_w); - FIND_EDGE(s->x1, s->x1, y >= 0, -1, 1, inw, scan_h); - FIND_EDGE(s->x2, s->x2, y < inw, +1, 1, inw, scan_h); + const uint8_t *rows = tmpbuf + s->x1; + const uint8_t *cols = tmpbuf + s->y1 * inw; + FIND_EDGE(s->y1, s->y1, y >= 0, -1, rows, inw, 1, scan_w); + FIND_EDGE(s->y2, s->y2, y < inh, +1, rows, inw, 1, scan_w); + FIND_EDGE(s->x1, s->x1, y >= 0, -1, cols, 1, inw, scan_h); + FIND_EDGE(s->x2, s->x2, y < inw, +1, cols, 1, inw, scan_h); // queue bboxes bboff = (s->frame_nb - 1) % s->window_size; diff --git a/tests/ref/fate/filter-metadata-cropdetect1 b/tests/ref/fate/filter-metadata-cropdetect1 index 25c80ccebc..1f02632fc2 100644 --- a/tests/ref/fate/filter-metadata-cropdetect1 +++ b/tests/ref/fate/filter-metadata-cropdetect1 @@ -1,9 +1,9 @@ pts=0 pts=1001 -pts=2002|tag:lavfi.cropdetect.y=314|tag:lavfi.cropdetect.x1=20|tag:lavfi.cropdetect.x2=851|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=601|tag:lavfi.cropdetect.w=832|tag:lavfi.cropdetect.h=288|tag:lavfi.cropdetect.x=20|tag:lavfi.cropdetect.limit=0.094118 -pts=3003|tag:lavfi.cropdetect.y=316|tag:lavfi.cropdetect.x1=20|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=864|tag:lavfi.cropdetect.h=304|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 +pts=2002|tag:lavfi.cropdetect.y=314|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=661|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=601|tag:lavfi.cropdetect.w=656|tag:lavfi.cropdetect.h=288|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 +pts=3003|tag:lavfi.cropdetect.y=316|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=304|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 pts=4004|tag:lavfi.cropdetect.y=122|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=115|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=496|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 -pts=5005|tag:lavfi.cropdetect.y=316|tag:lavfi.cropdetect.x1=20|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=864|tag:lavfi.cropdetect.h=304|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 +pts=5005|tag:lavfi.cropdetect.y=316|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=311|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=304|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 pts=6006|tag:lavfi.cropdetect.y=122|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=115|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=496|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 pts=7007|tag:lavfi.cropdetect.y=122|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=115|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=496|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 pts=8008|tag:lavfi.cropdetect.y=122|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=885|tag:lavfi.cropdetect.y1=115|tag:lavfi.cropdetect.y2=621|tag:lavfi.cropdetect.w=880|tag:lavfi.cropdetect.h=496|tag:lavfi.cropdetect.x=4|tag:lavfi.cropdetect.limit=0.094118 diff --git a/tests/ref/fate/filter-metadata-cropdetect2 b/tests/ref/fate/filter-metadata-cropdetect2 index a27577b99b..d8c8f778db 100644 --- a/tests/ref/fate/filter-metadata-cropdetect2 +++ b/tests/ref/fate/filter-metadata-cropdetect2 @@ -1,10 +1,10 @@ pts=0 pts=512 -pts=1024|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1221|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1200|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 +pts=1024|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1215|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1184|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 pts=1536|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1257|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1232|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=24|tag:lavfi.cropdetect.limit=0.094118 -pts=2048|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1221|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1200|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 -pts=2560|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1221|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1200|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 -pts=3072|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=912|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 -pts=3584|tag:lavfi.cropdetect.y=40|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=38|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=896|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 -pts=4096|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=912|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 -pts=4608|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1221|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1200|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=22|tag:lavfi.cropdetect.limit=0.094118 +pts=2048|tag:lavfi.cropdetect.y=22|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1215|tag:lavfi.cropdetect.y1=15|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1184|tag:lavfi.cropdetect.h=1088|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 +pts=2560|tag:lavfi.cropdetect.y=42|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1215|tag:lavfi.cropdetect.y1=37|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1184|tag:lavfi.cropdetect.h=1072|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 +pts=3072|tag:lavfi.cropdetect.y=40|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=37|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=896|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 +pts=3584|tag:lavfi.cropdetect.y=42|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=40|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=896|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 +pts=4096|tag:lavfi.cropdetect.y=40|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=817|tag:lavfi.cropdetect.y1=37|tag:lavfi.cropdetect.y2=937|tag:lavfi.cropdetect.w=784|tag:lavfi.cropdetect.h=896|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 +pts=4608|tag:lavfi.cropdetect.y=42|tag:lavfi.cropdetect.x1=21|tag:lavfi.cropdetect.x2=1215|tag:lavfi.cropdetect.y1=37|tag:lavfi.cropdetect.y2=1116|tag:lavfi.cropdetect.w=1184|tag:lavfi.cropdetect.h=1072|tag:lavfi.cropdetect.x=28|tag:lavfi.cropdetect.limit=0.094118 -- 2.54.0 >From 129153bc474712b4c9477f49de8ffc0158256968 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 30/38] avfilter/af_alimiter: convert the attack, release and asc_level options where they are used Fixes: fZnlZKlJmMn0 Fixes: wrong release time and asc level after a command Wrong release time and asc level after a command Replicated through UnModified FFmpeg with a plain output diff Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24672 --- libavfilter/af_alimiter.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libavfilter/af_alimiter.c b/libavfilter/af_alimiter.c index 8ef6d74afd..7318d5d446 100644 --- a/libavfilter/af_alimiter.c +++ b/libavfilter/af_alimiter.c @@ -97,22 +97,19 @@ static av_cold int init(AVFilterContext *ctx) { AudioLimiterContext *s = ctx->priv; - s->attack /= 1000.; - s->release /= 1000.; s->att = 1.; s->asc_pos = -1; - s->asc_coeff = pow(0.5, s->asc_coeff - 0.5) * 2 * -1; return 0; } -static double get_rdelta(AudioLimiterContext *s, double release, int sample_rate, +static double get_rdelta(AudioLimiterContext *s, double release, double asc_coeff, int sample_rate, double peak, double limit, double patt, int asc) { double rdelta = (1.0 - patt) / (sample_rate * release); if (asc && s->auto_release && s->asc_c > 0) { - double a_att = limit / (s->asc_coeff * s->asc) * (double)s->asc_c; + double a_att = limit / (asc_coeff * s->asc) * (double)s->asc_c; if (a_att > patt) { double delta = FFMAX((a_att - patt) / (sample_rate * release), rdelta / 10); @@ -134,7 +131,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const int channels = inlink->ch_layout.nb_channels; const int buffer_size = s->buffer_size; double *dst, *buffer = s->buffer; - const double release = s->release; + const double release = s->release / 1000.; + const double asc_coeff = pow(0.5, s->asc_coeff - 0.5) * 2 * -1; const double limit = s->limit; double *nextdelta = s->nextdelta; double level = s->auto_level ? 1 / limit : 1; @@ -179,7 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (peak > limit) { double patt = FFMIN(limit / peak, 1.); - double rdelta = get_rdelta(s, release, inlink->sample_rate, + double rdelta = get_rdelta(s, release, asc_coeff, inlink->sample_rate, peak, limit, patt, 0); double delta = (limit / peak - s->att) / buffer_size * channels; int found = 0; @@ -240,7 +238,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if ((s->pos + channels) % buffer_size == nextpos[s->nextiter]) { if (s->auto_release) { - s->delta = get_rdelta(s, release, inlink->sample_rate, + s->delta = get_rdelta(s, release, asc_coeff, inlink->sample_rate, peak, limit, s->att, 1); if (s->nextlen > 1) { double ppeak = 0, pdelta; @@ -373,7 +371,7 @@ static int config_input(AVFilterLink *inlink) return AVERROR(ENOMEM); memset(s->nextpos, -1, obuffer_size * sizeof(*s->nextpos)); - s->buffer_size = inlink->sample_rate * s->attack * inlink->ch_layout.nb_channels; + s->buffer_size = inlink->sample_rate * (s->attack / 1000.) * inlink->ch_layout.nb_channels; s->buffer_size -= s->buffer_size % inlink->ch_layout.nb_channels; if (s->latency) s->in_trim = s->out_pad = s->buffer_size / inlink->ch_layout.nb_channels - 1; -- 2.54.0 >From d9d7c83d7cece821529fa73b6eccc8920845dbf4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 31/38] avfilter/af_alimiter: do not mark attack as a runtime option Fixes: MxIcMabVhhFR Fixes: command without effect Command without effect Replicated through UnModified FFmpeg with a plain output diff Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24672 --- libavfilter/af_alimiter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_alimiter.c b/libavfilter/af_alimiter.c index 7318d5d446..786f210bff 100644 --- a/libavfilter/af_alimiter.c +++ b/libavfilter/af_alimiter.c @@ -76,13 +76,14 @@ typedef struct AudioLimiterContext { } AudioLimiterContext; #define OFFSET(x) offsetof(AudioLimiterContext, x) -#define AF AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +#define AF A | AV_OPT_FLAG_RUNTIME_PARAM static const AVOption alimiter_options[] = { { "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_DOUBLE, {.dbl=1},.015625, 64, AF }, { "level_out", "set output level", OFFSET(level_out), AV_OPT_TYPE_DOUBLE, {.dbl=1},.015625, 64, AF }, { "limit", "set limit", OFFSET(limit), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0625, 1, AF }, - { "attack", "set attack", OFFSET(attack), AV_OPT_TYPE_DOUBLE, {.dbl=5}, 0.1, 80, AF }, + { "attack", "set attack", OFFSET(attack), AV_OPT_TYPE_DOUBLE, {.dbl=5}, 0.1, 80, A }, { "release", "set release", OFFSET(release), AV_OPT_TYPE_DOUBLE, {.dbl=50}, 1, 8000, AF }, { "asc", "enable asc", OFFSET(auto_release), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF }, { "asc_level", "set asc level", OFFSET(asc_coeff), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, AF }, -- 2.54.0 >From 8f976f7c7fe354f99641fec8f984544ae95c63a9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 32/38] avfilter: make a frame whose format differs from the link writable with av_frame_make_writable() Fixes: A3O7F4s10WXJ Fixes: EINVAL on a format change EINVAL on a format change Replicated through UnModified FFmpeg with a plain output diff Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/avfilter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 5be67bbf3f..d078e404ff 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1596,6 +1596,8 @@ int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe) switch (link->type) { case AVMEDIA_TYPE_VIDEO: + if (frame->format != link->format) + return av_frame_make_writable(frame); out = ff_get_video_buffer(link, frame->width, frame->height); break; case AVMEDIA_TYPE_AUDIO: -- 2.54.0 >From 5efee2a1a435b7094a4cf04ee80d48a979010e0d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 33/38] avfilter/f_perms: free the input frame when it cannot be made writable or cloned Fixes: 1MIkYBeZ4sTX Fixes: memleak Memory leak Replicated through Modified FFmpeg with LSan Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/f_perms.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavfilter/f_perms.c b/libavfilter/f_perms.c index 7c35ceb770..f9e86105ff 100644 --- a/libavfilter/f_perms.c +++ b/libavfilter/f_perms.c @@ -97,13 +97,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) in_perm == out_perm ? " (no-op)" : ""); if (in_perm == RO && out_perm == RW) { - if ((ret = ff_inlink_make_frame_writable(inlink, &frame)) < 0) + if ((ret = ff_inlink_make_frame_writable(inlink, &frame)) < 0) { + av_frame_free(&frame); return ret; + } out = frame; } else if (in_perm == RW && out_perm == RO) { out = av_frame_clone(frame); - if (!out) + if (!out) { + av_frame_free(&frame); return AVERROR(ENOMEM); + } } ret = ff_filter_frame(ctx->outputs[0], out); -- 2.54.0 >From b611be85c9e1fe7229ae8349b5fbca3639d8ea7b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 34/38] avfilter/vf_hqdn3d: forget the configured width when the buffers are freed Fixes: WDZyf7w7BNU1 Fixes: NULL pointer dereference NULL dereference after a failed allocation Replicated through API with ASAN Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765 --- libavfilter/vf_hqdn3d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 80495aaa27..3b46b6d4f8 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -254,6 +254,7 @@ static int config_input(AVFilterLink *inlink) int i, depth; uninit(inlink->dst); + s->width = 0; s->hsub = desc->log2_chroma_w; s->vsub = desc->log2_chroma_h; -- 2.54.0 >From 78fa3becc3e92303defd813bd9e2cbfe45359d62 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:25:02 +0200 Subject: [PATCH 35/38] avfilter/avfiltergraph: do not copy the channel layouts compared in swap_channel_layouts_on_filter() Fixes: ZcCsKQC5oFuJ Fixes: memleak Memory leak Replicated through UnModified FFmpeg with LSan Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24577 --- libavfilter/avfiltergraph.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 7b58883c65..13c9930295 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -1186,15 +1186,14 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) continue; for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) { - AVChannelLayout in_chlayout = { 0 }, out_chlayout = { 0 }; + AVChannelLayout in_chlayout = link->outcfg.channel_layouts->channel_layouts[0]; + AVChannelLayout out_chlayout = outlink->incfg.channel_layouts->channel_layouts[j]; int in_channels; int out_channels; int count_diff; int matched_channels, extra_channels; int score = 100000; - av_channel_layout_copy(&in_chlayout, &link->outcfg.channel_layouts->channel_layouts[0]); - av_channel_layout_copy(&out_chlayout, &outlink->incfg.channel_layouts->channel_layouts[j]); in_channels = in_chlayout.nb_channels; out_channels = out_chlayout.nb_channels; count_diff = out_channels - in_channels; @@ -1209,8 +1208,8 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) out_channels = FF_LAYOUT2COUNT(&out_chlayout); score -= 10000 + FFABS(out_channels - in_channels) + (in_channels > out_channels ? 10000 : 0); - av_channel_layout_uninit(&in_chlayout); - av_channel_layout_uninit(&out_chlayout); + in_chlayout = (AVChannelLayout){ 0 }; + out_chlayout = (AVChannelLayout){ 0 }; /* Let the remaining computation run, even if the score value is not altered */ } -- 2.54.0 >From e4f109eca62a565ce18b79cc41e73343461e3470 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:45:22 +0200 Subject: [PATCH 36/38] avcodec/aac/aacdec_usac: map USAC channel elements from the UsacConfig only Fixes: th6ELuT3oDwj Fixes: wrong channel mapping and rejected frames Wrong channel mapping and rejected frames Replicated through UnModified FFmpeg with plain output diff Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24677 Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24678 --- libavcodec/aac/aacdec_usac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 5c6d04226d..ec95d7b92a 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -619,6 +619,7 @@ int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx, m4ac->sampling_index = ff_aac_sample_rate_idx(m4ac->sample_rate); m4ac->sbr = sbr_ratio > 0; + m4ac->chan_config = 0; channel_config_idx = get_bits(gb, 5); /* channelConfigurationIndex */ if (!channel_config_idx) { @@ -1922,8 +1923,6 @@ static int parse_audio_preroll(AACDecContext *ac, GetBitContext *gb) if (ret < 0) { *m4ac = m4ac_bak; return ret; - } else { - ac->oc[1].m4ac.chan_config = 0; } /* 7.18.3.3 Bitrate adaption -- 2.54.0 >From bf9a0e435b0f8dade6aaca5364941ea0dc59645c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:45:22 +0200 Subject: [PATCH 37/38] avcodec/x86/hevc: keep the slack sample out of the copied last 3-tap sample Fixes: UTli3J4oj0BS Fixes: uninitialised value reports Uninitialised value reports Replicated through UnModified FFmpeg with valgrind Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24661 --- libavcodec/x86/hevc/pred.asm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/x86/hevc/pred.asm b/libavcodec/x86/hevc/pred.asm index 3d1feee89f..31b14b3e49 100644 --- a/libavcodec/x86/hevc/pred.asm +++ b/libavcodec/x86/hevc/pred.asm @@ -233,8 +233,8 @@ PRED_PLANAR 32, 3 %rep (%3) / 16 FILTER_3TAP_16 %1, %2, %%i %if %%i == (%3) - 16 - pxor m1, m0 ; last sample is copied, not - pand m1, m4 ; filtered; select it out of m1 as + pxor m0, m1 ; last sample is copied, not + pand m0, m4 ; filtered; select it out of m1 as pxor m0, m1 ; the dst has no room past it %endif movu [%1 + %%i], m0 @@ -259,7 +259,7 @@ cglobal hevc_ref_filter_3tap_%1x%1_8, 4, 6, 5, fleft, ftop, left, top mova m3, [pb_1] pcmpeqb m4, m4 - pslldq m4, 15 ; selects the copied last sample + psrldq m4, 1 ; clears the copied last sample FILTER_3TAP_ARRAY fleftq, leftq, %%n FILTER_3TAP_ARRAY ftopq, topq, %%n -- 2.54.0 >From 1ca2ee7b7e3dab76d73a8c219460e86de3606949 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 05:45:22 +0200 Subject: [PATCH 38/38] avcodec/riscv/vc1dsp: fix unescaping of an escape byte at the start of a vector chunk Fixes: 2ACIzt6ruKw2 Fixes: output mismatch Output mismatch Replicated through UnModified FFmpeg with checkasm under qemu-riscv64 Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24592 --- libavcodec/riscv/vc1dsp_rvv.S | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/riscv/vc1dsp_rvv.S b/libavcodec/riscv/vc1dsp_rvv.S index e54167c34f..1ff5991288 100644 --- a/libavcodec/riscv/vc1dsp_rvv.S +++ b/libavcodec/riscv/vc1dsp_rvv.S @@ -429,10 +429,10 @@ func ff_vc1_unescape_buffer_rvv, zve32x bgez t2, 4f # found an escape byte? vse8.v v16, (a2) - addi t2, t0, -2 + addi t2, t0, -1 add a2, a2, t0 2: - vslidedown.vx v8, v16, t2 + vslidedown.vx v8, v12, t2 sub a1, a1, t0 vslidedown.vi v12, v8, 1 add a0, a0, t0 @@ -449,7 +449,6 @@ func ff_vc1_unescape_buffer_rvv, zve32x vse8.v v16, (a2) addi t0, t2, 1 add a2, a2, t2 - addi t2, t2, -1 - vsetvli zero, t0, e8, m4, ta, ma + vsetivli zero, 2, e8, m4, ta, ma j 2b endfunc -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
