Windows Media Foundation 音视频采集 小记

写在前面

我是个讲文明的人…… 不过有的时候实在忍不住了也要吐槽几句:

1. 我真是跟不上时代,到现在了还在研究 Windows 应用开发…… 咳;

2. DirectShow 是傻X!我只是想要获取 Camera 裸数据,尼玛却要让我学习神马各种 .ax, filter, graph... 相关资料少、又晦涩;

3. 在此祝愿 Windows XP 及其之前的版本早点退出历史舞台,这样 DirectShow 就不是必须的了!

 

音视频采集

Windows 7 以后, Media Foundation 支持音视频采集。 视频采集设备必须支持 UVC 1.1 驱动。 音频采集设备通过 Windows Audio Session API (WASAPI) 来支持。
采集设备在 Media Foundation 中表现为 Media Source 对象,暴露出 IMFMediaSource 接口。但是一般情况下应用程序不会直接用这个接口,而会使用更高层的API,比如 Source Reader IMFSourceReader 来控制采集设备。
 

列举设备并设置设备

1. 调用 MFCreateAttributes 函数创建属性库;
2. 设置 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 属性(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID 或 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
3. 调用 MFEnumDeviceSources 函数就会得到一组 IMFActivate 指针。每个指针指向一个设备;
4. 调用 GetAllocatedString 函数 可以获取设备名称,其中,
4.1. 用 GetAllocatedString 函数 的 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME 参数可以获取显示名称
4.2. 用 GetAllocatedString 函数 的 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 参数可以获取视频采集设备的物理名称,名称是唯一的,但不好阅读
4.3. 用 GetAllocatedString 函数 的 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 参数可以获取音频采集设备的物理名称,名称是唯一的,但不好阅读
5. 调用 IMFActivate::ActivateObject 或 MFCreateDeviceSource 方法来创建一个可用的 Media Source 对象实例。对于具体的一个采集设备(创建好了的 Media Source),获取设备所支持的格式,并设置采集格式:
5.1. 调用 IMFMediaSource::CreatePresentationDescriptor 获取媒体源(Media Source)的表现描述符(presentation descriptor)
5.2. 调用 IMFPresentationDescriptor::GetStreamDescriptorByIndex 获取视频流的流描述符(Stream Descriptor)
5.3. 调用 IMFStreamDescriptor::GetMediaTypeHandler 获取流描述符的媒体类型句柄(IMFMediaTypeHandler)
5.4. 调用 IMFMediaTypeHandler:: 的 GetMediaTypeCount 和 GetMediaTypeByIndex 来获取每一条目的格式(IMFMediaType,每一条目的格式包含许多属性,如宽高、采样格式、帧率),另外,教程还有一些实用函数,用于打印 IMFAttributes 。
6. 最后, IMFMediaTypeHandler::SetCurrentMediaType 设置指定条目的格式(IMFMediaType)。如果要修改 IMFMediaType 的某个属性(比如 Frame Rate)的话,就调用 IMFMediaType::SetItem 来设置具体的属性(比如 MF_MT_FRAME_RATE)。具体要看代码来理解。
 

通过 Source Reader 读取媒体

当获取到设备以后,一般用 Source Reader 来获取媒体
1. 调用 MFCreateSourceReaderFromMediaSource 关联 IMFMediaSource 和 IMFSourceReader;
2. 调用 IMFSourceReader::GetNativeMediaType 获取各种 Source 提供的媒体类型;
3. 调用 IMFSourceReader::SetCurrentMediaType 设置想要的媒体类型;
4. 调用 IMFSourceReader::ReadSample 来获取音频采样或视频采样(视频帧)。如果想要使用异步方式来 ReadSample,则需要设置一下 MF_SOURCE_READER_ASYNC_CALLBACK 。
 

相关文档:

https://msdn.microsoft.com/en-us/library/dd743690.aspx
https://msdn.microsoft.com/en-us/library/dd317912.aspx
https://msdn.microsoft.com/en-us/library/dd940326.aspx
https://msdn.microsoft.com/en-us/library/dd940328.aspx (设备使用时中途丢失的处理,待学)
https://msdn.microsoft.com/en-us/library/ee663602.aspx
https://msdn.microsoft.com/en-us/library/aa473818.aspx (媒体类型)

 

 

其他功能 

音视频采集 + 编码(Transcode): https://msdn.microsoft.com/en-us/library/ff485863.aspx

播放媒体文件:https://msdn.microsoft.com/en-us/library/ms703190.aspx

 

 

代码地址

在 Windows SDK 的 Samples\multimedia\mediafoundation 目录中

 

你可能感兴趣的:(Windows Media Foundation 音视频采集 小记)