代码之家  ›  专栏  ›  技术社区  ›  Abhineet

从Yuv444转换为RGB888

  •  1
  • Abhineet  · 技术社区  · 14 年前

    我是这个领域的新手,我非常需要你们的指导。

    我必须支持 yuv444 rgb 888 显示驱动模块。

    我做了一个测试 yv12 小精灵 rgb565 在WinCE 6.0 R3中,如下所述。

    //------------------------------------------------------------------------------
    // 
    // 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;   
    }    
    

    下面是此函数的流程。它告诉我们测试的开始和结束。

    *** 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
    *** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    请帮助我更改yuv444->rgb888的上述功能。

    1 回复  |  直到 14 年前
        1
  •  0
  •   Abhineet    14 年前

    我找到了解决办法

    //------------------------------------------------------------------------------
    //
    // Function: PP_CSC_YUV444_RGB888Test
    //
    // 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_YUV444_RGB888Test(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
    {
        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();
    
        RETAILMSG(1, (TEXT("===> YUV444->RGB888 TEST \r\n")));
    
        iInputWidth = PP_TEST_FRAME_WIDTH;
        iInputHeight = PP_TEST_FRAME_HEIGHT;
        iInputBPP = 3;
        iInputStride = iInputWidth * 3; // YUV444 is 24 bits per pixel
    
        iOutputWidth = PP_TEST_FRAME_WIDTH;
        iOutputHeight = PP_TEST_FRAME_HEIGHT;
        iOutputBPP = 3; // for RGB888 case
        iOutputStride = iOutputWidth * iOutputBPP;
        RETAILMSG(1,(L"At %s, Input -> width = %u, height = %u \r\n",__WFUNCTION__,iInputWidth,iInputHeight));
        RETAILMSG(1,(L"At %s, Output -> width = %u, height = %u \r\n",__WFUNCTION__,iOutputWidth,iOutputHeight));
        //-----------------------------
        // Configure PP
        //-----------------------------
    
        // Set up post-processing configuration data
        memset(&ppData, 0 , sizeof(ppData));
        // Set up input format and data width
        ppData.inputIDMAChannel.FrameFormat = icFormat_YUV444;
        ppData.inputIDMAChannel.DataWidth = icDataWidth_24BPP;
        // 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 = 0;
        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_24BPP;
        ppData.outputIDMAChannel.PixelFormat.component0_offset = 0;
        ppData.outputIDMAChannel.PixelFormat.component1_offset = 8;
        ppData.outputIDMAChannel.PixelFormat.component2_offset = 16;    
        ppData.outputIDMAChannel.PixelFormat.component3_offset = 24;
        ppData.outputIDMAChannel.PixelFormat.component0_width = 7;
        ppData.outputIDMAChannel.PixelFormat.component1_width = 7;
        ppData.outputIDMAChannel.PixelFormat.component2_width = 7;
        ppData.outputIDMAChannel.PixelFormat.component3_width = 0;    
        ppData.outputIDMAChannel.FrameSize.height = iOutputHeight;
        ppData.outputIDMAChannel.FrameSize.width = iOutputWidth;
        ppData.outputIDMAChannel.LineStride = iOutputWidth * 3;
    
        ppData.CSCEquation = CSCY2R_A1;
    
        ppData.inputIDMAChannel.UBufOffset = iInputHeight * iInputWidth;
        ppData.inputIDMAChannel.VBufOffset = 2 * iInputHeight * iInputWidth;
    
        // 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_YUV444_RGB888Test_clean_up;    
        }
    
        ppData.FlipRot.verticalFlip = FALSE;
        ppData.FlipRot.horizontalFlip = FALSE;
        ppData.FlipRot.rotate90 = FALSE;
    
        if (!PPConfigure(hPP, &ppData))
        {
            dwResult = TPR_FAIL;
            goto PP_CSC_YUV444_RGB888Test_clean_up;    
        }        
    
        //-----------------------------
        // Read first input buffer
        //-----------------------------
    
        // Read Input file for new frame
        if (!ReadImage(PP_TEST_YUV444_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_YUV444_RGB888Test_clean_up;    
        }
    
        //-----------------------------
        // Start PP
        //-----------------------------
        if (!PPStart(hPP))
        {
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPStart Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;    
        }        
    
        if (!PPInterruptEnable(hPP, FRAME_INTERRUPT))
        {
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPInterruptEnable Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_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;
            RETAILMSG(1, (TEXT("===========PPAddInputBuffer Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;     
        } 
    
        RETAILMSG(1,(L"Input time = %dms",(GetTickCount() - starttime)));
    
        UINT32 oTime = GetTickCount();
        if (!PPAddOutputBuffer(hPP,(UINT32) pOutputFramePhysAddr))
        {       
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPAddOutputBuffer Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;     
        }  
        RETAILMSG(1,(L"Output time = %dms",(GetTickCount() - oTime)));
    
        UINT32 waitTime = GetTickCount();
        if (!PPWaitForNotBusy(hPP, FRAME_INTERRUPT))
        {
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPWaitForNotBusy Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;    
        }    
        RETAILMSG(1,(L"Waiting time = %dms",(GetTickCount() - waitTime)));
    
        RETAILMSG(1, (TEXT("===========FLIP TIME: %dms & %d---%d\r\n"),(GetTickCount() - starttime),starttime,GetTickCount()));
    
        //-----------------------------
        // Stop PP
        //-----------------------------
    
        if (!PPStop(hPP))
        {
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPStop Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;    
        }
    
        if (!PPClearBuffers(hPP))
        {
            dwResult = TPR_FAIL;
            RETAILMSG(1, (TEXT("===========PPClearBuffers Failed \r\n")));
            goto PP_CSC_YUV444_RGB888Test_clean_up;    
        }    
    
        ShowRGB888Content((UINT8 *) pOutputFrameVirtAddr, (PP_TEST_FRAME_WIDTH), (PP_TEST_FRAME_HEIGHT));
    
        iOption = MessageBox( NULL,TEXT("After CSC(YUV444->RGB888). Is it correct?"),TEXT("Test result"),MB_YESNO );
        if ( IDNO == iOption )
        {
            dwResult = TPR_FAIL;
        }
        else 
        {
            dwResult = TPR_PASS;
        }
    
    PP_CSC_YUV444_RGB888Test_clean_up:
        if(NULL != pInputFrameVirtAddr)
        {
            FreePhysMem( pInputFrameVirtAddr );
            pInputFrameVirtAddr = NULL;
        }
    
        if(NULL != pOutputFrameVirtAddr)
        {
            FreePhysMem( pOutputFrameVirtAddr );
            pOutputFrameVirtAddr = NULL;
        }
    
        PPTestDeInit();
        return dwResult;   
    
    }    
    
    推荐文章