E_INVALIDARG 而 IMFTransform::ProcessOutput

Posted

技术标签:

【中文标题】E_INVALIDARG 而 IMFTransform::ProcessOutput【英文标题】:E_INVALIDARG while IMFTransform::ProcessOutput 【发布时间】:2018-08-06 22:22:11 【问题描述】:

我正在努力在 Media Foundation 中制作卡通着色器,为此我需要将我的相机原生提供的 NV12 转换为 RGB24。到目前为止,我对 IMFTransform 的尝试如下所示: 设置:

inputVideoTypes = new MFT_REGISTER_TYPE_INFO;
inputVideoTypes->guidMajorType = MFMediaType_Video;
inputVideoTypes->guidSubtype = MFVideoFormat_NV12;
outputVideoTypes = new MFT_REGISTER_TYPE_INFO;
outputVideoTypes->guidMajorType = MFMediaType_Video;
outputVideoTypes->guidSubtype = MFVideoFormat_RGB24;
IMFActivate **transformActivateArray = NULL;
UINT32 MFTcount;
hr = MFTEnumEx(MFT_CATEGORY_VIDEO_PROCESSOR, MFT_ENUM_FLAG_ALL, inputVideoTypes, outputVideoTypes, &transformActivateArray, &MFTcount);
hr = VP->GetAttributes(&VPAttributes);
hr = VPAttributes->SetUINT32(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK, TRUE);
hr = VP->SetInputType(0, streamType2, 0);
MediaFoundationSamples::LogMediaType(streamType2);
DWORD dwIndex = 4;
hr = VP->GetOutputAvailableType(0, dwIndex, &streamType3);
hr = MFSetAttributeSize(streamType3, MF_MT_FRAME_SIZE, 1280, 720);
hr = streamType3->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, 1);
hr = MFSetAttributeRatio(streamType3, MF_MT_FRAME_RATE, 30, 1);
hr = MFSetAttributeRatio(streamType3, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
streamType3->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
streamType3->SetUINT32(MF_MT_INTERLACE_MODE, 2);
MediaFoundationSamples::LogMediaType(streamType3);
hr = VP->SetOutputType(0, streamType3, 0);
hr = VP->GetInputStreamInfo(0, &InputInfo);
hr = VP->GetOutputStreamInfo(0, &OutputInfo);

InOnReadSample:

hr = VP->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL);
hr = VP->ProcessInput(0, sample, 0);
DWORD statusFlags;
hr = VP->GetOutputStatus(&statusFlags);
while (statusFlags == 0)

    hr = VP->ProcessInput(0, sample, 0);
    hr = VP->GetOutputStatus(&statusFlags);

DWORD outputStatus = 0;
IMFSample* outputSample;
MFCreateSample(&outputSample);
MFT_OUTPUT_DATA_BUFFER outputBuffer = ;
outputBuffer.pSample = outputSample;
hr = VP->ProcessOutput(0, 1, &outputBuffer, &outputStatus);

但问题是 ProcessOutput 返回 hr = E_INVALIDARG,我不知道为什么。奇怪的是OutputInfo 和InputInfo。两个 dwFlags 都是 0,但它们的 cbSize 似乎正常。

媒体类型日志:

输入(streamType2):

MF_MT_FRAME_SIZE    1280 x 720
MF_MT_YUV_MATRIX    2
MF_MT_MAJOR_TYPE    MFMediaType_Video
MF_MT_VIDEO_LIGHTING    3
MF_MT_VIDEO_CHROMA_SITING   1
MF_MT_AM_FORMAT_TYPE    F72A76A0-EB0A-11D0-ACE4-0000C0CC16BA
MF_MT_FIXED_SIZE_SAMPLES    1
MF_MT_VIDEO_NOMINAL_RANGE   1
MF_MT_FRAME_RATE    30 x 1
MF_MT_PIXEL_ASPECT_RATIO    1 x 1
MF_MT_ALL_SAMPLES_INDEPENDENT   1
MF_MT_FRAME_RATE_RANGE_MIN  128849018881
MF_MT_VIDEO_PRIMARIES   2
MF_MT_INTERLACE_MODE    2
MF_MT_FRAME_RATE_RANGE_MAX  128849018881
EA031A62-8BBB-43C5-B5C4-572D2D231C18  1
MF_MT_SUBTYPE   MFVideoFormat_NV12

输出(streamType3):

MF_MT_FRAME_SIZE    1280 x 720
MF_MT_MAJOR_TYPE    MFMediaType_Video
MF_MT_FIXED_SIZE_SAMPLES    1
MF_MT_FRAME_RATE    30 x 1
MF_MT_PIXEL_ASPECT_RATIO    1 x 1
MF_MT_ALL_SAMPLES_INDEPENDENT   1
MF_MT_INTERLACE_MODE    2
MF_MT_SUBTYPE   MFVideoFormat_RGB24

有人能告诉我我做错了什么吗?

谢谢!

【问题讨论】:

您是否尝试过让视频处理器转换分配输出样本? IE。注释掉以下行: outputBuffer.pSample = outputSample; 是的,我试过了,但是没用。 如果您确定 VP 是视频处理器 MFT,那么它可能需要 3D 管理器和输出的 directx 表面样本 我需要做什么才能提供 3D Manager 和那些表面样本?我是按照docs.microsoft.com/pl-pl/windows/desktop/medfound/…做的,没有提到类似的事情 【参考方案1】:

您尝试在未设置 Direct3D 感知的情况下转换缓冲区。这对于内存缓冲区来说很好,在这种模式下,您通常应该自己提供输入和输出缓冲区。零OutputInfo.dwFlags 恰恰表明了这一点。

因此,您的MFT_OUTPUT_DATA_BUFFER::pSample 初始化是正确的,但是您要提交什么样的样本以供输出?这是一个没有附加缓冲液的样本。因此,无效的论点。

使用MFCreateMemoryBuffer 为您的输出RGB24 样本分配内存,然后在ProcessOutput 调用中使用它。

【讨论】:

以上是关于E_INVALIDARG 而 IMFTransform::ProcessOutput的主要内容,如果未能解决你的问题,请参考以下文章

CoCreateInstance 返回 E_INVALIDARG

IMFTransform::ProcessOutput 返回 E_INVALIDARG

IAudioClient::Initialize 返回 (E_InvalidArg,0x80070057,-2147024809)

如何填充常量着色器以避免 E_INVALIDARG?

E_INVALIDARG 一个或多个参数无效。 dx11 创建输入布局

参数错误。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))