Telechips 8902 & WinCE6.0 平台下 overlay 使用冲突现象的分析
2014-04-02 19:41
363 查看
最近在分析播放视频(mkv 格式)引起显示异常的问题。
平台为: WinCE6.0;CPU 为 Telechips8902.
发现在主菜单/设置/多媒体类型选择等界面会出现问题;但在导航界面不会出现问题。所以分析问题的原因与主菜单等界面的显示方式有关,查看代码发现主菜单等界面使用 overlay 显示。
由于视频显示也采用 overlay 方式(怀疑 mkv 格式视频的显示比其它格式显示多使用一层 overlay 表面),可能是因为 overlay 表面使用冲突引起主菜单等显示异常的问题。需要分析视频显示的实现过程与 UI 的实现过程来确认是否是此原因?
UI 代码中 overlay 的实现是通过 IOCtrl 来实现的,没有通过系统标准的 overlay 访问接口。
Telechips 8902 共 2 层 overlay surface,视频播放使用一层(YUV);UI 的显示采用 IOCtrl 直接通过 OS 写屏操作,经测试发现使用一层 overlay(RGB) surface;此时如果视频播放的视频文件格式需要需要通过 overlay 显示 SUB-TITLE 时,与 UI 显示使用的 overlay 表面资源冲突。这样导致了如上问题的产生。
为了排除 UI 实现对上述结果的影响,采用 DirectDraw 示例工程 mosquito 与视频一起运行,看是否可以重现上述问题:
先运行 mosquito,界面出现蚊子飞的动画效果。此时,再运行 Telechips 的示例工程 TCMovieManager。先选择一首没有字幕的视频播放,发现视频与 mosquito 的效果(蚊子飞的动画)同时存在。此时将视频切换到带有字幕的视频,开始视频播放后,发现 mosquito 的效果(蚊子飞的动画)消失。这样就重现了 UI 界面与视频冲突的现象!
此问题,单独从应用层来分析比较难解决。
个人建议的方法:
(1)从 OS 入手,修改视频播放时对字幕(SUB-TITLE)的处理,字幕(SUB-TITLE)要不不显示、要不显示在视频 overlay 层上;
(2)考虑不再实现视频后台播放的功能。
附部分 mosquito 的源代码,主要包括 overlay 层格式与初始化:
平台为: WinCE6.0;CPU 为 Telechips8902.
发现在主菜单/设置/多媒体类型选择等界面会出现问题;但在导航界面不会出现问题。所以分析问题的原因与主菜单等界面的显示方式有关,查看代码发现主菜单等界面使用 overlay 显示。
由于视频显示也采用 overlay 方式(怀疑 mkv 格式视频的显示比其它格式显示多使用一层 overlay 表面),可能是因为 overlay 表面使用冲突引起主菜单等显示异常的问题。需要分析视频显示的实现过程与 UI 的实现过程来确认是否是此原因?
UI 代码中 overlay 的实现是通过 IOCtrl 来实现的,没有通过系统标准的 overlay 访问接口。
Telechips 8902 共 2 层 overlay surface,视频播放使用一层(YUV);UI 的显示采用 IOCtrl 直接通过 OS 写屏操作,经测试发现使用一层 overlay(RGB) surface;此时如果视频播放的视频文件格式需要需要通过 overlay 显示 SUB-TITLE 时,与 UI 显示使用的 overlay 表面资源冲突。这样导致了如上问题的产生。
为了排除 UI 实现对上述结果的影响,采用 DirectDraw 示例工程 mosquito 与视频一起运行,看是否可以重现上述问题:
先运行 mosquito,界面出现蚊子飞的动画效果。此时,再运行 Telechips 的示例工程 TCMovieManager。先选择一首没有字幕的视频播放,发现视频与 mosquito 的效果(蚊子飞的动画)同时存在。此时将视频切换到带有字幕的视频,开始视频播放后,发现 mosquito 的效果(蚊子飞的动画)消失。这样就重现了 UI 界面与视频冲突的现象!
此问题,单独从应用层来分析比较难解决。
个人建议的方法:
(1)从 OS 入手,修改视频播放时对字幕(SUB-TITLE)的处理,字幕(SUB-TITLE)要不不显示、要不显示在视频 overlay 层上;
(2)考虑不再实现视频后台播放的功能。
附部分 mosquito 的源代码,主要包括 overlay 层格式与初始化:
/* * Telechips 8902 支持 2 层 overlay * 只能创建一层 YUYV 的 overlay (可以再创建一层 RGB overlay) * RGB 模式可以创建多个,模式与顺序没有不影响创建 */ static DDPIXELFORMAT ddpfOverlayFormats[] = { //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0}, // YUYV - Leo.Zheng Telechips 8902 可以支持 //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}, // UYVY - Leo.Zheng Telechips 8902:Create No.1 surface return: 0x88760218 // {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00, 0x03e0, 0x001F, 0}, // 16-bit RGB 5:5:5 {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xF800, 0x07e0, 0x001F, 0}, // 16-bit RGB 5:6:5 }; #define PF_TABLE_SIZE (sizeof(ddpfOverlayFormats) / sizeof(ddpfOverlayFormats[0])) //----------------------------------------------------------------------------- // Name: InitApp() // Desc: Do work required for every instance of the application: // Create the window, initialize data //----------------------------------------------------------------------------- static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; WNDCLASS wc; DDSURFACEDESC ddsd; DDCAPS ddcaps; HRESULT hRet; DWORD dwUpdateFlags = 0; DDOVERLAYFX ovfx; DEVMODE DevMode; // Check for rotation support by getting the rotation angles supported. memset(&DevMode, 0, sizeof(DevMode)); DevMode.dmSize = sizeof(DevMode); DevMode.dmFields = DM_DISPLAYQUERYORIENTATION; if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) { g_RotationAngles = DevMode.dmDisplayOrientation; } else { OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled."); g_RotationAngles = -1; } // Get the current rotation angle. memset(&DevMode, 0, sizeof (DevMode)); DevMode.dmSize = sizeof (DevMode); DevMode.dmFields = DM_DISPLAYORIENTATION; if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) { g_CurrentAngle = DevMode.dmDisplayOrientation; } else { OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled."); g_CurrentAngle = -1; } // Set up and register window class. ...... // Create the main DirectDraw object hRet = DirectDrawCreate(NULL, &g_pDD, NULL); if(hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("DirectDrawCreate FAILED")); // Get normal mode. hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("SetCooperativeLevel FAILED")); // Get a primary surface interface pointer (only needed for init.) memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("CreateSurface FAILED")); // See if we can support overlays. memset(&ddcaps, 0, sizeof(ddcaps)); ddcaps.dwSize = sizeof(ddcaps); hRet = g_pDD->GetCaps(&ddcaps, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("GetCaps FAILED")); if (ddcaps.dwOverlayCaps == 0) return InitFail(hWnd, hRet, TEXT("Overlays are not supported in hardware!")); /* // Leo.Zheng Add if(!(capsDrv.dwCaps & DDCAPS_OVERLAY)) return FALSE; */ // Get alignment info to compute our overlay surface size. rs.left = 0; rs.top = 0; rs.right = BUG_WIDTH; rs.bottom = BUG_HEIGHT; if (ddcaps.dwAlignSizeSrc != 0) rs.right += rs.right % ddcaps.dwAlignSizeSrc; // Create the overlay flipping surface. We will attempt the pixel formats // in our table one at a time until we find one that jives. int i = 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP; ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT; ddsd.dwWidth = rs.right; ddsd.dwHeight = rs.bottom; ddsd.dwBackBufferCount = 1; do { // Leo.Zheng MStar 2521 只创建 16-bit RGB 5:6:5 成功; 创建 16-bit RGB 5:5:5 失败. ddsd.ddpfPixelFormat = ddpfOverlayFormats[i]; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL); // Leo.Zheng 此处调用后引起使用 IOCtrl 显示在 LCD 上的消失 RETAILMSG(1,(L"[mosquito]Create No.%d surface return: 0x%X\r\n",i + 1,hRet)); }while(hRet != DD_OK && (++i < PF_TABLE_SIZE)); if(hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("Unable to create overlay surface!")); // Load the images. if (LoadBugImages() != DD_OK) return InitFail(hWnd, hRet, TEXT("Unable to load images to overlay surface!")); // Finish setting up the overlay. int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000; rd.left=0; rd.top=0; // Adding 999 takes care of integer truncation problems. rd.right = (rs.right * StretchFactor1000 + 999) / 1000; rd.bottom = rs.bottom * StretchFactor1000 / 1000; if (ddcaps.dwAlignSizeDest != 0) rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest; // Set the flags we'll send to UpdateOverlay dwUpdateFlags = DDOVER_SHOW; // dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; // Leo.Zheng DDOVER_DDFX WinCE 不支持 // Does the overlay hardware support source color keying? // If so, we can hide the black background around the image. // This probably won't work with YUV formats memset(&ovfx, 0, sizeof(ovfx)); ovfx.dwSize = sizeof(ovfx); if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC) // MStar2521 不支持 color key { dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE; // Create an overlay FX structure so we can specify a source color key. // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag // isn't set. ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key ovfx.dckSrcColorkey.dwColorSpaceHighValue=0; } else { RETAILMSG(1,(L"[mosquito]cannot support color key: 0x%X(0x%x)\r\n",ddcaps.dwOverlayCaps,DDOVERLAYCAPS_CKEYSRC)); } // Update the overlay parameters. hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx); if (hRet != DD_OK) { // 在 MStar 2521 设备上运行第二个此程序实例时出错。 // 在 TeleChips 8902 设备上运行第三个此程序实例时出错。 return InitFail(hWnd, hRet, TEXT("Unable to show overlay surface: 0x%x!"),hRet); } // Set a bunch of position and velocity module vars. g_nOverlayXPos = 0; g_nOverlayYPos = 0; g_nOverlayXVel = RANDOM_VELOCITY(); g_nOverlayYVel = RANDOM_VELOCITY(); g_nOverlayWidth = rd.right - rd.left; g_nOverlayHeight = rd.bottom - rd.top; // Set the "destination position alignment" global so we won't have to // keep calling GetCaps() everytime we move the overlay surface. g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest; // Create a timer to flip the pages. if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL)) return InitFail(hWnd, hRet, TEXT("SetTimer FAILED")); return DD_OK; }
相关文章推荐
- Telechips 8902 & WinCE6.0 平台下 overlay 使用冲突现象的分析
- S3C2410 && WinCE6.0的中断处理分析 (转载自博客园牛人we-hjb)
- S3C2410 && WinCE6.0的中断处理分析
- S3C2410 && WinCE6.0的中断处理分析
- 基于linux-2.6.38.8内核的SDIO/wifi驱动分析&&android 平台USB wifi驱动移植及使用 SDIOwifi
- S3C2410 && WinCE6.0的中断处理分析 (转载自博客园牛人we-hjb)
- S3C2410 && WinCE6.0的中断处理分析
- S3C2410 && WinCE6.0的中断处理分析
- S3C2410 && WinCE6.0的中断处理分析
- S3C2410 && WinCE6.0的中断处理分析(转载)
- WinCE6.0学习之EBoot源码分析----startup.s(二)
- wince 6.0 下MFC 模态非模态方式使用dll中的窗口
- 使用Elasticsearch + Logstash + Kibana搭建日志集中分析平台实践
- ApkToolPlus 是一个可视化的跨平台 apk 分析工具,使用 java 语言开发的一个桌面应用。
- C#中Stack<T>类的使用及部分成员函数的源码分析
- Respones&Request原理及使用分析
- 大数据统计分析平台之二、ElasticSearch 6.2.1的安装与使用
- Android平台APK分析工具包androguard的部署使用和原理分析
- VB加载工程,出现在frmmain.frm中发现冲突名称,将使用名称'frmmain'
- SonarQube-5.6.3 代码分析平台搭建使用