如何使用DirectDraw直接显示RGB、YUV视频数据(播放yuv)

来源:互联网 发布:学算法入门看什么书 编辑:程序博客网 时间:2024/05/16 07:34



#include "draw.h"


void CTest100Dlg::OnButton1() 
{
// TODO: Add your control notification handler code here
CloseShowBMP();
InitDrawBMP(m_screen.GetSafeHwnd(),m_sel.GetCurSel());
}


void CTest100Dlg::OnButton2() 
{


CString strFilename,str;
CFileDialog openBox(TRUE,NULL,"",OFN_HIDEREADONLY,"bmp(*.bmp)|*.bmp|ALLFiles(*.*)|*.*||",NULL);
openBox.m_ofn.lpstrTitle="打开数据文件";
INT_PTR nResult = openBox.DoModal();
    // 如果文件打开则准备播放
    if (nResult == IDOK)
    {
strFilename=openBox.GetPathName();
    }
else
{
return;
}
    strFilename.ReleaseBuffer();
ReadBMP(strFilename);
    ShowBMP();
}


void CTest100Dlg::OnClose() 
{
// TODO: Add your message handler code here and/or call default
//MessageBox("sadf");
    CloseShowBMP();
CDialog::OnClose();
}


void CTest100Dlg::OnButton3() 
{
// TODO: Add your control notification handler code here
CString strFilename,str;
CFileDialog openBox(TRUE,NULL,"",OFN_HIDEREADONLY,"YUV(*.yuv)|*.yuv|ALLFiles(*.*)|*.*||",NULL);
openBox.m_ofn.lpstrTitle="打开数据文件";
INT_PTR nResult = openBox.DoModal();
    // 如果文件打开则准备播放
    if (nResult == IDOK)
    {
strFilename=openBox.GetPathName();
    }
else
{
return;
}
    strFilename.ReleaseBuffer();
CClientDC dc(this);
CDC *pdc = &dc;
ReadYUV(strFilename,pdc);


}


void CTest100Dlg::OnButton4() 
{




LPDIRECTDRAW         lpdd=NULL;
LPDIRECTDRAW7        lpdd7=NULL;
//LPDIRECTDRAWSURFACE7 lpddsback;
LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;
LPDIRECTDRAWSURFACE7 lpddsmypage[6];
LPDIRECTDRAWPALETTE  lpddpal=NULL;
DDSURFACEDESC2       ddsd;
LPDIRECTDRAWCLIPPER  lpDDClipper = NULL;


// TODO: 在此添加控件通知处理程序代码
height=width=widthBytes=0;
m_screen.SetWindowPos(&CWnd::wndBottom,0,0,720,576, SWP_NOMOVE | SWP_SHOWWINDOW);
UpdateWindow();
main_window_handle = m_screen.GetSafeHwnd();


if(DD_OK!=(DirectDrawCreateEx(NULL, (void **)&lpdd7, IID_IDirectDraw7, NULL)))
{
return ;
}
// set the cooperative level for full-screen mode
if(DD_OK != lpdd7->SetCooperativeLevel(AfxGetMainWnd()->GetSafeHwnd(), DDSCL_NORMAL))
{
return ;
}
/*设置控制级时,如果应用程序请求了 DDSCL_NORMAL 模式(表明应用程序以普通窗口的形式运行),则不需要提供一个指定窗口的句柄.给窗口句柄参数为 NULL, 所有的窗口都可以被设置为普通的控制级. */
// set the display mode to 640x480x256
// clear ddsd and set size
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);


// enable valid fields
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// create the primary surface


if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{
return ;
}


// 创建裁剪器
if (FAILED(lpdd7->CreateClipper(0, &lpDDClipper, NULL)))
return ; 
// 与窗口工作区关联


if (FAILED(lpDDClipper->SetHWnd(0, main_window_handle)))
{
lpDDClipper->Release();
return ;



if (FAILED(lpddsprimary->SetClipper(lpDDClipper)))
{
lpDDClipper->Release();
return ;
}




//
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.dwWidth = 720;
ddsd.dwHeight = 576;
ddsd.dwBackBufferCount= 0;//忽略            //忽略
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN| DDSCAPS_VIDEOMEMORY; 


ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags  = DDPF_FOURCC | DDPF_YUV ;
ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V','1','2');
ddsd.ddpfPixelFormat.dwYUVBitCount = 8;
//


if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsmypage[0], NULL)))
{
return ;
}


POINT p;


p.x = 0; p.y = 0;
m_screen.ClientToScreen(&p);//获取屏幕顶点
//m_screen.GetClientRect(&rcRectDest);


rcRectDest.left = 0;rcRectDest.top=0;rcRectDest.right = 720;rcRectDest.bottom = 576;




OffsetRect(&rcRectDest, p.x, p.y);//把窗口区域转化为屏幕区域坐标


SetRect(&rcRectSrc, 0, 0, 720, 576);//初始化窗口区域
/////////////////////////////////////////////////////////////
BYTE *buf[3];
buf[0] = new BYTE[720*576];
buf[1] = new BYTE[720*576/4];
buf[2] = new BYTE[720*576/4];
FILE *fp;


fp = fopen("d:\\temp\\VIDEO720576.yuv","rb+");



while(!feof(fp))
{
//fread(buf,720*576*3/2,1,fp);
if(DD_OK != lpddsmypage[0]->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR,NULL))
{
return ;
}


UCHAR  *lp_buffer = (UCHAR *)ddsd.lpSurface;
fread(buf[0],720*576,1,fp);
fread(buf[1],720*576/4,1,fp);
fread(buf[2],720*576/4,1,fp);



LPBYTE lpY = lp_buffer;
LPBYTE lpV = lp_buffer + ddsd.lPitch * 576;
LPBYTE lpU = lp_buffer + ddsd.lPitch * 576 * 5 / 4;
for (int k=0;k<576;k++)
{
memcpy(lpY + k*ddsd.lPitch,buf[0]+720*k,720);
if (k%2==0)
{
memcpy(lpU+ k*ddsd.lPitch/4  ,buf[1]+720*k/4,720/2);
memcpy(lpV+ k*ddsd.lPitch/4  ,buf[2]+720*k/4,720/2);
}
}
Sleep(40); 
//////////////////////////////////////////////////////////////////////////
//memcpy(bmp_buffer,buf[0],720*576*2);


if(DD_OK != lpddsmypage[0]->Unlock(NULL))
{
return ;
}
HRESULT     ddRval;
ddRval= lpddsprimary->Blt( &rcRectDest, lpddsmypage[0], &rcRectSrc, DDBLT_WAIT, NULL);
//while(ddRval == DDERR_WASSTILLDRAWING);
//ddRval=lpddsprimary->Flip(lpddsmypage[0],1);
if(DD_OK != ddRval)
{
return ;

}
//fclose(fp);
if(lpddsmypage)
{
lpddsmypage[0]->Release();
lpddsmypage[0]=NULL;
}
MessageBox(_T("over"));

}

http://download.csdn.net/detail/mao0514/8202699