Bug 21522 - [GM45] Bad chroma upsampling on videos
Summary: [GM45] Bad chroma upsampling on videos
Status: RESOLVED DUPLICATE of bug 22895
Alias: None
Product: xorg
Classification: Unclassified
Component: Driver/intel (show other bugs)
Version: 7.4 (2008.09)
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: haihao
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-02 07:45 UTC by bofphile
Modified: 2009-08-05 18:21 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Xorg.0.log (28.40 KB, text/x-log)
2009-05-02 07:45 UTC, bofphile
no flags Details
Output of lspci -vvnn (18.09 KB, application/octet-stream)
2009-05-02 07:47 UTC, bofphile
no flags Details
Output of lspci -vvnn (18.09 KB, text/x-log)
2009-05-02 07:49 UTC, bofphile
no flags Details

Description bofphile 2009-05-02 07:45:02 UTC
Created attachment 25368 [details]
Xorg.0.log

I'm using Ubuntu 9.04 with xserver-xorg-video-intel 2.7.0 from this ppa: https://launchpad.net/~ubuntu-x-swat/+archive/x-updates/





Problem: Whenever I view videos (with totem-gstreamer or mplayer), some areas of the picture are pixelated.

This is especially noticeable on reds. Here you can see what it looks like.
 (taken from this thread on Doom9's forum discussing this problem on Windows : http://forum.doom9.org/showthread.php?t=141066 )
http://pwp.netcabo.pt/kado/off.png


After some research, I found out this problem may be due to bad chroma upsampling. Below is an explanation I read  on the Doom9's forum:



"Well, since our eyes are less sensitive to chroma than to luma (i.e. we notice changes in brightness more than changes in color) video is usually compressed with the chroma (i.e. the color information) at half the resolution of the luma (brightness information) - that's part of what makes YV12 what it is.



For conversion back to RGB (which is what displays, well, display) you of course need to scale the chroma data so it's the same size as the luma data, and if you get blocks it has been done by point resizing (i.e. by making every "chroma pixel" twice as big), whereas my shader turns the point resizing into bilinear resizing (i.e. I interpolate between the existing values to make the chroma smoother)."



Also this problem occurs with SD (DVD) and HD (Bluray) content.'
Comment 1 bofphile 2009-05-02 07:47:49 UTC
Created attachment 25369 [details]
Output of lspci -vvnn
Comment 2 bofphile 2009-05-02 07:49:48 UTC
Created attachment 25370 [details]
Output of lspci -vvnn
Comment 3 Eric Anholt 2009-05-12 15:53:45 UTC
The driver does do bilinear filtering between the texels.  We don't do doubling of the texels, since we don't convert planar to packed.

Do you have a specific proposal of how to improve the situation?

Comment 4 bofphile 2009-05-13 02:56:11 UTC
Unfortunately I don't have much knowledge in programming or driver development. But I know there is a similar issue with the ATI Catalyst driver on Windows, as you can see with this link: http://forum.doom9.org/showthread.php?t=141066 , and someone created a shader for Media Player Classic HC to correct the problem via point resize:
"
/*
YV12 chroma upsampling fixer
by Kurt Bernhard 'Leak' Pruenner

Use with YV12 output if the half-resolution chroma 
gets upsampled in hardware by doubling the values
instead of interpolating between them.

(i.e. if you're getting blocky red edges on dark 
backgrounds...)
*/

sampler s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);

#define width (p0[0])
#define height (p0[1])

float4 getPixel(float2 tex, float dx, float dy)
{
	tex.x+=dx;
	tex.y+=dy;
	
	return tex2D(s0, tex);
}

float4 rgb2yuv(float4 rgb)
{
	float4x4 coeffs=
		{
			 0.299, 0.587, 0.114, 0.000,
			-0.147,-0.289, 0.436, 0.000,
			 0.615,-0.515,-0.100, 0.000,
			 0.000, 0.000, 0.000, 0.000
		};
		
	return mul(coeffs,rgb);
}

float4 yuv2rgb(float4 yuv)
{
	float4x4 coeffs=
		{
			 1.000, 0.000, 1.140, 0.000,
			 1.000,-0.395,-0.581, 0.000,
			 1.000, 2.032, 0.000, 0.000,
			 0.000, 0.000, 0.000, 0.000
		};
	
	return mul(coeffs,yuv);
}

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float dx=1/width;
	float dy=1/height;
	
	float4 yuv00=rgb2yuv(getPixel(tex,-dx,-dy));
	float4 yuv01=rgb2yuv(getPixel(tex,-dx,  0));
	float4 yuv02=rgb2yuv(getPixel(tex,-dx, dy));
	float4 yuv10=rgb2yuv(getPixel(tex,  0,-dy));
	float4 yuv11=rgb2yuv(getPixel(tex,  0,  0));
	float4 yuv12=rgb2yuv(getPixel(tex,  0, dy));
	float4 yuv20=rgb2yuv(getPixel(tex, dx,-dy));
	float4 yuv21=rgb2yuv(getPixel(tex, dx,  0));
	float4 yuv22=rgb2yuv(getPixel(tex, dx, dy));

	float4 yuv=
		(yuv00*1+yuv01*2+yuv02*1+
		 yuv10*2+yuv11*4+yuv12*2+
		 yuv20*1+yuv21*2+yuv22*1)/16;
	
	yuv.r=yuv11.r;

	return yuv2rgb(yuv);
}

"

Here is a description of what it does "What it does is actually quite dumb - it takes each pixel from the (blocky) RGB image the shader gets fed as well as the ones to the right, bottom right and bottom, converts them back to YUV, averages the U and V values of those 4 pixels then converts the result back to RGB and returns it, effectively turning the ugly point resize that creates the blocky edges into a bilinear resize that is much easier on the eyes..."

Now I don't know if this can be done at the driver level ?
Comment 5 bofphile 2009-06-07 09:57:50 UTC
Do you think this can be solved relatively easily ? Also I tried the ATI open source driver "radeonhd" (on my desktop with a Radeon HD3850) and this issue was not present.
Comment 6 bofphile 2009-06-11 01:19:12 UTC
It seems like my is related to this one "xvideo: broken bilinear filter for the red color component": https://bugs.freedesktop.org/show_bug.cgi?id=19856
Comment 7 haihao 2009-08-05 18:21:25 UTC
It should be fixed by the following commit:
commit 79b6851148574419389ac8055b0c31b8bdac3ab3
Author: Eric Anholt <eric@anholt.net>
Date:   Wed Aug 5 12:45:16 2009 -0700

    Fix sampler indexes on i965 planar video.

    We only set up one sampler, because all of our sampling is the same.  By
    using a non-zero index for the other two samplers, we'd dereference
(likely)
    zeroed data, resulting in using NEAREST filtering.  This was a regression
in
    40671132cb3732728703c6444f4577467fa9223f which incidentally switched from
    having 6 samplers to 1.

    Bug #22895, #19856


*** This bug has been marked as a duplicate of bug 22895 ***


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.