[FFmpeg-user] How chrRangeToJpeg_c() works?

Andrew Randrianasulu randrianasulu at gmail.com
Thu Sep 12 20:47:19 EEST 2024


пн, 9 сент. 2024 г., 23:19 Andrew Randrianasulu <randrianasulu at gmail.com>:

>
>
> пн, 9 сент. 2024 г., 23:04 Andrew Randrianasulu <randrianasulu at gmail.com>:
>
>>
>>
>> пн, 9 сент. 2024 г., 18:06 Andrew Randrianasulu <randrianasulu at gmail.com
>> >:
>>
>>> Looking at libswscale/swscale.c (due to
>>> https://trac.ffmpeg.org/ticket/11182#comment:5) I do not understand
>>> how it works :)
>>>
>>> why shits to 11 and to 12 ?
>>>
>>> // FIXME all pal and rgb srcFormats could do this conversion as well
>>> // FIXME all scalers more complex than bilinear could do half of this
>>> transform
>>> static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
>>> {
>>>     int i;
>>>     for (i = 0; i < width; i++) {
>>>         dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
>>>         dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
>>>     }
>>> }
>>>
>>> static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
>>> {
>>>     int i;
>>>     for (i = 0; i < width; i++) {
>>>         dstU[i] = (dstU[i] * 1799 + 4081085) >> 11; // 1469
>>>         dstV[i] = (dstV[i] * 1799 + 4081085) >> 11; // 1469
>>>     }
>>> }
>>>
>>> ===
>>> can anyone knowledgeable  write/add some more comments in code ? please
>>> :)
>>>
>>
>>
>> it seems that same code (under slightly different name) was living in
>> swscale_template.c since at least 2009 ...
>>
>>
>>
>> https://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff/c1977fbbd7d1e7825010e301fa236e910b760aab..bae76dc3eb6e5cd07f5881092d375ddc0270f693:/libswscale/swscale_template.c
>>
>
>
> and it was commited in 2008:
>
>
> https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/6bc0c7928a386d5cf99c198ec1b795aff6bf7656
>
> Fix jpeg yuv.
>
> author Michael Niedermayer <michaelni at gmx.at>
> Mon, 8 Sep 2008 15:36:38 +0300 (12:36 +0000)
> committer Michael Niedermayer <michaelni at gmx.at>
> Mon, 8 Sep 2008 15:36:38 +0300 (12:36 +0000)
> commit 6bc0c7928a386d5cf99c198ec1b795aff6bf7656
> tree a90c126c5d92e65bfe4ad9dac24473eaae8464ed tree
> parent f7b1d72f45c97f3fc57632a0a23d01cee51c4a4e commit | diff
>
> Fix jpeg yuv.
> Fixes issue504.
>
> Originally committed as revision 27547 to svn://
> svn.mplayerhq.hu/mplayer/trunk/libswscale
>
> hm, but this does not make it less opaque for me ;)
>

so, libwebp source code comments hint that it was 16:16 fixed point
representation for yuv-rgb matrix coefficients

https://github.com/leapmotion/FreeImage/blob/master/Source/LibWebP/src/dsp/yuv.h

====
// This JPEG-YUV colorspace, only for comparison!
// These are also 16bit precision coefficients from Rec.601, but with full
// [0..255] output range.
static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
  const int luma = 19595 * r + 38470 * g + 7471 * b;
  return (luma + rounding) >> YUV_FIX;  // no need to clip
}

static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
  const int u = -11058 * r - 21710 * g + 32768 * b;
  return VP8ClipUV(u, rounding);
}

static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
  const int v = 32768 * r - 27439 * g - 5329 * b;
  return VP8ClipUV(v, rounding);
}

===

and same file includes 14bit constants for arm cpus ...


amazing, just need to know how to convert fp64 to fixedpoint ....

https://embeddedartistry.com/blog/2018/07/12/simple-fixed-point-conversion-in-c/

it uses round() from libc (?)

also on vogons

https://www.vogons.org/viewtopic.php?t=100401

but ffmpeg's function probably uses some matrix math because color
converter is fused with scaler?

also I found few routines in libquicktime and mjpegtools.



> I guess it was working for all those years .. mostly?
>
>
>>
>>


More information about the ffmpeg-user mailing list