converting YUV422 to RGB565

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



I have a tv card that outputs only YUV422 (packed), but both

mplayer CVS-021029-16:03-2.95.4: 
    mplayer -tv on:driver=v4l:norm=NTSC:width=640:height=480:outfmt=yuy2)

and xawtv 3.72:
    xawtv -geometry 640x480 -v 2  

seem to display it incorrectly (everything is pink and green).  
Incidentally, my X server is running in 16bpp RGB565 mode and the
xawtv output shows YUV422 being selected as the output palette and an
attempt to convert the image:
v4l: getimage
ioctl: VIDIOCMCAPTURE(0,fmt=7,size=640x480): ok
ioctl: VIDIOCSYNC(0): ok
gd: convert

Since both programs seem to behave the same, I figure it might be a problem 
on my end.

The video4linux driver has the following code:

int lgv_5480tvr_ioctl (struct video_device *dev,
                       unsigned int cmd,
                       void *arg)
{
    switch (cmd) {
    case VIDIOCSPICT: {
        struct video_picture v;
        if (copy_from_user(&v, arg, sizeof(v)))
            return -EFAULT;
        if (v.palette != VIDEO_PALETTE_YUV422) {
            return -EINVAL;
        }
        ...
        return 0;
    }
    case VIDIOCMCAPTURE: {
        struct video_mmap v;
        if (copy_from_user(&v, arg, sizeof(v)))
            return -EFAULT;
        if (v.format != VIDEO_PALETTE_YUV422) {
            return -EINVAL;
        }
        ...
        return 0;
    }
    ...
}

This is the code I use to correctly convert to RGB24:

{
    int i, j, y, cr, cb, r, g, b;
    unsigned char *p1, *p2;
    int pitch_bytes;
    char *p;
    FILE *fp;

    fp = fopen ("screen-cap.ppm", "w");
    fprintf (fp, "P6\n# CREATOR: app (YUV_422)\n%d %d\n255", 
             capW, capH);
    p = video_data;  /* raw captured data */
    pitch_bytes = capW * 2;

    p1 = p;
    for (j = 0;  j < capH;  j++) {
        cr = cb = 0;
        p2 = p1;
        for (i = 0;  i < capW;  i++) {
            if (i & 1)
                cr = *p2++;
            else
                cb = *p2++;
            y = *p2++;

            /* YCrCb to RGB conversion formula from
             * "Video Demystified" by Keith Jack.
             * (ISBN 1-878707-09-4). 
             */

            b = 1.164 * (y - 16)                         + 2.018 * (cb -
128);
            g = 1.164 * (y - 16)  -  0.813 * (cr - 128)  - 0.391 * (cb -
128);
            r = 1.164 * (y - 16)  +  1.596 * (cr - 128);
#define LIMIT(x) ((x) = ((x) < 0) ? 0 : ((x) > 255) ? 255 : (x))
            LIMIT (r);
            LIMIT (g);
            LIMIT (b);
            putc (r, fp);
            putc (g, fp);
            putc (b, fp);
        }
        p1 += pitch_bytes;
    }

    fclose (fp);
}

Do I actually have YUV422 (packed) or is it some other wierd YUV422
thing??





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux