当前位置: 代码迷 >> 多媒体/流媒体开发 >> ddraw Yuv 显示有关问题,拖动屏幕图像晃动
  详细解决方案

ddraw Yuv 显示有关问题,拖动屏幕图像晃动

热度:7912   发布时间:2013-02-26 00:00:00.0
ddraw Yuv 显示问题,拖动屏幕图像晃动!
(1)yuv overlay 时,显示在mfc的picture控件上,然后我拖动对话框,发现yuv overlay的表面有时会拖出picture控件,即图像出现晃动现象;

(2)还有一个问题就是当我将MFC对话框拖出屏幕范围,yuv overlay的表面还是在屏幕的范围内;即当MFC对话框部分拖出屏幕范围时,overlay的图像不会跟踪只显示部分图像;

(3)还有就是当切换到另一个页面的时候,此时对话框看不到,但是yuv overlay的表面还是显示在屏幕上;

我用的函数是UpdateOverlay函数;源码如下:
//初始化表面函数
HRESULT CDirectDrawSurface::DirectDrawInit(HWND hWnd, int width, int height)
{

HRESULT hr=S_FALSE;
hr=CoInitialize(0);
DDSURFACEDESC2 ddsd;

//store width, height 
m_width = width;
m_height = height;

hr = CoCreateInstance(CLSID_DirectDraw,
NULL, CLSCTX_ALL, IID_IDirectDraw7, (LPVOID *)&m_lpDD);

if(!FAILED(hr))
hr = IDirectDraw7_Initialize(m_lpDD, NULL);
if (hr!=DD_OK)
{
printf("create directdraw object failed\n");
}

if(m_lpDD->SetCooperativeLevel(m_hWnd,DDSCL_NORMAL)!=DD_OK)
return S_FALSE;

memset( &ddsd, 0, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

// The primary surface is not a page flipping surface this time
hr = m_lpDD->CreateSurface( &ddsd, &m_lpDDSPrimary, NULL );

if (hr!=DD_OK)
{
printf("create directdraw surface failed\n");
}
else
{
DDCAPS capsDrv; 
memset(&capsDrv,0,sizeof(capsDrv)); 
capsDrv.dwSize=sizeof(DDCAPS); 
hr=m_lpDD-> GetCaps(&capsDrv,NULL); 
if(hr==DD_OK && (capsDrv.dwCaps & DDCAPS_OVERLAY))  
{ // determine Overlay support. 
DDPIXELFORMAT PixelFormat[] = { 
//{ sizeof(DDPIXELFORMAT), DDPF_FOURCC, FOURCC_YV12, 0, 0, 0, 0, 0 }, // YV12 
//{ sizeof(DDPIXELFORMAT), DDPF_FOURCC, FOURCC_Y411, 0, 0, 0, 0, 0 }, // Y411 
{ sizeof(DDPIXELFORMAT), DDPF_FOURCC, FOURCC_YUY2, 0, 0, 0, 0, 0 }, // YUY2 
{ sizeof(DDPIXELFORMAT), DDPF_FOURCC, FOURCC_UYVY, 0, 0, 0, 0, 0 } // UYVY 
}; 

int i, nPixelFormat=sizeof(PixelFormat)/sizeof(DDPIXELFORMAT); 

//创建覆盖表面 
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; 
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY; // Overlay related APIs will fail without hardware support.  
ddsd.dwWidth=1628; 
ddsd.dwHeight=1236; 
for(i=0;i <nPixelFormat;i++)  

memcpy(&ddsd.ddpfPixelFormat,&PixelFormat[i],sizeof(DDPIXELFORMAT)); 

hr=m_lpDD-> CreateSurface(&ddsd,&m_lpDDSOverlay,NULL); 
if(hr==DD_OK) { 
char tmpBuf[256]; 
sprintf(tmpBuf, "创建第%d种OVERLAY表面成功 ! ",i); 
::MessageBox(NULL,tmpBuf, "DirectDraw初始化 ",MB_ICONINFORMATION); 
break; 

}
}

}


if ((hr = m_lpDD->CreateClipper(0, &m_lpClipper, NULL)) != DD_OK ||
(hr = m_lpClipper->SetHWnd(0, hWnd) ) != DD_OK ||
(hr = m_lpDDSPrimary->SetClipper(m_lpClipper) ) != DD_OK)
{
if (m_lpDDSPrimary != NULL)
{
m_lpDDSPrimary->Release();
m_lpDDSPrimary = NULL;
}
m_hWnd = hWnd;
return DD_OK;
}

m_hWnd = hWnd;

return hr;
}

//UpdateOverlay更新刷新表面函数:
RECT PicRect,ScreenRect; //图像区域与屏幕显示区域;
HRESULT CDirectDrawSurface::DrawYuvToOverlaySurface(RECT ScreenRect,BYTE *YuvBuf,int width,int height)
{
BYTE *pSurf;
DDSURFACEDESC2 ddsd;
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);