From 6dfaba896fddaea098abec8ac84ff67375a7c6f1 Mon Sep 17 00:00:00 2001 From: lusoris Date: Fri, 9 Oct 2026 18:19:54 +0200 Subject: [PATCH] avcodec/av1dec: remove the coding bias from exported chroma grain params export_film_grain() copied cb_mult, cb_luma_mult and cb_offset (and the Cr equivalents) straight from the bitstream, where they are coded with a bias of 128, 128 and 256. AVFilmGrainAOMParams holds them unbiased: the uv_offset documentation gives a range of [-256, 255], the AFGS1 parser in aom_film_grain.c subtracts the bias, the film grain synthesizer uses the values as signed multipliers and offsets, and libdav1d exports them unbiased. The AR coefficients a few lines above are already unbiased the same way. With -export_side_data film_grain and a hwaccel, the native decoder therefore exported values 128 or 256 higher than libdav1d for the same stream, and any consumer applying the exported grain scaled chroma noise wrong. Signed-off-by: lusoris (cherry picked from commit 2a8c6d30b934f9bd8429f96f605e5fc7c5751679) --- libavcodec/av1dec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index d614c8d68a..e4255d0745 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -1087,12 +1087,12 @@ static int export_film_grain(AVCodecContext *avctx, AVFrame *frame) aom->ar_coeffs_uv[1][i] = film_grain->ar_coeffs_cr_plus_128[i] - 128; } - aom->uv_mult[0] = film_grain->cb_mult; - aom->uv_mult[1] = film_grain->cr_mult; - aom->uv_mult_luma[0] = film_grain->cb_luma_mult; - aom->uv_mult_luma[1] = film_grain->cr_luma_mult; - aom->uv_offset[0] = film_grain->cb_offset; - aom->uv_offset[1] = film_grain->cr_offset; + aom->uv_mult[0] = film_grain->cb_mult - 128; + aom->uv_mult[1] = film_grain->cr_mult - 128; + aom->uv_mult_luma[0] = film_grain->cb_luma_mult - 128; + aom->uv_mult_luma[1] = film_grain->cr_luma_mult - 128; + aom->uv_offset[0] = film_grain->cb_offset - 256; + aom->uv_offset[1] = film_grain->cr_offset - 256; return 0; }