vs2010MFC D3D播放YUV格式视频详细制作全过程

本文详细介绍了如何使用Visual Studio 2010和DirectX SDK开发一个用于播放YUV格式视频的播放器,包括环境配置、代码实现以及运行过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


目录(?)[+]

1.环境配置

1.1 Microsoft Visual Studio 2010安装

先下载Visual Studio 2010,然后双击setup.exe安装,安装时有一步选择vc++安装就可以了,其他步骤直接点击下一步。

1.2DirectX  SDK安装

  先下载DXSDK_Feb10,然后解压,解压完双击DXSDK_Feb10.exe进行安装,安装时请记住自己的安装路径以便后续操作,一直点下一步直到完成安装即可。

2.YUV视频播放器编写

2.1创建项

先运行vs2010,新建项目,模板选择Visual C++ 中MFC中的MFC应用程序,然后输入项目名称“myplayer”,点击确定,弹出一个MFC应用程序向导对话框,点击下一步,应用程序类型选择基于对话框(D),然后点击完成。

2.2设置DirectX  SDK环境

2.2.1右击刚才创建的项目,选择属性,弹出一个项目属性页。

2.2.2点击配置属性里的VC++目录,然后选择包含目录那一行,在那行后边会出现一个倒立黑色小三角形。如下图:


左击倒立三角,弹出一个单行的框,里边写着编辑,左击编辑两个字,弹出包含目录对话框,如下图,左击下图红色正方形标示的图标,在红色长方形处会弹出一行空白框,空白框后边有个按钮,左击那个按钮。


左击按钮后出现一个选择目录对话框,根据自己安装DirectX  SDK时的路径找到如下图红色标示区的文件夹,双击这个文件夹进入里边,找到Include文件夹,双击Include文件夹,然后点击“选择文件夹”按钮,接下来一直点击确定即可。

 

2.2.3包含d3d9.lib文件

  先执行上边的2.2.1操作,如下图找到配置属性下的链接器双击,再双击输入,单击附加依赖项这一行,出现黑色倒立小三角形,单击三角形出现编辑两个字。


单击编辑这两个字,出现如下图的附加依赖项对话框,如下图红色标示处自己写上d3d9.lib,点击确定按钮。至此DirectX  SDK环境设置完成。

 

2.3创建一个用于显示YUV视频的窗口。

2.3.1下图使我们创建项目时自动生成的MFC窗口,把下图中红色标示的控件删除。

2.3.2如下图把vs2010窗口右边的红色标示的工具箱打开。

 

2.3.3展开工具箱后用如下红色标示的两个控件创建窗口。

2.3.4播放窗口如下图:

 

 

上图中间是Picture Control控件,用来显示视频,选中这个控件,在vs2010窗口右侧属性那如下图把ID属性改为“IDC_VIDEO”。

 

 

2.3.5在自己创建的项目的头文件右击选择“添加”—>“新建项”,弹出添加新项窗口。


在添加新项窗口中选择如下图红色标示的项,然后输入名称,点击“添加”按钮。一共要添加四个*.h的文件,名称分别输入为PlayControl、DEFINE、ColourSpaceConvert 和D3DDisplay。


添加完四个*.h的文件,再按这种方法添加三个*.cpp的文件,如下图单击选择红色区域,然后输入名称,点击“添加”按钮。名称分别为PlayControl、ColourSpaceConvert 和D3DDisplay。


2.3.6代码

2.3.6.1  DEFINE.h
[cpp]  view plain copy
  1. #ifndef MESSAGE_H_  
  2. #define MESSAGE_H_  
  3. #define D3D_ARGB32              1  
  4. #define D3D_YUV422              2  
  5. #define IMAGE_WIDTH            352 //分辨率  
  6. #define IMAGE_HEIGHT            288//分辨率  
  7. #define YUVPLANE IMAGE_WIDTH*IMAGE_HEIGHT*3/2  
  8. #define RGBPLANE IMAGE_WIDTH*IMAGE_HEIGHT*4  
  9. #endif//MESSAGE_H_  

2.3.6.2  ColourSpaceConvert.h
[cpp]  view plain copy
  1. //经典的YUV转换到RGB的函数的头文件  
  2. #if !defined(AFX_COLOURSPACECONVERT_H__92911B35_FC87_4C19_9007_1D735942D76E__INCLUDED_)  
  3. #define AFX_COLOURSPACECONVERT_H__92911B35_FC87_4C19_9007_1D735942D76E__INCLUDED_  
  4. #if _MSC_VER > 1000  
  5. #pragma once  
  6. #endif // _MSC_VER > 1000  
  7. class CColourSpaceConvert    
  8. {  
  9. public:  
  10.     CColourSpaceConvert();  
  11.     virtual ~CColourSpaceConvert();  
  12. void YUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori, int width,int height);  
  13.       
  14. private:  
  15. //YUV===>RGB  
  16.      long int crv_tab[256];  
  17.      long int cbu_tab[256];  
  18.      long int cgu_tab[256];  
  19.      long int cgv_tab[256];  
  20.      long int tab_76309[256];  
  21.      unsigned char clp[1024];  
  22.      void InitConvertTable();  
  23. };  
  24. #endif  

2.3.6.3  PlayControl.h
[cpp]  view plain copy
  1. #if !defined(AFX_PLAYCONTROL_H__C3D14174_0157_4809_B573_DEA1F90DADB6__INCLUDED_)  
  2. #define AFX_PLAYCONTROL_H__C3D14174_0157_4809_B573_DEA1F90DADB6__INCLUDED_  
  3.   
  4. #if _MSC_VER > 1000  
  5. #pragma once  
  6. #endif // _MSC_VER > 1000  
  7. #include "D3DDisplay.h"  
  8. #include "DEFINE.h"  
  9. #include <stdio.h>  
  10. #define WM_MANAGE WM_USER + 1001  
  11.  class CPlayControl :public CWinThread  
  12. {  
  13.     DECLARE_DYNCREATE(CPlayControl)  
  14. public:  
  15.     CPlayControl();  
  16.     virtual ~CPlayControl();  
  17. virtual BOOL InitInstance();  
  18.     virtual int ExitInstance();  
  19.     int Init(HWND hwnd, char *filename);  
  20.     void Play();  
  21.     void Stop();  
  22.     void Pause();  
  23. private:  
  24.     CD3DDisplay m_D3D;  
  25.     BYTE *yuvbuf;  
  26.     BYTE *rgbbuf;  
  27.     FILE *f_in;//输入的文件句柄  
  28.     int m_State;  
  29. protected:  
  30.       
  31.   
  32.     void OnManage(WPARAM wParam, LPARAM lParam);  
  33.     DECLARE_MESSAGE_MAP()  
  34.           
  35. };  
  36. #endif   

2.3.6.4  D3DDisplay.h
[cpp]  view plain copy
  1. #if !defined(AFX_D3DDISPLAY_H__D2B5461A_AF44_411A_8FEA_8439E0FB5628__INCLUDED_)  
  2. #define AFX_D3DDISPLAY_H__D2B5461A_AF44_411A_8FEA_8439E0FB5628__INCLUDED_  
  3. #if _MSC_VER > 1000  
  4. #pragma once  
  5. #endif // _MSC_VER > 1000  
  6. #include <d3dx9.h>  
  7. class CD3DDisplay    
  8. {  
  9. public:  
  10.     int GetFormt();  
  11.     HRESULT RenderSample(BYTE* pSampleBuffer);  
  12.     HRESULT RenderTOSrceen();  
  13.     HRESULT InitGeometry();  
  14.     HRESULT CreateTexture();  
  15.     HRESULT InitD3D(HWND hWnd);  
  16.     void ClearD3D();  
  17.     CD3DDisplay();  
  18.     virtual ~CD3DDisplay();  
  19. private:  
  20.     LPDIRECT3D9             m_pD3D;   
  21.     LPDIRECT3DDEVICE9       m_pd3dDevice;   
  22.     LPDIRECT3DTEXTURE9      m_pTexturesvideo;   
  23.     LPDIRECT3DVERTEXBUFFER9 m_pVBvideo;     //视频矩形的顶点缓存区接口指针  
  24.     LPDIRECT3DTEXTURE9      m_pTexturesbmp;  
  25.     LPDIRECT3DVERTEXBUFFER9 m_pVBbmp;       //位图矩形的顶点缓存区接口指针  
  26.   
  27.     HWND m_hWnd;  
  28.     D3DFORMAT m_Format;  
  29.     LPD3DXFONT m_p2Dfont;  
  30. };  
  31. #endif  


2.3.6.5  ColourSpaceConvert.cpp
[cpp]  view plain copy
  1. //经典的YUV转换到RGB的函数的实现  
  2. #include "stdafx.h"  
  3. #include "ColourSpaceConvert.h"  
  4. CColourSpaceConvert::CColourSpaceConvert()  
  5. {  
  6.     //InitLookupTable();  
  7.     InitConvertTable();  
  8. }  
  9.   
  10. CColourSpaceConvert::~CColourSpaceConvert()  
  11. {  
  12.   
  13. }  
  14. //YUV===>RGB  
  15. void CColourSpaceConvert::InitConvertTable()  
  16. {  
  17.    long int crv,cbu,cgu,cgv;  
  18.    int i,ind;     
  19.        
  20.    crv = 104597;   
  21. cbu = 132201;   
  22.    cgu = 25675;   
  23.  cgv = 53279;  
  24.     
  25.    for (i = 0; i < 256; i++) {  
  26.       crv_tab[i] = (i-128) * crv;  
  27.       cbu_tab[i] = (i-128) * cbu;  
  28.       cgu_tab[i] = (i-128) * cgu;  
  29.       cgv_tab[i] = (i-128) * cgv;  
  30.       tab_76309[i] = 76309*(i-16);  
  31.    }  
  32.        
  33.    for (i=0; i<384; i++)  
  34.       clp[i] =0;  
  35.    ind=384;  
  36.    for (i=0;i<256; i++)  
  37.        clp[ind++]=i;  
  38.    ind=640;  
  39.    for (i=0;i<384;i++)  
  40.        clp[ind++]=255;  
  41. }  
  42.   
  43. void CColourSpaceConvert::YUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,  
  44.                                  int width,int height)  
  45. {  
  46.     int y1,y2,u,v;   
  47.     unsigned char *py1,*py2;  
  48.     int i,j, c1, c2, c3, c4;  
  49.     unsigned char *d1, *d2;  
  50.   
  51.     py1=src0;  
  52.     py2=py1+width;  
  53.     d1=dst_ori;  
  54.     d2=d1+3*width;  
  55.     for (j = 0; j < height; j += 2) {   
  56.         for (i = 0; i < width; i += 2) {  
  57.   
  58.             u = *src1++;  
  59.             v = *src2++;  
  60.   
  61.             c1 = crv_tab[v];  
  62.             c2 = cgu_tab[u];  
  63.             c3 = cgv_tab[v];  
  64.             c4 = cbu_tab[u];  
  65.   
  66.             //up-left  
  67.             y1 = tab_76309[*py1++];   
  68.             *d1++ = clp[384+((y1 + c1)>>16)];    
  69.             *d1++ = clp[384+((y1 - c2 - c3)>>16)];  
  70.             *d1++ = clp[384+((y1 + c4)>>16)];  
  71.   
  72.             //down-left  
  73.             y2 = tab_76309[*py2++];  
  74.             *d2++ = clp[384+((y2 + c1)>>16)];    
  75.             *d2++ = clp[384+((y2 - c2 - c3)>>16)];  
  76.             *d2++ = clp[384+((y2 + c4)>>16)];  
  77.   
  78.             //up-right  
  79.             y1 = tab_76309[*py1++];  
  80.             *d1++ = clp[384+((y1 + c1)>>16)];    
  81.             *d1++ = clp[384+((y1 - c2 - c3)>>16)];  
  82.             *d1++ = clp[384+((y1 + c4)>>16)];  
  83.   
  84.             //down-right  
  85.             y2 = tab_76309[*py2++];  
  86.             *d2++ = clp[384+((y2 + c1)>>16)];    
  87.             *d2++ = clp[384+((y2 - c2 - c3)>>16)];  
  88.             *d2++ = clp[384+((y2 + c4)>>16)];  
  89.         }  
  90.         d1 += 3*width;  
  91.         d2 += 3*width;  
  92.         py1+=   width;  
  93.         py2+=   width;  
  94.     }         
  95. }  

2.3.6.6  PlayControl.cpp
[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include "PlayControl.h"  
  3. #include "ColourSpaceConvert.h"  
  4. #include  <afx.h>  
  5. /////////////////////////////////////////////////////////////////////////////  
  6. // CPlayControl  
  7. IMPLEMENT_DYNCREATE(CPlayControl, CWinThread)  
  8. CPlayControl::CPlayControl()  
  9. {  
  10.     m_State = 0;  
  11.     f_in = NULL;  
  12.     rgbbuf = NULL;   
  13.     yuvbuf = NULL;  
  14.     CreateThread();  
  15. }  
  16. CPlayControl::~CPlayControl()  
  17. {  
  18.     f_in = NULL;  
  19.     rgbbuf = NULL;   
  20.     yuvbuf = NULL;  
  21. }  
  22. BOOL CPlayControl::InitInstance()  
  23. {  
  24.     // TODO:  perform and per-thread initialization here  
  25.     return TRUE;  
  26. }  
  27. int CPlayControl::ExitInstance()  
  28. {  
  29.     // TODO:  perform any per-thread cleanup here  
  30.     return CWinThread::ExitInstance();  
  31. }  
  32. BEGIN_MESSAGE_MAP(CPlayControl, CWinThread)  
  33.     //{{AFX_MSG_MAP(CPlayControl)  
  34.         // NOTE - the ClassWizard will add and remove mapping macros here.  
  35.         ON_THREAD_MESSAGE(WM_MANAGE,OnManage)  
  36.     //}}AFX_MSG_MAP  
  37. END_MESSAGE_MAP()  
  38. /////////////////////////////////////////////////////////////////////////////  
  39. // CPlayControl message handlers  
  40. int CPlayControl::Init(HWND hwnd, char *filename)  
  41. {  
  42.     m_D3D.InitD3D(hwnd);  
  43.     m_D3D.CreateTexture();  
  44.     m_D3D.InitGeometry();  
  45.     if(m_D3D.GetFormt() == D3D_ARGB32)  
  46.     {  
  47.         rgbbuf = new BYTE[RGBPLANE];   
  48.         yuvbuf = new BYTE[YUVPLANE];  
  49.     }  
  50.     else  
  51.     {  
  52.         return -1;  
  53.     }     
  54.     if(!rgbbuf || !yuvbuf)  
  55.     {  
  56.         delete [] rgbbuf;  
  57.         delete [] yuvbuf;  
  58.         rgbbuf = NULL;   
  59.         yuvbuf = NULL;  
  60.         return -1;  
  61.     }  
  62.     f_in=fopen(filename,"rb");  
  63.     if (f_in == NULL)  
  64.     {  
  65.         return -1;  
  66.     }  
  67.     m_State = 1;  
  68.     return 0;  
  69. }  
  70. void CPlayControl::Play()  
  71. {  
  72.     m_State = 1;  
  73. }  
  74. void CPlayControl::Stop()  
  75. {  
  76.     m_State = 0;          
  77. }  
  78. void CPlayControl::Pause()  
  79. {  
  80.     m_State = 2;  
  81. }  
  82. void CPlayControl::OnManage(WPARAM wParam, LPARAM lParam)  
  83. {  
  84.     CColourSpaceConvert m_csc;  
  85.     if(f_in == NULL)  
  86.         return;  
  87.     while(1)  
  88.     {  
  89.         if(m_State == 1)  
  90.         {  
  91.             if(fread(yuvbuf, YUVPLANE, 1, f_in))  
  92.             {  
  93.                 m_csc.YUV2RGB(yuvbuf,   
  94.                     yuvbuf + IMAGE_HEIGHT*IMAGE_WIDTH*5/4,   
  95.                     yuvbuf + IMAGE_HEIGHT*IMAGE_WIDTH,  
  96.                     rgbbuf, IMAGE_WIDTH, IMAGE_HEIGHT);  
  97.                 m_D3D.RenderSample(rgbbuf);  
  98.                 m_D3D.RenderTOSrceen();   
  99.                 Sleep(33);  
  100.             }  
  101.             else  
  102.                 break;  
  103.         }  
  104.         else if(m_State == 2)  
  105.             continue;  
  106.         else  
  107.             break;  
  108.     }  
  109.     fclose(f_in);  
  110. }  

 
2.3.6.7  D3DDisplay.cpp
[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include "D3DDisplay.h"  
  3. #include "DEFINE.h"  
  4. #ifdef _DEBUG  
  5. #undef THIS_FILE  
  6. static char THIS_FILE[]=__FILE__;  
  7. #define new DEBUG_NEW  
  8. #endif  
  9. struct CUSTOMVERTEX//顶点缓存  
  10. {       
  11.     float x,y,z,rhw;    //顶点坐标   
  12.     DWORD color;        //顶点颜色  
  13.     float tu,tv;        //纹理坐标  
  14. };   
  15. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)  
  16. //////////////////////////////////////////////////////////////////////  
  17. // Construction/Destruction  
  18. //////////////////////////////////////////////////////////////////////  
  19. CD3DDisplay::CD3DDisplay()  
  20. {  
  21.     m_pd3dDevice = NULL;  
  22.     m_pD3D = NULL;  
  23.     m_p2Dfont = NULL;  
  24.     m_pTexturesvideo = NULL;  
  25.     m_pVBvideo = NULL;  
  26.     m_pTexturesbmp = NULL;  
  27.     m_pVBbmp = NULL;  
  28.     m_hWnd = NULL;  
  29.     m_Format = (D3DFORMAT)0;  
  30. }  
  31. CD3DDisplay::~CD3DDisplay()  
  32. {  
  33.     ClearD3D();   
  34. }  
  35. HRESULT CD3DDisplay::InitD3D(HWND hWnd)//初始化d3d  
  36. {  
  37.     D3DPRESENT_PARAMETERS d3dpp;//显示参数设置  
  38.     if(hWnd == NULL)  
  39.         return -1;  
  40.     m_hWnd = hWnd;  
  41.     //D3DFMT_A8R8G8B8表示一个32位像素,从左开始,8位为ALPHA通道,8位分配给红色,8位分配给绿色,8位分配给蓝色  
  42.     m_Format = D3DFMT_A8R8G8B8;  
  43.     if(NULL == (m_pD3D = Direct3DCreate9( D3D_SDK_VERSION )))//创建d3d对象  
  44.         return -1;  
  45.     ZeroMemory( &d3dpp, sizeof(d3dpp) );//清空显示参数,重新设置参数  
  46.     d3dpp.Windowed = TRUE;//FALSE,表示要渲染全屏,如果为TRUE,表示要渲染窗口  
  47.     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//交换缓冲支持的效果类型,指定表面在交换链中D是如何被交换的  
  48.     //D3DSWAPEFFECT_DISCARD,则后备缓冲区的东西被复制到屏幕上后,后备缓冲区的东西就没有什么用可以丢弃  
  49.     d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;//后备缓冲的格式D3DFMT_UNKNOWN,这时候它将使用桌面的格式  
  50.     d3dpp.EnableAutoDepthStencil = TRUE;//如果要使用缓冲或模板缓冲则把它设为TRUE  
  51.     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;//如果启动了深度缓冲那么这个参数将为深度设定缓冲格式  
  52.     //D3DFMT_16深度缓冲  
  53.     d3dpp.BackBufferWidth = IMAGE_WIDTH;//后备缓冲的宽度和高度  
  54.     d3dpp.BackBufferHeight = IMAGE_HEIGHT;//在全屏模式下这两者的值必需符合显卡所支持的分辨率  
  55.       
  56.     if( FAILED( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT,  
  57.         D3DDEVTYPE_HAL,   
  58.         m_hWnd,  
  59.         D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,  
  60.         &d3dpp,   
  61.         &m_pd3dDevice ) ) )//创建d3d设备  
  62.         return -1;  
  63.     return 0;  
  64. }  
  65. void CD3DDisplay::ClearD3D()//释放d3d  
  66. {  
  67.     if(m_pd3dDevice != NULL)  
  68.         m_pd3dDevice->Release();  
  69.     if(m_pD3D != NULL)  
  70.         m_pD3D->Release();   
  71.     if(m_p2Dfont != NULL)  
  72.         m_p2Dfont->Release();   
  73.     if(m_pVBvideo != NULL)  
  74.         m_pVBvideo->Release();  
  75.     if(m_pTexturesvideo != NULL)  
  76.         m_pTexturesvideo->Release();  
  77.     if(m_pVBbmp != NULL)  
  78.         m_pVBbmp->Release();   
  79.     if(m_pTexturesbmp != NULL)  
  80.         m_pTexturesbmp->Release();   
  81.     m_hWnd = NULL;  
  82.     m_Format = (D3DFORMAT)0;  
  83. }  
  84. HRESULT CD3DDisplay::CreateTexture()//创建纹理  
  85. {  
  86.     HRESULT hr = 0;  
  87.     D3DSURFACE_DESC ddsd;  
  88.     hr = m_pd3dDevice->CreateTexture( IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, m_Format,   
  89.         D3DPOOL_MANAGED, &m_pTexturesvideo, NULL);  
  90.     if( FAILED(hr))  
  91.     {  
  92.         return -1;  
  93.     }  
  94. hr = m_pTexturesvideo->GetLevelDesc( 0, &ddsd );//获得加载图片的宽和高及些信息  
  95.     if(FAILED(hr))  
  96.         return -1;  
  97.     if ((ddsd.Format != D3DFMT_A8R8G8B8) && (ddsd.Format != D3DFMT_YUY2))   
  98.         return -1;  
  99.   
  100.     return 0;  
  101. }  
  102. HRESULT CD3DDisplay::InitGeometry()//创建视频几何建立顶点缓存并初始化纹坐标  
  103. {  
  104.     HRESULT hr = 0;  
  105.     CUSTOMVERTEX* pVertices = NULL;  
  106.     RECT rect;  
  107.     //创建视频矩形  
  108.     rect.top = 0;             
  109.     rect.left = 0;  
  110.     rect.right = IMAGE_WIDTH;  
  111.     rect.bottom = IMAGE_HEIGHT;  
  112.     CUSTOMVERTEX vertices[4] =  //顶点缓存  
  113.     {     // x, y, z, rhw, color  
  114.         { (float)rect.left, (float)rect.top,   
  115.             0.0f, 1.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 0.0f },   
  116.         { (float)rect.right, (float)rect.top,   
  117.         0.0f, 1.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f },   
  118.         { (float)rect.left, (float)rect.bottom,   
  119.         0.0f, 1.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f },   
  120.         { (float)rect.right, (float)rect.bottom,   
  121.         0.0f, 1.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 1.0f }  
  122.     };  
  123.     m_pd3dDevice->CreateVertexBuffer(sizeof(vertices), //指定缓冲区的大小  
  124.         0, //指定顶点缓冲区的属性  
  125.         D3DFVF_CUSTOMVERTEX, //开始创建的定点格式  
  126.         D3DPOOL_DEFAULT, //指定顶点缓冲区的内存类型  
  127.         &m_pVBvideo, //视频矩形的顶点缓存区接口指针  
  128.         NULL ); //保留参数  
  129. m_pVBvideo->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ); //填充顶点缓冲区  
  130.     memcpy( pVertices, vertices, sizeof(vertices));   
  131.     m_pVBvideo->Unlock();      
  132.     return hr;  
  133. }  
  134. HRESULT CD3DDisplay::RenderSample(BYTE *pSampleBuffer)  
  135. {  
  136.     HRESULT hr = 0;  
  137.     BYTE * pTextureBuffer = NULL;  
  138.     D3DLOCKED_RECT d3dlr;  
  139.     LONG  lTexturePitch;       
  140.         hr = m_pTexturesvideo->LockRect( 0, &d3dlr, 0, 0 );  
  141.     if( FAILED(hr))  
  142.     {  
  143.         return -1;  
  144.     }  
  145.     lTexturePitch = d3dlr.Pitch;  
  146.     pTextureBuffer = static_cast<byte *>(d3dlr.pBits);  
  147.     for(int i = 0; i < IMAGE_HEIGHT; i++ )   
  148.     {  
  149.         BYTE *pBmpBufferOld = pSampleBuffer;  
  150.         BYTE *pTxtBufferOld = pTextureBuffer;     
  151.         for (int j = 0; j < IMAGE_WIDTH; j++)   
  152.         {  
  153.             pTextureBuffer[0] = pSampleBuffer[0];  
  154.             pTextureBuffer[1] = pSampleBuffer[1];  
  155.             pTextureBuffer[2] = pSampleBuffer[2];  
  156.             pTextureBuffer[3] = 0xFF;  
  157.             pTextureBuffer += 4;  
  158.             pSampleBuffer  += 3;  
  159.         }  
  160.         pSampleBuffer  = pBmpBufferOld + IMAGE_WIDTH *3;  
  161.         pTextureBuffer = pTxtBufferOld + lTexturePitch;  
  162.     }  
  163.     hr = m_pTexturesvideo->UnlockRect(0);  
  164.     if( FAILED(hr))  
  165.     {  
  166.         return -1;  
  167.     }  
  168.     return 0;  
  169. }  
  170. HRESULT CD3DDisplay::RenderTOSrceen()//传递到屏幕  
  171. {  
  172.     HRESULT hr = 0;  
  173.     hr = m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0 );  
  174.     if( FAILED(hr))  
  175.     {  
  176.         return -1;  
  177.     }  
  178.     hr = m_pd3dDevice->BeginScene();  
  179.     if( FAILED(hr))  
  180.     {  
  181.         return -1;  
  182.     }  
  183.     //显示视频  
  184.     hr = m_pd3dDevice->SetTexture( 0, m_pTexturesvideo );  
  185.     m_pd3dDevice->SetStreamSource( 0, m_pVBvideo, 0, sizeof(CUSTOMVERTEX));   
  186.     hr = m_pd3dDevice->SetVertexShader( NULL );//设置可编程渲染管道的Shader程序  
  187.     m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); //设置固定渲染管道Ì的顶点格式  
  188.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );//渲染一组非索引  
  189.     m_pd3dDevice->SetTexture( 0, NULL );   
  190.     m_pd3dDevice->EndScene();  
  191.     m_pd3dDevice->Present( NULL, NULL, NULL, NULL );  
  192.     return hr;  
  193. }  
  194. int CD3DDisplay::GetFormt()  
  195. {  
  196.     return D3D_ARGB32;    
  197. }  

2.3.6.8  按钮点击事件函数

双击你自己创建的用于播放YUV视频的窗体上的那四个按钮,进入单击事件代码区,然后分别写入相应代码。

首先在myplayerDlg.h中加入头文件声明#include "PlayControl.h",在类中加上

[cpp]  view plain copy
  1. private:  
  2.     CPlayControl m_PlayControl;  

双击“打开文件”按钮后写入代码:

[cpp]  view plain copy
  1. void CmyplayerDlg::OnBnClickedButton1()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CString file_name = "";  
  5.     CFileDialog fd(TRUE,  NULL,   
  6.                    file_name,   
  7.                    OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,   
  8.                    NULL, NULL);  
  9.       
  10.     if (fd.DoModal() == IDOK)   
  11.     {  
  12.         m_PlayControl.Init(::GetDlgItem(GetSafeHwnd(),IDC_VIDEO),   
  13.             fd.GetPathName().GetBuffer(fd.GetPathName().GetLength()));  
  14.           
  15.         m_PlayControl.PostThreadMessage(WM_MANAGE, 0, 0);  
  16.     }  
  17. }  

双击“播放”按钮后写入代码:

[cpp]  view plain copy
  1. void CmyplayerDlg::OnBnClickedButton2()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     m_PlayControl.Play();  
  5. }  

双击“暂停”按钮后写入代码:

[cpp]  view plain copy
  1. void CmyplayerDlg::OnBnClickedButton3()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     m_PlayControl.Pause();  
  5. }  
  6. 双击“停止”按钮后写入代码:  
  7. void CmyplayerDlg::OnBnClickedButton4()  
  8. {  
  9.     // TODO: 在此添加控件通知处理程序代码  
  10.     m_PlayControl.Stop();  
  11. }  

3.程序内部运行过程

  运行时,初始化播放界面,操作人员点击“打开文件”按钮,选择自己要播放的YUV格式视频文件,点击一下这个视频文件,程序会先用PlayControl类的对象调用PlayControl.cpp中Init()函数来创建D3D设备(创建D3D设备调用D3DDisplay类),然后PlayControl类的对象传递消息触发消息响应函数PlayControl.cpp中的OnManage()函数,OnManage()函数中使用ColourSpaceConvert类的对象调用ColourSpaceConvert.cpp中的YUV2RGB()函数将YUV视频转换为RGB格式,然后D3D设备调用D3DDisplay.cpp中的RenderSample()函数和RenderToScreen()函数对视频渲染并在屏幕上显示。

4.注意事项

4.1在DEFINE.h文件中

#define IMAGE_WIDTH            352 //分辨率

#define IMAGE_HEIGHT            288//分辨率

这两句是设置分辨率的,可以更改为自己YUV视频的分辨率来正确播放视频。

4.2字符集错误

若出现不能将参数2 从“wchar_t *”转换为“char *”的错误,右击项目名选择“属性”,按下图红色区域把字符集改为“使用多字节字符集”。



5.其他:

本文附带的项目文件“myplayer”需要在安装了DirectX SDK的电脑上运行,请按上文中1.2所述进行安装。

若安装完运行出错,请按2.2所述配置SDK环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值