#include "stdafx.h"
#include "MyDDraw.h"
CMyDDraw::CMyDDraw(void)
{
m_hShowHwnd = NULL;
m_lpDD = NULL;
m_lpDDSPrimary = NULL;
m_lpDDSOffScr = NULL;
m_lpddsback = NULL;
memset(m_ddsd, 0, sizeof(DDSURFACEDESC2));
m_nWith = 0;
m_nHeight = 0;
}
CMyDDraw::~CMyDDraw(void)
{
}
BOOL CMyDDraw::Init(HWND hWnd)
{
ASSERT(hWnd != NULL);
m_hShowHwnd = hWnd;
// 创建DirectCraw对象
if (DirectDrawCreateEx(NULL, (VOID**)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create DDraw. \n");
return FALSE;
}
// 设置协作层
if (m_lpDD->SetCooperativeLevel(m_hShowHwnd,
DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK)
{
DPrintf("\n zhao -- Error Create Level.\n");
return FALSE;
}
// 创建主表面
ZeroMemory(&m_ddsd, sizeof(m_ddsd));
m_ddsd.dwSize = sizeof(m_ddsd);
m_ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
m_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
m_ddsd.dwBackBufferCount = 1;
if (m_lpDD->CreateSurface(&m_ddsd, &m_lpDDSPrimary, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create Primary Surface.");
return FALSE;
}
m_ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
m_ddsd.dwWidth = 800;
m_ddsd.dwHeight = 600;
HRESULT HR = m_lpDDSPrimary->GetAttachedSurface(&m_ddsd.ddsCaps, &m_lpddsback);
if(FAILED(HR))
return HR;
LPDIRECTDRAWCLIPPER pcClipper; //Cliper
if( m_lpDD->CreateClipper( 0, &pcClipper, NULL ) != DD_OK )
return FALSE;
if( pcClipper->SetHWnd( 0, hWnd ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
if( m_lpDDSPrimary->SetClipper( pcClipper ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
// Done with clipper
pcClipper->Release();
// 创建YUV表面
ZeroMemory(&m_ddsd, sizeof(m_ddsd));
m_ddsd.dwSize = sizeof(m_ddsd);
m_ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
m_ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
m_ddsd.dwWidth = m_nWith;
m_ddsd.dwHeight = m_nHeight;
m_ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
m_ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV ;
m_ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V', '1', '2');
m_ddsd.ddpfPixelFormat.dwYUVBitCount = 8;
if (m_lpDD->CreateSurface(&m_ddsd, &m_lpDDSOffScr, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create Off Surface.");
return FALSE;
}
return TRUE;
}
void CMyDDraw::UnInit()
{
}
BOOL CMyDDraw::ShowVideo(BYTE* pY, BYTE *pU, BYTE *pV, int nFlag)
{
LPBYTE lpSurf = (LPBYTE)m_ddsd.lpSurface;
LPBYTE PtrY = pY;
LPBYTE PtrU = pU;
LPBYTE PtrV = pV;
HRESULT ddRval;
do {
ddRval = m_lpDDSOffScr->Lock(NULL,&m_ddsd,DDLOCK_WAIT | DDLOCK_WRITEONLY,NULL);
} while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
return 1;
//m_nWith 每一行数据长度
int nOffset = DRAW_TOP*m_nWith+DRAW_LEFT;
// 填充离屏表面
if( lpSurf != NULL )
{
int i = 0;
// fill Y data
pY += nOffset;
for(i = 0; i < (int)m_ddsd.dwHeight; i++)
{
memcpy(lpSurf, pY, m_ddsd.dwWidth);
pY += m_nWith;
lpSurf += m_ddsd.lPitch;
}
// fill V data
pV += DRAW_TOP * m_nWith / 4 + DRAW_LEFT / 2;
for(i = 0; i < (int)m_ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, pV, m_ddsd.dwWidth / 2);
pV += m_nWith / 2;
lpSurf += m_ddsd.lPitch / 2;
}
// fill U data
pU += DRAW_TOP * m_nWith / 4 + DRAW_LEFT / 2;
for(i = 0; i < (int)m_ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, pU, m_ddsd.dwWidth / 2);
pU += m_nWith / 2;
lpSurf += m_ddsd.lPitch / 2;
}
}
m_lpDDSOffScr->Unlock(NULL);
ddRval = m_lpddsback->Blt(NULL, m_lpDDSOffScr, NULL, DDBLT_WAIT, NULL);
}
#include "MyDDraw.h"
CMyDDraw::CMyDDraw(void)
{
m_hShowHwnd = NULL;
m_lpDD = NULL;
m_lpDDSPrimary = NULL;
m_lpDDSOffScr = NULL;
m_lpddsback = NULL;
memset(m_ddsd, 0, sizeof(DDSURFACEDESC2));
m_nWith = 0;
m_nHeight = 0;
}
CMyDDraw::~CMyDDraw(void)
{
}
BOOL CMyDDraw::Init(HWND hWnd)
{
ASSERT(hWnd != NULL);
m_hShowHwnd = hWnd;
// 创建DirectCraw对象
if (DirectDrawCreateEx(NULL, (VOID**)&m_lpDD, IID_IDirectDraw7, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create DDraw. \n");
return FALSE;
}
// 设置协作层
if (m_lpDD->SetCooperativeLevel(m_hShowHwnd,
DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK)
{
DPrintf("\n zhao -- Error Create Level.\n");
return FALSE;
}
// 创建主表面
ZeroMemory(&m_ddsd, sizeof(m_ddsd));
m_ddsd.dwSize = sizeof(m_ddsd);
m_ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
m_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
m_ddsd.dwBackBufferCount = 1;
if (m_lpDD->CreateSurface(&m_ddsd, &m_lpDDSPrimary, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create Primary Surface.");
return FALSE;
}
m_ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
m_ddsd.dwWidth = 800;
m_ddsd.dwHeight = 600;
HRESULT HR = m_lpDDSPrimary->GetAttachedSurface(&m_ddsd.ddsCaps, &m_lpddsback);
if(FAILED(HR))
return HR;
LPDIRECTDRAWCLIPPER pcClipper; //Cliper
if( m_lpDD->CreateClipper( 0, &pcClipper, NULL ) != DD_OK )
return FALSE;
if( pcClipper->SetHWnd( 0, hWnd ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
if( m_lpDDSPrimary->SetClipper( pcClipper ) != DD_OK )
{
pcClipper->Release();
return FALSE;
}
// Done with clipper
pcClipper->Release();
// 创建YUV表面
ZeroMemory(&m_ddsd, sizeof(m_ddsd));
m_ddsd.dwSize = sizeof(m_ddsd);
m_ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
m_ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
m_ddsd.dwWidth = m_nWith;
m_ddsd.dwHeight = m_nHeight;
m_ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
m_ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV ;
m_ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V', '1', '2');
m_ddsd.ddpfPixelFormat.dwYUVBitCount = 8;
if (m_lpDD->CreateSurface(&m_ddsd, &m_lpDDSOffScr, NULL) != DD_OK)
{
DPrintf("\n zhao -- Error Create Off Surface.");
return FALSE;
}
return TRUE;
}
void CMyDDraw::UnInit()
{
}
BOOL CMyDDraw::ShowVideo(BYTE* pY, BYTE *pU, BYTE *pV, int nFlag)
{
LPBYTE lpSurf = (LPBYTE)m_ddsd.lpSurface;
LPBYTE PtrY = pY;
LPBYTE PtrU = pU;
LPBYTE PtrV = pV;
HRESULT ddRval;
do {
ddRval = m_lpDDSOffScr->Lock(NULL,&m_ddsd,DDLOCK_WAIT | DDLOCK_WRITEONLY,NULL);
} while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
return 1;
//m_nWith 每一行数据长度
int nOffset = DRAW_TOP*m_nWith+DRAW_LEFT;
// 填充离屏表面
if( lpSurf != NULL )
{
int i = 0;
// fill Y data
pY += nOffset;
for(i = 0; i < (int)m_ddsd.dwHeight; i++)
{
memcpy(lpSurf, pY, m_ddsd.dwWidth);
pY += m_nWith;
lpSurf += m_ddsd.lPitch;
}
// fill V data
pV += DRAW_TOP * m_nWith / 4 + DRAW_LEFT / 2;
for(i = 0; i < (int)m_ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, pV, m_ddsd.dwWidth / 2);
pV += m_nWith / 2;
lpSurf += m_ddsd.lPitch / 2;
}
// fill U data
pU += DRAW_TOP * m_nWith / 4 + DRAW_LEFT / 2;
for(i = 0; i < (int)m_ddsd.dwHeight/2; i++)
{
memcpy(lpSurf, pU, m_ddsd.dwWidth / 2);
pU += m_nWith / 2;
lpSurf += m_ddsd.lPitch / 2;
}
}
m_lpDDSOffScr->Unlock(NULL);
ddRval = m_lpddsback->Blt(NULL, m_lpDDSOffScr, NULL, DDBLT_WAIT, NULL);
}