S5PV210 WINCE HDMI全屏显示的问题

来源:互联网 发布:软件验收测试大纲 编辑:程序博客网 时间:2024/04/29 05:36

2013-03-21

通过SMDK210自带的DOC《SMDKV210_WinCE60_TVOUT_UserManual.pdf》了解到

其HDMI驱动通过应用程序DeviceIoControl调用
操作顺序是:
1.打开TV
2.打开图像层(GRP层)
3.打开视频层(Video层)

以下这张图很好的说明了层的关系


http://www.yespartner.com/yespartner/lect_view.asp?gotopage=1&searchString=&schcontent=&schsubject=&schuid=81&cate=1
给了我很大启示,网上很多人是在研究直接把fb放到GRP层,可是这样不能全屏的问题
发现Video层可以轻易解决大小的问题,但是现在卡在Video层需要YUV格式
而fb读出来的是RGB格式

DOC中
// because video processor supports only YUV420 NV12 type, need 2 values about address 
unsigned int uiTopYAddress;  // Y data start address of source image 
unsigned int uiTopCAddress;  // C data start address of source image 

所以,我在研究怎么解决这个格式转换问题,有大神说用VP——VIDEO PROCESSOR
不知道是什么东西,估计只能明天再话精力了解了。

今天code出来的:

    DWORD dwBytes;// Turn on TV//1st Step: Driver Open HANDLE hVideoDrv =INVALID_HANDLE_VALUE;hVideoDrv = CreateFile( L"TVD0:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hVideoDrv == INVALID_HANDLE_VALUE) { RETAILMSG(1,(L"[VDE:ERR] TVD0 Open Device Failed\n")); return; } //Read HPD status bool bHpdStatus;DeviceIoControl(hVideoDrv, IOCTL_STDA_HDMI_GET_HPD_STATUS, NULL, 0, &bHpdStatus, sizeof(BOOL), &dwBytes, NULL);if(bHpdStatus == FALSE) { RETAILMSG(1, (TEXT("bHpdStatus is false!\r\n")));//exit(0);}  //If HPD status is plugged, you should read HDMI available mode.STDA_ARG_HDMI_AVAILABLE_MODE tMode;DeviceIoControl(hVideoDrv, IOCTL_STDA_HDMI_AVAILABLE_MODE, NULL, 0, &tMode, sizeof(STDA_ARG_HDMI_AVAILABLE_MODE), &dwBytes, NULL);RETAILMSG(1, (TEXT("___________________Mode________________\r\n")));RETAILMSG(1, (TEXT("bHDMI_480P_16_9 = %d\r\n"),tMode.bHDMI_480P_16_9));RETAILMSG(1, (TEXT("bHDMI_480P_4_3 = %d\r\n"),tMode.bHDMI_480P_4_3));RETAILMSG(1, (TEXT("bHDMI_576P_16_9 = %d\r\n"),tMode.bHDMI_576P_16_9));RETAILMSG(1, (TEXT("bHDMI_576P_4_3 = %d\r\n"),tMode.bHDMI_576P_4_3));RETAILMSG(1, (TEXT("bHDMI_720P_60_16_9 = %d\r\n"),tMode.bHDMI_720P_60_16_9));RETAILMSG(1, (TEXT("bHDMI_1080P_60_16_9 = %d\r\n"),tMode.bHDMI_1080P_60_16_9));RETAILMSG(1, (TEXT("bHDMI_1080P_30_16_9 = %d\r\n"),tMode.bHDMI_1080P_30_16_9));RETAILMSG(1, (TEXT("bHDMI_1080I_60_16_9 = %d\r\n"),tMode.bHDMI_1080I_60_16_9));RETAILMSG(1, (TEXT("bLPCM2CH = %d\r\n"),tMode.bLPCM2CH));RETAILMSG(1, (TEXT("bHDMI_CS_RGB = %d\r\n"),tMode.bHDMI_CS_RGB));RETAILMSG(1, (TEXT("bHDMI_CS_YCBCR444 = %d\r\n"),tMode.bHDMI_CS_YCBCR444));RETAILMSG(1, (TEXT("bHDMI_CS_YCBCR422 = %d\r\n"),tMode.bHDMI_CS_YCBCR422));RETAILMSG(1, (TEXT("bHDMI_COLORIMETRY_EXTENDED_xvYCC601 = %d\r\n"),tMode.bHDMI_COLORIMETRY_EXTENDED_xvYCC601));RETAILMSG(1, (TEXT("bHDMI_COLORIMETRY_EXTENDED_xvYCC709 = %d\r\n"),tMode.bHDMI_COLORIMETRY_EXTENDED_xvYCC709));RETAILMSG(1, (TEXT("bHDMI_CD_36_HDMI_CS_RGB = %d\r\n"),tMode.bHDMI_CD_36_HDMI_CS_RGB));RETAILMSG(1, (TEXT("bHDMI_CD_36_HDMI_CS_YCBCR444 = %d\r\n"),tMode.bHDMI_CD_36_HDMI_CS_YCBCR444));RETAILMSG(1, (TEXT("bHDMI_CD_36_HDMI_CS_YCBCR422 = %d\r\n"),tMode.bHDMI_CD_36_HDMI_CS_YCBCR422));RETAILMSG(1, (TEXT("bHDMI_CD_30_HDMI_CS_RGB = %d\r\n"),tMode.bHDMI_CD_30_HDMI_CS_RGB));RETAILMSG(1, (TEXT("bHDMI_CD_30_HDMI_CS_YCBCR444 = %d\r\n"),tMode.bHDMI_CD_30_HDMI_CS_YCBCR444));RETAILMSG(1, (TEXT("bHDMI_CD_30_HDMI_CS_YCBCR422 = %d\r\n"),tMode.bHDMI_CD_30_HDMI_CS_YCBCR422));RETAILMSG(1, (TEXT("bHDMI_CD_24_HDMI_CS_RGB = %d\r\n"),tMode.bHDMI_CD_24_HDMI_CS_RGB));RETAILMSG(1, (TEXT("bHDMI_CD_24_HDMI_CS_YCBCR444 = %d\r\n"),tMode.bHDMI_CD_24_HDMI_CS_YCBCR444));RETAILMSG(1, (TEXT("bHDMI_CD_24_HDMI_CS_YCBCR422 = %d\r\n"),tMode.bHDMI_CD_24_HDMI_CS_YCBCR422));//2nd Step: Request Resource     if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_RSC_REQUEST_TVOUT_INTERFACE, NULL, 0, NULL, 0, &dwBytes, NULL))     {              }//3rd Step: Configure TVout Interface     TVOUT_OUTPUT_IF tTVoutIF;     tTVoutIF.dispMode = TVOUT_720P_60;//TVOUT_1080P_60;//TVOUT_1080I_60;//TVOUT_720P_60;     tTVoutIF.outMode = TVOUT_OUTPUT_HDMI_YCBCR;//需要音频则需要TVOUT_OUTPUT_HDMI_YCBCR//TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE;//TVOUT_OUTPUT_HDMI_YCBCR;      if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_TVOUT_INIT_INTERFACE_PARAM, &tTVoutIF, sizeof(TVOUT_OUTPUT_IF), NULL, 0, &dwBytes, NULL))     {          // error is occurred     }#if 1 // change Back Ground Layer colorSTDA_ARG_BG_COLOR tBgp;tBgp.uiColorY = 0;//绿色?tBgp.uiColorCb = 0;tBgp.uiColorCr = 0;if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_BG_INIT_COLOR, &tBgp, sizeof(STDA_ARG_BG_COLOR), NULL, 0, &dwBytes, NULL))     { // error is occurred     } #endif // change Back Ground Layer color//Initialize HDMI Audio HDMI_AUDIO_TYPE m_audioType;DeviceIoControl(hVideoDrv, IOCTL_STDA_HDMI_INIT_AUDIO, &m_audioType, sizeof(HDMI_AUDIO_TYPE), NULL, 0, &dwBytes, NULL); //4th Step: Start display on TV    if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_TVOUT_START, NULL, 0, NULL, 0, &dwBytes, NULL))     { // error is occurred     } //Now, TV is connected and Back Ground Layer is displayed on TV.//Default Back Ground Layer Color is Black.//You can change Back Ground Layer color with IOCTL_STDA_BG_INIT_COLOR API. #if 0   // Show GRP0 Layer on TV //1st Step: Request Resource     if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_RSC_REQUEST_GRAPHIC_0, NULL, 0, NULL, 0, &dwBytes, NULL))     {         // error is occurred     }  //2nd Step: Configure GRP Layer     HDC hWinmain;    unsigned int  DispPhyAddr;    hWinmain = ::GetDC (NULL);    ExtEscape(hWinmain, DRVESC_GET_FB_PHY_ADDR, 0, NULL, sizeof(DispPhyAddr), (LPSTR)&DispPhyAddr);    ::ReleaseDC (NULL, hWinmain);    //RETAILMSG(1, (TEXT("DispPhyAddr = 0x%x\r\n"),DispPhyAddr));  STDA_ARG_GRP_BASIC_PARAM tGrp;    tGrp.bWinBlending = FALSE; // if this value is TRUE, applying alpha blending to Grp0 Layer     tGrp.uiAlpha = 0x0; // alpha blending value. Ranges are 0x00 ~ 0xff //Alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中黑表示全透明,白表示不透明,灰表示半透明。    tGrp.uiPriority = 2; // 该值用来确定video layer的优先级     tGrp.color = VM_DIRECT_RGB8888;//VM_DIRECT_RGB565;     tGrp.bBlankChange = FALSE;  // if FALSE, color key method is used.     tGrp.bPixelBlending = FALSE;// if TRUE, pixel blending is used.//当true,静态图像变透明    tGrp.bPreMul = FALSE;     tGrp.uiBlankColor = 0x0;     tGrp.uiBaseAddress = DispPhyAddr;     tGrp.uiSpan = 800;     tGrp.uiWidth = 800;//1280;     tGrp.uiHeight = 480;//720;     tGrp.uiSrcOffsetX = 0;//水平循环移动    tGrp.uiSrcOffsetY = 0;//垂直循环移动    tGrp.uiDestOffsetX = 50;//100;//50;//左右移动     tGrp.uiDestOffsetY = 30;//24; //上下移动    tGrp.uiScaleEnH = 0; //大于5则2倍放大    tGrp.uiScaleEnV = 0;      if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_GRP0_INIT_PROCESSING_PARAM, &tGrp, sizeof(STDA_ARG_GRP_BASIC_PARAM), NULL, 0, &dwBytes, NULL))     {         // error is occurred     }  //2013年3月20日17:01:52 设置TVOUT_1080P_60 然后2倍放大 勉强大一点 //3rd Step: Show GRP Layer on TV     if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_GRP0_START, NULL, 0, NULL, 0, &dwBytes, NULL))     {         // error is occurred     }#endif    // Show GRP0 Layer on TV #if 1 // Show Video Layer on TV//1st Step: Request Resource if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_RSC_REQUEST_VIDEO_PROCESSOR, NULL, 0, NULL, 0, &dwBytes, NULL)) { // error is occurred }//2nd Step: Configure Video Layer     HDC hWinmain;    unsigned int  DispPhyAddr;    hWinmain = ::GetDC (NULL);    ExtEscape(hWinmain, DRVESC_GET_FB_PHY_ADDR, 0, NULL, sizeof(DispPhyAddr), (LPSTR)&DispPhyAddr);    ::ReleaseDC (NULL, hWinmain);    RETAILMSG(1, (TEXT("DispPhyAddr = 0x%x\r\n"),DispPhyAddr));STDA_ARG_VIDEO_BASIC_PARAM tVideoParam; tVideoParam.bWinBlending = FALSE; tVideoParam.srcColor = VPROC_SRC_COLOR_NV12IB;//VPROC_SRC_COLOR_NV12IW;//勉强看到颜色//VPROC_SRC_COLOR_TILE_NV12; tVideoParam.srcCodec = VPROC_SRC_CODEC_PROGRESSIVE; tVideoParam.uiAlpha = 0; tVideoParam.uiPriority = 2;//3; tVideoParam.uiTopYAddress = DispPhyAddr;//+(800*480*4*4); tVideoParam.uiTopCAddress = DispPhyAddr+(800*480*2); tVideoParam.srcImgEndian = TVOUT_LITTLE_ENDIAN_MODE;//TVOUT_BIG_ENDIAN_MODE;//TVOUT_LITTLE_ENDIAN_MODE; tVideoParam.uiImgWidth = 800;//DisplayBufWidth; tVideoParam.uiImgHeight = 480;//DisplayBufHeight; tVideoParam.uiSrcOffsetX = 0;//DisplayOffsetX; tVideoParam.uiSrcOffsetY = 0;//DisplayOffsetY; tVideoParam.uiSrcWidth = 800;//DisplayWidth; tVideoParam.uiSrcHeight = 480;//DisplayHeight; tVideoParam.uiDestWidth = 1280;tVideoParam.uiDestHeight = 720; tVideoParam.uiDestOffsetX = 0; tVideoParam.uiDestOffsetY = 0; if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_VL_INIT_PROCESSING_PARAM, &tVideoParam, sizeof(STDA_ARG_VIDEO_BASIC_PARAM), NULL, 0, &dwBytes, NULL)) { // error is occurred } //3rd Step: Show Video Layer on TV if(!DeviceIoControl(hVideoDrv, IOCTL_STDA_VL_START, NULL, 0, NULL, 0, &dwBytes, NULL)) { // error is occurred } #endif // Show Video Layer on TV


2013-3-25

我勒个去,被某大神坑了...看手册明白VP和MIXER的作用了...


原来安卓那边他们是,先用屏幕录像机,把RGB转成YUV再通过VP调整大小放到Video层,搞什么...为什么一开始不说清楚呢?!走弯路浪费公司人力资源而已嘛...