VS2010基于DirectShows实现视频预览控件

     之前用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
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
//指定视频采集设备的友好名字,为它创建一个Filter IBaseFilter * CTestPreviewDlg::CreateVideoDevice(const char * inFriendlyName) { return CreateHardwareFilter(CLSID_VideoInputDeviceCategory,inFriendlyName); } //根据设备的友好名字,创建一个代表该设备的Filter IBaseFilter * CTestPreviewDlg::CreateHardwareFilter(GUID inCategory,const char * inFriendlyName) { //创建一个系统枚举组件对象 ICreateDevEnum * enumHardware = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL, IID_ICreateDevEnum,(void**)&enumHardware); if(FAILED(hr)) { return NULL; } IBaseFilter * hardwareFilter = NULL; IEnumMoniker * enumMoniker = NULL; //为指定的目录创建枚举器 hr = enumHardware->CreateClassEnumerator(inCategory,&enumMoniker,0); if(enumMoniker) { enumMoniker->Reset(); ULONG fetched = 0; IMoniker * moniker = NULL; char friendlyName[256]; //枚举得到该目录下所有的设备,逐个进行名字匹配 while(!hardwareFilter && SUCCEEDED(enumMoniker->Next(1,&moniker, &fetched)) && fetched) { if(moniker) { IPropertyBag * propertyBag = NULL; VARIANT name; friendlyName[0] = 0; hr = moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&propertyBag); //读取设备的友好名字 if(SUCCEEDED(hr)) { name.vt = VT_BSTR; hr = propertyBag->Read(L"Friendlyname",&name,NULL); } if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP,0,name.bstrVal,-1, friendlyName,256,NULL,NULL); //如果当前设备的友好名字与用户指定的设备名字相同, //则将当前设备标识绑定为Filter形式 if(strcmp(friendlyName,inFriendlyName) == 0) { moniker->BindToObject(0,0,IID_IBaseFilter, (void**)&hardwareFilter); } } //释放使用过的接口 if(propertyBag) { propertyBag->Release(); propertyBag = NULL; } moniker->Release(); } } enumMoniker->Release(); } enumHardware->Release(); return hardwareFilter; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值