Opened 2 years ago

Closed 2 years ago

Last modified 6 months ago

#8034 closed defect (wontfix)

zscale: inaccurate conversion from YCbCr Narrow range to RGB Full range

Reported by: cepesh Owned by:
Priority: normal Component: avfilter
Version: git-master Keywords: zscale
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug: inaccurate conversion from BT.2020 NCL YCbCr Narrow range to BT.2020 RGB Full range using zscale filter
How to reproduce (on the latest github windows build ffmpeg-20190722-3883c9d-win64-static):

ffmpeg started on 2019-07-24 at 11:10:42
Report written to "ffmpeg-20190724-111042.log"
Command line:
"C:\\tools\\ffmpeg-20190722-3883c9d-win64-static\\bin\\ffmpeg.exe" -loglevel debug -report -s 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf "zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full" -vframes 1 ffmpeg_3883c9d_zscale.TIFF -y
ffmpeg version N-94383-g3883c9d147 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190716
  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. 32.100 / 56. 32.100
  libavcodec     58. 55.100 / 58. 55.100
  libavformat    58. 30.100 / 58. 30.100
  libavdevice    58.  9.100 / 58.  9.100
  libavfilter     7. 58.100 /  7. 58.100
  libswscale      5.  6.100 /  5.  6.100
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.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 'zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full'.
Reading option '-vframes' ... matched as option 'vframes' (set the number of video frames to output) with argument '1'.
Reading option 'ffmpeg_3883c9d_zscale.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 @ 000001ed6f27c780] Opening 'YUV_pattern-2fr.v210' for reading
[file @ 000001ed6f27cfc0] Setting default whitelist 'file,crypto'
[v210 @ 000001ed6f27c780] Format v210 probed with size=2048 and score=50
[v210 @ 000001ed6f27c780] Before avformat_find_stream_info() pos: 0 bytes read:32768 seeks:0 nb_streams:1
[v210 @ 000001ed6f27c780] All info found
[v210 @ 000001ed6f27c780] Estimating duration from bitrate, this may be inaccurate
[v210 @ 000001ed6f27c780] 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 ffmpeg_3883c9d_zscale.TIFF.
Applying option vf (set video filters) with argument zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full.
Applying option vframes (set the number of video frames to output) with argument 1.
Successfully parsed a group of options.
Opening an output file: ffmpeg_3883c9d_zscale.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_zscale_0 @ 000001ed6f284f80] Setting 'dither' to value 'none'
[Parsed_zscale_0 @ 000001ed6f284f80] Setting 'matrix' to value 'bt2020nc'
[Parsed_zscale_0 @ 000001ed6f284f80] Setting 'matrixin' to value 'bt2020nc'
[Parsed_zscale_0 @ 000001ed6f284f80] Setting 'in_range' to value 'limited'
[Parsed_zscale_0 @ 000001ed6f284f80] Setting 'out_range' to value 'full'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'video_size' to value '3840x2160'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'pix_fmt' to value '66'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'time_base' to value '1/25'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'pixel_aspect' to value '0/1'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 000001ed6f285100] Setting 'frame_rate' to value '25/1'
[graph 0 input from stream 0:0 @ 000001ed6f285100] w:3840 h:2160 pixfmt:yuv422p10le tb:1/25 fr:25/1 sar:0/1 sws_param:flags=2
[format @ 000001ed6f2973c0] Setting 'pix_fmts' to value 'rgb24|rgb48le|pal8|rgba|rgba64le|gray|ya8|gray16le|ya16le|monob|monow|yuv420p|yuv422p|yuv440p|yuv444p|yuv410p|yuv411p'
[auto_scaler_0 @ 000001ed6f297980] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 000001ed6f297980] w:iw h:ih flags:'bicubic' interl:0
[format @ 000001ed6f2973c0] auto-inserting filter 'auto_scaler_0' between the filter 'Parsed_zscale_0' and the filter 'format'
[AVFilterGraph @ 000001ed6f2825c0] query_formats: 4 queried, 2 merged, 1 already done, 0 delayed
[auto_scaler_0 @ 000001ed6f297980] picking rgb48le out of 17 ref:yuv422p10le alpha:0
[Parsed_zscale_0 @ 000001ed6f284f80] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:yuv422p10le sar:0/1
[auto_scaler_0 @ 000001ed6f297980] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:rgb48le sar:0/1 flags:0x4
[Parsed_zscale_0 @ 000001ed6f284f80] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:yuv422p10le sar:0/1
Output #0, image2, to 'ffmpeg_3883c9d_zscale.TIFF':
  Metadata:
    encoder         : Lavf58.30.100
    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.55.100 tiff
Clipping frame in rate conversion by 0.000008
No more output streams to write to, finishing.
[image2 @ 000001ed6f28eb40] Opening 'ffmpeg_3883c9d_zscale.TIFF' for writing
[file @ 000001ed6f2d4e80] Setting default whitelist 'file,crypto'
[AVIOContext @ 000001ed6f2d4f80] Statistics: 0 seeks, 13 writeouts
frame=    1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.0883x    
video:3195kB 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 (ffmpeg_3883c9d_zscale.TIFF):
  Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (3271738 bytes); 
  Total: 1 packets (3271738 bytes) muxed
1 frames successfully decoded, 0 decoding errors
[AVIOContext @ 000001ed6f285200] Statistics: 22118400 bytes read, 0 seeks

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

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

100% Magenta - ALMOST CORRECT
Source YCbCr value = 0x015a, 0x343, 0x039c
Observed RGB value = 65535, 0, 65535
Expected RGB value = 65533, 0, 65535

Attachments (1)

20190724-ffmpeg-zscale-bug.zip (117.0 KB ) - added by cepesh 2 years ago.
source V210 file (BT.2020 NCL) and output TIFF

Download all attachments as: .zip

Change History (11)

by cepesh, 2 years ago

source V210 file (BT.2020 NCL) and output TIFF

comment:1 by Elon Musk, 2 years ago

You should report this to zimg github page not here.
zscale is just wrapper around that library,

comment:2 by cepesh, 2 years ago

Thanks for your quick response. How confident are you that the issue is purely in the zimg library rather than in the ffmpeg wrapper?

I've raised this issue https://github.com/sekrit-twc/zimg/issues/109 hope, it's the right place

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

Replying to richardpl:

You should report this to zimg github page not here.
zscale is just wrapper around that library,

zimg dev can't reproduce the issue with vapoursynth. https://github.com/sekrit-twc/zimg/issues/109#issuecomment-514687758

What are the next steps?

comment:4 by cepesh, 2 years ago

In this post richardpl advised

Could you use zscale=other parameters as usual,format=rgb48le instead of what are you using currently?

I have tried that and the situation improved a lot. This seems to be placing the issue back into ffmpeg rather than zimg library.

ffmpeg started on 2019-07-29 at 08:45:19
Report written to "ffmpeg-20190729-084519.log"
Command line:
"C:\\tools\\ffmpeg-20190722-3883c9d-win64-static\\bin\\ffmpeg.exe" -loglevel debug -report -s 3840x2160 -vcodec v210 -i YUV_pattern-2fr.v210 -vf "zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full,format=rgb48le" -vframes 1 ffmpeg_3883c9d_zscale_format_rgb48le.TIFF -y
ffmpeg version N-94383-g3883c9d147 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190716
  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. 32.100 / 56. 32.100
  libavcodec     58. 55.100 / 58. 55.100
  libavformat    58. 30.100 / 58. 30.100
  libavdevice    58.  9.100 / 58.  9.100
  libavfilter     7. 58.100 /  7. 58.100
  libswscale      5.  6.100 /  5.  6.100
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.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 'zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full,format=rgb48le'.
Reading option '-vframes' ... matched as option 'vframes' (set the number of video frames to output) with argument '1'.
Reading option 'ffmpeg_3883c9d_zscale_format_rgb48le.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 @ 000001516e19b840] Opening 'YUV_pattern-2fr.v210' for reading
[file @ 000001516e19c8c0] Setting default whitelist 'file,crypto'
[v210 @ 000001516e19b840] Format v210 probed with size=2048 and score=50
[v210 @ 000001516e19b840] Before avformat_find_stream_info() pos: 0 bytes read:32768 seeks:0 nb_streams:1
[v210 @ 000001516e19b840] All info found
[v210 @ 000001516e19b840] Estimating duration from bitrate, this may be inaccurate
[v210 @ 000001516e19b840] 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 ffmpeg_3883c9d_zscale_format_rgb48le.TIFF.
Applying option vf (set video filters) with argument zscale=dither=none:matrix=bt2020nc:matrixin=bt2020nc:in_range=limited:out_range=full,format=rgb48le.
Applying option vframes (set the number of video frames to output) with argument 1.
Successfully parsed a group of options.
Opening an output file: ffmpeg_3883c9d_zscale_format_rgb48le.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_zscale_0 @ 000001516e1a4a00] Setting 'dither' to value 'none'
[Parsed_zscale_0 @ 000001516e1a4a00] Setting 'matrix' to value 'bt2020nc'
[Parsed_zscale_0 @ 000001516e1a4a00] Setting 'matrixin' to value 'bt2020nc'
[Parsed_zscale_0 @ 000001516e1a4a00] Setting 'in_range' to value 'limited'
[Parsed_zscale_0 @ 000001516e1a4a00] Setting 'out_range' to value 'full'
[Parsed_format_1 @ 000001516e1a3300] Setting 'pix_fmts' to value 'rgb48le'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'video_size' to value '3840x2160'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'pix_fmt' to value '66'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'time_base' to value '1/25'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'pixel_aspect' to value '0/1'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] Setting 'frame_rate' to value '25/1'
[graph 0 input from stream 0:0 @ 000001516e1b69c0] w:3840 h:2160 pixfmt:yuv422p10le tb:1/25 fr:25/1 sar:0/1 sws_param:flags=2
[format @ 000001516e1b8880] Setting 'pix_fmts' to value 'rgb24|rgb48le|pal8|rgba|rgba64le|gray|ya8|gray16le|ya16le|monob|monow|yuv420p|yuv422p|yuv440p|yuv444p|yuv410p|yuv411p'
[auto_scaler_0 @ 000001516e1bc980] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 000001516e1bc980] w:iw h:ih flags:'bicubic' interl:0
[Parsed_format_1 @ 000001516e1a3300] auto-inserting filter 'auto_scaler_0' between the filter 'Parsed_zscale_0' and the filter 'Parsed_format_1'
[AVFilterGraph @ 000001516e1a2800] query_formats: 5 queried, 3 merged, 1 already done, 0 delayed
[Parsed_zscale_0 @ 000001516e1a4a00] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:yuv422p10le sar:0/1
[auto_scaler_0 @ 000001516e1bc980] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:rgb48le sar:0/1 flags:0x4
[Parsed_zscale_0 @ 000001516e1a4a00] w:3840 h:2160 fmt:yuv422p10le sar:0/1 -> w:3840 h:2160 fmt:yuv422p10le sar:0/1
Output #0, image2, to 'ffmpeg_3883c9d_zscale_format_rgb48le.TIFF':
  Metadata:
    encoder         : Lavf58.30.100
    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.55.100 tiff
Clipping frame in rate conversion by 0.000008
No more output streams to write to, finishing.
[image2 @ 000001516e1ae440] Opening 'ffmpeg_3883c9d_zscale_format_rgb48le.TIFF' for writing
[file @ 000001516e1b9cc0] Setting default whitelist 'file,crypto'
[AVIOContext @ 000001516e1eeb40] Statistics: 0 seeks, 13 writeouts
frame=    1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.0957x    
video:3195kB 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 (ffmpeg_3883c9d_zscale_format_rgb48le.TIFF):
  Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (3271738 bytes); 
  Total: 1 packets (3271738 bytes) muxed
1 frames successfully decoded, 0 decoding errors
[AVIOContext @ 000001516e1a4b00] Statistics: 22118400 bytes read, 0 seeks

comment:5 by Elon Musk, 2 years ago

Resolution: fixed
Status: newclosed

in reply to:  5 comment:6 by cepesh, 2 years ago

Resolution: fixed
Status: closedreopened

Replying to richardpl:
Can you please advise what has been fixed and in which commit?

comment:7 by Elon Musk, 2 years ago

You have not provided new info what is incorrect now.

comment:8 by Elon Musk, 2 years ago

Resolution: needs_more_info
Status: reopenedclosed

Please provide new info what is incorrect now and then reopen ticket.

in reply to:  8 comment:9 by Balling, 2 years ago

Resolution: needs_more_info
Status: closedreopened

Replying to richardpl:

Please provide new info what is incorrect now and then reopen ticket.

So, this is normal https://github.com/sekrit-twc/zimg/issues/109#issuecomment-515552048
?
"FFmpeg instructs z.lib to perform a no-op conversion from YUV to YUV, and instead uses its internal code to convert to RGB."

BTW, I read that the same problem was in Xbox One X blu-ray player))) Micro$oft thankfully solved it not long ago.

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

comment:10 by Elon Musk, 2 years ago

Resolution: wontfix
Status: reopenedclosed

Yes that is normal and intended way to use filter. Always use format filter after this filter, otherwise it will not do much.

Note: See TracTickets for help on using tickets.