媒体基础 SetInputType returns "The stream number provided was invalid"
Media Foundation SetInputType returns "The stream number provided was invalid"
为了简单起见,我正在使用我机器上可用的软件 H264 编码器 MFT 开发 H.264 编码器(与我最终将使用的英特尔 QSV 硬件编码器相反)。根据一些教程,我整理了以下代码:
IMFTransform* encoder;
DWORD numInputs, numOutputs;
DWORD *inputIDs, *outputIDs;
MFRatio fps = { 24, 1 }, par = { 1, 1 };
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
return hr;
}
// Create the MFT
hr = FindVideoEncoder(false, true, true, &encoder);
if (FAILED(hr))
{
return hr;
}
// Obtain number of streams attached to MFT
encoder->GetStreamCount(&numInputs, &numOutputs);
// Allocate appropriate size arrays
inputIDs = new DWORD[numInputs];
outputIDs = new DWORD[numOutputs];
// Obtain stream IDs
encoder->GetStreamIDs(numInputs, inputIDs, numOutputs, outputIDs);
// Set input and output types
IMFMediaType *inputType, *outputType;
CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&outputType, MFMediaType_Video, MFVideoFormat_H264);
hr = encoder->SetOutputType(outputIDs[0], outputType, 0);
if (FAILED(hr))
{
return hr;
}
CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&inputType, MFMediaType_Video, MFVideoFormat_Base);
hr = encoder->SetInputType(inputIDs[0], inputType, 0);
if (FAILED(hr))
{
return hr;
}
下一行代码失败,给出的 HRESULT 值为 "The stream number provided was invalid"。
hr = encoder->SetOutputType(outputIDs[0], outputType, 0);
我试图在 SetOutputType 之前调用 SetInputType,但是它产生了同样的错误。我究竟做错了什么?预先感谢您的回答。
编辑:添加了 CreateVideoType 函数以显示如何创建 outputType 和 inputType
HRESULT CreateVideoType(
UINT32 width,
UINT32 height,
MFVideoInterlaceMode interlaceMode,
const MFRatio& frameRate,
const MFRatio& par,
IMFMediaType **ppType,
GUID majorType,
GUID subtype
)
{
if (ppType == NULL)
{
return E_POINTER;
}
LONG lStride = 0;
UINT cbImage = 0;
IMFMediaType *pType = NULL;
// Set the subtype GUID from the FOURCC or D3DFORMAT value.
//subtype.Data1 = D3DFMT_A8R8G8B8;
if (FAILED(MFCreateMediaType(&pType)))
{
goto done;
}
if (FAILED(pType->SetGUID(MF_MT_MAJOR_TYPE, majorType)))
{
goto done;
}
if (FAILED(pType->SetGUID(MF_MT_SUBTYPE, subtype)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_INTERLACE_MODE, interlaceMode)))
{
goto done;
}
if (FAILED(MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, width, height)))
{
goto done;
}
// Calculate the default stride value.
if (FAILED(pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride))))
{
goto done;
}
// Calculate the image size in bytes.
if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_SAMPLE_SIZE, cbImage)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)))
{
goto done;
}
// Frame rate
if (FAILED(MFSetAttributeRatio(pType, MF_MT_FRAME_RATE, frameRate.Numerator, frameRate.Denominator)))
{
goto done;
}
// Pixel aspect ratio
if (FAILED(MFSetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, par.Numerator, par.Denominator)))
{
goto done;
}
// Return the pointer to the caller.
*ppType = pType;
(*ppType)->AddRef();
done:
SafeRelease(&pType);
return S_OK;
}
Microsoft H264 编码器 MFT 未实现 GetStreamIDs
- 它 returns E_NOTIMPL。您必须将输入和输出流 ID 设置为 0。
正如 Evgeny 在讨论中指出的那样,在代码运行之前有几个问题需要解决。将 inputID
和 outputID
更改为 0 对 SetInputType
和 SetOutputType
调用起到了作用,但是视频类型的创建存在一些问题。
首先创建输出类型:
CreateH264VideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&outputType, MFMediaType_Video, MFVideoFormat_H264);
在我删除的函数 CreateH264VideoType 中
// Calculate the image size in bytes.
if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
{
goto done;
}
我不得不添加
// Profile
if (FAILED(pType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Base)))
{
goto done;
}
// Bitrate
if (FAILED(pType->SetUINT32(MF_MT_AVG_BITRATE, 166723584)))
{
goto done;
}
对于 CreateUncompressedVideoType,我删除了 MFCalculateImageSize 并添加了比特率属性集调用。这解决了编码器初始化错误。
为了简单起见,我正在使用我机器上可用的软件 H264 编码器 MFT 开发 H.264 编码器(与我最终将使用的英特尔 QSV 硬件编码器相反)。根据一些教程,我整理了以下代码:
IMFTransform* encoder;
DWORD numInputs, numOutputs;
DWORD *inputIDs, *outputIDs;
MFRatio fps = { 24, 1 }, par = { 1, 1 };
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
return hr;
}
// Create the MFT
hr = FindVideoEncoder(false, true, true, &encoder);
if (FAILED(hr))
{
return hr;
}
// Obtain number of streams attached to MFT
encoder->GetStreamCount(&numInputs, &numOutputs);
// Allocate appropriate size arrays
inputIDs = new DWORD[numInputs];
outputIDs = new DWORD[numOutputs];
// Obtain stream IDs
encoder->GetStreamIDs(numInputs, inputIDs, numOutputs, outputIDs);
// Set input and output types
IMFMediaType *inputType, *outputType;
CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&outputType, MFMediaType_Video, MFVideoFormat_H264);
hr = encoder->SetOutputType(outputIDs[0], outputType, 0);
if (FAILED(hr))
{
return hr;
}
CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&inputType, MFMediaType_Video, MFVideoFormat_Base);
hr = encoder->SetInputType(inputIDs[0], inputType, 0);
if (FAILED(hr))
{
return hr;
}
下一行代码失败,给出的 HRESULT 值为 "The stream number provided was invalid"。
hr = encoder->SetOutputType(outputIDs[0], outputType, 0);
我试图在 SetOutputType 之前调用 SetInputType,但是它产生了同样的错误。我究竟做错了什么?预先感谢您的回答。
编辑:添加了 CreateVideoType 函数以显示如何创建 outputType 和 inputType
HRESULT CreateVideoType(
UINT32 width,
UINT32 height,
MFVideoInterlaceMode interlaceMode,
const MFRatio& frameRate,
const MFRatio& par,
IMFMediaType **ppType,
GUID majorType,
GUID subtype
)
{
if (ppType == NULL)
{
return E_POINTER;
}
LONG lStride = 0;
UINT cbImage = 0;
IMFMediaType *pType = NULL;
// Set the subtype GUID from the FOURCC or D3DFORMAT value.
//subtype.Data1 = D3DFMT_A8R8G8B8;
if (FAILED(MFCreateMediaType(&pType)))
{
goto done;
}
if (FAILED(pType->SetGUID(MF_MT_MAJOR_TYPE, majorType)))
{
goto done;
}
if (FAILED(pType->SetGUID(MF_MT_SUBTYPE, subtype)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_INTERLACE_MODE, interlaceMode)))
{
goto done;
}
if (FAILED(MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, width, height)))
{
goto done;
}
// Calculate the default stride value.
if (FAILED(pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride))))
{
goto done;
}
// Calculate the image size in bytes.
if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_SAMPLE_SIZE, cbImage)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE)))
{
goto done;
}
if (FAILED(pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)))
{
goto done;
}
// Frame rate
if (FAILED(MFSetAttributeRatio(pType, MF_MT_FRAME_RATE, frameRate.Numerator, frameRate.Denominator)))
{
goto done;
}
// Pixel aspect ratio
if (FAILED(MFSetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, par.Numerator, par.Denominator)))
{
goto done;
}
// Return the pointer to the caller.
*ppType = pType;
(*ppType)->AddRef();
done:
SafeRelease(&pType);
return S_OK;
}
Microsoft H264 编码器 MFT 未实现 GetStreamIDs
- 它 returns E_NOTIMPL。您必须将输入和输出流 ID 设置为 0。
正如 Evgeny 在讨论中指出的那样,在代码运行之前有几个问题需要解决。将 inputID
和 outputID
更改为 0 对 SetInputType
和 SetOutputType
调用起到了作用,但是视频类型的创建存在一些问题。
首先创建输出类型:
CreateH264VideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
&outputType, MFMediaType_Video, MFVideoFormat_H264);
在我删除的函数 CreateH264VideoType 中
// Calculate the image size in bytes.
if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
{
goto done;
}
我不得不添加
// Profile
if (FAILED(pType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Base)))
{
goto done;
}
// Bitrate
if (FAILED(pType->SetUINT32(MF_MT_AVG_BITRATE, 166723584)))
{
goto done;
}
对于 CreateUncompressedVideoType,我删除了 MFCalculateImageSize 并添加了比特率属性集调用。这解决了编码器初始化错误。