[FFmpeg-trac] #7978(undetermined:reopened): inaccurate conversion from YCbCr Narrow range to RGB Full range

FFmpeg trac at avcodec.org
Wed Mar 8 19:41:38 EET 2023

```#7978: inaccurate conversion from YCbCr Narrow range to RGB Full range
-------------------------------------+-------------------------------------
Reporter:  cepesh       |                    Owner:  (none)
Type:  defect       |                   Status:  reopened
Priority:  normal       |                Component:
|  undetermined
Version:  unspecified  |               Resolution:
Keywords:               |               Blocked By:
Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
Comment (by Balling):

>At least in my mind, all standards I know of assume 255 (8-bit) = 1023
(10-bit) = 65535 (16-bit) = 100% = 1.0 (float)..

That is not the case for **limited range YCbCr or limited RGB** (only for
full RGB and YCBCr), they have values reserved for sync, 0 and 255 for 8
bit and 0, 1, 2, 3 and 1019, 1020, 1021, 1023 for all 3 components. We
know from BT.601 the consensus is to use the following: 255.75 means that
first 8 bit is before the dot and last two bits are after the dot, after
is encoded as follows: 00 is 00, 25 is 01, 50 is 10, 75 is 11. If we omit
.00 that means last two bits are 0, which means 8 bit 255 value is 255.00,
not 255.75, with 255.75 being all ones. From this we see that if we say
black level is at 16.00, it means that it is all ones for 8 bit, but for
10 bit it has last two bits as 0. In fact that means that in bitshift < 4
is used to convert from 8 bit to 10 bit, which is the case for 1.0 float
value Y 235 and Cb, Cr 240 too. 240 * 4 is 960.

Ideally 960 was supposed to be 962, but it is not.

>They simply pad the 8bit number with two trailing zeros to convert to
8bit space. It's not perfect, but it's fast, simple and good enough
(wasting 0.3% of available steps).

https://web.archive.org/web/20150912033144/http://www.spectracal.com/forum/viewtopic.php?f=51&t=1962#p12485&mobile=on

What also should be considered is that if we convert from RGB to 8 bit or
10 bit YCBCR limited it will not be just a bitshift vetween those, as
clarified here: https://en.wikipedia.org/wiki/SMPTE_color_bars

So here we have a bug. We know to decode 10 bit YCbCr we need 12 bit RGB,
so for white it should be 4095, 4095, 4095 already, then to convert from
these RGB values to 16 bit RGB we need to (4095+1) * 4 -1 and we get
65536.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/7978#comment:11>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
```