MediaFoundation HEVC H265 编码

Posted

技术标签:

【中文标题】MediaFoundation HEVC H265 编码【英文标题】:MediaFoundation HEVC H265 encoding 【发布时间】:2018-11-14 01:09:44 【问题描述】:

我能够使用 MediaFoundation 成功编码 H264 视频。

现在我想导出 HEVC,根据official documentation,它是受支持的。

我正在按照那里的描述做所有事情,但是每当我想为编写器设置输入媒体类型时,都会出现错误:

没有找到合适的转换来编码或解码内容。

这是我所做的简短代码:

/* 设置输出媒体类型 */

IMFMediaType* pMediaTypeOut = nullptr;
MFCreateMediaType(&pMediaTypeOut);
pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_HEVC);
MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, 640, 480);
MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, 30, 1);
pMediaTypeOut->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH265VProfile_Main_420_8);
pMediaTypeOut->SetUINT32(MF_MT_MPEG2_LEVEL, eAVEncH265VLevel1);

// Add it to the sink writer
m_pWriter->AddStream(pMediaTypeOut, &m_streamIndex);

/* 设置输入媒体类型 */

IMFMediaType* pMediaTypeIn = nullptr;
MFCreateMediaType(&pMediaTypeIn);
pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, 640, 480);
MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, 30, 1),
MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1),

// Here it ends up with an error
m_pWriter->SetInputMediaType(m_streamIndex, pMediaTypeIn, nullptr);

有谁知道 HEVC 编码是否真的受支持,或者它只是一个文档。 而如果真的得到微软的支持,那我做错了什么?

顺便说一句:我使用的是最新版本的 Windows 10。 为了代码简单,省略了错误检查

【问题讨论】:

【参考方案1】:

您的输出媒体类型不完整:

MF_MT_AVG_BITRATE 平均编码比特率,以比特/秒为单位。必须大于零。

MF_MT_INTERLACE_MODE 的类似问题。

有效的代码 sn-p:

Check(MFStartup(MF_VERSION));

ComPtr<IMFSinkWriter> SinkWriter;
Check(MFCreateSinkWriterFromURL(L"D:\\temp.mp4", nullptr, nullptr, SinkWriter.GetAddressOf()));

ComPtr<IMFMediaType> OutputMediaType;
Check(MFCreateMediaType(OutputMediaType.GetAddressOf()));
Check(OutputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
Check(OutputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_HEVC));
Check(MFSetAttributeSize(OutputMediaType.Get(), MF_MT_FRAME_SIZE, 640, 480));
Check(OutputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
Check(MFSetAttributeRatio(OutputMediaType.Get(), MF_MT_FRAME_RATE, 30, 1));
//Check(OutputMediaType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH265VProfile_Main_420_8));
//Check(OutputMediaType->SetUINT32(MF_MT_MPEG2_LEVEL, eAVEncH265VLevel1));
Check(OutputMediaType->SetUINT32(MF_MT_AVG_BITRATE, 1000000));

DWORD StreamIndex;
Check(SinkWriter->AddStream(OutputMediaType.Get(), &StreamIndex));

ComPtr<IMFMediaType> InputMediaType;
Check(MFCreateMediaType(InputMediaType.GetAddressOf()));
Check(InputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
Check(InputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12));
Check(MFSetAttributeSize(InputMediaType.Get(), MF_MT_FRAME_SIZE, 640, 480));
Check(InputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
Check(MFSetAttributeRatio(InputMediaType.Get(), MF_MT_FRAME_RATE, 30, 1)),
//Check(MFSetAttributeRatio(InputMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1)),

Check(SinkWriter->SetInputMediaType(StreamIndex, InputMediaType.Get(), nullptr));

【讨论】:

【参考方案2】:

也许您可以先通过DXVA Checker 工具检查h265 编码器是否存在,或者以编程方式使用MFEnumEx(MFT_CATEGORY_VIDEO_ENCODER, ...) 进行查找。

如果找不到,您可以尝试安装HEVC Video Extension on MS App Store。在 2018 Fall Creator 更新之后,似乎 MS 已将 MF HEVC 编解码器分离到应用程序包中。此外,需要通过供应商的 VGA 驱动程序安装 HW HEVC 编码器。

【讨论】:

是的!安装来自@Roman 的扩展和代码对我有帮助!非常感谢

以上是关于MediaFoundation HEVC H265 编码的主要内容,如果未能解决你的问题,请参考以下文章

hevc和h.264的区别

iOS ijkplayer 硬解H265(hevc)4k视频问题解决

iOS ijkplayer 硬解H265(hevc)4k视频问题解决

iOS ijkplayer 硬解H265(hevc)4k视频问题解决

h264, h265 和 libvpx 比较(h264/avc, hevc 和vp9比较)

iOS利用ffmpeg 转码hevc到h264 ,以及 保存h265 h264流