MFT的调用流程

应朋友要求,写了个,CSDN也发下吧。

异步MFT不讨论,我只说同步MFT模型。
一般对于一个同步MFT,你只需要实现以下的方法即可。
GetInputCurrentType
GetInputAvailableType*
GetOutputCurrentType
GetOutputAvailableType
SetInputType
SetOutputType
ProcessMessage -> DARIN or FLUSH
ProcessInput
ProcessOutput
GetInputStreamInfo
GetOutputStreamInfo
GetInputStatus*
GetOutputStatus*

(注:带*号表示这个方法对于音频MFT的话可以不需要实现)

1、首先会调用MFT的GetAttributes方法取得MFT的属性信息,比如是否异步MFT啊,是否支持D3D加速啊什么的。
2、然后会调用GetStreamCount方法取得MFT当前提供的Stream总数。
3、然后再调用GetStreamIDs取得MFT的Stream标识符。
4、然后调用GetInputStreamAttributes方法取得每个Stream的属性。
5、(关键)调用SetInputType方法(尝试)设置输入的媒体类型。
6、(关键)然后调用GetOutputAvailableType方法获取上一步SetInputType后,MFT生成的所有可用的输出类型列表,当然MFT也可以不提供输出类型列表。
7、(关键)调用GetOutputCurrentType取得SetInputType后,MFT保存的当前设置准备输出的类型。
8、调用GetOutputStreamAttributes取得输出流的属性。
9、(关键)管道线经过一系列的判断啊啥的,最终从GetOutputAvailableType或者GetOutputCurrentType拿到一个MFT内部可以用的输出类型,可能会稍加改动,最终把这个类型调用SetOutputType方法真正设置给MFT,让MFT输出的类型为这个。
10、然后调用ProcessMessage,消息为MFT_MESSAGE_NOTIFY_BEGIN_STREAMING。
11、后面会有频繁的调用GetInputCurrentType和GetOutputCurrentType。
12、然后调用ProcessMessage,消息为MFT_MESSAGE_NOTIFY_START_OF_STREAM。
13、(关键)调用GetOutputStreamInfo取得输出的Sample信息,比如需要系统分配的缓存大小等。
14、(关键)系统会第一次调用ProcessOutput,判断MFT是不是有预输出Sample,几乎所有MFT这里都是返回需要更多输入。(0xc00d6d72)
15、(关键)然后系统调用ProcessInput输入一个Sample。
16、(关键)调用GetOutputStreamInfo取得输出Sample的信息。
17、(关键)调用ProcessOutput尝试获取输出样本,如果MFT要求更多输入,则重复。

整个Pipeline会重复执行15、16、17步,直到快播放完成时,系统会调用:
18、系统会调用ProcessMessage,消息为MFT_MESSAGE_COMMAND_DRAIN,此时MFT内部应该有一个flag被置位为进入drain模式。
19、然后系统会频繁调用ProcessOutput直到没有任何Sample可以输出,MFT返回需要更多输入,并且自动把drain模式的flag取消。
20、然后系统调用ProcessMessage,消息为MFT_MESSAGE_COMMAND_FLUSH,要求MFT释放内部资源和缓存(比如MFT_MESSAGE_NOTIFY_START_OF_STREAM时申请的资源,第一次调用ProcessInput时申请的资源),注意这个消息处理后,本次SetInputType的内部MediaType依然有效,就是GetInputCurrentType和GetOutputCurrentType不变。
21、等待系统重新SetInputType,或者重新开始MFT_MESSAGE_NOTIFY_START_OF_STREAM->ProcessInput。

对于某些MFT来说,它并不缓存样本,比如每次ProcessInput就可以获得ProcessOutput后的Sample,那MFT_MESSAGE_COMMAND_DRAIN和MFT_MESSAGE_COMMAND_FLUSH其实都可以忽略,简单的返回S_OK即可。

你可能感兴趣的:(MFT的调用流程)