我在MS Media Foundation论坛上发布了我的问题,到目前为止还没有人能够回应。我在MS论坛和Stackoverflow上看到了与我的问题类似的线程,但我没有找到任何解决方案。 我已经设置了一个包含几个变换的管道。此管道的目的是能够自定义组件,即交换媒体接收器并使用自定义组件与内置组件进行转换。
我的问题在于H264编码器。解码器工作正常。我枚举了编码器。它返回一个H264编码器。我尝试过以两种方式设置媒体类型。 FYI输出媒体类型设置正确。根据MS文档,需要首先设置输出。我只设置IMFTranform属性而不是ICodecAPI attrbs。设置输出后,我移动到输入。
有两种方式: 1)创建空白媒体类型,设置attrbs并应用它们2)或获取可用的输入类型,然后修改我感兴趣的属性,如帧宽,高度,帧速率和隔行扫描模式。 SetInputType因C00D36D5(媒体类型无效)而失败。不知道为什么。 MFTrace表示失败,但没有说明缺失的原因。有任何想法吗? 以下是从头开始设置的示例代码:
HRESULT MediaFoundationManager::FindEncoder(IMFTransform **decoder, IMFMediaType *type)
{
HRESULT hr = S_OK;
UINT32 count = 0;
CLSID *ppCLSIDs = NULL;
MFT_REGISTER_TYPE_INFO info = { 0 };
info.guidMajorType = MFMediaType_Video;
info.guidSubtype = MFVideoFormat_YUY2;
MFT_REGISTER_TYPE_INFO outInfo = {0};
outInfo.guidMajorType = MFMediaType_Video;
outInfo.guidSubtype = MFVideoFormat_H264;
hr = MFTEnum( MFT_CATEGORY_VIDEO_ENCODER,
0, // Reserved
&info, // Input type
&outInfo, // Output type
NULL, // Reserved
&ppCLSIDs,
&count
);
if (SUCCEEDED(hr) && count == 0)
hr = MF_E_TOPO_CODEC_NOT_FOUND;
if (SUCCEEDED(hr))
hr = CoCreateInstance(ppCLSIDs[0], NULL, CLSCTX_ALL, IID_PPV_ARGS(decoder));
if (SUCCEEDED(hr))
{
ConfigureMFTFromScratch(*decoder,info.guidSubtype,outInfo.guidSubtype, true);
}
}
CoTaskMemFree(ppCLSIDs);
return hr;
}
void MediaFoundationManager::ConfigureMFTFromScratch(IMFTransform *transform, GUID inputFormat, GUID outputFormat, bool h264)
{
CComPtr<IMFMediaType> inputMediaType = NULL;
CComPtr<IMFMediaType> outputMediaType = NULL;
Helper::CheckHR(MFCreateMediaType(&inputMediaType),"Create Media Type");
Helper::CheckHR(MFCreateMediaType(&outputMediaType),"Create Media Type");
Helper::CheckHR(inputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),"Set major type");
Helper::CheckHR(inputMediaType->SetGUID(MF_MT_SUBTYPE, inputFormat),"Set Sub type");
Helper::CheckHR(MFSetAttributeSize(inputMediaType, MF_MT_FRAME_SIZE,_inputInfo.FrameWidth, _inputInfo.FrameHeight),"Set Frame Size");
Helper::CheckHR(inputMediaType->SetUINT64(MF_MT_FRAME_RATE, _inputInfo.FrameRate),"Set Frame rate");
Helper::CheckHR(inputMediaType->SetUINT32(MF_MT_AVG_BITRATE, _inputInfo.BitRate),"Set Bit rate");
Helper::CheckHR(inputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlaceMode::MFVideoInterlace_Progressive),"Set Interlace Mode");
Helper::CheckHR(MFSetAttributeRatio(inputMediaType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1),"Set Aspect Ratio");
Helper::CheckHR(outputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),"Set major type");
Helper::CheckHR(outputMediaType->SetGUID(MF_MT_SUBTYPE, outputFormat),"Set Sub type");
Helper::CheckHR(MFSetAttributeSize(outputMediaType, MF_MT_FRAME_SIZE,_inputInfo.FrameWidth, _inputInfo.FrameHeight),"Set Frame Size");
Helper::CheckHR(outputMediaType->SetUINT64(MF_MT_FRAME_RATE, _inputInfo.FrameRate),"Set Frame rate");
Helper::CheckHR(outputMediaType->SetUINT32(MF_MT_AVG_BITRATE, _inputInfo.BitRate),"Set Bit rate");
Helper::CheckHR(outputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlaceMode::MFVideoInterlace_Progressive),"Set Interlace Mode");
Helper::CheckHR(MFSetAttributeRatio(outputMediaType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1),"Set Aspect Ratio");
if (h264)
{
UINT32 level = -1;
outputMediaType->SetUINT32(MF_MT_MPEG2_LEVEL, level);
Helper::CheckHR(outputMediaType->SetUINT32(MF_MT_MPEG2_PROFILE , eAVEncH264VProfile_Main),"Set Profile Mode");
Helper::CheckHR(transform->SetOutputType(0, outputMediaType, 0),"Set output type");
Helper::CheckHR(transform->SetInputType(0, inputMediaType, 0),"Set input type");
}
else
{
Helper::CheckHR(transform->SetInputType(0, inputMediaType, 0),"Set input type");
Helper::CheckHR(transform->SetOutputType(0, outputMediaType, 0),"Set output type");
}
}
如果你们指出我正确的方向,我真的很感激。