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

ProRes RAW software decoding produces incorrect pixels on AVX2-capable x86-64 
systems because the shared ProRes DSP initializer selects transposed 
coefficients for the regular 12-bit AVX2 iDCT, while RAW decoding calls the 
natural-order Bayer C iDCT.

Add `ff_prores_rawdsp_init()` to select the Bayer callback and its identity 
permutation together. Regular ProRes CPU dispatch remains unchanged. Remove the 
obsolete comment describing the RAW iDCT as 12-bit.

Fixes #25461. The regression was verified at 3b3be6e58fb0 against its parent 
7bcb37ac2000.

Validation used frame 0 of `4.2K23.976ProResRAWHQ.mov`, the public sample 
linked from #20298. Before the fix, default x86-64 decoding produces 
`940bad34124c61b32670dc38dd3b8019`, while `-cpuflags -avx2` produces 
`f024d374258798806f71a8ea242d3943`. After the fix, both produce the latter 
hash, matching the parent commit and an unmodified AArch64 master build. The 
issue also reproduces on release/9.1 at 11e9765e94a0.

All nine ProRes FATE decode tests and `fate-checkasm-proresdsp` pass. Vulkan's 
quantization-matrix conversion was checked for consistency with the identity 
permutation in source; Vulkan decoding was not runtime-tested.


>From 24fe02c02c9c2ef255f909a3d4d0ee50840581cd Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 28 Oct 2026 00:10:14 +0000
Subject: [PATCH] avcodec/prores_raw: initialize DSP independently of regular
 ProRes

The 12-bit ProRes AVX2 IDCT uses transposed coefficients, but the
ProRes RAW Bayer IDCT expects natural order. Sharing the regular
ProRes initializer makes RAW decoding use the wrong scan and quantizer
layout on AVX2-capable x86-64 systems.

Add a RAW DSP initializer that selects the Bayer IDCT and its matching
permutation together. Leave regular ProRes CPU dispatch unchanged.
Remove the obsolete description of the RAW IDCT as 12-bit.

Verified the regression at 3b3be6e58fb0 against its parent using frame 0
of 4.2K23.976ProResRAWHQ.mov linked in PR #20298. Default and -avx2
CPU flags now both produce f024d374258798806f71a8ea242d3943, matching
the parent commit and an AArch64 build. All nine ProRes FATE decode
tests and fate-checkasm-proresdsp pass.

Fixes: 3b3be6e58fb07c8177ef6aa4fe28ebbb7b57eaa1
Fixes: #25461
Reported-by: Hyperlite-Media
Assisted-by: Fairy
---
 libavcodec/prores_raw.c | 4 +---
 libavcodec/proresdsp.c  | 9 ++++++++-
 libavcodec/proresdsp.h  | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c
index 36c3879f73d..4b653cd2b50 100644
--- a/libavcodec/prores_raw.c
+++ b/libavcodec/prores_raw.c
@@ -58,9 +58,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     s->pix_fmt = AV_PIX_FMT_NONE;
 
     ff_blockdsp_init(&s->bdsp);
-    /* Coefficients and the iDCT are 12-bit, the linearization curve then
-     * expands the result to the 16-bit linear output range. */
-    ff_proresdsp_init(&s->prodsp, 12);
+    ff_prores_rawdsp_init(&s->prodsp);
 
     ff_permute_scantable(s->scan, ff_prores_interlaced_scan, 
s->prodsp.idct_permutation);
 
diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c
index 919a5d67972..f7a1b9c999d 100644
--- a/libavcodec/proresdsp.c
+++ b/libavcodec/proresdsp.c
@@ -177,7 +177,6 @@ av_cold void ff_proresdsp_init(ProresDSPContext *dsp, int 
bits_per_raw_sample)
     } else {
         av_assert1(bits_per_raw_sample == 12);
         dsp->idct_put = prores_idct_put_12_c;
-        dsp->idct_put_bayer = prores_idct_put_bayer_12_c;
         dsp->idct_permutation_type = FF_IDCT_PERM_NONE;
     }
 
@@ -188,3 +187,11 @@ av_cold void ff_proresdsp_init(ProresDSPContext *dsp, int 
bits_per_raw_sample)
     ff_init_scantable_permutation(dsp->idct_permutation,
                                   dsp->idct_permutation_type);
 }
+
+av_cold void ff_prores_rawdsp_init(ProresDSPContext *dsp)
+{
+    dsp->idct_put_bayer = prores_idct_put_bayer_12_c;
+    dsp->idct_permutation_type = FF_IDCT_PERM_NONE;
+    ff_init_scantable_permutation(dsp->idct_permutation,
+                                 dsp->idct_permutation_type);
+}
diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h
index 75c782fb563..00aeaf02731 100644
--- a/libavcodec/proresdsp.h
+++ b/libavcodec/proresdsp.h
@@ -35,6 +35,7 @@ typedef struct ProresDSPContext {
 } ProresDSPContext;
 
 void ff_proresdsp_init(ProresDSPContext *dsp, int bits_per_raw_sample);
+void ff_prores_rawdsp_init(ProresDSPContext *dsp);
 
 void ff_proresdsp_init_x86(ProresDSPContext *dsp, int bits_per_raw_sample);
 
-- 
2.54.0

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

Reply via email to