Conversion from YUV444 to RGB888
- by Abhi
I am new in this field and i desperately need some guidance from u all. 
I have to support yuv444 to rgb 888 in display driver module.
There is one test which i have done for yv12 → rgb565 in wince 6.0 r3 which is mentioned below.   
//------------------------------------------------------------------------------
// 
// Function: PP_CSC_YV12_RGB565Test 
// 
// This function tests the Post-processor 
// 
//
//
// Parameters: 
// uiMsg 
// [in] Ignored. 
// 
// tpParam 
// [in] Ignored. 
// 
// lpFTE 
// [in] Ignored. 
// 
// Returns: 
// Specifies if the test passed (TPR_PASS), failed (TPR_FAIL), or was 
// skipped (TPR_SKIP). 
// 
//
TESTPROCAPI PP_CSC_YV12_RGB565Test(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
    {
 LogEntry(L"%d : In %s Function \r\n",++abhineet,__WFUNCTION__);
    UNREFERENCED_PARAMETER(tpParam);
    UNREFERENCED_PARAMETER(lpFTE);    
    DWORD dwResult= TPR_SKIP;
    ppConfigData ppData;
    DWORD iInputBytesPerFrame, iOutputBytesPerFrame;
    UINT32 iInputStride, iOutputStride;
    UINT16 iOutputWidth, iOutputHeight, iOutputBPP;
    UINT16 iInputWidth, iInputHeight, iInputBPP;
    int iOption;
    PP_TEST_FUNCTION_ENTRY();
    // Validate that the shell wants the test to run
    if (uMsg != TPM_EXECUTE)
    {
        return TPR_NOT_HANDLED;
    }
    PPTestInit();
    iInputWidth = PP_TEST_FRAME_WIDTH; //116
    iInputHeight = PP_TEST_FRAME_HEIGHT; //160
    iInputBPP = PP_TEST_FRAME_BPP; //2
    iInputStride = iInputWidth * 3/2; // YV12 is 12 bits per pixel
    iOutputWidth = PP_TEST_FRAME_WIDTH;
    iOutputHeight = PP_TEST_FRAME_HEIGHT;
    iOutputBPP = PP_TEST_FRAME_BPP;
    iOutputStride = iOutputWidth * iOutputBPP;
    // Allocate buffers for input and output frames
    iInputBytesPerFrame = iInputStride * iInputHeight;
    pInputFrameVirtAddr = (UINT32 *) AllocPhysMem(iInputBytesPerFrame, PAGE_EXECUTE_READWRITE, 0, 0, (ULONG *) &pInputFramePhysAddr);
    iOutputBytesPerFrame = iOutputStride * iOutputHeight;
    pOutputFrameVirtAddr = (UINT32 *) AllocPhysMem(iOutputBytesPerFrame, PAGE_EXECUTE_READWRITE, 0, 0, (ULONG *) &pOutputFramePhysAddr);
    if ((NULL == pInputFrameVirtAddr) || (NULL == pOutputFrameVirtAddr))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }
    //-----------------------------
    // Configure PP
    //-----------------------------
    // Set up post-processing configuration data
    memset(&ppData, 0 , sizeof(ppData));
    // Set up input format and data width
    ppData.inputIDMAChannel.FrameFormat = icFormat_YUV420;
    ppData.inputIDMAChannel.DataWidth = icDataWidth_8BPP;
    // dummy value for YUV
    ppData.inputIDMAChannel.PixelFormat.component0_offset = 0;
    ppData.inputIDMAChannel.PixelFormat.component1_offset = 8;
    ppData.inputIDMAChannel.PixelFormat.component2_offset = 16;
    ppData.inputIDMAChannel.PixelFormat.component3_offset = 24;
    ppData.inputIDMAChannel.PixelFormat.component0_width = 8-1;
    ppData.inputIDMAChannel.PixelFormat.component1_width = 8-1;
    ppData.inputIDMAChannel.PixelFormat.component2_width = 8-1;
    ppData.inputIDMAChannel.PixelFormat.component3_width = 8-1;
    ppData.inputIDMAChannel.FrameSize.height = iInputHeight;
    ppData.inputIDMAChannel.FrameSize.width = iInputWidth;
    ppData.inputIDMAChannel.LineStride = iInputWidth;
    // Set up output format and data width
    ppData.outputIDMAChannel.FrameFormat = icFormat_RGB;
    ppData.outputIDMAChannel.DataWidth = icDataWidth_16BPP;
    ppData.outputIDMAChannel.PixelFormat.component0_offset = RGB_COMPONET0_OFFSET;
    ppData.outputIDMAChannel.PixelFormat.component1_offset = RGB_COMPONET1_OFFSET;
    ppData.outputIDMAChannel.PixelFormat.component2_offset = RGB_COMPONET2_OFFSET;    
    ppData.outputIDMAChannel.PixelFormat.component3_offset = RGB_COMPONET3_OFFSET;
    ppData.outputIDMAChannel.PixelFormat.component0_width = RGB_COMPONET0_WIDTH -1;
    ppData.outputIDMAChannel.PixelFormat.component1_width = RGB_COMPONET1_WIDTH -1;
    ppData.outputIDMAChannel.PixelFormat.component2_width = RGB_COMPONET2_WIDTH -1;
    ppData.outputIDMAChannel.PixelFormat.component3_width = RGB_COMPONET3_WIDTH;    
    ppData.outputIDMAChannel.FrameSize.height = iOutputHeight;
    ppData.outputIDMAChannel.FrameSize.width = iOutputWidth;
    ppData.outputIDMAChannel.LineStride = iOutputStride;
    // Set up post-processing channel CSC parameters
    // based on input and output
    ppData.CSCEquation = CSCY2R_A1;
    ppData.inputIDMAChannel.UBufOffset = iInputHeight * iInputWidth + (iInputHeight * iInputWidth)/4;
    ppData.inputIDMAChannel.VBufOffset = iInputHeight * iInputWidth;
    ppData.FlipRot.verticalFlip = FALSE;
    ppData.FlipRot.horizontalFlip = FALSE;
    ppData.FlipRot.rotate90 = FALSE;
    if (!PPConfigure(hPP, &ppData))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }        
    //-----------------------------
    // Read first input buffer
    //-----------------------------
    // Read Input file for new frame
    if (!ReadImage(PP_TEST_YV12_FILENAME,pInputFrameVirtAddr,iInputBytesPerFrame,PP_TEST_FRAME_WIDTH,PP_TEST_FRAME_HEIGHT))
    {
        g_pKato->Log(PP_ZONE_ERROR, (TEXT("fail to ReadImage()!\r\n")));
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }
    //-----------------------------
    // Start PP
    //-----------------------------
    if (!PPStart(hPP))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }        
    if (!PPInterruptEnable(hPP, FRAME_INTERRUPT))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }    
    //-----------------------------
    // Queue Input/Output Buffers
    //-----------------------------
    UINT32 starttime = GetTickCount();
    // Add input and output buffers to PP queues.
    if (!PPAddInputBuffer(hPP, (UINT32) pInputFramePhysAddr))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }    
    if (!PPAddOutputBuffer(hPP,(UINT32) pOutputFramePhysAddr))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }    
    if (!PPWaitForNotBusy(hPP, FRAME_INTERRUPT))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }    
    RETAILMSG(1, (TEXT("===========FLIP TIME: %dms====== \r\n"),  GetTickCount()-starttime));
    //-----------------------------
    // Stop PP
    //-----------------------------
    if (!PPStop(hPP))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }
    if (!PPClearBuffers(hPP))
    {
        dwResult = TPR_FAIL;
        goto PP_CSC_YV12_RGB565Test_clean_up;    
    }    
    ShowRGBContent((UINT8 *) pOutputFrameVirtAddr, PP_TEST_FRAME_WIDTH, PP_TEST_FRAME_HEIGHT);
    iOption = MessageBox( NULL,TEXT("After CSC(YV12->RGB565). Is it correct?"),TEXT("Test result"),MB_YESNO );
    if ( IDNO == iOption )
    {
        dwResult = TPR_FAIL;
    }
    else 
    {
        dwResult = TPR_PASS;
    }
PP_CSC_YV12_RGB565Test_clean_up:
    if(NULL != pInputFrameVirtAddr)
    {
        FreePhysMem( pInputFrameVirtAddr );
        pInputFrameVirtAddr = NULL;
    }
    if(NULL != pOutputFrameVirtAddr)
    {
        FreePhysMem( pOutputFrameVirtAddr );
        pOutputFrameVirtAddr = NULL;
    }
    PPTestDeInit();
 LogEntry(L"%d :Out %s Function \r\n",++abhineet,__WFUNCTION__);
    return dwResult;   
}    
The below is the flow for this function. It tells the start and end of this test.
*** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
*** TEST STARTING
***
*** Test Name:      PP CSC(YV12-RGB565) Test
*** Test ID:        500
*** Library Path:   pp_test.dll
*** Command Line:
*** Kernel Mode:    Yes
*** Random Seed:    24421
*** Thread Count:   0
*** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
*******Abhineet-PPTEST : 338 : In ShellProc Function 
*******Abhineet-PPTEST : 339 : In Debug Function 
PP_TEST: ShellProc(SPM_BEGIN_TEST, ...) called
*******Abhineet-PPTEST : 340 :Out Debug Function 
    BEGIN TEST: "PP CSC(YV12-RGB565) Test", Threads=0, Seed=24421
*******Abhineet-PPTEST : 341 :Out ShellProc Function 
*******Abhineet-PPTEST : 342 : In PP_CSC_YV12_RGB565Test Function 
    PP_CSC_YV12_RGB565Test
*******Abhineet-PPTEST : 343 : In PPTestInit Function 
*******Abhineet-PPTEST : 344 : In GetPanelDimensions Function 
*******Abhineet-PPTEST : 345 :Out GetPanelDimensions Function 
    GetPanelDimensions: width=1024  height=768  bpp=16
*******Abhineet-PPTEST : 346 :Out PPTestInit Function 
*******Abhineet-PPTEST : 347 : In ReadImage Function 
RELFSD: Opening file flags_112x160.yv12 from desktop
*******Abhineet-PPTEST : 348 :Out ReadImage Function 
===========FLIP TIME: 1ms====== 
*******Abhineet-PPTEST : 349 : In ShowRGBContent Function 
*******Abhineet-PPTEST : 350 :Out ShowRGBContent Function 
*******Abhineet-PPTEST : 351 : In PPTestDeInit Function 
*******Abhineet-PPTEST : 352 :Out PPTestDeInit Function 
*******Abhineet-PPTEST : 353 :Out PP_CSC_YV12_RGB565Test Function
*******Abhineet-PPTEST : 354 : In DllMain Function 
*******Abhineet-PPTEST : 355 :Out DllMain Function 
*******Abhineet-PPTEST : 356 : In ShellProc Function 
*******Abhineet-PPTEST : 357 : In Debug Function 
PP_TEST: ShellProc(SPM_END_TEST, ...) called
*******Abhineet-PPTEST : 358 :Out Debug Function 
END TEST: "PP CSC(YV12-RGB565) Test", PASSED, Time=6.007
*******Abhineet-PPTEST : 359 :Out ShellProc Function 
*** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*** TEST COMPLETED
***
*** Test Name:      PP CSC(YV12-RGB565) Test
*** Test ID:        500
*** Library Path:   pp_test.dll
*** Command Line:
*** Kernel Mode:    Yes
*** Result:         Passed
*** Random Seed:    24421
*** Thread Count:   1
*** Execution Time: 0:00:06.007
*** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Please help me out to make changes to the above function for yuv444-rgb888.