请教各位ddraw高手如何实现双缓冲绘制yuv数据
现在有经过ffmpeg解码后的yuv图像数据,目前实现了基于copy模式的ddraw surface绘制,但是感觉效率不高,请教哪位高手:
1)如何使用ddraw实现双缓冲绘制?
2)如何实现ddraw绘制yuv420数据高效绘制,是否双缓冲能够提高效率。
3)如果您有效率较高的绘制yuv数据的ddraw代码,请附在下面,谢谢了。
我目前的代码实现:
附代码:
//------------------------------------------------------------------------
/**
使用directshow方式绘制图像
\param pAVFrame 解码后图像帧数据
\return status 状态码
*/
//------------------------------------------------------------------------
VxInt32 CDisplay::ddshow_draw(int imgWidth, int imgHeight, AVFrame* pAVFrame)
{
VxInt32 status = LIVE_OK;
LPBYTE PtrY = (unsigned char *)pAVFrame->data[0];
LPBYTE PtrU = (unsigned char *)pAVFrame->data[1];
LPBYTE PtrV = (unsigned char *)pAVFrame->data[2];
int ddRval = 0;
do
{
ddRval = m_lpDDSOffScr->Lock(NULL, &m_ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
if ( DDERR_SURFACELOST == ddRval)
{
m_lpDDSOffScr->Restore();
ddRval = m_lpDDSOffScr->Lock(NULL, &m_ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
}
} while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
{
DLL_TRACE(__FILE__, __LINE__, "m_lpDDSOffScr->Lock failed ddRval = %d", ddRval);
return LIVE_FAILED;
}
LPBYTE lpSurf = (LPBYTE)m_ddsd.lpSurface;
if(lpSurf)
{
int i = 0;
for (i = 0; i < imgHeight; i++)
{
memcpy(lpSurf, PtrY, imgWidth);
PtrY += pAVFrame->linesize[0];
lpSurf += m_ddsd.lPitch;
}
for (i = 0; i < imgHeight/2; i++)
{
memcpy(lpSurf, PtrV, imgWidth/2);
PtrV += pAVFrame->linesize[1];
lpSurf += m_ddsd.lPitch/2;
}
for (i = 0; i < imgHeight/2; i++)
{
memcpy(lpSurf, PtrU, imgWidth/2);
PtrU += pAVFrame->linesize[2];
lpSurf += m_ddsd.lPitch/2;
}
}
m_lpDDSOffScr->Unlock(NULL);
DDBLTFX ddbltfx;
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwROP = SRCCOPY;
RECT rect;
status = this->GetShowRect(rect);
if (ISFAILED(status))
{
DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw GetShowRect failed = %d !!!!!", status);
return status;
}
DWORD dret = m_lpDDSPrimary->Blt(&rect, m_lpDDSOffScr, NULL, DDBLT_ROP, &ddbltfx);
if ( DDERR_SURFACELOST == dret)
{
m_lpDDSPrimary->Restore();
DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw m_lpDDSPrimary Restore ");
}
// DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw dret=%d !!!!!", dret);
return status;
}