directdraw显示yuv420(YV12)

简介: <p>height=width=widthBytes=0;<br>  m_screen.SetWindowPos(&CWnd::wndBottom,0,0,720,576, SWP_NOMOVE | SWP_SHOWWINDOW);<br>  UpdateWindow();<br>  main_window_handle = m_screen.GetSafeHwnd();</

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);
 //DDPIXELFORMAT camdispPixelFormat = {sizeof(DDPIXELFORMAT), DDPF_FOURCC, mmioFOURCC('Y','U','1','2'), 0,0,0,0,0}; 
 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);//初始化窗口区域
 /////////////////////////////////////////////////////////////
    FILE *fp;
 buf[0] = new BYTE[720*576];
 buf[1] = new BYTE[720*576/4];
 buf[2] = new BYTE[720*576/4];
 fp = fopen("d:\\temp\\test.yuv","rb+");
 while(!feof(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);
  }

  for (int k=0;k<576/2;k++)
  {
   memcpy(lpU+ k*ddsd.lPitch/2  ,buf[1]+720*k/2,720/2);
   memcpy(lpV+ k*ddsd.lPitch/2 ,buf[2]+720*k/2,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);
  if(DD_OK != ddRval)
  {
   return ;
  }
 }
 fclose(fp);
 if(lpddsmypage)
 {
  lpddsmypage[0]->Release();
  lpddsmypage[0]=NULL;
 }
 MessageBox(_T("over"));

相关文章
|
5月前
|
编解码 算法 vr&ar
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(二)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
200 1
|
5月前
|
存储 编解码 算法
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(一)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
361 1
|
编解码 Linux
SDL图像显示
计算机屏幕上的图像是由一个一个点组成的,不同颜色的点集合在一起,就构成了一幅图片。在屏幕上显示图像,就是对每一个像素点进行着色。首先我们对图片进行分析,取出每一个点的像素,CPU会将其保存在显存中,然后计算机会根据保存的像素,在屏幕上从上到下逐行逐点显示出来
168 0
|
块存储
DirectX--yuv420p上实现的字符叠加
<p><img src="http://img.blog.csdn.net/20141217111324616?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFvMDUxNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>
2001 0
|
存储 vr&ar C++
最简单的视音频播放示例2:GDI播放YUV, RGB
前一篇文章对“Simplest Media Play”工程作了概括性介绍。后续几篇文章打算详细介绍每个子工程中的几种技术。在记录Direct3D,OpenGL这两种相对复杂的技术之前,打算先记录一种和它们属于同一层面的的简单的技术——GDI作为热身。
1484 0
|
存储 API C++
最简单的视音频播放示例7:SDL2播放RGB/YUV
本文记录SDL播放视频的技术。在这里使用的版本是SDL2。实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API。在Windows平台下,SDL封装了Direct3D这类的API用于播放视频;封装了DirectSound这类的API用于播放音频。
2226 0
|
存储 API 开发工具
最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)
上一篇文章记录了GDI播放视频的技术。打算接下来写两篇文章记录Direct3D(简称D3D)播放视频的技术。Direct3D应该Windows下最常用的播放视频的技术。实际上视频播放只是Direct3D的“副业”,它主要用于3D游戏制作。
2156 0
|
存储 缓存 API
最简单的视音频播放示例5:OpenGL播放RGB/YUV
本文记录OpenGL播放视频的技术。OpenGL是一个和Direct3D同一层面的技术。相比于Direct3D,OpenGL具有跨平台的优势。尽管在游戏领域,DirectX的影响力已渐渐超越OpenGL并被大多数PC游戏开发商所采用,但在专业高端绘图领域,OpenGL因为色彩准确,仍然是不能被取代的主角。
1526 0
directdraw显示yuv视频,出现屏保时,yuv显示不出来,表面丢失
原因是: DDrawSurface 丢失, DDraw表面在很多情况下都会丢失(如:启动其他全屏独占程序,屏保,或锁屏时), 表面丢失其实就是表面所使用的内存或显存被DirectDraw系统释放, 分配给其他程序. 如果表面丢失, 对此表面的操作都会返回 DDERR_SURFACELOST , 此时应该调用 IDirectDrawSurface 接口方法 Restore 来恢复表面(重新申请内存或显存)。
1182 0
directdraw的多画面显示rgb
// showpicDlg.cpp : 实现文件 // #include "stdafx.h" #include "showpic.h" #include "showpicDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif   // ...
970 0