Media foundation——Media source:Writing a Custom Media Source
来源:互联网 发布:学arm用先学单片机吗 编辑:程序博客网 时间:2024/06/05 00:52
编写自定义的媒体源(Writing a Custom Media Source)
本主题描述如何在微软MF基础上实现自定义媒体源。它包含以下部分:
- 创建表示描述符
- 开始媒体源
- 索引
- 暂停媒体源
- 产生源数据
- 样本请求
- 分配采样样本
- 流中的间隙
- 关闭媒体源
- Live源
创建表示描述符
IMFMediaSource::CreatePresentationDescriptor方法,返回一个来自源表示描述符的拷贝。要创建演示文稿描述符,您必须知道源内容中流的数目和每一个流的可能格式。对于每一个流,创建一个流描述符(stream descriptor)如下:
1.创建一个媒体类型(media type)的数组。在数组中的每一个媒体类型表示一个流可能的格式。更多的关于创建媒体类型,参考: Media Types。
2.调用MFCreateStreamDescriptor 来创建流的描述符。通过媒体类型数组。函数返回IMFStreamDescriptor指针。
3.调用 IMFStreamDescriptor::GetMediaTypeHandler来获得流描述符的媒体类型处理程序。
4.使用一个在step 1 中创建好的媒体类型。调用 IMFMediaTypeHandler::SetCurrentMediaType来设置默认的流格式。一般来说,你应该使用最优质的格式。
5.可选,在流描述符上设置属性。参见 Stream Descriptor Attributes,可以获取适用于流描述符的属性列表。
现在创建表示描述符:
1.调用 MFCreatePresentationDescriptor 传入流描述符的数组,函数返回IMFPresentationDescriptor指针。
2.调用 IMFPresentationDescriptor::SelectStream来选择一条或多条默认的流。在默认的配置中至少有一个流必须被选中。
3.可选的,在演示文稿描述符上设置属性。查看Presentation Descriptor Attributes.来获取适用于流描述符的属性列表。
你应该创建一次演示文稿描述符来确定内容,无论是在启动之前或源程序的源程序解析足够的源数据之后。 CreatePresentationDescriptor 方法应该返回一个演示文稿描述符的副本。调用 IMFPresentationDescriptor::Clone. 来创建副本。返回一个副本可以防止客户端修改原始的演示文稿描述符的状态,例如属性或流选择。然而,要知道,克隆创建一个浅的副本,所以客户端可以修改底层的流描述符。
开始媒体源(Starting the Media Source)
IMFMediaSource::Start 方法 开始媒体源或者索引到一个新的位置。无论之前的状态是暂停或者播放,一个Start调用会引起seek操作,并指定一个新的开始时间。否则,Start方法将导致开始。当Start操作完成时,产生如下的事件。
1.发送一个 MENewStream 事件给每一个新的流——以前没有被选中的流现在会被选中。事件的数据是向流的指针。
2.发送 MEUpdatedStream 事件给每个以前被选定,现在也是被选定的流。事件的数据是向流的指针。(不要向没有选中的流发送事件)。
3.如果源正在被索引,发送 MESourceSeeked 事件。否则发送MESourceStarted 事件。事件的数据是在Start 方法中设定好的开始时间。对于MESourceStarted 事件,如果开始事件是VT_EMPTY, 那么给事件设置 MF_EVENT_SOURCE_ACTUAL_START属性。属性值是实际开始时间。
4.对于每条流,如果正在被索引,那么发送 MEStreamSeeked事件。否则发送MESourceStarted 事件。事件的数据就是开始时间。(媒体源通过调用 IMFMediaEventGenerator::QueueEvent 方法,能够在流上排队事件)。
当一条流没有被选中,关闭这条流。这条流就不能够再排队任何事件了。
Start 方法的时间格式在pguidTimeFormat parameter 被给出。标准时间格式,通过GUID_NULL,100纳秒为单位。一个媒体源必须支持这种事件格式。
索引(seeking)
当索引的时候,请求的起始位置可能不会落在一个精确的样本边界上。此外,对于压缩的内容,开始位置可能介于关键帧之间。流应将采样从最早的点需要要求在起始位置产生一个压缩的样品。对于视频来讲,这意味着从前一个关键帧开始。该管道负责从解码器中删除多余的帧,以便在被请求的时间开始播放。
在源事件 (MESourceStarted, MESourceSeeked, MEStreamStarted, and MEStreamSeeked) 中的起始时间是请求的起始时间(时间值在 Start 方法中定义),而不考虑实际起始位置。
例如,假设一个视频流的前几帧有以下特点:
暂停媒体源(Pausing the Media Source)
IMFMediaSource::Pause 方法用于暂停媒体源。
当源被暂停时,一个流可以创建新的样本,并将它们存储在队列中,但流不发送样本。下面是这个规则的一些例外情况:
- 实时的源应该在暂停时删除数据。
- 如果源从网络获取数据,它可能会暂停服务器。
如果源被暂停的时候,客户端调用 IMFMediaStream::RequestSample 方法,请求也会在队列中,直到源程序再次启动。请求不能够被丢弃。
暂停只能在开始状态是才会被允许,否则 Pause 应该会返回MF_E_INVALID_STATE_TRANSITION。
产生源数据(Generating Source Data)
MF使用了pull module, 意味着流通过响应管道的请求来产生和传递样本。当媒体源正在运行并且流被选中的时候,流就能够传递样本。只有当客户端请求一个新的样本时,数据流才提供数据。
样本请求(Sample Request)
客户端通过 IMFMediaStream::RequestSample. 方法来请求信的样本。这里是操作的顺序:
1.客户端调用IMFMediaStream::RequestSample。参数是一个指向一个可选的令牌对象,这样客户端用于跟踪该请求。客户端实现这个令牌。令牌必须暴露IUnknown接口。客户端可以通过一个空指针来代替一个令牌。
2.如果客户端提供了令牌,媒体流调用AddRef的令牌,令牌放在FIFO队列。方法的返回以及其余的步奏都是异步发生。
3.当更多的数据可用时,媒体流就产生了新的样本。
4.媒体流从队列中拉出第一个令牌。
5.如果令牌不为空的话,流媒体设置 MFSampleExtension_Token 属性的媒体样本。属性的值是一个令牌指针。
6.媒体流发送 MEMediaSample 事件。事件数据是一个指向 IMFSample 接口的样本。
7.如果客户端提供了一个令牌,媒体流在令牌对象上调用Release。
如果媒体不能满足客户的 RequestSample 请求,它从队列中把令牌取出并调用释放令牌命令,但不发送MEMediaSample事件。
- Media foundation——Media source:Writing a Custom Media Source
- Media foundation——Media source:Media source object module
- Media foundation——Media source:Media Source Events
- Media foundation——Media source:Presentation Descriptors
- media foundation (Using the Source Reader to Process Media Data)
- Open Source Media Framework
- Media Foundation学习笔记(七)Media Foundation的架构 Source Reader
- Media Foundation学习笔记(七)Media Foundation的架构 Source Reader
- Media Foundation——架构
- Media Foundation
- HTML5 MSE(Media Source Extensions)
- MSE(Media Source Extensions) 规范
- media
- media
- @media
- Media
- media
- Open Source SIP Stack and Media Links
- iOS EnumerateObjectsUsingBlock和for-in对比
- Logstash+ElasticSearch+Kibana日志分析系统
- 提交spark sample作业失败
- Android WebView 加载本地SD卡的html
- Extjs TreeStore无限制加载数据的问题
- Media foundation——Media source:Writing a Custom Media Source
- codeforces 232D Fence
- PHP中return 和 exit 、break和contiue 区别与用法
- 43. Multiply Strings
- intellij的link with editor功能
- SpringMVC实现JSON数据的请求与响应
- Python 连接 MySQL数据库
- Ofbiz Web详解(Ofbiz后门页)
- 宏的使用__VA_ARGS__, __FILE__, __FUNCTION__,__TIME__等