directshow 采集摄像头数据并录制视频(含压缩)

最近使用directshow 做了一个摄像头视频的采集模块,录制视频后同步进行压缩,主要有两种压缩方法,一种是调用x264进行每一帧数据的压缩,一种是创建一个Filter进行压缩。记录下主要的实现过程。首先,枚举当前支持的摄像头详细信息,主要是通过枚举设备信息,然后返回每个设备的描述信息给用户界面: static TCHAR ** EnumAllDevices(int *num) { CoInitialize(NULL); int nCaptureDeviceNumber = 0; //
摘要由CSDN通过智能技术生成

最近使用directshow 做了一个摄像头视频的采集模块,录制视频后同步进行压缩,主要有两种压缩方法,一种是调用x264进行每一帧数据的压缩,一种是创建一个Filter进行压缩。记录下主要的实现过程。

首先,枚举当前支持的摄像头详细信息,主要是通过枚举设备信息,然后返回每个设备的描述信息给用户界面:

	static TCHAR ** EnumAllDevices(int *num)
	{
		CoInitialize(NULL);
		int nCaptureDeviceNumber = 0; //Device Count
		TCHAR **pCapDeviceName = (TCHAR **)malloc(10 * sizeof(TCHAR *));//先初始化二维数组的行
		for (int i = 0; i<10; i++)//再初始化二维数组的列
			pCapDeviceName[i] = (TCHAR *)malloc(MAX_PATH * sizeof(TCHAR));


		ICreateDevEnum *pDevEnum;
		IEnumMoniker   *pEnumMon;
		IMoniker	   *pMoniker;
		HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
										IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
		if (SUCCEEDED(hr))
		{
			hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0);
			if (hr == S_FALSE)
			{
				hr = VFW_E_NOT_FOUND;
				return 0;
			}
			pEnumMon->Reset();
			ULONG cFetched;
			while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
			{
				IPropertyBag *pProBag;
				hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
				if (SUCCEEDED(hr))
				{
					VARIANT varTemp;
					varTemp.vt = VT_BSTR;
					hr = pProBag->Read(L"FriendlyName",&varTemp,NULL);
					if (SUCCEEDED(hr))
					{
						StringCchCopy(pCapDeviceName[nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal);
						wprintf(L"[%d] %s\n", nCaptureDeviceNumber, pCapDeviceName[nCaptureDev
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DirectShow是Windows平台上的一个多媒体框架,用于处理音频和视频流。使用DirectShow捕捉摄像头视频数据需要以下步骤: 1. 枚举可用的视频捕捉设备并选择需要使用的设备。 2. 创建一个Filter Graph Manager对象,用于管理DirectShow图形。 3. 创建一个视频捕捉设备的Filter对象,并添加到Filter Graph Manager中。 4. 创建一个Sample Grabber Filter对象,用于获取视频数据。 5. 创建一个Null Renderer对象,用于显示视频数据。 6. 将Sample Grabber Filter对象和Null Renderer对象添加到Filter Graph Manager中,并建立连接。 7. 设置Sample Grabber Filter对象的回调函数,用于处理视频数据。 8. 开始视频捕捉。 以下是C++代码示例: ```cpp #include <dshow.h> // 枚举可用的视频捕捉设备 HRESULT EnumerateDevices(REFGUID category, IEnumMoniker** ppEnum) { // 创建系统设备枚举器 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum); if (FAILED(hr)) { return hr; } // 枚举视频捕捉设备 hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; } pDevEnum->Release(); return hr; } // 创建Filter Graph Manager对象 IGraphBuilder* pGraphBuilder = NULL; IMediaControl* pMediaControl = NULL; IMediaEventEx* pMediaEvent = NULL; HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraphBuilder); if (FAILED(hr)) { return hr; } // 创建视频捕捉设备的Filter对象 IEnumMoniker* pEnumMoniker = NULL; hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnumMoniker); if (FAILED(hr)) { return hr; } IMoniker* pMoniker = NULL; ULONG cFetched; while (pEnumMoniker->Next(1, &pMoniker, &cFetched) == S_OK) { IBaseFilter* pFilter = NULL; hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter); if (SUCCEEDED(hr)) { // 添加到Filter Graph Manager中 pGraphBuilder->AddFilter(pFilter, L"Video Capture"); pFilter->Release(); } pMoniker->Release(); } pEnumMoniker->Release(); // 创建Sample Grabber Filter对象 ISampleGrabber* pSampleGrabber = NULL; hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSampleGrabber); if (FAILED(hr)) { return hr; } // 设置Sample Grabber Filter对象的回调函数 hr = pSampleGrabber->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber); if (FAILED(hr)) { return hr; } AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; mt.formattype = FORMAT_VideoInfo; hr = pGrabber->SetMediaType(&mt); if (FAILED(hr)) { return hr; } hr = pGrabber->SetCallback(&SampleGrabberCallback, 0); if (FAILED(hr)) { return hr; } // 创建Null Renderer对象 IBaseFilter* pNullRenderer = NULL; hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNullRenderer); if (FAILED(hr)) { return hr; } // 将Sample Grabber Filter对象和Null Renderer对象添加到Filter Graph Manager中,并建立连接 hr = pGraphBuilder->AddFilter(pSampleGrabber, L"Sample Grabber"); if (FAILED(hr)) { return hr; } hr = pGraphBuilder->AddFilter(pNullRenderer, L"Null Renderer"); if (FAILED(hr)) { return hr; } IPin* pGrabberOut = GetPin(pSampleGrabber, PINDIR_OUTPUT); IPin* pRendererIn = GetPin(pNullRenderer, PINDIR_INPUT); hr = pGraphBuilder->Connect(pGrabberOut, pRendererIn); if (FAILED(hr)) { return hr; } // 开始视频捕捉 hr = pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&pMediaControl); if (FAILED(hr)) { return hr; } hr = pMediaControl->Run(); if (FAILED(hr)) { return hr; } // 处理视频数据的回调函数 HRESULT SampleGrabberCallback::SampleCB(double Time, IMediaSample *pSample) { BYTE* pData = NULL; pSample->GetPointer(&pData); long lDataLen = pSample->GetActualDataLength(); // 处理视频数据 return S_OK; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值