Hi Drew,

Thanks for the bug report!

On Mon, Aug 25, 2025 at 10:50 AM Drew Dunne via ffmpeg-devel <
ffmpeg-devel@ffmpeg.org> wrote:

> A solid color image of 8-bit YUV: Y=157, U=164, V=98.
>
> Specify the input as:
>
> Input range: MPEG
> In color matrix: BT470BG
> In color primaries: BT470M
> In color transfer characteristics: Gamma 28
>
> Output as:
> Out color range: JPEG
> Out color matrix: BT.709
> Out color primaries: BT.709
> Out color transfer characteristics: BT.709
>
> During the calculation you get:
>
> Input YUV:                             y=157,      u=164,      v-98
> Post-yuv2rgb BT.470BG:                 r=0.456055, g=0.684152, b=0.928606
> Post-apply gamma28 linear LUT:         r=0.110979, g=0.345494, b=0.812709
> Post-color rotation BT.470M to BT.709: r=-0.04161, g=0.384626, b=0.852400
> Post-apply Rec.709 delinear LUT:       r=-0.16382, g=0.615932, b=0.923793
> Post-rgb2yuv Rec.709 matrix:           y=120,      u=190,      v=25
>
> Where with this change, the delinear LUT output would be clamped to 0,
> so the result would be:
> r=0.000000, g=0.612390, b=0.918807 and a final output of
> y=129, u=185, v=46


So for those of us playing along, a repro looks like this:

$ hexdump /tmp/in.yuv
0000000 9d9d 9d9d 62a4
$ git diff
diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index e1f4725f635..512eb620fcf 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -348,11 +348,20 @@ static int convert(AVFilterContext *ctx, void *data,
int job_nr, int n_jobs)
          */
         s->yuv2rgb(rgb, s->rgb_stride, in_data, td->in_linesize, w, h,
                    s->yuv2rgb_coeffs, s->yuv_offset[0]);
+        printf("post-yuv2rgb - R: %d, G: %d, B: %d\n",
+               rgb[0][0], rgb[1][0], rgb[2][0]);
         if (!s->rgb2rgb_passthrough) {
             apply_lut(rgb, s->rgb_stride, w, h, s->lin_lut);
-            if (!s->lrgb2lrgb_passthrough)
+            printf("post-linearize - R: %d, G: %d, B: %d\n",
+                   rgb[0][0], rgb[1][0], rgb[2][0]);
+            if (!s->lrgb2lrgb_passthrough) {
                 s->dsp.multiply3x3(rgb, s->rgb_stride, w, h,
s->lrgb2lrgb_coeffs);
+                printf("post-rgb2rgb - R: %d, G: %d, B: %d\n",
+                       rgb[0][0], rgb[1][0], rgb[2][0]);
+            }
             apply_lut(rgb, s->rgb_stride, w, h, s->delin_lut);
+            printf("post-delinearize - R: %d, G: %d, B: %d\n",
+                   rgb[0][0], rgb[1][0], rgb[2][0]);
         }
         if (s->dither == DITHER_FSB) {
             s->rgb2yuv_fsb(out_data, td->out_linesize, rgb, s->rgb_stride,
w, h,
$ make -j4 && ./ffmpeg -s 2x2 -pix_fmt yuv420p -f rawvideo -c:v rawvideo -i
/tmp/in.yuv -vf
colorspace=ispace=bt470bg:iprimaries=bt470m:itrc=gamma28:irange=mpeg:range=jpeg:all=bt709
-y /tmp/out.yuv
[..]
post-yuv2rgb - R: 13076, G: 19616, B: 26625
post-linearize - R: 3182, G: 9906, B: 23302
post-rgb2rgb - R: -1193, G: 11028, B: 24440
post-delinearize - R: -4697, G: 17660, B: 26487

Patch looks OK. Drew, would it be possible to submit the patch at
code.ffmpeg.org so I can merge it using our new system?

Thanks,
Ronald
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-le...@ffmpeg.org

Reply via email to