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 目录中

 

posted @ 2016-02-09 20:27  R.H.Zhang  阅读(7193)  评论(1编辑  收藏  举报