我能够使用MediaFoundation成功编码H264视频。
现在我要导出受official documentation支持的HEVC。
我正在按照此处所述进行所有操作,但是每当我想将输入媒体类型设置为writer时,都会出现错误:
这是我所做的简短代码:
/ *设置输出媒体类型* /
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编码是否真正受支持,或者仅仅是文档。 如果Microsoft确实支持它,那我在做什么错了?
顺便说一句:我正在使用Windows 10的最新版本。 为了简化代码,省略了错误检查
答案 0 :(得分:2)
也许您可以先使用DXVA Checker工具检查h265编码器是否存在,或者以编程方式使用MFEnumEx(MFT_CATEGORY_VIDEO_ENCODER, ...)进行查找。
如果未找到,则可以尝试安装HEVC Video Extension on MS App Store。在2018 Fall Creator更新后,MS似乎已将MF HEVC编解码器分离到应用程序包中。另外,需要通过供应商的VGA驱动程序安装硬件HEVC编码器。
答案 1 :(得分:2)
您的输出媒体类型不完整:
MF_MT_AVG_BITRATE
平均编码比特率,以每秒比特数为单位。必须大于零。
与MF_MT_INTERLACE_MODE
类似的问题。
有效的代码段:
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));