MFTransform::ProcessOutput 挂在函数 CDXVAFrameManager::WaitOnSampleReturnedByRenderer 中

问题描述 投票:0回答:1

我正在尝试让 HEVC 视频解码器与 Media Foundation 一起使用。我所拥有的正在工作 - 大约六帧 - 然后 MFTransform::ProcessOutput 函数无限期地挂起,并出现以下调用堆栈:

NtWaitForMultipleObjects()
WaitForMultipleObjectsEx()
CDXVAFrameManager::WaitOnSampleReturnedByRenderer(void)
CH265DecoderTransform::ProcessOutput(unsigned long,unsigned long,struct _MFT_OUTPUT_DATA_BUFFER *,unsigned long *)

我认为这是因为我没有发布我应该发布的东西。但我不知道是什么。

我有一个 MFTransform 视频解码器和视频处理器,分别用于解码 HEVC 数据和从 NV12 转换为 RGB。它们通过发送 MFT_MESSAGE_SET_D3D_MANAGER 消息连接到用于渲染的 DirectX 11 设备。在此配置中,他们自己创建样本(MFT_OUTPUT_STREAM_PROVIDES_SAMPLES 在 MFT_OUTPUT_STREAM_INFO 结构中设置),并在完成后释放它们。

正如我上面提到的,这是有效的。至少有几帧。视频样本被解码为 NV12、转换为 RGB 并显示。

我正在查询

D3D11Multithread
对象并将
TRUE
传递给
SetMultithreadProtected
。这没有明显的区别。我是否需要通过
Enter
/
Leave
调用来保护对 DirectX 的每次调用?

我在这里找到了这个问题:https://social.msdn.microsoft.com/Forums/azure/en-US/fd399107-69d3-4b55-81a9-9ab6db089cfa/video-decoding-with-custom-mft-or- msft-h264-decoder-mft?forum=mediafoundationdevelopment 具有完全相同的问题,但用相当神秘的方式解决了:

...通过释放 Windows 内部分配的指针来实现此功能。

但是我不知道哪些指针意味着什么。

在解码器挂起之前,解码器的

ProcessOutput
仅返回
S_OK
。如果我在解码器挂起之前暂停它,然后运行帧处理器,它会返回
MF_E_SAMPLEALLOCATOR_EMPTY
,这表明 RGB 样本中的某些内容没有被清理。

但是什么?

据我所知,我的代码中没有资源泄漏。我将发布由媒体基金会转换创建的所有样本。 (当我的智能指针类稍后尝试合法释放它们时,尝试强制释放它们会导致崩溃。)

我需要查询示例缓冲区并释放它们吗?或者它们包含的表面?通过调用

RemoveAllBuffers
强制删除样本缓冲区没有任何区别。

我注意到解码器返回一个

CPooledSample
样本,而视频处理器返回一个
CMFTrackedSample
,那么解码器是否没有收到样本已发布的通知?这是我应该做的事情吗?

编辑: 我的代码相关部分的副本可以在这里找到:https://pastebin.com/Y6p30MRG

windows-10 ms-media-foundation
1个回答
0
投票

好吧,这是(我相信任何人都不会感到惊讶)我的一个愚蠢的错误,以及媒体基金会对我的错误的极其糟糕的反应:

我没有打电话

MFStartup

但事实上,媒体基金会并没有费心告诉我这一点,只是假装一切都很好(直到事实并非如此),坦率地说,这是一个令人尴尬的糟糕“设计”。

一旦我开始打电话

MFStartup
,其他一切就开始按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.