PR #25104 opened by romainhedouin
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25104
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25104.patch

compute_contrast_change() restarted its search at 0 for every histogram bin, 
making it quadratic in the histogram size. Both histograms are cumulative, so 
the search position never has to move back.

1080p, per frame:
16-bit 3.1 s -> 9 ms
12-bit 16 -> 4 ms
8-bit is unchanged
I also added the FATE test that proves that the output is unchanged. Let me 
know if I shouldn't have.

Found during a code review sweep of ffmpeg using an LLM.

Signed-off-by: romainhedouin <[email protected]>

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->



>From 3efaa75d65066058c651b40985dcb33d44947ca7 Mon Sep 17 00:00:00 2001
From: romainhedouin <[email protected]>
Date: Thu, 15 Oct 2026 19:48:04 +0200
Subject: [PATCH] avfilter/vf_midequalizer: Don't restart the search for every
 bin

compute_contrast_change() restarted its search at 0 for every histogram
bin, making it quadratic in the histogram size. Both histograms are
cumulative, so the search position never has to move back.

1080p, per frame: 16-bit 3.1 s -> 9 ms, 12-bit 16 -> 4 ms; 8-bit is
unchanged.
I also added the FATE test that proves that the output is unchanged.

Found during a code review sweep of ffmpeg using an LLM.

Signed-off-by: romainhedouin <[email protected]>
---
 libavfilter/vf_midequalizer.c      |  7 +++----
 tests/fate/filter-video.mak        |  3 +++
 tests/ref/fate/filter-midequalizer | 10 ++++++++++
 3 files changed, 16 insertions(+), 4 deletions(-)
 create mode 100644 tests/ref/fate/filter-midequalizer

diff --git a/libavfilter/vf_midequalizer.c b/libavfilter/vf_midequalizer.c
index 9720cefdf2..86bebdbbe5 100644
--- a/libavfilter/vf_midequalizer.c
+++ b/libavfilter/vf_midequalizer.c
@@ -172,12 +172,11 @@ static void compute_histogram16(const uint16_t *src, 
ptrdiff_t linesize,
 static void compute_contrast_change(float *histogram1, float *histogram2,
                                     unsigned *cchange, size_t hsize)
 {
-    int i;
+    int i, j = 0;
 
+    // both histograms are cumulative, so j never has to move back
     for (i = 0; i < hsize; i++) {
-        int j;
-
-        for (j = 0; j < hsize && histogram2[j] < histogram1[i]; j++);
+        for (; j < hsize && histogram2[j] < histogram1[i]; j++);
 
         cchange[i] = (i + j) / 2;
     }
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index ebbc0a7d1c..59dd6c20b9 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -1009,6 +1009,9 @@ fate-filter-xfade-slideup16: CMD = framecrc 
-filter_complex "color=c=red:s=8x8:r
 FATE_FILTER-$(call FILTERFRAMECRC, COLOR XFADE FORMAT) += 
fate-filter-xfade-duration0
 fate-filter-xfade-duration0: CMD = framecrc -filter_complex 
"color=c=red:s=8x8:r=8:d=4,format=yuv444p[a];color=c=0x0000ff:s=8x8:r=8:d=4,format=yuv444p[b];[a][b]xfade=transition=squeezeh:offset=1:duration=0"
 
+FATE_FILTER-$(call FILTERFRAMECRC, NULLSRC GEQ FORMAT MIDEQUALIZER) += 
fate-filter-midequalizer
+fate-filter-midequalizer: CMD = framecrc -filter_complex 
"nullsrc=s=64x48:r=5:d=1,format=yuv420p10le,geq=lum=mod(X*X+Y*3+N*17\,1024):cb=mod(X*5+Y\,1024):cr=mod(X+Y*9\,1024)[a];nullsrc=s=64x48:r=5:d=1,format=yuv420p10le,geq=lum=min(1023\,X*Y):cb=mod(X*Y\,1024):cr=mod(X*3\,512)[b];[a][b]midequalizer"
 -pix_fmt yuv420p10le
+
 FATE_SAMPLES_FFPROBE += $(FATE_METADATA_FILTER-yes)
 FATE_SAMPLES_FFMPEG += $(FATE_FILTER_SAMPLES-yes)
 FATE_FFPROBE += $(FATE_FILTER_FFPROBE-yes)
diff --git a/tests/ref/fate/filter-midequalizer 
b/tests/ref/fate/filter-midequalizer
new file mode 100644
index 0000000000..b11335f360
--- /dev/null
+++ b/tests/ref/fate/filter-midequalizer
@@ -0,0 +1,10 @@
+#tb 0: 1/5
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 64x48
+#sar 0: 1/1
+0,          0,          0,        1,     9216, 0xee42116f
+0,          1,          1,        1,     9216, 0xb8f11c88
+0,          2,          2,        1,     9216, 0xcedd2a7f
+0,          3,          3,        1,     9216, 0x66872ec0
+0,          4,          4,        1,     9216, 0x615138f0
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to