This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit faa7c882cb86334aa962340451e087c30e063d31 Author: Lynne <[email protected]> AuthorDate: Sun Sep 20 23:39:32 2026 +0900 Commit: Lynne <[email protected]> CommitDate: Thu Sep 24 08:02:22 2026 +0900 prores_raw: use the 16-bit iDCT The decoder converted the 32-bit output of its transform to 16 bits through an empirically found offset, and added one to every DC coefficient to compensate for the bias of the result. Neither reproduces the transform well: against a bit-exact model of the reference decoder, most samples are off, with a quantizer-dependent bias and errors of up to 357 out of 65535 at the extremes of the range, and the DC offset only helps on HQ material. Use the 16-bit output variant of simple_idct instead, with the dequantized coefficients saturated to 16 bits as the reference does, and the centered transform output biased in the output stage. Against an exact transform, the error drops from 5.6 LSB RMS with a maximum of 21 to 0.49 LSB RMS with a maximum of 2.3 and no bias, on par with the reference decoder's 0.29 and 2.4. The decoded output agrees with the reference decoder on 95% of the samples of a 5.7K RAW HQ frame with a log curve, within 3.5 LSB of a 14-bit sensor in its top stop and within 1 LSB elsewhere. Speed is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_016LFnYMstwe4woBzpxfzDzg --- libavcodec/prores_raw.c | 4 ++-- libavcodec/proresdsp.c | 28 ++++++++++++---------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index dc11b14331..36c3879f73 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -185,7 +185,7 @@ static int decode_comp(AVCodecContext *avctx, TileContext *tile, if (dc < 0) goto end; int prev_dc = (dc >> 1) ^ -(dc & 1); - block[0] = prev_dc + 1; + block[0] = prev_dc; for (int n = 1; n < nb_blocks; n++) { if ((n & 15) == 1) @@ -202,7 +202,7 @@ static int decode_comp(AVCodecContext *avctx, TileContext *tile, sign = dc_add < 0; prev_dc += dc_add; - block[n*64] = prev_dc + 1; + block[n*64] = prev_dc; } for (int n = nb_blocks; n < nb_codes;) { diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c index cf4aa9d0cf..919a5d6797 100644 --- a/libavcodec/proresdsp.c +++ b/libavcodec/proresdsp.c @@ -42,9 +42,9 @@ #undef BIT_DEPTH #undef IN_IDCT_DEPTH -/* 32bit iDCT for the ProRes RAW */ +/* 16-bit iDCT for ProRes RAW */ #define IN_IDCT_DEPTH 32 -#define BIT_DEPTH 12 +#define BIT_DEPTH 16 #include "simple_idct_template.c" #undef BIT_DEPTH #undef IN_IDCT_DEPTH @@ -83,21 +83,18 @@ static void prores_idct_12(int16_t *restrict block, const int16_t *restrict qmat } /* - * 32-bit iDCT for the ProRes RAW - * qmat must be s->qmat[i] * scale + * ProRes RAW iDCT: 16-bit coefficients to a 16-bit output centered on zero */ -static void prores_idct_bayer_32(int32_t *restrict block, const int16_t *restrict qmat) +static void prores_idct_bayer_16(int32_t *restrict block, const int16_t *restrict qmat) { for (int i = 0; i < 64; i++) - block[i] = (block[i] * qmat[i]) >> 1; + block[i] = av_clip_int16(block[i] * qmat[i]); for (int i = 0; i < 8; i++) - idctRowCondDC_int32_12bit(block + i*8, 0); + idctRowCondDC_int32_16bit(block + i*8, 0); - for (int i = 0; i < 8; i++) { - block[i] += 8192; - idctSparseCol_int32_12bit(block + i); - } + for (int i = 0; i < 8; i++) + idctSparseCol_int32_16bit(block + i); } #define CLIP_MIN (1 << 2) ///< minimum value for clipping resulting pixels @@ -131,10 +128,9 @@ static inline void put_pixel_bayer_lin_curve_12(uint16_t *dst, ptrdiff_t linesiz { for (int y = 0; y < 8; y++, dst += linesize) { for (int x = 0; x < 8; x++) { - /* Convert the 32-bit input into 16-bits (lrintf(x*16 - 15.5f) = 16) */ - int u = av_clip_uint16(in[(y << 3) + x]*16 - 16); - uint32_t seg = (uint32_t)u >> 13; - uint32_t frac = (uint32_t)u & 0x1FFF; + uint32_t u = av_clip_uint16(in[(y << 3) + x] + 32768); + uint32_t seg = u >> 13; + uint32_t frac = u & 0x1FFF; uint32_t cp0 = lin_curve[seg]; uint32_t cp1 = seg < 7 ? lin_curve[seg + 1] : 0; uint32_t o = (cp0 * 8192 + ((cp1 - cp0) & 0xFFFF) * frac + 4096) >> 13; @@ -169,7 +165,7 @@ static void prores_idct_put_bayer_12_c(uint16_t *out, ptrdiff_t linesize, int32_t *block, const int16_t *qmat, const uint16_t *lin_curve) { - prores_idct_bayer_32(block, qmat); + prores_idct_bayer_16(block, qmat); put_pixel_bayer_lin_curve_12(out, linesize << 1, block, lin_curve); } -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
