VideoHelp Forum
+ Reply to Thread
Results 1 to 11 of 11
Thread
  1. Hi
    Can anybody tell me what is wrong with this C language function to convert YUV422 to YUV411? The image has the right definition but the colors are all mess up.
    static int conv422to411(char * src,char * dst, int width, int height)

    {
    int y1,y2, y3, y4,u,v;
    char * dst_inicial=dst;
    int rgb1, rgb2, rgb3, rgb4;
    int i=0;
    char buffer_yuv[12];
    unsigned char *clp=NULL;
    {
    /* intra frame */
    for (i=0; i< width*height*2; i+=8)
    {
    u=src[i];
    y1=src[i+1];
    v =src[i+2];
    y2=src[i+3];
    y3=src[i+5];
    y4=src[i+7];
    // move to YUV 411 buffer
    *dst++ = u; // move U
    *dst++ = y1; // move Y1
    *dst++ = v; // move V
    *dst++ = y2; // move y2
    *dst++ = y3; // move y3
    *dst++ = y4; // move y4
    }
    }

    Thanks
    Quote Quote  
  2. What is your YUV 4:2:2 format? YUY2? UYVY? And the 4:1:1 format? You intend to point sample U and Y?
    Quote Quote  
  3. Thanks for your reply.

    The YUV 4:2:2's format is UYVY..
    The YUV 4:1:1's format is UYVYYY

    I didn't understand this question : You intend to point sample U and Y?
    Quote Quote  
  4. Are you sure the 4:1:1 format is YUVYYY, not UYYVYY?

    Sorry, I made a typo. I meant to ask if you wanted to point sample U and V (not Y). You're reducing two U values to one U value, and two V values to one V value. You're code is doing so by throwing away one U and one V.
    Quote Quote  
  5. Sorry the 4:1:1 format is UYVYYY. I included the code for the 4:1:1 to RGB decoder in C# below.
    I just want to make the 411 image to be as close to the original 422 is.
    To be honest I just throw U and V because I don't know to think a better procedure.

    namespace YUYDecoder
    {
    public class YUYDecoder
    {
    private int clip(int x){
    if (x>255) x=255;
    else if (x<0) x=0;
    return x;
    }

    private int get_pixel_yuv(byte y, sbyte u, sbyte v, sbyte x){
    int r, g, b;
    r=clip(((y<<12) + v*5743 + 2048)>>12);
    g=clip(((y<<12) - u*1411 - v*2925 + 2048)>>12);
    b=clip(((y<<12) + u*7258 + 2048)>>12);

    r = clip(r + x);
    g = clip(g + x);
    b = clip(b + x);

    return (r<<16)|(g<<8)|b;
    }

    public unsafe byte[] Decode(int width, int height, byte[] buffer, sbyte brightness)
    {
    byte[] acol = new byte[width * height * 4];

    fixed (byte* pcol = acol, pbuf1 = buffer) {
    int* col = (int *)pcol;
    byte* buf1 = (byte*)pbuf1;
    // Stopwatch sw = Stopwatch.StartNew();

    for (int y = 0; y < height; y++)
    {
    for (int x = 0; x < width; x += 4, buf1 += 6)
    { UYVYYY
    if (x < width)
    {
    *col++ = get_pixel_yuv(buf1[1], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
    *col++ = get_pixel_yuv(buf1[3], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
    *col++ = get_pixel_yuv(buf1[4], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
    *col++ = get_pixel_yuv(buf1[5], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
    }
    }
    }

    // sw.Stop();
    // long milliSec = sw.ElapsedMilliseconds;
    }

    return acol;
    }

    public bool Brighten(Bitmap b, int nBrightness)
    {
    // GDI+ return format is BGR, NOT RGB.
    BitmapData bmData
    = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    int stride = bmData.Stride;
    System.IntPtr Scan0 = bmData.Scan0;
    unsafe
    {
    int nVal;
    byte* p = (byte*)(void*)Scan0;
    int nOffset = stride - b.Width * 3;
    int nWidth = b.Width * 3;
    for (int y = 0; y < b.Height; ++y)
    {
    for (int x = 0; x < nWidth; ++x)
    {
    nVal = (int)(p[0] + nBrightness);
    if (nVal < 0) nVal = 0;
    if (nVal > 255) nVal = 255;
    p[0] = (byte)nVal;
    ++p;
    }
    p += nOffset;
    }
    }
    b.UnlockBits(bmData);
    return true;
    }

    }
    }
    Quote Quote  
  6. Any idea on how I can improve the code ?
    Thanks
    Quote Quote  
  7. So your code basically works but the colors are wrong? If you replace u and v with 128 (ie replace u=src[i]; with u=128;, and the same for v) do you get a perfect greyscale image?

    I would start by changing your "char" definitions for the YUV values to "unsigned char". And the same for the "int y1,y2, y3, y4,u,v". That will prevent possible automatic sign extension problems.

    Why don't you get rid of all the temp variables and change the inner loop to:

    Code:
    	for (i=0; i< width*height*2; i+=8)
    	{
    		// move UYVY(*2) to UYVYYY buffer
    		*dst++ = src[i];   // move U
    		*dst++ = src[i+1]; // move Y1
    		*dst++ = src[i+2]; // move V
    		*dst++ = src[i+3]; // move y2
    		*dst++ = src[i+5]; // move y3
    		*dst++ = src[i+7]; // move y4
    	}
    Last edited by jagabo; 3rd Apr 2014 at 11:09.
    Quote Quote  
  8. Hi
    I modify the code as your instruction and the image now is entirely green.
    Thanks
    Quote Quote  
  9. It worked on a small 4x2 image when I tested it. Time for the debugger, I guess.
    Quote Quote  
  10. Thanks a lot for your attention. I will make some testing and post the result.
    Quote Quote  
  11. Make sure your UYVY image has a mod 4 width. If you're building 16 bit code you will run into overflow problems with larger images.
    Quote Quote  



Similar Threads