BOOL CDDrawShow::DrawYV12byDraw7(LPBYTE lpY, LPBYTE lpV, LPBYTE lpU, DWORD width, DWORD height)
{
if ((m_dwHeight != height) || (m_dwWidth != width))
{
DestroyDDrawObj();//自定义方法,不用理会
CreateDDrawObj(YV12, m_hPlayWnd, width, height);//自定义方法,不用理会
}
if (!m_lpDDSOffScr || !m_lpDDSPrimary || !m_lpDD )
{
return S_FALSE;
}
if (!lpY || !lpV || !lpU)
{
return S_FALSE;
}
//将解码得到的YUV数据拷贝到YUV表面
HRESULT ddRval; // DirectDraw 函数返回值
RECT rctDest; // 目标区域
RECT rctSour; // 源区域
ddRval = m_lpDDSOffScr->Lock(NULL,&m_ddsd,/*DDLOCK_DONOTWAIT*/DDLOCK_WAIT | DDLOCK_WRITEONLY,NULL);
// while(ddRval == DDERR_WASSTILLDRAWING);
if( ddRval == DDERR_SURFACELOST )
{
//MessageBox("DDERR_SURFACELOST");
ddRval = m_lpDDSOffScr->Restore();
ddRval = m_lpDDSOffScr->Lock(NULL, &m_ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
}
if(ddRval != DD_OK)
return FALSE;
// 填充离屏表面
LPBYTE lpSurf = (LPBYTE)m_ddsd.lpSurface;
if(lpSurf)
{
unsigned int i = 0;
for (i=0;i<m_ddsd.dwHeight;i++)
{
memcpy(lpSurf, lpY, m_ddsd.dwWidth);
lpY += m_dwWidth;
lpSurf += m_ddsd.lPitch;
}
for (i=0;i<m_ddsd.dwHeight/2;i++)
{
memcpy(lpSurf, lpV, m_ddsd.dwWidth/2);
lpV += m_dwWidth/2;
lpSurf += m_ddsd.lPitch/2;
}
for (i=0;i<m_ddsd.dwHeight/2;i++)
{
memcpy(lpSurf, lpU, m_ddsd.dwWidth/2);
lpU += m_dwWidth/2;
lpSurf += m_ddsd.lPitch/2;
}
}
m_lpDDSOffScr->Unlock(NULL);
//YUV表面的显示
rctSour.left = 0;
rctSour.top = 0;
rctSour.right = m_ddsd.dwWidth;
rctSour.bottom = m_ddsd.dwHeight;
::GetClientRect(m_hPlayWnd,&rctDest);
::ClientToScreen(m_hPlayWnd, (LPPOINT)&rctDest.left);
::ClientToScreen(m_hPlayWnd, (LPPOINT)&rctDest.right);
ddRval = m_lpDDSPrimary->Blt(&rctDest, m_lpDDSOffScr, &rctSour, DDBLT_WAIT, NULL);
// while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
{
// MessageBox(NULL,"blt error",NULL,MB_OK);
return FALSE;
}
return TRUE;
}
以上代码是C++,将YV12格式的视频流显示出来。跪求:C#的实现方式。换个思路也行。其它第三方组件能解决这个问题也可以。倒计时,此问题不解决,只有离职了。
哥啊……
你把代码排版一下啊……
已经排版,请求帮助!
你需要熟悉一下.net调用COM,熟悉一下DDraw。
编译成dll然后用p/invoke试试呢?
LZl离职了没。