Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#4978 closed defect (wontfix)

Color range is wrong in media players, correct in PNG output

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

Description

Hi,

I've been trying to track down an issue where the colors are too muted in media players (MPlayer, VLC, ffplay all behave identically). I made a H.264 file that contains only the Y'CbCr? triplet (63,102,240), which should be a pure red, and have explicitly set the limited-range flag. (If I specify full-range, saturation becomes correct but the luma range gets wrong.) I have verified with raw YUV output that these value indeed came correct through the encoder.

ffprobe correctly understands that TV range is in use:

ffprobe version 2.8.1 Copyright (c) 2007-2015 the FFmpeg developers
  built with gcc 5.2.1 (Debian 5.2.1-23) 20151028
  configuration: 
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
Input #0, mpegts, from '/home/sesse/dev/nageru/test.ts':
  Duration: 00:00:01.47, start: 0.083333, bitrate: 473 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720, 60 tbr, 90k tbn, 120k tbc
    Stream #0:1[0x101]: Audio: mp3 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 256 kb/s

However, if I play with ffplay and take a screenshot (with import from ImageMagick?), the color comes out as RGB=(233,0,2). This isn't right.

I was wondering if I had set something wrong in the flags, but then I tried PNG output:

klump:~/nmu/ffmpeg-2.8.1> ./ffmpeg -i ~/dev/nageru/test.ts test%03d.png                         

Opening one of these PNG files show that the output color is RGB=(254,0,0), which is the correct one!

FWIW, I've tried -vo x11 in MPlayer, so I'm fairly certain this isn't about xv or something similar. I might be missing something, though.

I've marked this as swscale, since I honestly don't know where this could be otherwise.

Attachments (3)

test.ts (84.8 KB) - added by Sesse 4 years ago.
Example H.264 file
png-output.png (4.5 KB) - added by Sesse 4 years ago.
Output from PNG encoder (correct)
ffplay-output.png (302 bytes) - added by Sesse 4 years ago.
ffplay output (incorrect)

Download all attachments as: .zip

Change History (10)

Changed 4 years ago by Sesse

Example H.264 file

Changed 4 years ago by Sesse

Output from PNG encoder (correct)

comment:1 Changed 4 years ago by gjdfgh

  • Resolution set to wontfix
  • Status changed from new to closed

ffplay and mplayer doesn't usually output video correctly if unusual color ranges or matrices are used.

(Edit: clarification.)

Last edited 4 years ago by gjdfgh (previous) (diff)

Changed 4 years ago by Sesse

ffplay output (incorrect)

comment:2 Changed 4 years ago by Sesse

So should I take this bug to MPlayer and VLC, then?

comment:3 Changed 4 years ago by Sesse

And what would usual color ranges or matrices be for 720p, if not Rec. 709?

comment:4 Changed 4 years ago by gjdfgh

Yes, you should. As long as the libavcodec output is correct (check with ffprobe -show_frames or so), it's up to the player to handle this correctly.

And what would usual color ranges or matrices be for 720p, if not Rec. 709?

I read this wrong; limited range is of course not unusual for ycbcr. But MPlayer does as far as I remember only output bt.601 (except with vdpau, where it uses the video resolution to guess bt.601 vs. bt.709). Xv also is fixed to bt.601, unless you use unofficial vendor-specific extensions. libswscale can do the conversion somewhat correctly, but only if you tell it so (which is why it works with ffmpeg CLI, but not with MPlayer -vo x11).

comment:5 Changed 4 years ago by Sesse

-show_frames says pix_fmt=yuv420p, so I guess that's right (ie., yuvj420p would be full-range). I can't see anything about BT.601 vs. BT.709 YUV coefficients there, though; shouldn't there be something?

Based on what you're saying, is there no correct matrix I can set to make it work properly everywhere? Because if I set BT.601 YUV coefficients, MPlayer will guess incorrectly for VDPAU output, even if I mark it correctly in the stream?

comment:6 Changed 4 years ago by gjdfgh

It appears ffprobe doesn't actually dump this parameter. (Seems like an oversight.)

Based on what you're saying, is there no correct matrix I can set to make it work properly everywhere? Because if I set BT.601 YUV coefficients, MPlayer will guess incorrectly for VDPAU output, even if I mark it correctly in the stream?

Yes. Player support is a bit spotty.

comment:7 Changed 4 years ago by Sesse

I added -show_streams and it says:

color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709

Then I copied-and-pasted the code from there to -show_frames and it says:

color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709

Ie., the same. So ffmpeg is indeed pushing this correctly through, the players are just not doing it correctly.

I'll try switching to BT.601 YUV coefficients; with some luck, it will at least be better most places, and it will still be correct assuming a player that cares.

Note: See TracTickets for help on using tickets.