Bug 46800 - [SNB] Full/Limited Color range not working automatically for 1000/1001 CEA modes
Summary: [SNB] Full/Limited Color range not working automatically for 1000/1001 CEA modes
Status: CLOSED FIXED
Alias: None
Product: DRI
Classification: Unclassified
Component: DRM/Intel (show other bugs)
Version: unspecified
Hardware: All Linux (All)
: medium enhancement
Assignee: Ville Syrjala
QA Contact: Intel GFX Bugs mailing list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-29 18:41 UTC by Paul Owen
Modified: 2017-07-24 23:02 UTC (History)
8 users (show)

See Also:
i915 platform:
i915 features:


Attachments
Proposed patch to fix the RGB color range property (7.75 KB, patch)
2013-01-09 18:39 UTC, Ville Syrjala
no flags Details | Splinter Review
Revised patch (5.89 KB, patch)
2013-01-10 12:18 UTC, Ville Syrjala
no flags Details | Splinter Review

Description Paul Owen 2012-02-29 18:41:35 UTC
This is a report following a discussion with Jesse Barnes on the intel-gfx mailing list (HDMI colour space and depth questions (YCbCr, xvYCC, Deep Colour). I'll just copy paste the discussion since that seems easiest.

On 28 February 2012 17:59, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
> There are several places we need to set extended vs normal range:
> DSP*CNTR (bit 25)
> PIPE*CONF (bits 26 and 13)
> TRANS*CONF (bit 10, for xvYCC DP configs)
> DVS*CNTR (for sprites, bit 21)

Okay - good learning exercise for me this! So by default, latest 3.3
kernel (github / master) upon boot xrandr reports Broadcast RGB as
Full. For that intel_reg_read reports the following (hope I'm looking
at the correct registers):

intel_reg_read 0x70008 (PIPEACONF): 0xC0000000 / bits 26 and 13 aren't set
intel_reg_read 0x70180 (DSPACNTR) : 0xD8004400 / bit 25 isn't set

Okay - so just as an experiment, running xrandr -d :0 --output HDMI3
--set "Broadcast RGB" "Limited 16-235" and rerunning the above gives
exactly the same result, i.e. no bits set. So trying intel_reg_write
with the following commands (hope my binary is correct!):

intel_reg_write 0x70008 0xC4002000
intel_reg_write 0x70180 0xDA004400

Seems to have the desired effect - that is video seems to have the
correct colour range - this is by eye since my TV doesn't seem to
report the actual input range anywhere. Running just the first command
seems to raise the brightness/decrease the contrast (or just raise
gamma - not sure) - the second brings it back down - so both as you
say are needed. Changing refresh seems to knock out the effect of the
second command. Re-running that second command fixes it once more.
I've posted on the XBMC forum in the hope others can try this to see
what effect it has.

If this can be automated in some way (EDID/manufacturer data maybe? defaulting to limited range for TV's?) that would be superb.
Comment 1 Chris Wilson 2012-03-01 01:34:12 UTC
Bouncing to DRM first to check the underwiring. My suspicion though is that spaces are not handled correctly in the strings, and that could be anywhere between xrandr -> X -> ddx -> drm -> i915.
Comment 2 Oyvind Kvalsvoll 2012-10-18 02:21:25 UTC
I confirm this bug, there are 2 issues: 

1. At startup, Full 0..255 RGB range should be enabled ("Broadcast RGB" = Full), but it is not. 
xrandr reports Full, but inspection using greyscale confirm that levels 16..235 from applications (desktop, picture viewers, movie players) are mapped to 0..255 on the hdmi output. 

2. Setting to Full using xrandr does not work. 


Quite incredible that Intel has not addressed this issue, as it is quite serious. 

The Full range (0..255) should be enabled as default, as this is the configuration that will give both desktop applications (as for viewing a picture) and movie playback correct representation on the screen. 
If Limited 16..235 is set on my system, this will give clipped pictures and also wrong levels on movies, as the movies are mapped from 16..235->0..255 on playback, consequently leading to clipping and wrong scaling. 


I have fixed my system by creating scripts that sets the register directly, in addition to running xrandr, it is not enough to just set the registers, it seems that what happens depends on previous state. 
Writing correct values to all correct registers will presumably do this properly, I just need something that works on my system, I only need to run the RGB_Full.sh script on startup, then the screen will be ok both for desktop apps and movie playback. 
 
The scripts that will actually set the "Broadcast RGB" mode correctly: 


RGB_Full.sh:
---------------------
#!/bin/bash
# Enable full RGB range 0..255 on Intel HD

xrandr --output HDMI2 --set "Broadcast RGB" "Limited 16:235"

intel_reg_write 0x70008 0xC4002000
intel_reg_write 0x70180 0xDA004400

xrandr --output HDMI2 --set "Broadcast RGB" "Full"

intel_reg_write 0x70180 0xDA004400
---------------------

RGB_Limited.sh: 
---------------------
#!/bin/bash
# Enable limited RGB range 16..235 on Intel HD

intel_reg_write 0x70008 0xC0000000
intel_reg_write 0x70180 0xD8004400

xrandr --output HDMI2 --set "Broadcast RGB" "Limited 16:235"
---------------------
 

Tested on:
Intel HD2000/i3 2120T/Asus P8H67
Ubuntu 12.04, kernel 3.2.0.26.
XBMC 12.0-ALPHA2 Git:20120510
HDMI to Denon AVR, Panasonic Plasma screen.
Comment 3 hanzoh 2012-12-20 14:31:26 UTC
I can confirm the issue on an i3-3225 (Intel HD4000) with the latest drivers from xorg-edgers (on Ubuntu 12.10).

The scripts provided by Oyvind seem to help a bit, but when switching from 50Hz to 24Hz, the settings are lost and I have to set them again.

Please fix this issue as it is crucial for appliances like HTPCs!
Comment 4 Ville Syrjala 2013-01-09 18:39:06 UTC
Created attachment 72746 [details] [review]
Proposed patch to fix the RGB color range property

Please give this patch a try. So far it seems to work on ILK and SNB for me.
Comment 5 Ville Syrjala 2013-01-10 12:18:04 UTC
Created attachment 72776 [details] [review]
Revised patch

Slightly nicer patch based on review from Daniel. Functionally identical to the first one though.
Comment 6 Paul Owen 2013-01-10 19:20:19 UTC
The patch seems to have fixed the issue of the xrandr command not working (kernel 3.8.0 RC3) – had to manually edit i915_reg.h. Can now switch between full and limited modes and all seems fine, also retains the setting between refresh rate changes. Is there any way this can be automated? For example is there information in the EDID that could be used? That would obviously be the preferred solution. This however is a very welcome step forward.
Comment 7 Ville Syrjala 2013-01-11 12:04:35 UTC
(In reply to comment #6)
> The patch seems to have fixed the issue of the xrandr command not working
> (kernel 3.8.0 RC3) – had to manually edit i915_reg.h. Can now switch between
> full and limited modes and all seems fine, also retains the setting between
> refresh rate changes. Is there any way this can be automated? For example is
> there information in the EDID that could be used? That would obviously be
> the preferred solution. This however is a very welcome step forward.

I don't think EDID gives us anything quite like that.

Based on a quick glance a the CEA and HDMI specs, there are a few things however that we could use to make it automatic in some cases.

The CEA EDID extension block has a bit that tells whether the display supports selecting the RGB range. But if that bit is not set, then there's no direct way to tell which range the display uses by default.

The CEA spec does state that the source should use limited range for all CEA video modes, except 640x480. I'm not quite sure what should happen with non-CEA modes, perhaps full range should be used.

Also the AVI infoframe has the capability to tell the display which range the source is sending. I need to check if were providing that information correctly or not.

And I suppose if the display is actually a DVI display instead of HDMI, we should probably default to full range.

The question is how do we want to implement the automatic mode. Should we leave it up to userspace to do it, or do we provide another setting for the 'Broadcast RGB' property, say "Automatic", which would let the kernel make these decisions.
Comment 8 Paul Owen 2013-01-11 16:12:38 UTC
The CEA mode and DVI solution sounds promising and probably (largely?)
explains what we see with drivers from nvidia or under windows (which
afaik default to limited range on televisions, full range on
monitors). As for how to treat automation, my personal preference
would be automatic but with manual override - how this would impact
existing users is of course the clincher. I also tend to think that
the selection should move to the xorg.conf rather than require xrandr.
Comment 9 Ville Syrjala 2013-01-14 14:32:32 UTC
(In reply to comment #8)
> The CEA mode and DVI solution sounds promising and probably (largely?)
> explains what we see with drivers from nvidia or under windows (which
> afaik default to limited range on televisions, full range on
> monitors). As for how to treat automation, my personal preference
> would be automatic but with manual override - how this would impact
> existing users is of course the clincher. I also tend to think that
> the selection should move to the xorg.conf rather than require xrandr.

I just posted the first cut for an automatic solution to the mailing list.

It's also available in my git tree here:
https://gitorious.org/vsyrjala/linux/commits/rgb_quant_range2

I wasn't able to test the AVI infoframe stuff as my TV doesn't support it. But otherwise it seems to work as intended, ie. the driver changes to limited range when a CEA video mode (except 640x480) is used, and otherwise uses full range.

My TV seems fairly happy with it, assuming I haven't changed the defaults on the TV side. This TV allows me to select the quantization range in CEA modes, and it remembers the selection for each mode. The default I assume is limited range for those. For non-CEA modes the TV is hardcoded to use full range, without any option to override it.

As for xorg.conf, I'll leave stuff like that for Chris to decide.
Comment 10 Paul Owen 2013-01-29 15:53:49 UTC
> It's also available in my git tree here:https://gitorious.org/vsyrjala/linux/commits/rgb_quant_range2
>
> I wasn't able to test the AVI infoframe stuff as my TV doesn't support it. But
> otherwise it seems to work as intended, ie. the driver changes to limited range
> when a CEA video mode (except 640x480) is used, and otherwise uses full range.
>
> My TV seems fairly happy with it, assuming I haven't changed the defaults on
> the TV side. This TV allows me to select the quantization range in CEA modes,
> and it remembers the selection for each mode. The default I assume is limited
> range for those. For non-CEA modes the TV is hardcoded to use full range,
> without any option to override it.
>
> As for xorg.conf, I'll leave stuff like that for Chris to decide.
>
>  ------------------------------
> You are receiving this mail because:
>
>    - You reported the bug.
>
>  I finally tried this out yesterday, all seems to work okay with one
(potential) issue. I set a modeline to try (fractional framerate issues
aside) set a mode for 1280x720 @ 59.94Hz. When switching to this mode the
automatic setting seems to set the range to full. As noted it's fine on
1280x720 @ 50Hz and @ 60Hz. Equally it works fine if explicitly setting
Limited Range. I cannot test 1920x1080 modes since the TV doesn't support
full HD but my guess would be the same thing would be seen for 23.976Hz. Of
course this could all be but a blip.
Comment 11 Daniel Vetter 2013-01-29 15:58:17 UTC
It's somewhat expected - we do the automagic broadcast mode detection by comparing the passed-in mode to the exact mode from the hdmi spec. Now unfortunately no one has yet bothered to teach the drm core that some hdmi/cea modes also work with 1000/1001 the refresh rate. So we neither expose those in the mode lists the kernel generates, no do we correctly set hdmi infoframe parameters and decide about the broadcast mode correctly ...
Comment 12 Florian Mickler 2013-03-04 22:52:42 UTC
A patch referencing this bug report has been merged in Linux v3.9-rc1:

commit 3685a8f38f2c54bb6058c0e66ae0562f8ab84e66
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Thu Jan 17 16:31:28 2013 +0200

    drm/i915: Fix RGB color range property for PCH platforms
Comment 13 Marco Vuano 2013-04-09 17:47:36 UTC
Using limited range always create banding on non-video material (only 220 levels are used), furthermore on televisions and monitors set to accept a full range it lowers contrast. Many televisions now have a setting to accept full range RGB values over HDMI, and it is much easier to find for non-expert than using xrandr. 
In fact, on Windows we have the inverse problem, that is only limited range RGB values are output when using modes related to television with Intel GPUs, and I think this is a worse problem than having full range RGB values output as default (I solved the latter problem in much less time just by setting correctly my TV monitor). You can see the discussion on these two threads:
http://communities.intel.com/message/156323
Therefore, while I think that the automatic setting makes sense, I still think that the default setting should be full range, with the option on xrandr to set limited or automatic range.
Comment 14 Marco Vuano 2013-04-09 17:49:20 UTC
The other thread is
communities.intel.com/message/137125
Comment 15 Ville Syrjala 2013-04-10 19:06:17 UTC
(In reply to comment #10)
> > It's also available in my git tree here:https://gitorious.org/vsyrjala/linux/commits/rgb_quant_range2
> >
> > I wasn't able to test the AVI infoframe stuff as my TV doesn't support it. But
> > otherwise it seems to work as intended, ie. the driver changes to limited range
> > when a CEA video mode (except 640x480) is used, and otherwise uses full range.
> >
> > My TV seems fairly happy with it, assuming I haven't changed the defaults on
> > the TV side. This TV allows me to select the quantization range in CEA modes,
> > and it remembers the selection for each mode. The default I assume is limited
> > range for those. For non-CEA modes the TV is hardcoded to use full range,
> > without any option to override it.
> >
> > As for xorg.conf, I'll leave stuff like that for Chris to decide.
> >
> >  ------------------------------
> > You are receiving this mail because:
> >
> >    - You reported the bug.
> >
> >  I finally tried this out yesterday, all seems to work okay with one
> (potential) issue. I set a modeline to try (fractional framerate issues
> aside) set a mode for 1280x720 @ 59.94Hz. When switching to this mode the
> automatic setting seems to set the range to full. As noted it's fine on
> 1280x720 @ 50Hz and @ 60Hz. Equally it works fine if explicitly setting
> Limited Range. I cannot test 1920x1080 modes since the TV doesn't support
> full HD but my guess would be the same thing would be seen for 23.976Hz. Of
> course this could all be but a blip.

I took a stab at fixing the mode matching with fractional refresh rates.

Could you give this branch a try and see if it works for you?
git://gitorious.org/vsyrjala/linux.git cea_clocks3
Comment 16 m3rocket 2013-05-14 19:06:50 UTC
I'm now using the build with the 3.9 kernel that includes this fix. The auto-detect seems to work well in my setup (i3 w/HD3000, Zotac ID82). 

However, it seems like there is still the problem even with the color range set properly. It looks like the green and blue saturation levels at 75% to 100% stimulus are being output incorrectly? I posted screen shots demonstrating this problem here:
http://openelec.tv/forum/116-vaapi-intel/63796-incorrect-green-levels-and-or-over-saturation
Comment 17 Oyvind Kvalsvoll 2013-05-15 02:18:41 UTC
(In reply to comment #16)
> I'm now using the build with the 3.9 kernel that includes this fix. The
> auto-detect seems to work well in my setup (i3 w/HD3000, Zotac ID82). 
> 
> However, it seems like there is still the problem even with the color range
> set properly. It looks like the green and blue saturation levels at 75% to
> 100% stimulus are being output incorrectly? I posted screen shots
> demonstrating this problem here:
> http://openelec.tv/forum/116-vaapi-intel/63796-incorrect-green-levels-and-or-
> over-saturation

Yes, indeed it look like the green level is clipped in the upper range. 
I never noticed, once the grey levels were right I thought it was good and fixed.
Comment 18 Ville Syrjala 2013-05-29 13:47:49 UTC
(In reply to comment #16)
> I'm now using the build with the 3.9 kernel that includes this fix. The
> auto-detect seems to work well in my setup (i3 w/HD3000, Zotac ID82). 
> 
> However, it seems like there is still the problem even with the color range
> set properly. It looks like the green and blue saturation levels at 75% to
> 100% stimulus are being output incorrectly? I posted screen shots
> demonstrating this problem here:
> http://openelec.tv/forum/116-vaapi-intel/63796-incorrect-green-levels-and-or-
> over-saturation

I would guess that the problem is somewhere else. Maybe the CSC is using BT.601 conversion matrix instead of BT.709?

I tried to code up a small tool to generate similar patterns and can't reproduce the problem on my IVB at least. Depending on the picture settings of my TV, I can get some clipping on different channels (blue seems to clip most, then red, and green the least). In "Movie" mode I don't get any clipping however.

You should grab the framebuffer contents and see what kind of levels are actually being scanned out (assuming you're not using an overlay plane to scan out YUV directly...)
Comment 19 Daniel Vetter 2013-10-28 18:20:08 UTC
Ville: Isn't this now fixed? If so please close, bonus points for adding commit citations ;-)
Comment 20 Ville Syrjala 2013-10-28 18:38:29 UTC
Yeah, let's just close it finally.

This is a list of commits that implement the various user observable changes related to this bug (hopefully didn't forget any important ones):

commit e6e792092e816bea0797995c886fb057c91d4546
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Fri May 31 15:23:41 2013 +0300

    drm/edid: Add both 60Hz and 59.94Hz CEA modes to connector's mode list

commit a90b590e957d66ea357aeff4cee8425f2567ed33
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Wed Apr 24 19:07:18 2013 +0300

    drm/edid: Check both 60Hz and 59.94Hz when looking for a CEA mode

commit abedc077b45eff0b5a8630af8431ad5d59213582
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Thu Jan 17 16:31:31 2013 +0200

    drm/i915: Provide the quantization range in the AVI infoframe

commit 55bc60db5988c8366751d3d04dd690698a53412c
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Thu Jan 17 16:31:29 2013 +0200

    drm/i915: Add "Automatic" mode for the "Broadcast RGB" property
Comment 21 Lauri Mylläri 2013-11-18 18:30:16 UTC
The quantization range signaling doesn't seem to be working on Haswell.

I am outputting from a D54250WYK NUC to Pioneer KRP-500m (via Yamaha RX-A1000) and seeing grey blacks with the default limited RGB range. When I switch to full range using xrandr, picture is fine. I assume my monitor supports switching RGB range automatically as my bluray player is able to signal it (switch player output RGB range between full and limited, displayed black levels do not change; I can verify that the output range really changes by setting input range manually in the Pioneer).

There are more people in the xbmc forum nuc thread (see for example starting at http://forum.xbmc.org/showthread.php?tid=176718&pid=1548847#pid1548847) reporting grey blacks with the default setting, so it's probably not just my system. Based on http://forum.xbmc.org/showthread.php?tid=176718&pid=1552262#pid1552262 (and the few comments following), same issue may be present on earlier chipsets too.

Unfortunately I don't have access to an HDMI analyzer. Is there any other way I could supply useful data?


For best quality it would be nice to have full range output, but have the ability to signal limited range if desired. This would preserve blacker-than-black, whiter-than-white and avoid banding from luma range expansion.
Comment 22 Daniel Vetter 2013-11-18 18:48:04 UTC
(In reply to comment #21)
> The quantization range signaling doesn't seem to be working on Haswell.
> 
> I am outputting from a D54250WYK NUC to Pioneer KRP-500m (via Yamaha
> RX-A1000) and seeing grey blacks with the default limited RGB range. When I
> switch to full range using xrandr, picture is fine. I assume my monitor
> supports switching RGB range automatically as my bluray player is able to
> signal it (switch player output RGB range between full and limited,
> displayed black levels do not change; I can verify that the output range
> really changes by setting input range manually in the Pioneer).
> 
> There are more people in the xbmc forum nuc thread (see for example starting
> at http://forum.xbmc.org/showthread.php?tid=176718&pid=1548847#pid1548847)
> reporting grey blacks with the default setting, so it's probably not just my
> system. Based on
> http://forum.xbmc.org/showthread.php?tid=176718&pid=1552262#pid1552262 (and
> the few comments following), same issue may be present on earlier chipsets
> too.
> 
> Unfortunately I don't have access to an HDMI analyzer. Is there any other
> way I could supply useful data?
> 
> 
> For best quality it would be nice to have full range output, but have the
> ability to signal limited range if desired. This would preserve
> blacker-than-black, whiter-than-white and avoid banding from luma range
> expansion.

Please file a new bug and provid details about your kernel (booting with drm.debug=0xe and dmesg preferred, it's all in there).
Comment 23 Ville Syrjala 2013-11-18 19:28:01 UTC
(In reply to comment #21)
> The quantization range signaling doesn't seem to be working on Haswell.
> 
> I am outputting from a D54250WYK NUC to Pioneer KRP-500m (via Yamaha
> RX-A1000) and seeing grey blacks with the default limited RGB range. When I
> switch to full range using xrandr, picture is fine. I assume my monitor
> supports switching RGB range automatically as my bluray player is able to
> signal it (switch player output RGB range between full and limited,
> displayed black levels do not change; I can verify that the output range
> really changes by setting input range manually in the Pioneer).

Hmm. We're supposed to be sending the quantization range in the infoframe iff the sink says it supports quantization range selection.

To verify boot /w drm.debug=6 and look for "CEA VCDB ..." in the log. Or just attach the EDID here, and I can double check whether we're decoding it correctly.

But note that we support RGB output only, whereas your bluray player could be outputting YCbCr, which has its own quantization range selection. In theory
I think we should default to YCbCr for CEA formats when the sink supports it.
But that still doesn't excuse the sink for not respecting the spec wrt. the
RGB quantization range rules. I can only assume that the compliance tests (if there are any, I don't know) don't check for this case since there appear to a significant number of monitors that fail this.

> 
> There are more people in the xbmc forum nuc thread (see for example starting
> at http://forum.xbmc.org/showthread.php?tid=176718&pid=1548847#pid1548847)
> reporting grey blacks with the default setting, so it's probably not just my
> system. Based on
> http://forum.xbmc.org/showthread.php?tid=176718&pid=1552262#pid1552262 (and
> the few comments following), same issue may be present on earlier chipsets
> too.
> 
> Unfortunately I don't have access to an HDMI analyzer. Is there any other
> way I could supply useful data?
> 
> 
> For best quality it would be nice to have full range output, but have the
> ability to signal limited range if desired. This would preserve
> blacker-than-black, whiter-than-white and avoid banding from luma range
> expansion.

We're trying to do it according to spec. Limited range for CEA video formats except 640x480, and full range for the rest. If we would default to full range, we'd cause problems for spec compliant monitors that don't implement the quantization range selection infoframe knob. That's assuming there are enough
spec compliant monitors out there to justify it. If there are a lot more non-compliant monitors, then I guess we should rethink this decision. Unfortunately I have no way of knowing what the ratio of bad vs. good monitors is.
Comment 24 Lauri Mylläri 2013-11-18 20:06:04 UTC
Thank you for the quick response. I will open a new bug and provide logs tonight.

(In reply to comment #23)
> But note that we support RGB output only, whereas your bluray player could
> be outputting YCbCr, which has its own quantization range selection.

This should not be an issue. The player (Oppo BDP-93) allows selecting between "RGB Video Level", "RGB PC Level", "YCbCr 4:4:4" and "YCbCr 4:2:2". These all seem to function as expected (tested with manual input settings on the monitor). Switching between "RGB Video Level" and "RGB PC Level" doesn't affect visible black levels when monitor is set to automatic input format, but using manual input level setting on the monitor confirms that the RGB range changes between them.

Of course this is still not a perfect data point as the player and monitor are a popular combination and there may be something Pioneer specific in the player firmware.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.