IMFSinkWriter中的错误?

时间:2015-04-29 05:57:51

标签: ms-media-foundation

我以两种方式实现了编码器。

1)基于SDK Transcoder示例,该示例使用拓扑和转码配置文件

2)基于IMFSourceReader和IMFSinkWriter,其中Sinkwriter将样本传递给Sourcewriter进行转码

我在Windows 8.1上使用Nvidia(Quadro K2200)和Intel GPU(P4600 / P4700)测试了这两种实现

但是,只有拓扑实现使用GPU(两者都有)。

在2)我都设置了“MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS”,我猜这个没有设置,因为1)与GPU一起工作,有或没有为容器类型设置此标志。

是否有使用IMFSinkWriter启用GPU的技巧或者这是媒体基础中的错误?

1 个答案:

答案 0 :(得分:2)

我最初遇到了同样的问题。您没有提到如何配置源阅读器的输出类型(以及接收器的输入类型),但我发现如果您允许系统处理它(通过选择阅读器的输出类型为RGB32) ,性能将是可怕的,所有CPU绑定。 (为简洁起见,省略了错误检查)

hr = videoMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
hr = videoMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
hr = reader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, nullptr, videoMediaType);
reader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, true);

文档同意,表明此配置对于从视频中获取单个快照非常有用。因此,如果您将阅读器配置为提供本机媒体类型,则性能非常出色,但您现在必须自己转换格式。

reader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, videoMode->GetIndex(), videoMediaType);

从这里开始,如果您正在处理简单的颜色转换(例如来自网络摄像头的YUY2或YUV),那么有一些选项。我最初尝试编写自己的转换器,然后使用带有HLSL的{​​{1}}将其推送到GPU。这非常有效,但在您的情况下,格式并不是那么简单。

最终,创建和配置颜色转换器的实例(作为DirectCompute)可以很好地工作。

IMFTransform

创建并配置单独的样本和缓冲区。

Microsoft::WRL::ComPtr<IMFMediaType> mediaTransform;
hr = ::CoCreateInstance(CLSID_CColorConvertDMO, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMFTransform), reinterpret_cast<void**>(mediaTransform.GetAddressOf());

// set the input type of the transform to the NATIVE output type of the reader
hr = mediaTransform->SetInputType(0u, videoMediaType.Get(), 0u);

从源接收样本时,将它们移交给要转换的变换。

IMFSample* transformSample;
hr = ::MFCreateSample(&transformSample);
hr = ::MFCreateMemoryBuffer(RGB_MFT_OUTPUT_BUFFER_SIZE, &_transformBuffer);
hr = transformSample->AddBuffer(transformBuffer);

MFT_OUTPUT_DATA_BUFFER* transformDataBuffer;
transformDataBuffer = new MFT_OUTPUT_DATA_BUFFER();
transformDataBuffer->pSample = _transformSample;
transformDataBuffer->dwStreamID = 0u;
transformDataBuffer->dwStatus = 0u;
transformDataBuffer->pEvents = nullptr;

然后,当然,最终将转换后的样品交给水槽,就像今天一样。我相信这会奏效,你会成为一个非常幸福的人。对我来说,我从20%的CPU利用率(最初的实施)下降到2%(我同时显示视频)。祝好运。我希望你喜欢你的项目。