之前用VFW实现视频预览控件,使用的时候经常会弹出视频源选择窗口,为了解决这个问题,采用最新的DirectShow来实现视频预览,而且VFW目前基本上已经不使用了,DirectX的功能比较强大。因需求比较单一,还是只实现简单的视频预览功能,并没有实时存储视频。实现过程完全参照MSDN实现。要使用DirectShow的功能首先需要包含头文件
#include<dshow.h>,并引入库 #pragma comment(lib,"strmiids.lib")
一、控件界面
界面还是和上篇VFW实现方法一样。
视频预览大致流程是“枚举视频设备 -> 初始化并绑定视频采集过滤器 -> 将视频导入特定的流中” ,具体实现方法参考MSDN上的DirectShow部分。
为显示界面添加CPreviewWindow类,下面是PreviewWindow.h的实现。
#pragma once
#include "afxwin.h"
#include <atlbase.h>
#include <windows.h>
#include <dshow.h>
#include <vector>
using namespace std;
#ifndef SAFE_RELEASE
#define SAFE_RELEASE( x ) if ( NULL != x ) { x->Release( ); x = NULL; }
#endif
#pragma comment(lib,"strmiids.lib")
typedef struct Device
{
CString Description;
CString FrindlyName;
int WaveInID;
CString DevicePath;
}Device,*PDevice;
// CPreviewWindow 对话框
class CPreviewWindow : public CDialogEx
{
DECLARE_DYNAMIC(CPreviewWindow)
public:
CPreviewWindow(CWnd* pParent = NULL); // 标准构造函数
virtual ~CPreviewWindow();
HWND GetHwnd();//返回对话框类句柄
// 对话框数据
enum { IDD = IDD_VIDEOVIEW };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CStatic m_video;
public:
//CVideoCapture(void);
//~CVideoCapture(void);
HRESULT EnumDevices(REFGUID category);//枚举设备
HRESULT InitCaptureGraphBuilder();<span style="white-space:pre"> </span>//初始化视频采集过滤器
BOOL InitPreview();
void StartPreview();
void StopPreview();
void CancelPreview();
void PausePreview();
public:
IEnumMoniker *pEnum;
IMoniker *pMoniker;
vec