关于MFT的消息处理

MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
客户端可以不发送这个消息,如果客户端发送这个消息,则必需已经为MFT设置了输入媒体类型,并且这个消息应该在ProcessInput前发送。
发送这个消息通知MFT申请ProcessInput的资源和缓冲区。
如果客户端不发送这个消息,则MFT应该在第一次ProcessInput时申请资源和缓冲区。

MFT_MESSAGE_NOTIFY_END_STREAMING:
客户端可以不发送这个消息,但是如果客户端需要发送这个消息,则必需已经发送过了MFT_MESSAGE_NOTIFY_BEGIN_STREAMING消息。
当MFT接受到这个消息后,则释放一些内部的缓冲区和资源。但是MFT不需要清空内部样本队列(Flush)和重设输入媒体类型。

MFT_MESSAGE_NOTIFY_BEGIN_STREAMING和MFT_MESSAGE_NOTIFY_END_STREAMING消息一般是成对发送,可能的情况是ProcessInput前发送MFT_MESSAGE_NOTIFY_BEGIN_STREAMING,然后ProcessOutput后发送MFT_MESSAGE_NOTIFY_END_STREAMING,这2个消息一般是提醒MFT可以申请或者释放内部的缓冲区,而如果客户端都不发送这2个消息,则应该在第一次ProcessInput时申请缓冲区。

MFT_MESSAGE_NOTIFY_START_OF_STREAM:

对于同步属性的MFT组件,客户端可以不发送这个消息。
而对于异步的MFT组件,客户端则必需发送这个消息。
发送这个消息给MFT,通知MFT组件准备处理第一个样本。
这里所谓的“处理第一个样本”,可能是ProcessInput被调用,也可能是ProcessOutput被调用,而不一定是ProcessInput被调用,在MFT_MESSAGE_NOTIFY_START_OF_STREAM消息接受前,ProcessInput和ProcessOutput应该是一次都没有被调用过的,在MFT_MESSAGE_NOTIFY_START_OF_STREAM接受后,一般Pipeline会调用ProcessOutput方法。

MFT_MESSAGE_NOTIFY_END_OF_STREAM:

客户端可以不发送这个消息。
在一个流处理结束之后,如果客户端需要再次调用ProcessInput方法,则应该给第一个样本设置MFSampleExtension_Discontinuity属性,这个属性表明流已经“中断”了,不管客户端是否发送MFT_MESSAGE_NOTIFY_END_OF_STREAM消息,都应该遵守这个原则。
在发送这个消息给MFT之后,客户端通常会接着发送MFT_MESSAGE_COMMAND_DRAIN消息,然后调用ProcessOutput方法“排空”在MFT组件中缓存的样本。
但是,如果客户端不发送MFT_MESSAGE_COMMAND_DRAIN消息,则MFT在接受到MFT_MESSAGE_NOTIFY_END_OF_STREAM消息后,应该在下次第一次ProcessInput被调用时,把缓存的样本全部清空。
接受到这个消息时,MFT不需要清空内部样本队列(Flush)和重设输入媒体类型。

MFT_MESSAGE_COMMAND_DRAIN:
客户端发送这个消息后,则MFT组件开始进入“排空”模式,进入“排空”模式后,则MFT不接受任何新的输入(ProcessInput方法无效)。
对于同步MFT来说,客户端发送这个消息后,会循环调用ProcessOutput方法把MFT内部缓存的所有样本都Pull出来,直到ProcessOutput返回MF_E_TRANSFORM_NEED_MORE_INPUT则结束循环。
只要MFT的内部缓存还有数据,则客户端调用ProcessInput方法会失败,当ProcessOutput拉空所有内部缓存后,MFT则自动退出“排空”模式接受新的输入。
MFT应该在ProcessOutput忽略那种不能成为一个输出样本的数据。
对于异步MFT来说,MFT接受到这个消息后,则循环发送METransformHaveOutput事件直到MFT没有数据可以输出,在此期间,MFT不应该发送METransformNeedInput事件。
在最后的METransformHaveOutput事件发送完成后,MFT则应该发送一个METransformDrainComplete事件,表示MFT已经退出“排空”模式。
退出排空模式后,MFT不应该发送METransformNeedInput事件,直到它接受到客户端发送MFT_MESSAGE_NOTIFY_START_OF_STREAM消息。

在客户端排空MFT后,则客户端可以继续调用ProcessInput方法处理更多的输入样本,但是第一个样本必需有MFSampleExtension_Discontinuity属性。
如果同步MFT内部没有样本队列,比如一个ProcessInput后则可以ProcessOutput,则不需要理会这个消息。

MFT_MESSAGE_COMMAND_FLUSH:

所有MFT组件都必需响应这个消息,MFT接受到这个消息后,抛弃所有准备输出的样本缓存或者清空队列。
MFT组件接受到这个消息后,当前保存的输入输出类型已经无效,客户端可以SetInputType重新设置输入类型。
对于异步MFT,接受到这个消息后,在下一次客户端发送MFT_MESSAGE_NOTIFY_START_OF_STREAM前,都不应该再发送METransformNeedInput事件。

MFT_MESSAGE_SET_D3D_MANAGER:
如果一个MFT支持DXVA API,则它可以实现这个消息,不然应该在接受到这个消息后返回E_NOTIMPL。
消息的参数中包含有响应的接口,如果是D3D11的MFT,则可以获取到IMFDXGIDeviceManager接口,如果是D3D9的MFT,则应该获取到IDirect3DDeviceManager9接口。
这个消息只会给视频的MFT发送,并且这个MFT组件必需返回MF_SA_D3D_AWARE属性,如果这个MFT有多个输出流,则客户端不应该发送这个消息给MFT组件。
关于D3D视频加速MFT,请见Direct3D-Aware MFTs。

你可能感兴趣的:(关于MFT的消息处理)