MediaFoundation视频采集

原因:由于目前pc平台采集DirectShow老旧和复杂,故了解MediaFoundation简单调用。

概述:利用MediaFoundation实现视频采集,利用同步方式实现视频数据的读取。

MediaFoundation介绍:

MediaFoundation是DirectShow的替代,vist及以上才能支持,也就是说xp不支持,且不同的系统某些功能支持情况也不同,提供了两种编码模型,第一种是Media Session为主的Media pipeline模型,复杂。

第二种就是通过SourceReader,sinkWirter等模块开发,简单。

SDK VersionLibraries
vistaevr.lib mf.lib mfplat.lib
server2008
win7

如果目标是server2008,链接库如下:

evr_vista.lib,mf_vista.lib,mfplat_vist.lib

如果目标是win7或以上,链接库如下:

evr.lib,mf.lib,mfplat.lib

主要流程如下:

1:引入头文件和静态库

#include<mfapi.h>
#include<mfidl.h>
#include<mfreadwrite.h>
#include<wmsdkidl.h>

#pragma comment(lib,"mfplat.lib")
#pragma comment(lib,"mf.lib")
#pragma comment(lib,"Mfreadwrite.lib")
#pragma comment(lib,"mfuuid.lib")
#pragma comment(lib,"evr.lib")

初始化MF

hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
hr = MFStartup(MF_VERSION);

枚举设备创建采集源,通过该方法目前发现不能找到本机的虚拟设备,只能找到对应的usb摄像头,如有知道望告知。

IMFMediaSource *pSource = nullptr;
IMFAttributes *pAttributes = nullptr;

HRESULT hr = MFCreateAttributes(&pAttributes, 1);
hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
		MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
MFEnumDeviceSources(pAttributes, &ppDevices, &count); 
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(&pSource));

2:创建Source Reader用于数据读取

IMFSourceReader *pSourceReader = nullptr;

MFCreateSourceReaderFromMediaSource(*ppSource, nullptr/*pAttributes*/, &pSourceReader);

3:设置Source Reader媒体数据类型,此时如果媒体类型不支持则设置也会成功,但是读取数据时会失败,所以需要知道源设备支持的类型。

IMFMediaType *mediatype = nullptr;
	
hr = MFCreateMediaType(&mediatype);
mediatype->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
mediatype->SetGUID(MF_MT_SUBTYPE, WMMEDIASUBTYPE_YUY2);	//设置支持的类型 否则读取失败
hr = MFSetAttributeSize(mediatype, MF_MT_FRAME_SIZE, 640, 480);

hr = pSourceReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, nullptr, mediatype);

4:获取源设备支持类型,

IMFPresentationDescriptor *pDescriptor;
IMFStreamDescriptor	*pStreamDes;
IMFMediaTypeHandler	*pMediaHand;
IMFMediaType	*pMediaType;

hr = pSource->CreatePresentationDescriptor(&pDescriptor);
hr = pDescriptor->GetStreamDescriptorByIndex(0, &bSelect, &pStreamDes);
hr = pStreamDes->GetMediaTypeHandler(&pMediaHand);
pMediaHand->GetMediaTypeCount(&dcount);
for(int i=0;i<dcount;i++)
{
    pMediaHand->GetMediaTypeByIndex(i,&pMediaType);
    pMediaType->GetCount();
    ....
}

5:同步读取数据

hr = pSourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM,
			0, &index, &flags, &llvideoTs, &sampe);
if (sampe)
 {
			BYTE *data = nullptr;
			IMFMediaBuffer *buffer = nullptr;
			DWORD dmax=0, dcurrent = 0;
			
			sampe->GetBufferByIndex(0, &buffer);
			buffer->Lock(&data, &dmax, &dcurrent);
			buffer->Unlock();
			buffer->Release();
		}

 

总结:上面就是利用MF简单的视频数据采集。相对于DShow简单了很多,不需要创建Grap,Filter,也不需要Pin的连接。

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值