direct yuv



CWnd *pDdrawDisplay;
FILE *pFileYUV=NULL;


#define HEIGHT         480
#define WIDTH          720
#define DRAW_TOP       0
#define DRAW_LEFT      0
#define DRAW_HEIGHT    480
#define DRAW_WIDTH     720


HWND hWnd;
HANDLE hEvent;
HANDLE hThread;
DWORD dwThreadID;
BOOL DrawYV12();
BOOL CDlgDisplay::OnInitDialog() 
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
hThread=CreateThread(NULL,
        0,
                         (LPTHREAD_START_ROUTINE)DrawYV12,
        NULL,
CREATE_SUSPENDED,//0,
                         &dwThreadID);

return TRUE;  // return TRUE unless you set the focus to a control
             // EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgDisplay::OnStart() 
{
// TODO: Add your control notification handler code here
SetEvent(hEvent);
ResumeThread(hThread);
}
void CDlgDisplay::OnStop() 
{
// TODO: Add your control notification handler code here
ResetEvent(hEvent);
SuspendThread(hThread);
}
BOOL DrawYV12()
{
CString               strFrameNum;
LPDIRECTDRAW          lpDD;           //DirectDraw对象指针
LPDIRECTDRAWSURFACE   lpDDSPrimary;   //DirectDraw主表面指针
LPDIRECTDRAWSURFACE   lpDDSOffScr;    //DirectDraw离屏表面指针
DDSURFACEDESC         ddsd;           //DirectDraw表面描述
RECT                  rctDest;        //目标区域
RECT                  rctSour;        //源区域
HRESULT               ddRval;         //DirectDraw函数返回值
hWnd=pDdrawDisplay->GetSafeHwnd();
//创建DirectDraw对象
ddRval=DirectDrawCreate(NULL,&lpDD,NULL);
if(DD_OK!=ddRval)
{
AfxMessageBox("DirectDraw对象创建不成功!");
return FALSE;
}

//设置协作层
ddRval=lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL|DDSCL_NOWINDOWCHANGES);
    if(DD_OK!=ddRval)
{
AfxMessageBox("协作层设置不成功!");
return FALSE;
}


//创建主表面
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
ddRval=lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL);
if(DD_OK!=ddRval)
{
AfxMessageBox("主表面创建不成功!");
return FALSE;
}


//创建离屏表面对象
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.ddsCaps.dwCaps=DDSCAPS_OVERLAY;//DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY
ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.dwWidth=DRAW_WIDTH;
ddsd.dwHeight=DRAW_HEIGHT;
ddsd.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags=DDPF_FOURCC|DDPF_YUV;
ddsd.ddpfPixelFormat.dwFourCC=MAKEFOURCC('Y','V','1','2');//('Y','U','Y','2');
ddsd.ddpfPixelFormat.dwYUVBitCount=8;
ddRval=lpDD->CreateSurface(&ddsd,&lpDDSOffScr,NULL);
if(DD_OK!=ddRval)
{
AfxMessageBox("离屏表面创建不成功!");
return FALSE;
}

//加载yv12图象文件
// FILE *fYUV=fopen("E://directdraw//YUVPlayer//testdata//D1.yuv","rb+");
FILE *fYUV=fopen("f://capture.yuv","rb+");
LPBYTE lpAllYUV=new BYTE[WIDTH*HEIGHT*3/2];


for(int f=0;f<500;f++)
{
WaitForSingleObject(hEvent,INFINITE);
strFrameNum.Format("%d",f);
pDdrawDisplay->SetWindowText(strFrameNum);
UINT iLen=fread(lpAllYUV,1,WIDTH*HEIGHT*3/2,fYUV);
if(0==iLen)
{
// AfxMessageBox("Can not find the YUV input file!");
}
LPBYTE lpYUV=lpAllYUV;
LPBYTE lpY=lpYUV;
LPBYTE lpV=lpY+WIDTH*HEIGHT;//lpYUV+WIDTH*HEIGHT;
LPBYTE lpU=lpV+WIDTH*HEIGHT/4;//lpYUV+WIDTH*HEIGHT*3/2;
ddRval=lpDDSOffScr->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_WRITEONLY,NULL);
while(DDERR_WASSTILLDRAWING==ddRval);
if(DD_OK!=ddRval)
{
AfxMessageBox("离屏表面锁定不成功!");
return FALSE;
}


LPBYTE lpSurf=(LPBYTE)ddsd.lpSurface;
LPBYTE lpY1=lpSurf;
LPBYTE lpV1=lpY1+ddsd.lPitch*HEIGHT;
LPBYTE lpU1=lpV1+ddsd.lPitch*HEIGHT/4;
int nOffset=DRAW_TOP*WIDTH+DRAW_LEFT;
//填充离屏表面
if(lpSurf)
{
int i=0;
//fill Y data
lpY+=nOffset;
for(i=0;i<ddsd.dwHeight;i++)
{
memcpy(lpSurf,lpY,ddsd.dwWidth);
lpY+=WIDTH;
lpSurf+=ddsd.lPitch;
}
//fill V data
lpV+=DRAW_TOP*WIDTH/4+DRAW_LEFT/2;
for(i=0;i<ddsd.dwHeight/2;i++)
{
memcpy(lpSurf,lpV,ddsd.dwWidth/2);
lpV+=WIDTH/2;
lpSurf+=ddsd.lPitch/2;
}
//file U data
lpU+=DRAW_TOP*WIDTH/4+DRAW_LEFT/2;
for(i=0;i<ddsd.dwHeight/2;i++)
{
memcpy(lpSurf,lpU,ddsd.dwWidth/2);
lpU+=WIDTH/2;
lpSurf+=ddsd.lPitch/2;
}
}
lpDDSOffScr->Unlock(NULL);

//Blt到主表面
rctSour.left=0;
rctSour.top=0;
rctSour.right=ddsd.dwWidth;
rctSour.bottom=ddsd.dwHeight;
GetClientRect(hWnd,&rctDest);
ClientToScreen(hWnd,(LPPOINT)&rctDest.left);
ClientToScreen(hWnd,(LPPOINT)&rctDest.right);
ddRval=lpDDSPrimary->Blt(&rctDest,lpDDSOffScr,&rctSour,DDBLT_WAIT,NULL);
while(DDERR_WASSTILLDRAWING==ddRval);
if(DD_OK!=ddRval)
{
AfxMessageBox("Blt到主表面不成功!");
return FALSE;
}
/*else
{
AfxMessageBox("Blt到主表面成功!");
}*/
Sleep(30);
SetEvent(hEvent);
}
//释放DirectDraw对象
fclose(fYUV);
delete lpAllYUV;
if(lpDD!=NULL)
{
if(lpDDSPrimary!=NULL)
{
lpDDSPrimary->Release();
lpDDSPrimary=NULL;
}
if(lpDDSOffScr!=NULL)
{
lpDDSOffScr->Release();
lpDDSOffScr=NULL;
}
lpDD->Release();
lpDD=NULL;
}
return TRUE;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值