Go to previous topic
Go to next topic
Last Post 12 Oct 2009 07:17 PM by  dblockil
cvideo evm test example
 1 Replies
Author Messages
dblockil
New Member
New Member
Posts:


--
02 Oct 2009 01:33 PM
    I have the cvideo example working on my EVM. Now what I am trying to do is convert the YCbCr format to RGB. I think I understand how the data is stored in DDR Ram, at least I am able to produce a good BW image plot in CCS 3.3 image graphic view. My assumption is that Y0,Y2,Y4 etc is store in LUM_TOP buffer, Y1,Y3,Y5 etc is stored in LUM_BOTTOM buffer. CHROM_BOT and CHROM_BOTTOM I think are what have me confused. Is Cb stored in CHROM_TOP and Cr stored in CHROM_BOTTOM? What is the formula to convert from YCrCb to RGB? I have tried the following code below but have not been able to get a good RGB image. The commented code are a number of my different trys. This code is inside a dual r and c for loop, looping through 480X720 rgb values.
    Thanks

    Dan Block

    myrgb = (rgb *)(0xC2000000);
    ytop = (unsigned char *)(0xC1000000);
    ybottom = (unsigned char *)(0xC1000000 + 240*720);

    Cb = (unsigned char *)(0xC1000000 + 2*240*720);
    Cr = (unsigned char *)(0xC1000000 + 3*240*720);

    /* coeff[] = { 0x2000, 0x2BDD, -0x0AC5, -0x1658, 0x3770 }; */
    /* */
    /* [ 1.0000 0.0000 1.3707 ] [ Y' - 16 ] [ R'] */
    /* [ 1.0000 -0.3365 -0.6982 ] * [ Cb - 128 ] = [ G'] */
    /* [ 1.0000 1.7324 0.0000 ] [ Cr - 128 ] [ B'] */
    /* */
    myrgb[r*720+c].r=(unsigned char)( (ytop[(r/2)*720+c]-16) + 1.3707*(Cr[(r/2)*720+c]-128));myrgb[r*720+c].g=(unsigned char)( (ytop[(r/2)*720+c]-16) - 0.3365*(Cb[(r/2)*720+c]-128) - 0.6982*(Cr[(r/2)*720+c]-128) );myrgb[r*720+c].b=(unsigned char)( (ytop[(r/2)*720+c]-16) + 1.7324*(Cb[(r/2)*720+c]-128) );

    myrgb[(r+1)*720+c].r=(unsigned char)( (ybottom[((r+1)/2)*720+c]-16) + 1.3707*(Cr[((r+1)/2)*720+c]-128));
    myrgb[(r+1)*720+c].g=(unsigned char)( (ybottom[((r+1)/2)*720+c]-16) - 0.3365*(Cb[((r+1)/2)*720+c]-128) - 0.6982*(Cr[((r+1)/2)*720+c]-128) );
    myrgb[(r+1)*720+c].b=(unsigned char)( (ybottom[((r+1)/2)*720+c]-16) + 1.7324*(Cb[((r+1)/2)*720+c]-128));




    /* 2. Y'CbCr -> RGB conversion with the 219-level range of Y' */
    /* expanded to fill the full RGB dynamic range. (The matrix */
    /* has been scaled by 255/219.) Expected ranges are [16..235] */
    /* for Y' and [16..240] for Cb and Cr. */
    /* */
    /* coeff[] = { 0x2543, 0x3313, -0x0C8A, -0x1A04, 0x408D }; */
    /* */
    /* [ 1.1644 0.0000 1.5960 ] [ Y' - 16 ] [ R'] */
    /* [ 1.1644 -0.3918 -0.8130 ] * [ Cb - 128 ] = [ G'] */
    /* [ 1.1644 2.0172 0.0000 ] [ Cr - 128 ] [ B'] */

    // myrgb[r*720+c].r=(unsigned char)( 1.1644*(ytop[(r/2)*720+c]-16) + 1.5960*(Cr[(r/2)*720+c]-128));
    // myrgb[r*720+c].g=(unsigned char)( 1.1644*(ytop[(r/2)*720+c]-16) - 0.3918*(Cb[(r/2)*720+c]-128) - 0.8130*(Cr[(r/2)*720+c]-128) );
    // myrgb[r*720+c].b=(unsigned char)( 1.1644*(ytop[(r/2)*720+c]-16) + 2.0172*(Cb[(r/2)*720+c]-128) );

    // myrgb[(r+1)*720+c].r=(unsigned char)( 1.1644*(ybottom[((r+1)/2)*720+c]-16) + 1.5960*(Cr[((r+1)/2)*720+c]-128));
    // myrgb[(r+1)*720+c].g=(unsigned char)( 1.1644*(ybottom[((r+1)/2)*720+c]-16) - 0.3918*(Cb[((r+1)/2)*720+c]-128) - 0.8130*(Cr[((r+1)/2)*720+c]-128) );
    // myrgb[(r+1)*720+c].b=(unsigned char)( 1.1644*(ybottom[((r+1)/2)*720+c]-16) + 2.0172*(Cb[((r+1)/2)*720+c]-128));


    // myrgb[r*720+c].r=(unsigned char)( ytop[(r/2)*720+c] + 1.402*Cr[(r/2)*720+c]);
    // myrgb[r*720+c].g=(unsigned char)( ytop[(r/2)*720+c] - 0.344*Cb[(r/2)*720+c] - 0.714*Cr[(r/2)*720+c] );
    // myrgb[r*720+c].b=(unsigned char)( ytop[(r/2)*720+c] + 1.772*Cb[(r/2)*720+c] );

    // myrgb[(r+1)*720+c].r=(unsigned char)( ybottom[((r+1)/2)*720+c] + 1.402*Cr[((r+1)/2)*720+c]);
    // myrgb[(r+1)*720+c].g=(unsigned char)( ybottom[((r+1)/2)*720+c] - 0.344*Cb[((r+1)/2)*720+c] - 0.714*Cr[((r+1)/2)*720+c] );
    // myrgb[(r+1)*720+c].b=(unsigned char)( ybottom[((r+1)/2)*720+c] + 1.772*Cb[((r+1)/2)*720+c] );

    /*
    Cint = (int)ytop[(r/2)*720+c] - 16;
    // Dint = (int)((Cr[(r/2)*720+c]*1.403) + 0.5) - 128;
    // Eint = (int)((Cb[(r/2)*720+c]*1.773) + 0.5) - 128;
    Dint = (int)((Cr[(r/2)*720+c]) + 0.5) - 128;
    Eint = (int)((Cb[(r/2)*720+c]) + 0.5) - 128;

    redint=( 298*Cint + 409*Eint + 128)>>8;
    greenint=( 298*Cint - 100*Dint - 208*Eint + 128 )>>8;
    blueint=( 298*Cint + 516*Dint + 128)>>8;

    myrgb[r*720+c].r=(unsigned char)redint;
    myrgb[r*720+c].g=(unsigned char)greenint;
    myrgb[r*720+c].b=(unsigned char)blueint;

    Cint = (int)ybottom[((r+1)/2)*720+c] - 16;
    redint=( 298*Cint + 409*Eint + 128)>>8;
    greenint=( 298*Cint - 100*Dint - 208*Eint + 128 )>>8;
    blueint=( 298*Cint + 516*Dint + 128)>>8;

    myrgb[(r+1)*720+c].r=(unsigned char)redint;
    myrgb[(r+1)*720+c].g=(unsigned char)greenint;
    myrgb[(r+1)*720+c].b=(unsigned char)blueint;
    */


    // BW
    // myrgb[r*720+c].r=(unsigned char)( ytop[(r/2)*720+c]);
    // myrgb[r*720+c].g=(unsigned char)( ytop[(r/2)*720+c]);
    // myrgb[r*720+c].b=(unsigned char)( ytop[(r/2)*720+c]);

    // myrgb[(r+1)*720+c].r=(unsigned char)( ybottom[((r+1)/2)*720+c]);
    // myrgb[(r+1)*720+c].g=(unsigned char)( ybottom[((r+1)/2)*720+c]);
    // myrgb[(r+1)*720+c].b=(unsigned char)( ybottom[((r+1)/2)*720+c]);
    dblockil
    New Member
    New Member
    Posts:


    --
    12 Oct 2009 07:17 PM
    I think I have answered my own question after a bunch of trial and error. Here is the way I think the YCbCr data is stored in the cvideo example.

    ytop = (unsigned char *)(0xC1000000);
    ybottom = (unsigned char *)(0xC1000000 + 240*720);

    Ctop = (unsigned char *)(0xC1000000 + 2*240*720);
    Cbottom = (unsigned char *)(0xC1000000 + 3*240*720);

    Naming convention
    Pixel Row 0 Column 0 Y0Cb0Cr0
    Pixel Row 1 Column 0 Y1Cb0Cr0
    Pixel Row 0 Column 1 Y2Cb2Cr2
    Pixel Row 1 Column 1 Y3Cb2Cr2
    Pixel Row 0 Column 2 Y4Cb4Cr4
    Pixel Row 1 Column 2 Y5Cb4Cr4
    Pixel Row 0 Column 3 Y6Cb6Cr6
    Pixel Row 1 Column 3 Y7Cb6Cr6


    Then you pull the YCbCr data out in this fashion
    Y0 = ytop(0) ;
    Y1 = ybottom(0);
    Cb0 = Ctop(0);
    Cr0 = Ctop(1);
    Y2 = ytop(1);
    Y3 = ybottom(1);
    Cb2 = Cbottom(0);
    Cr2 = Cbottom(1);
    Then repeating again
    Y4 = ytop(2) ;
    Y5 = ybottom(2);
    Cb4 = Ctop(2);
    Cr4 = Ctop(3);
    Y6 = ytop(3);
    Y7 = ybottom(3);
    Cb6 = Cbottom(2);
    Cr6 = Cbottom(3);

    Does this look correct?


    ---