wrong colors with Xv extension and image format id: 0x59565955 (UYVY) from an rgb mapping

Tomas Carnecky tom at dbservice.com
Thu Jan 22 02:36:59 PST 2009


On 01/22/2009 11:26 AM, Amos Tibaldi wrote:
>
>
> 2009/1/22 Tomas Carnecky <tom at dbservice.com <mailto:tom at dbservice.com>>
>
>     On 01/22/2009 06:15 AM, Amos Tibaldi wrote:
>
>
>         Hello,
>         I am trying to use the Xv extension in order to display images on
>         windows. I have obtained the image formats with
>         xvc.fo <http://xvc.fo> <http://xvc.fo> = XvListImageFormats(
>         xvc.display, xvc.port, (int
>
>         *)&formats );
>         and I have chosen the format
>         id: 0x59565955 (UYVY)
>         guid: 55595659-0000-0010-8000-00aa00389b71
>         bits per pixel: 16
>         number of planes: 1
>         type: YUV (packed)
>
>
>     [snip]
>
>
>         and to display the image with
>         void XVWindow::Redraw()
>         {
>         unsigned short int u, y, v;
>         RGBToUYVY(255,255,0,&u,&y,&v);
>         unsigned short int thecolor = u << 12 | y << 8 | v << 4 | y;
>
>         for ( int y=0; y<ImageHeight; y++ )
>         for ( int x=0; x<ImageWidth; x++ )
>         ((unsigned short int *)BGimage->data)[ y * ImageWidth + x ] =
>         thecolor;
>
>         counter++;
>         XvPutImage( xvc.display, xvc.port, window, gc,
>         BGimage, 0, 0, ImageWidth, ImageHeight,
>         0, 0, WindowWidth, WindowHeight );
>         }
>
>
>     I think you are confused by 'bits per pixel: 16' in the Xv format
>     list. Your code in :Redraw() that composes the pixel is wrong. I
>     know I couldn't explain it better, so I'm including a link to a
>     website that explains it pretty well:
>     http://www.fourcc.org/yuv.php#YUY2
>     (Each macropixel is 32 bits, so each of the YUV components is 8 bit
>     and not 4 like you used in your code)
>
>     tom
>
>
> Hello, BGImage->data_size is equal to w x h x 2 bytes (2B per pixel in
> the data allocated), and X has calculated it. Moreover I have tried even
> with
> <<24 |<<16|<<8 and the thing is the same. Are you sure of that?
>

Yes, I'm sure of that.

There's one Y per pixel, U and V are downsampled (one U and one V per 
two pixels). You need to process two pixels at once. Y0 and Y1 is 
separate for each pixel, U0 and V0 is for both pixels.

Your code should be:
for ( int x=0; x<ImageWidth/2; x+=2 ) {
   // get r,g,b of pixel one, convert that to Y0
   // get r,g,b of pixel two, convert that to Y1
   // average of r,g,b of pixel one+two, convert that to U0 and V0

   // assuming BGimage->data is of type 'unsigned char', eg. 8 bit

   // now we write one 'macropixel' or two 'screen-pixels'
   // that's 32bits, but because it's two screen pixels, the effective
   // 'bits per pixel' is 16.
   BGimage->data[ y * ImageWidth + (x + 0) ] = Y0;
   BGimage->data[ y * ImageWidth + (x + 1) ] = U0;
   BGimage->data[ y * ImageWidth + (x + 2) ] = Y1;
   BGimage->data[ y * ImageWidth + (x + 3) ] = V0;
}






More information about the xorg mailing list