maksylon
maksylon

Reputation: 49

E_INVALIDARG while IMFTransform::ProcessOutput

I am struggling to make cartoon shader in Media Foundation, and to do so I need to convert NV12 provided by my camera natively to RGB24. By far my tries with IMFTransform looks like this: Setup:

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);

But the problem is that ProcessOutput returns hr = E_INVALIDARG and I have no idea why. Weird things are OutputInfo and InputInfo. both dwFlags are 0, but their cbSize seems normal.

Logs of MediaTypes:

input (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

output (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

Is anyone able to tell me what I am doing wrong?

Thank you!

Upvotes: 0

Views: 408

Answers (1)

Roman Ryltsov
Roman Ryltsov

Reputation: 69672

You try to convert buffers without setting up Direct3D awareness. This is fine for memory buffers and in this mode you are typically supposed to provide both input and output buffers yourselves. Zero OutputInfo.dwFlags suggests exactly this.

So you are on the right track there with your MFT_OUTPUT_DATA_BUFFER::pSample initialization but what kind of sample you are submitting for output? It is a sample with no buffer attached. Hence, invalid argument.

Use MFCreateMemoryBuffer to allocate memory for your output RGB24 sample and then use it in ProcessOutput call.

Upvotes: 2

Related Questions