• Telechips 8902 & WinCE6.0 平台下 overlay 使用冲突现象的分析


    最近在分析播放视频(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 层格式与初始化:

      1 /* 
      2  * Telechips 8902 支持 2 层 overlay 
      3  * 只能创建一层 YUYV 的 overlay (可以再创建一层 RGB overlay) 
      4  * RGB 模式可以创建多个,模式与顺序没有不影响创建 
      5 */  
      6 static DDPIXELFORMAT ddpfOverlayFormats[] = {  
      7     //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0},  // YUYV - Leo.Zheng Telechips 8902 可以支持  
      8     //{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  
      9     // {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x7C00, 0x03e0, 0x001F, 0},        // 16-bit RGB 5:5:5  
     10     {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0xF800, 0x07e0, 0x001F, 0},        // 16-bit RGB 5:6:5  
     11 };  
     12   
     13 #define PF_TABLE_SIZE (sizeof(ddpfOverlayFormats) / sizeof(ddpfOverlayFormats[0]))  
     14   
     15   
     16   
     17 //-----------------------------------------------------------------------------  
     18 // Name: InitApp()  
     19 // Desc: Do work required for every instance of the application:  
     20 //          Create the window, initialize data  
     21 //-----------------------------------------------------------------------------  
     22 static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow)  
     23 {  
     24     HWND                        hWnd;  
     25     WNDCLASS                    wc;  
     26     DDSURFACEDESC               ddsd;  
     27     DDCAPS                      ddcaps;  
     28     HRESULT                     hRet;  
     29     DWORD                       dwUpdateFlags = 0;  
     30     DDOVERLAYFX                 ovfx;  
     31     DEVMODE                     DevMode;  
     32   
     33     // Check for rotation support by getting the rotation angles supported.  
     34     memset(&DevMode, 0, sizeof(DevMode));  
     35     DevMode.dmSize = sizeof(DevMode);  
     36     DevMode.dmFields = DM_DISPLAYQUERYORIENTATION;  
     37     if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))  
     38     {  
     39         g_RotationAngles = DevMode.dmDisplayOrientation;  
     40     }  
     41     else  
     42     {  
     43         OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled.");  
     44         g_RotationAngles = -1;  
     45     }  
     46   
     47     // Get the current rotation angle.  
     48     memset(&DevMode, 0, sizeof (DevMode));  
     49     DevMode.dmSize = sizeof (DevMode);  
     50     DevMode.dmFields = DM_DISPLAYORIENTATION;  
     51     if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))  
     52     {  
     53         g_CurrentAngle = DevMode.dmDisplayOrientation;  
     54     }  
     55     else  
     56     {  
     57         OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled.");  
     58         g_CurrentAngle = -1;  
     59     }  
     60   
     61     // Set up and register window class.  
     62     ......  
     63   
     64     // Create the main DirectDraw object  
     65     hRet = DirectDrawCreate(NULL, &g_pDD, NULL);  
     66     if(hRet != DD_OK)  
     67         return InitFail(hWnd, hRet, TEXT("DirectDrawCreate FAILED"));  
     68   
     69     // Get normal mode.  
     70     hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);  
     71     if (hRet != DD_OK)  
     72         return InitFail(hWnd, hRet, TEXT("SetCooperativeLevel FAILED"));  
     73   
     74     // Get a primary surface interface pointer (only needed for init.)  
     75     memset(&ddsd, 0, sizeof(ddsd));  
     76     ddsd.dwSize = sizeof(ddsd);  
     77     ddsd.dwFlags = DDSD_CAPS;  
     78     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  
     79     hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);  
     80     if (hRet != DD_OK)  
     81         return InitFail(hWnd, hRet, TEXT("CreateSurface FAILED"));  
     82   
     83     // See if we can support overlays.  
     84     memset(&ddcaps, 0, sizeof(ddcaps));  
     85     ddcaps.dwSize = sizeof(ddcaps);  
     86     hRet = g_pDD->GetCaps(&ddcaps, NULL);  
     87     if (hRet != DD_OK)  
     88         return InitFail(hWnd, hRet, TEXT("GetCaps FAILED"));  
     89   
     90     if (ddcaps.dwOverlayCaps == 0)  
     91         return InitFail(hWnd, hRet, TEXT("Overlays are not supported in hardware!"));  
     92     /* // Leo.Zheng Add 
     93     if(!(capsDrv.dwCaps & DDCAPS_OVERLAY)) 
     94         return FALSE; 
     95     */  
     96   
     97     // Get alignment info to compute our overlay surface size.  
     98     rs.left = 0;  
     99     rs.top = 0;  
    100     rs.right = BUG_WIDTH;  
    101     rs.bottom = BUG_HEIGHT;  
    102     if (ddcaps.dwAlignSizeSrc != 0)  
    103         rs.right += rs.right % ddcaps.dwAlignSizeSrc;  
    104       
    105     // Create the overlay flipping surface. We will attempt the pixel formats  
    106     // in our table one at a time until we find one that jives.  
    107     int i = 0;  
    108     memset(&ddsd, 0, sizeof(ddsd));  
    109     ddsd.dwSize = sizeof(ddsd);  
    110     ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP;  
    111     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;  
    112     ddsd.dwWidth = rs.right;  
    113     ddsd.dwHeight = rs.bottom;  
    114     ddsd.dwBackBufferCount = 1;  
    115     do  
    116     {   // Leo.Zheng MStar 2521 只创建 16-bit RGB 5:6:5 成功; 创建 16-bit RGB 5:5:5 失败.  
    117         ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];  
    118         hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);            // Leo.Zheng 此处调用后引起使用 IOCtrl 显示在 LCD 上的消失  
    119         RETAILMSG(1,(L"[mosquito]Create No.%d surface return: 0x%X
    ",i + 1,hRet));  
    120     }while(hRet != DD_OK && (++i < PF_TABLE_SIZE));  
    121     if(hRet != DD_OK)  
    122         return InitFail(hWnd, hRet, TEXT("Unable to create overlay surface!"));  
    123   
    124     // Load the images.  
    125     if (LoadBugImages() != DD_OK)  
    126         return InitFail(hWnd, hRet, TEXT("Unable to load images to overlay surface!"));  
    127   
    128     // Finish setting up the overlay.  
    129     int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000;  
    130   
    131     rd.left=0;   
    132     rd.top=0;  
    133     // Adding 999 takes care of integer truncation problems.  
    134     rd.right  = (rs.right * StretchFactor1000 + 999) / 1000;  
    135     rd.bottom = rs.bottom * StretchFactor1000 / 1000;  
    136     if (ddcaps.dwAlignSizeDest != 0)  
    137         rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest;  
    138   
    139     // Set the flags we'll send to UpdateOverlay  
    140     dwUpdateFlags = DDOVER_SHOW;  
    141     // dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;           // Leo.Zheng DDOVER_DDFX WinCE 不支持  
    142   
    143     // Does the overlay hardware support source color keying?  
    144     // If so, we can hide the black background around the image.  
    145     // This probably won't work with YUV formats  
    146     memset(&ovfx, 0, sizeof(ovfx));  
    147     ovfx.dwSize = sizeof(ovfx);  
    148     if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC)           // MStar2521 不支持 color key  
    149     {  
    150         dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;  
    151   
    152         // Create an overlay FX structure so we can specify a source color key.  
    153         // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag   
    154         // isn't set.  
    155         ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key  
    156         ovfx.dckSrcColorkey.dwColorSpaceHighValue=0;  
    157     }  
    158     else  
    159     {  
    160         RETAILMSG(1,(L"[mosquito]cannot support color key: 0x%X(0x%x)
    ",ddcaps.dwOverlayCaps,DDOVERLAYCAPS_CKEYSRC));  
    161     }  
    162   
    163     // Update the overlay parameters.  
    164     hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx);  
    165     if (hRet != DD_OK)  
    166     {  
    167         // 在 MStar 2521 设备上运行第二个此程序实例时出错。  
    168         // 在 TeleChips 8902 设备上运行第三个此程序实例时出错。  
    169         return InitFail(hWnd, hRet, TEXT("Unable to show overlay surface: 0x%x!"),hRet);  
    170     }  
    171   
    172     // Set a bunch of position and velocity module vars.  
    173     g_nOverlayXPos = 0;  
    174     g_nOverlayYPos = 0;  
    175     g_nOverlayXVel = RANDOM_VELOCITY();  
    176     g_nOverlayYVel = RANDOM_VELOCITY();  
    177     g_nOverlayWidth = rd.right - rd.left;  
    178     g_nOverlayHeight = rd.bottom - rd.top;  
    179       
    180     // Set the "destination position alignment" global so we won't have to  
    181     // keep calling GetCaps() everytime we move the overlay surface.  
    182     g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest;  
    183   
    184     // Create a timer to flip the pages.  
    185     if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))  
    186         return InitFail(hWnd, hRet, TEXT("SetTimer FAILED"));  
    187   
    188     return DD_OK;  
    189 }  
  • 相关阅读:
    android 权限及原理
    通讯协议的相关知识(备忘)
    MongoDB安装以及java开发入门<二>
    Struts2架构图
    Lucene查询对象笔记_TermQuery(笔记)
    mongodb指南(翻译)(二十) developer zone 索引(四)地理信息索引(转载)
    项目结尾公共模块WebService封装
    Redhat 5.5下安装MongoDB
    wsimport生成客户端出现的异常
    Hibernate关于空间表查询时的的一个异常
  • 原文地址:https://www.cnblogs.com/91program/p/5205088.html
Copyright © 2020-2023  润新知