directshow 视频显示,USB接口按钮触发事件捕获

本文介绍了如何使用DirectShow库在Windows环境下实现视频显示,并通过USB接口按钮触发事件来捕获视频帧。示例代码展示了创建图形过滤器,设置视频窗口,捕获和保存视频帧到BMP文件的过程。同时,代码中包含错误处理和事件监听,确保程序稳定运行。
摘要由CSDN通过智能技术生成
//窗口模式,课按钮触发截图
#include <Windows.h> 
#include <tchar.h> 
#include <DShow.h> 
#include <qedit.h> 
#include <atlbase.h> 
#include <streams.h> 
#include <assert.h> 

#define DEFAULT_VIDEO_WIDTH     640 
#define DEFAULT_VIDEO_HEIGHT    480 
#define WIN_STYLE (WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) 
#define EXT_STYLE (WS_EX_APPWINDOW | WS_EX_OVERLAPPEDWINDOW) 

enum PLAYSTATE {Stopped, Paused, Running, Init}; 

typedef HANDLE zbar_event_t; 
typedef struct zbar_mutex_s { 
	int count; 
	CRITICAL_SECTION mutex; 
} zbar_mutex_t; 

struct video_state_s { 
	HANDLE captured; 
	HWND hwnd;                  /* vfw interface */
	HANDLE notify;              /* capture thread status change */
	int bi_size;                /* size of bih */
	BITMAPINFOHEADER *bih;      /* video format details */


	//主要的用于摄像头预览
	IGraphBuilder* m_pGraph;
	ICaptureGraphBuilder2* m_pBuilder;
	IBaseFilter* pSrcFilter;
	IMediaControl* g_pMC;
	IVideoWindow* g_pVW;
	IMediaEventEx * g_pME; 
	CComPtr<ISampleGrabber> pGrabber; 
	HINSTANCE hInstance; 

	//静态拍照
	IAMVideoControl* m_pAMVideoControl;
	IBaseFilter* m_pTSG_Filter;
	ISampleGrabber* m_pTSG;
	IBaseFilter *m_pNull;

	AM_MEDIA_TYPE mt; 
	AM_MEDIA_TYPE g_StillMediaType; 
}; 


struct zbar_processor_s { 
	const void *userdata;               /* application data */
	unsigned req_width, req_height;     /* application requested video size */
	int req_intf, req_iomode;           /* application requested interface */
	int input;                          /* user input status */
	int threaded; 
	int visible;                        /* output window mapped to display */
	int streaming;                      /* video enabled */
	int dumping;                        /* debug image dump */
	void *display;                      /* X display connection */
	unsigned long xwin;                 /* toplevel window */
	zbar_mutex_t mutex;                 /* shared data mutex */
	int lock_level; 
	HINSTANCE hInstance; 
}; 


typedef struct video_state_s video_state_t; 


static inline int _zbar_mutex_init (zbar_mutex_t *lock) 
{ 
	lock->count = 1; 
	InitializeCriticalSection(&lock->mutex); //函数功能初始化一个临界资源对象 
	return(0); 
} 

static inline void _zbar_mutex_destroy (zbar_mutex_t *lock) 
{ 
	DeleteCriticalSection(&lock->mutex); 
} 

static inline int _zbar_mutex_lock (zbar_mutex_t *lock) 
{ 
	EnterCriticalSection(&lock->mutex); 
	if(lock->count++ < 1) 
		assert(0); 
	return(0); 
} 

static inline int _zbar_mutex_unlock (zbar_mutex_t *lock) 
{ 
	if(lock->count-- <= 1) 
		assert(0); 
	LeaveCriticalSection(&lock->mutex); 
	return(0); 
} 
class CSampleGrabberCB : public ISampleGrabberCB
{
public:
	long Width;
	long Height;
	HWND cb_hwnd;
	bool bFirst;

	CSampleGrabberCB( )
	{
		Width = 0;
		Height = 0;
		cb_hwnd = NULL;
		bFirst = false;
	} 


	STDMETHODIMP_(ULONG) AddRef() { return 1; }
	STDMETHODIMP_(ULONG) Release() { return 2; }
	STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
	{
		if (NULL == ppvObject) 
			return E_POINTER;
		if (riid == __uuidof(IUnknown))
		{
			*ppvObject = static_cast<IUnknown*>(this);
			return S_OK;
		}
		if (riid == __uuidof(ISampleGrabberCB))
		{
			*ppvObject = static_cast<ISampleGrabberCB*>(this);
			return S_OK;
		}
		return E_NOTIMPL;
	}

	STDMETHODIMP SampleCB(double SampleTime,IMediaSample* pSample)
	{
		return E_NOTIMPL;
	}
	STDMETHODIMP BufferCB(double Time,BYTE* pBuffer,long lBufferSize)
	{
		video_state_t *state = (video_state_t *)GetWindowLong(cb_hwnd,0);

		HWND cb_hwndTemp = (HWND)GetWindowLong(cb_hwnd,4);

		if (!bFirst)//初次启动会有消息过来
		{
			bFirst = true;
			return S_OK;
		}
		if (!pBuffer)
			return E_POINTER;

		if ((state->g_StillMediaType.majortype != MEDIATYPE_Video) 
//指定视频采集设备的友好名字,为它创建一个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、付费专栏及课程。

余额充值