Search

Technical Discussion Group Forum

This forum is provided for user discussion. While Beacon EmbeddedWorks support staff and engineers participate, Beacon EmbeddedWorks does not guarantee the accuracy of all information within in the Technical Discussion Group (TDG).

The "Articles" forums provide brief Articles written by Beacon EmbeddedWorks engineers that address the most frequently asked technical questions.

To receive email notifications when updates are posted for a Beacon EmbeddedWorks product download, please subscribe to the TDG Forum of interest.

TDG Forum

PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 12 Oct 2009 07:17 PM by  dblockil
cvideo evm test example
 1 Replies
Sort:
You are not authorized to post a reply.
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?
    You are not authorized to post a reply.