首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

DirectDraw多线程使用的诸多有关问题,请问DDraw高手

2012-03-15 
DirectDraw多线程使用的诸多问题,请教DDraw高手我用DirectDraw来播放电影,对解码器解出的BMP图象序列写屏。

DirectDraw多线程使用的诸多问题,请教DDraw高手
我用DirectDraw来播放电影,对解码器解出的BMP图象序列写屏。
我建立了一个类,它做如下的事情:
1、初始化函数
      (1)创建一个准备用于播放的窗口,它后来要么附着到主窗口内,要么作为一个
            分离窗口。
      (2)创建一个默认32位的主表面,并Clipper到上面的播放窗口,再创建一个离屏
            表面,离屏表面将依据解码器输出的BMP宽、高和位数动态创建。
      m_hPlayWnd   =   CreateWindow(   s_szWndName,   _T( " "),  
            WS_OVERLAPPEDWINDOW|WS_POPUP|WS_SIZEBOX,
            0,   0,   320,   240,   NULL,   NULL,   GetModuleHandle(   NULL   ),   0   );
      DDSURFACEDESC2   ddsd;
      if(   FAILED(   DirectDrawCreateEx(   NULL,   (VOID**)&m_lpDDraw,  
            IID_IDirectDraw7,   NULL   )   )   ||FAILED(m_lpDDraw-> SetCooperativeLevel
            (   NULL,   DDSCL_NORMAL   ))   )
            return   FALSE;
      memset(   &ddsd,   0,   sizeof(ddsd)   );
      ddsd.dwSize     =   sizeof(ddsd);
      ddsd.dwFlags   =   DDSD_CAPS;
      ddsd.ddsCaps.dwCaps   =   DDSCAPS_PRIMARYSURFACE   |   DDSCAPS_VIDEOMEMORY;
      if(   FAILED(m_lpDDraw-> CreateSurface(   &ddsd,   &m_lpddsPrimary,   NULL   ))   )
            return   FALSE;
      m_lpDDraw-> CreateClipper(   0,   &m_lpddClipper,   NULL   );
      m_lpddClipper-> SetHWnd(   0,   m_hPlayWnd   );
      m_lpddsPrimary-> SetClipper(   m_lpddClipper   );

      memset(   &ddsd,   0,   sizeof(ddsd)   );
      ddsd.dwSize   =   sizeof(ddsd);
      ddsd.dwFlags   =   DDSD_CAPS   |   DDSD_HEIGHT   |   DDSD_WIDTH;
      ddsd.ddsCaps.dwCaps   =   DDSCAPS_OFFSCREENPLAIN   |   DDSCAPS_SYSTEMMEMORY;  
      ddsd.dwWidth     =   m_nWidth;
      ddsd.dwHeight   =   m_nHeight;
      m_lpDDraw-> CreateSurface(   &ddsd,   &m_lpddsBack,   NULL   );
2、播放BMP函数
      先对离屏表面GetDC(),然后把BMP数据StretchBlt到离屏表面。
      最后调用主表面的Blt,显示离屏表面内的BMP图象。
      HDC   hDC;
      ddrval   =   m_lpddsBack-> GetDC(   &hDC   );
      SetDIBitsToDevice(   hDC,   0,   0,   m_nWidth,   m_nHeight,   0,   0,   0,   m_nHeight,
            m_pPicBuff,   (LPBITMAPINFO)&m_biInfo,   DIB_RGB_COLORS   );
      m_lpddsBack-> ReleaseDC(   hDC   );
      ddrval   =   m_lpddsPrimary-> Blt(   &dstRect,   m_lpddsBack,   &srcRect,  
            DDBLT_ASYNC,   NULL   );

问题之一:
      解码器线程,和创建DDraw的线程,以及播放窗口不在同一个线程,也不可能在同
      一个线程。这就造成了播放窗口在拖动时,整个屏幕都不停的闪烁。

      试着将创建DDraw和播放窗口放入主线程,解码线程通过PostMessage往播放窗口


      Post一个消息,来进行Draw   BMP。这样改善了播放窗口拖动时屏幕的闪烁,但还
      是不可避免其他任何窗口拖动时,屏幕出现的闪烁。
 
      测试中基本可以断定是多线程造成的屏幕闪烁,因为上述可以改善闪烁,就说明
      了这点。可Windows   Media   Player就一点也不闪烁。

      这个播放过程,其实很简单。但是闪烁问题困扰我很久了,不知你们在开发过程
      中是否遇到同样的问题。
问题之二:
      当播放窗口拖动到屏幕边缘,以让一部分画面超出边缘,这时,DirectDraw始终
      将图象画在屏幕左上角。

问题之三:
      当主表面   和   离屏表面的位数不同,例如,主32位,离屏16位,这时图象出现了
      扭曲。

      盼望各位行家能够指出原因所在,我将感激不尽。也希望参与大家讨论,分不是问题。

[解决办法]
关注
[解决办法]
多线程使用应该没有问题吧。


[解决办法]
应该跟多线程没问题,考虑一下双缓冲,一般闪烁都是因为这个造成的。

热点排行