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

,小弟我的directdraw视频显示程序被别的窗口覆盖时会一片雪白,里面是代码

2012-09-11 
求助,我的directdraw视频显示程序被别的窗口覆盖时会一片雪白,里面是代码。我的代码是照着网上的代码写的,

求助,我的directdraw视频显示程序被别的窗口覆盖时会一片雪白,里面是代码。
我的代码是照着网上的代码写的,没有干扰的时候显示没问题,一有别的窗口覆盖,甚至聊天软件弹出个窗口我的播放窗口就会一片雪白,但是程序还在跑,因为还在读硬盘里的数据。代码如下。

#define w 352
#define h 288

LPDIRECTDRAW lpDD= NULL;
LPDIRECTDRAWSURFACE lpDDSPrimary= NULL;
LPDIRECTDRAWSURFACE lpDDSOffScr= NULL;
DDSURFACEDESCddsd;

HWND h_Wnd;
RECT oldRect;
//销毁
int ddraw_uninit()
{
if(lpDD != NULL)
{
if(lpDDSPrimary != NULL)
{
lpDDSPrimary->Release();
lpDDSPrimary = NULL;
}
if(lpDDSOffScr != NULL)
{
lpDDSOffScr->Release();
lpDDSOffScr = NULL;
}
lpDD->Release();
lpDD = NULL;
}
return 0;
}

//初始化
int ddraw_init()
{
ddraw_uninit();
  if (DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK) 
return -1;

  if (lpDD->SetCooperativeLevel(h_Wnd,
DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK)
  return -1;

ZeroMemory(&ddsd, sizeof(ddsd));
  ddsd.dwSize = sizeof(ddsd);
  ddsd.dwFlags = DDSD_CAPS;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  if (lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL) != DD_OK)
  return -1;

LPDIRECTDRAWCLIPPER pcClipper; 
if( lpDD->CreateClipper( 0, &pcClipper, NULL ) != DD_OK )
return FALSE;
if( pcClipper->SetHWnd( 0, h_Wnd ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
if( lpDDSPrimary->SetClipper( pcClipper ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
pcClipper->Release();



ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; //DDSCAPS_OVERLAY DDSCAPS_OFFSCREENPLAIN;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
ddsd.dwWidth = w;
ddsd.dwHeight = h;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV ;
ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V','1','2');
ddsd.ddpfPixelFormat.dwYUVBitCount = 8;
if (lpDD->CreateSurface(&ddsd, &lpDDSOffScr, NULL) != DD_OK)
{
AfxMessageBox("CreateSurface错误!");
return -1;
}
return 0;
}

//播放
int ddraw_play(char *buffer)
{
RECTrctDest;
RECTrctSour;
HRESULTddRval;

do {
ddRval = lpDDSOffScr->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
} while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
{
AfxMessageBox("Lock错误!");
return -1;
}
LPBYTE lpSurf = (LPBYTE)ddsd.lpSurface;
LPBYTE lpY = (LPBYTE)buffer;
LPBYTE lpU = (LPBYTE)buffer + w * h;
LPBYTE lpV = (LPBYTE)buffer + w * h * 5 / 4;
if(lpSurf)
{
int i = 0;
for(i=0; i<ddsd.dwHeight; i++)
{
memcpy(lpSurf, lpY, ddsd.dwWidth);
lpY += w;
lpSurf += ddsd.lPitch;
}
for(i=0; i<ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, lpV, ddsd.dwWidth / 2);
lpV += w / 2;
lpSurf += ddsd.lPitch / 2;
}
for(i=0; i<ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, lpU, ddsd.dwWidth / 2);
lpU += w / 2;
lpSurf += ddsd.lPitch / 2;
}
}
lpDDSOffScr->Unlock(NULL);
/*
rctSour.left = 0;
rctSour.top = 0;
rctSour.right = ddsd.dwWidth;
rctSour.bottom = ddsd.dwHeight;
GetClientRect(h_Wnd,&rctDest);
ClientToScreen(h_Wnd, (LPPOINT)&rctDest.left);
ClientToScreen(h_Wnd, (LPPOINT)&rctDest.right);
*/
do 
{
//ddRval = lpDDSPrimary->Blt(&rctDest, lpDDSOffScr, &rctSour, DDBLT_WAIT, NULL);


ddRval = lpDDSPrimary->Blt(NULL, lpDDSOffScr, NULL, DDBLT_WAIT, NULL);
} while (ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
{
AfxMessageBox("blt错误!");
return -1;
}
if(lpDDSPrimary->IsLost() == DDERR_SURFACELOST)
{
AfxMessageBox("lost");
}
return 0;
}

//对播放的包装
int inputData(char *data)
{
RECT rect;
if(GetWindowRect(h_Wnd, &rect))
{
if( rect.bottom != oldRect.bottom ||
rect.left != oldRect.left ||
rect.right != oldRect.right ||
rect.top != oldRect.top)
{
ddraw_init();
memcpy(&oldRect, &rect, sizeof(RECT));
}
if(ddraw_play(data) != 0)
{
AfxMessageBox("ddraw_play错误1!");
ddraw_init();
if(ddraw_play(data) != 0)
{
AfxMessageBox("ddraw_play错误2!");
return S_FALSE;
}
}
}
return 0;
}

//读yuv数据,调用播放函数
void CDdrawtestView::OnEditPlay() 
{
// TODO: Add your command handler code here
h_Wnd = m_hWnd;
memset(&oldRect, 0, sizeof(oldRect));
FILE *fp = fopen("test.yuv", "rb");
char frame[352*288*3/2];
while (fread(frame, 1, 352*288*3/2, fp))
{
inputData(frame);
}
fclose(fp);
ddraw_uninit();
}

我所有对错误的捕捉都没有生效。请告诉我错在哪里。谢谢。

[解决办法]
When a DirectDraw surface is lost, many methods will return DDERR_SURFACELOST, and perform no other function. A IDirectDrawSurface::Restore should be called to reallocate surface memory and reattach it to the DirectDrawSurface object.
[解决办法]
帮顶
[解决办法]
帮顶
[解决办法]
估计是directdraw 显示设置参数没有设置对。
[解决办法]
需要使用directdraw的几个表层
LPDIRECTDRAW m_lpDD;
DDSURFACEDESC m_ddsd;
LPDIRECTDRAWCLIPPER m_lpDDClipper;
LPDIRECTDRAWSURFACE m_lpDDSPrimary;
LPDIRECTDRAWSURFACE m_lpDDSOffScr;
这些结构都要用到,你看你的哪些没有用到

热点排行