S5PV210 WINCE HDMI全屏显示的问题
通过SMDK210自带的DOC《SMDKV210_WinCE60_TVOUT_UserManual.pdf》了解到
其HDMI驱动通过应用程序DeviceIoControl调用
操作顺序是:
1.打开TV
2.打开图像层(GRP层)
3.打开视频层(Video层)
4.再配置HDMI相关
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 color
STDA_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