Opened 7 years ago

Closed 7 years ago

Last modified 5 years 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 7 years ago.
source V210 file (BT.2020 NCL) and output TIFF

Download all attachments as: .zip

Change History (11)

by cepesh, 7 years ago

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

comment:1 by Elon Musk, 7 years ago

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

comment:2 by cepesh, 7 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, 7 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, 7 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, 7 years ago

Resolution: → fixed
Status: new → closed

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

Resolution: fixed
Status: closed → reopened

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

comment:7 by Elon Musk, 7 years ago

You have not provided new info what is incorrect now.

comment:8 by Elon Musk, 7 years ago

Resolution: → needs_more_info
Status: reopened → closed

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

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

Resolution: needs_more_info
Status: closed → reopened

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 5 years ago by Balling (previous) (diff)

comment:10 by Elon Musk, 7 years ago

Resolution: → wontfix
Status: reopened → closed

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.