有效地将异步 IMFSourceReader 连接到同步 IMFTransform

Posted

技术标签:

【中文标题】有效地将异步 IMFSourceReader 连接到同步 IMFTransform【英文标题】:Efficiently connecting an asynchronous IMFSourceReader to a synchronous IMFTransform 【发布时间】:2020-11-01 12:49:25 【问题描述】:

给定一个异步 IMFSourceReader 连接到一个仅同步的 IMFTransform。

那么对于 IMFSourceReaderCallback::OnReadSample() 回调,最好不要直接在 OnReadSample 中调用 IMFTransform::ProcessInput,而是将生成的样本推送到另一个队列中以供另一个线程调用转换 ProcessInput?

或者我只是在复制通常在内部执行的相同工作源阅读器?或者换一种说法,OnReadSample 中的工作是否存在阻止源阅读器中任何进一步的解码工作的风险,否则这些工作可能会更加异步地发生?

所以我建议如下:

WorkQueue transformInputs;
...

//  Called back async
HRESULT OnReadSampleCallback(... IMFSample* sample)

    // Push sample and return immediately
    Push(transformInputs, sample); 


//  Different worker thread awoken for transformInputs queue samples
void OnTransformInputWork()

    //  Transform object is not async capable
    transform->TransformInput(0, Pop(transformInputs), 0);
    ...

在“实现回调接口”中涉及到了这一点,但没有详细说明: https://docs.microsoft.com/en-us/windows/win32/medfound/using-the-source-reader-in-asynchronous-mode

还是完全取决于源阅读器在内部设置的任何内容并且不容易确定?

【问题讨论】:

【参考方案1】:

IMFSourceReaderCallback::OnReadSample 中执行长阻塞操作不是一个好主意。没有什么会是致命或严重的,但这不是预期的用途。

考虑到您之前关于音频格式转换的问题,音频样本数据转换速度足够快,可以在此类回调中发生。

此外,不清楚或没有记录(取决于实际实现),ProcessInput 通常是即时的,仅引用输入数据。在这种情况下,ProcessOutput 的计算成本会很高。如果您不在同一个回调中直接执行ProcessOutput,您可能会遇到 MFT 不再接受输入的情况,因此您无论如何都必须实现一个队列。

考虑到所有这些,假设您的处理不是太繁重,您只需在回调中进行处理而忽略性能影响,否则您将开始执行队列。

【讨论】:

我还想知道是否有一个同步的 IMFTransform 对象池(在我当前的情况下是音频重采样器)馈送到任务系统,这可能是一个很好的设计。但随后您必须刷新转换以描绘并行处理的转换块,并确保它们在之后排序。我怀疑这个重采样器会以一种避免内部缓冲任何部分结果的方式来描述块。正如您所说,尽管对于音频重采样,它可能已经非常快了。 不需要多次转换,您甚至无法正常工作。您将拥有一个 MFT 实例以将数据作为流连续处理。重采样本身足够快,回调中的问题更多与阻塞/同步有关,而不是处理缓慢。

以上是关于有效地将异步 IMFSourceReader 连接到同步 IMFTransform的主要内容,如果未能解决你的问题,请参考以下文章

pandas 有效地将 DataFrames 与不匹配的分类列和 MultiIndex 级别连接起来

使用 IMFSourceReader 打开视频文件

如何通过 IMFSourceReader 使用自定义堆

处理来自 IMFSourceReader 和 IMFSample 的图像数据

使用 IMFSourceReader 进行音频流式传输(Microsoft Media Foundation)

在使用 IMFSourceReader 时转换流媒体类型