DirectDr视频上画图,DirectDraw+GDI,画面闪??

peimoxu 2008-09-16 05:03:51
要的效果是每帧视频显示完后,再在视频上画一些其它的图形,
视频是用DirectDraw画的,其它图形是用GDI画的,没法用双缓冲,
现在的问题是视频图像之上的图形闪的厉害,不知有没有解决的好办法?


void DrawVideo(VideoData &data)
{
//DirectDraw画视频

RECT wndRect;
GetClientRect(hWnd, &wndRect);
HDC hdc = GetWindowDC(hWnd);

//画其它图形???

ReleaseDC(hWnd, hdc);
}

...全文
600 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
wutaihua 2011-07-08
  • 打赏
  • 举报
回复
顶贴啊。
red-fly 2011-07-08
  • 打赏
  • 举报
回复
先记住,以后可能有用,呵呵
peimoxu 2008-09-17
  • 打赏
  • 举报
回复
谢谢,照你的方法搞定了
zzywany123 2008-09-17
  • 打赏
  • 举报
回复
	ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;

hr = m_pDD->CreateSurface(&ddsd, &m_pPrimarySurface, NULL);
if (hr != S_OK)
{
m_pDD->Release();
m_pDD = NULL;
sError.Format("Create Primary Surface failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}

LPDIRECTDRAWCLIPPER pcClipper; // Cliper
hr = m_pDD->CreateClipper( 0, &pcClipper, NULL );
if( hr != DD_OK )
{
m_pDD->Release();
m_pPrimarySurface->Release();
m_pDD = NULL;
m_pPrimarySurface = NULL;
sError.Format("Create clipper failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}

hr = pcClipper->SetHWnd( 0, hWnd );
if( hr != DD_OK )
{
m_pPrimarySurface->Release();
pcClipper->Release();
m_pDD->Release();
m_pPrimarySurface = NULL;
m_pDD = NULL;
pcClipper = NULL;
sError.Format("Clipper SetHWnd failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}
hr = m_pPrimarySurface->SetClipper( pcClipper );
if( hr != DD_OK )
{
pcClipper->Release();
m_pDD->Release();
m_pPrimarySurface->Release();
m_pPrimarySurface = NULL;
m_pDD = NULL;
pcClipper = NULL;
sError.Format("PrimarySurface SetClipper failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}

// Done with clipper
pcClipper->Release();

// 创建YUV表面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
ddsd.dwWidth = m_nImageWidth;
ddsd.dwHeight = m_nImageHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV ;
ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V', '1', '2');

hr = m_pDD->CreateSurface(&ddsd, &m_pBackSurface, NULL);
if ( hr != DD_OK)
{
m_pDD->Release();
m_pPrimarySurface = NULL;
m_pDD = NULL;
sError.Format("Create BackSurface failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}

//OSD表面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.dwWidth = m_nImageWidth;
ddsd.dwHeight = m_nImageHeight;

hr = m_pDD->CreateSurface(&ddsd, &m_pOsdSurface, NULL);
if ( hr != DD_OK)
{
m_pDD->Release();
m_pPrimarySurface = NULL;
m_pDD = NULL;
sError.Format("Create m_pOsdSurface failed:%d, %.8x\n", GetLastError(), hr);
OutputDebugString(sError);
return false;
}



	do 
{
hr = m_pBackSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
} while(hr == DDERR_WASSTILLDRAWING);

if(hr != DD_OK)
return;

LPBYTE lpSurf = (LPBYTE)ddsd.lpSurface;
int nHalfWidth = ddsd.dwWidth>>1;
int nHalfHeight = m_nImageHeight>>1;
int nHalfPitch = ddsd.lPitch>>1;

if(lpSurf != NULL)
{
for (int i = 0;i < m_nImageHeight;i++)
{
memcpy(lpSurf, py, ddsd.dwWidth);
py += m_nImageWidth;
lpSurf += ddsd.lPitch;
}
for (i = 0;i < nHalfHeight;i++)
{
memcpy(lpSurf, pv, nHalfWidth);
pv += nHalfWidth;
lpSurf += (ddsd.lPitch>>1);
}

for (i = 0;i < nHalfHeight;i++)
{
memcpy(lpSurf, pu, nHalfWidth);
pu += nHalfWidth;
lpSurf += nHalfPitch;
}
}
else
{
m_pBackSurface->Unlock(NULL);
return;
}

m_pBackSurface->Unlock(NULL);
hr = m_pOsdSurface->Blt(&SrcRect, m_pBackSurface, &SrcRect, DDBLT_WAIT, NULL);
if (hr != DD_OK)
{
hr = m_pPrimarySurface->Blt(&DestRect, m_pBackSurface, &SrcRect, DDBLT_WAIT, NULL);
}
else
{
HDC hDC = NULL;
hr = m_pOsdSurface->GetDC(&hDC);
if ((hr == DD_OK)&&(hDC != NULL))
{

RECT OsdRect;

OsdRect.left = 0;
OsdRect.top = 0;
OsdRect.right = 640;
OsdRect.bottom = 480;
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB(0, 0xFF, 0));

TextOut(hDC, 0, 0, m_sOsdMsg, m_sOsdMsg.GetLength());


m_pOsdSurface->ReleaseDC(hDC);
m_pPrimarySurface->Blt(&DestRect, m_pOsdSurface, &SrcRect, DDBLT_WAIT, NULL);
}
}
peimoxu 2008-09-17
  • 打赏
  • 举报
回复
我的程序是在对话框上显示一个视频窗口,不能全屏,
不知道 DDSCAPS_BACKBUFFER 怎么创建??
peimoxu 2008-09-17
  • 打赏
  • 举报
回复

ddrval = DirectDrawCreateEx(NULL, (void**)&_lpdd, IID_IDirectDraw7, NULL);
if(FAILED(ddrval))
{
return CREATE_OBJ_FAILED;
}
ddrval = _lpdd->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
//ddrval = _lpdd->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);用这句会失败,返回E_INVALIDARG
if(FAILED(ddrval))
{
_lpdd->Release();
_lpdd = NULL;
return DDRAW_ERROR;
}

ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
//换成下面的CreateSurface也失败,返回-2005532447
//ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
//ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
//ddsd.dwBackBufferCount=1;

ddrval = _lpdd->CreateSurface(&ddsd, &_lpddsPrimary, NULL);

//ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
//_lpddsPrimary->GetAttachedSurface(&ddsd.ddsCaps, &_lpddsPrimary2);
peimoxu 2008-09-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zzywany123 的回复:]
另外建一个表面,先把backsurface的图像blt到这个表面上面,然后获取这个表面的dc,在上面绘图 完了再blt到主表面去
[/Quote]
这个中间的表面怎么建啊,DDSCAPS_OFFSCREENPLAIN ? DDSCAPS_PRIMARYSURFACE
zzywany123 2008-09-17
  • 打赏
  • 举报
回复
另外建一个表面,先把backsurface的图像blt到这个表面上面,然后获取这个表面的dc,在上面绘图 完了再blt到主表面去

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧