Opened 2 years ago

Last modified 6 weeks ago

#7978 reopened defect

inaccurate conversion from YCbCr Narrow range to RGB Full range

Reported by: cepesh Owned by:
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug: inaccurate conversion from YCbCr Narrow range to RGB Full range
How to reproduce:

Command line:
"C:\\tools\\ffmpeg-4.1.3\\bin\\ffmpeg.exe" -loglevel debug -report -s 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf "scale=in_color_matrix=bt2020:in_range=tv" -vframes 1 tiff_bug_00.tiff -y
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.3.1 (GCC) 20190414
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100

100% White
Source YCbCr value = 0x03ac, 0x0200, 0x0200 (940, 512, 512)
Observed RGB value = 65283, 65283, 65283
Expected RGB value = 65535, 65535, 65535

58% White
Source YCbCr value = 0x023c, 0x0200, 0x0200 (572, 512, 512)
Observed RGB value = 37858, 37858, 37858
Expected RGB value = 38004, 38004, 38004

100% Magenta
Source YCbCr value = 0x015a, 0x343, 0x039c
Observed RGB value = 65280, 0, 65289
Expected RGB value = 65533, 0, 65535

Attachments (1)

20190629-ffmpeg-bug.zip (144.1 KB ) - added by cepesh 2 years ago.
Zip archive includes both the source V210 file (2 frames inside. resolution 3840x2160) and TIFF output

Download all attachments as: .zip

Change History (10)

by cepesh, 2 years ago

Attachment: 20190629-ffmpeg-bug.zip added

Zip archive includes both the source V210 file (2 frames inside. resolution 3840x2160) and TIFF output

comment:1 by Carl Eugen Hoyos, 2 years ago

Priority: importantnormal
Version: 4.1unspecified

Please test current FFmpeg git head and provide the command line together with the complete, uncut console output to make this a valid ticket.

in reply to:  1 comment:2 by cepesh, 2 years ago

Replying to cehoyos:

Please test current FFmpeg git head and provide the command line together with the complete, uncut console output to make this a valid ticket.

Sure, no problem. Retested on N-94137-g89b96900fa

ffmpeg started on 2019-06-30 at 11:10:10
Report written to "ffmpeg-20190630-111010.log"
Command line:
"C:\\tools\\ffmpeg-20190629-89b9690-win64-static\\bin\\ffmpeg.exe" -loglevel debug -report -s 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf "scale=in_color_matrix=bt2020:in_range=tv" -vframes 1 tiff_bug_00.tiff -y
ffmpeg version N-94137-g89b96900fa Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190621
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 30.100 / 56. 30.100
  libavcodec     58. 53.100 / 58. 53.100
  libavformat    58. 28.101 / 58. 28.101
  libavdevice    58.  7.100 / 58.  7.100
  libavfilter     7. 55.100 /  7. 55.100
  libswscale      5.  4.101 /  5.  4.101
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Splitting the commandline.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Reading option '-s' ... matched as option 's' (set frame size (WxH or abbreviation)) with argument '3840x2160'.
Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'v210'.
Reading option '-i' ... matched as input url with argument 'YUV_pattern-2fr.v210'.
Reading option '-vf' ... matched as option 'vf' (set video filters) with argument 'scale=in_color_matrix=bt2020:in_range=tv'.
Reading option '-vframes' ... matched as option 'vframes' (set the number of video frames to output) with argument '1'.
Reading option 'tiff_bug_00.tiff' ... matched as output url.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Applying option report (generate a report) with argument 1.
Applying option y (overwrite output files) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input url YUV_pattern-2fr.v210.
Applying option s (set frame size (WxH or abbreviation)) with argument 3840x2160.
Applying option vcodec (force video codec ('copy' to copy stream)) with argument v210.
Successfully parsed a group of options.
Opening an input file: YUV_pattern-2fr.v210.
[NULL @ 000002c7c2a2b680] Opening 'YUV_pattern-2fr.v210' for reading
[file @ 000002c7c2a2c700] Setting default whitelist 'file,crypto'
[v210 @ 000002c7c2a2b680] Format v210 probed with size=2048 and score=50
[v210 @ 000002c7c2a2b680] Before avformat_find_stream_info() pos: 0 bytes read:32768 seeks:0 nb_streams:1
[v210 @ 000002c7c2a2b680] All info found
[v210 @ 000002c7c2a2b680] Estimating duration from bitrate, this may be inaccurate
[v210 @ 000002c7c2a2b680] After avformat_find_stream_info() pos: 22118400 bytes read:22118400 seeks:0 frames:1
Input #0, v210, from 'YUV_pattern-2fr.v210':
  Duration: 00:00:00.08, start: 0.000000, bitrate: 4423680 kb/s
    Stream #0:0, 1, 1/25: Video: v210, 1 reference frame, yuv422p10le, 3840x2160, 0/1, 4423680 kb/s, 25 tbr, 25 tbn, 25 tbc
Successfully opened the file.
Parsing a group of options: output url tiff_bug_00.tiff.
Applying option vf (set video filters) with argument scale=in_color_matrix=bt2020:in_range=tv.
Applying option vframes (set the number of video frames to output) with argument 1.
Successfully parsed a group of options.
Opening an output file: tiff_bug_00.tiff.
Successfully opened the file.
Stream mapping:
  Stream #0:0 -> #0:0 (v210 (native) -> tiff (native))
Press [q] to stop, [?] for help
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
detected 32 logical cores
[Parsed_scale_0 @ 000002c7c2a34700] Setting 'in_color_matrix' to value 'bt2020'
[Parsed_scale_0 @ 000002c7c2a34700] Setting 'in_range' to value 'tv'
[Parsed_scale_0 @ 000002c7c2a34700] Setting 'flags' to value 'bicubic'
[Parsed_scale_0 @ 000002c7c2a34700] w:iw h:ih flags:'bicubic' interl:0
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'video_size' to value '3840x2160'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'pix_fmt' to value '66'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'time_base' to value '1/25'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'pixel_aspect' to value '0/1'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] Setting 'frame_rate' to value '25/1'
[graph 0 input from stream 0:0 @ 000002c7c2a32d40] w:3840 h:2160 pixfmt:yuv422p10le tb:1/25 fr:25/1 sar:0/1 sws_param:flags=2
[format @ 000002c7c2a47880] Setting 'pix_fmts' to value 'rgb24|rgb48le|pal8|rgba|rgba64le|gray|ya8|gray16le|ya16le|monob|monow|yuv420p|yuv422p|yuv440p|yuv444p|yuv410p|yuv411p'
[AVFilterGraph @ 000002c7c2a322c0] query_formats: 4 queried, 3 merged, 0 already done, 0 delayed
[Parsed_scale_0 @ 000002c7c2a34700] picking rgb48le out of 17 ref:yuv422p10le alpha:0
[Parsed_scale_0 @ 000002c7c2a34700] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:rgb48le sar:0/1 flags:0x4
Output #0, image2, to 'tiff_bug_00.tiff':
  Metadata:
    encoder         : Lavf58.28.101
    Stream #0:0, 0, 1/25: Video: tiff, 1 reference frame, rgb48le, 3840x2160, 0/1, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.53.100 tiff
Clipping frame in rate conversion by 0.000008
No more output streams to write to, finishing.
[image2 @ 000002c7c2a3e280] Opening 'tiff_bug_00.tiff' for writing
[file @ 000002c7c2e6c880] Setting default whitelist 'file,crypto'
[AVIOContext @ 000002c7c2a83580] Statistics: 0 seeks, 21 writeouts
frame=    1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.103x    
video:5147kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Input file #0 (YUV_pattern-2fr.v210):
  Input stream #0:0 (video): 1 packets read (22118400 bytes); 1 frames decoded; 
  Total: 1 packets (22118400 bytes) demuxed
Output file #0 (tiff_bug_00.tiff):
  Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (5270238 bytes); 
  Total: 1 packets (5270238 bytes) muxed
1 frames successfully decoded, 0 decoding errors
[AVIOContext @ 000002c7c2a34940] Statistics: 22118400 bytes read, 0 seeks

comment:3 by cepesh, 2 years ago

Hi there. Is there any more information required from my side for this to go through your initial registration?

comment:4 by Balling, 7 weeks ago

Resolution: invalid
Status: newclosed

See downstream: https://github.com/sekrit-twc/zimg/issues/109

"found that you must add 'format=gbrp16le' after 'zscale'. Otherwise, FFmpeg instructs z.lib to perform a no-op conversion from YUV to YUV, and instead uses its internal code to convert to RGB. After I did this, I verified that I got '38004' when converting from '572'. This bug(?) exists in FFmpeg, not z.lib."

Last edited 7 weeks ago by Balling (previous) (diff)

comment:5 by Balling, 7 weeks ago

Okay, actually the real bug here is that the values inside YUV_pattern-2fr.v210 are not what you said they should be.

Check out: ffmpeg -video_size 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf extractplanes=y crazystuff.png

yuv422p10le that is used in v210 file are also a problem.

comment:6 by Balling, 7 weeks ago

Resolution: invalid
Status: closedreopened

Okay, I was wrong, I used yuvview (hex view in settings) and your file is indeed using in hex 0x3ac 0x200 0x200. So the bug here is not about the scale: even normal production of a png will produce 65283 Y only png. I suppose the idea that 10 bit value in png 16 bit per component will be just multiply with 64 is wrong. Sigh.

Last edited 7 weeks ago by Balling (previous) (diff)

comment:7 by pdr0, 7 weeks ago

Use zscale instead

ffmpeg -s 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf zscale=matrixin=2020_ncl,format=gbrp16le -an -frames:v 1 out_zscale.png

100% white
65535, 65535, 65535

58% white
38004, 38004, 38004

100% Magenta
65533, 0, 65535

comment:8 by Balling, 6 weeks ago

So, yes. I was able to confirm the bug:

ffmpeg.exe -video_size 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf scale=in_color_matrix=bt2020:in_range=tv,format=gbrp10le -f rawvideo rawle.rgb

(Do not use gbrp10be, since YUVview does not support BE.)

Open in YUVview, first select it being GBR (not RGB, select it is planar, select it is 10 bit) then select it is 3840x2160, it will crash at least once. Then if you will activate hex viewer in settings and zoom in you will get the hex values. Indeed white is 1020 10 bit, just like in 16 bit png (65283 / 64 =1020). Now, as described in ITU docs it is normal to use 1020 instead of 1023 since that is what naïve implementation will give. WOW.

Last edited 6 weeks ago by Balling (previous) (diff)

comment:9 by Balling, 6 weeks ago

Same happens with BT.601 matrix too with white color that is of course not caring about matrix. And BT.709.

Note: See TracTickets for help on using tickets.