- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm having problems running Intel® Quick Sync Video H.264 Encoder MFT. The setup, ProcessInput and ProcessOutput are all returning S_OK but the sample from ProcessOutput is NULL and the status is MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE. Any idea what could be wrong?
This is the output:
Intel® Quick Sync Video H.264 Encoder MFT
Start encoding
ProcessInput frame 1
ProcessInput frame 2
ProcessInput frame 3
ProcessInput frame 4
ProcessOutput MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
from the following code (ignore any leaks that are unrelated to my issue):
void main() { HRESULT hr = S_OK; hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) { OutputDebugString(L"CoInitializeEx failed\n"); return; } hr = MFStartup(MF_VERSION); if (FAILED(hr)) { OutputDebugString(L"MFStartup failed\n"); return; } IMFActivate **devices = NULL; IMFTransform *encoder = NULL; IMFMediaEventGenerator *eventGenerator = NULL; GUID inFormat = MFVideoFormat_NV12; GUID outFormat = MFVideoFormat_H264; MFT_REGISTER_TYPE_INFO inputInfo = { MFMediaType_Video, inFormat }; MFT_REGISTER_TYPE_INFO outputInfo = { MFMediaType_Video, outFormat }; uint32_t flags = MFT_ENUM_FLAG_HARDWARE; uint32_t count; uint32_t fps = 25; uint32_t width = 1280; uint32_t height = 720; IMFAttributes *attributes; uint32_t asynch; uint32_t len = 0; MFCalculateImageSize(inFormat, width, height, &len); hr = MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, flags, &inputInfo, &outputInfo, &devices, &count); if (FAILED(hr)) { OutputDebugString(L"MFTEnumEx failed\n"); return; } if (count == 0) { OutputDebugString(L"No devices\n"); return; } LPWSTR szFriendlyName = NULL; hr = devices[0]->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &szFriendlyName, NULL); OutputDebugString(szFriendlyName); OutputDebugString(L"\n"); hr = devices[0]->ActivateObject(IID_PPV_ARGS(&encoder)); if (FAILED(hr)) { OutputDebugString(L"ActivateObject failed\n"); return; } for (size_t idx = 0; idx < count; ++idx) { devices[idx]->Release(); } CoTaskMemFree(devices); encoder->QueryInterface(&eventGenerator); hr = encoder->GetAttributes(&attributes); if (FAILED(hr)) { return; } hr = attributes->GetUINT32(MF_TRANSFORM_ASYNC, &asynch); hr = attributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE); attributes->Release(); if (FAILED(hr)) { return; } DWORD inputCount = 0, outputCount = 0, inputId = 0, outputId = 0; hr = encoder->GetStreamCount(&inputCount, &outputCount); if (FAILED(hr)) { return; } if (inputCount == 0 || outputCount == 0) { return; } DWORD *inputIds = new DWORD[inputCount]; DWORD *outputIds = new DWORD[outputCount]; hr = encoder->GetStreamIDs(inputCount, inputIds, outputCount, outputIds); auto cleanStreamIds = [&inputIds, &outputIds] { delete[] inputIds; inputIds = NULL; delete[] outputIds; outputIds = NULL; }; if (FAILED(hr)) { if (hr != E_NOTIMPL) { OutputDebugString(L"GetStreamIDs failed\n"); cleanStreamIds(); return; } } else { inputId = inputIds[0]; outputId = outputIds[0]; } cleanStreamIds(); IMFMediaType *outputType = NULL; hr = MFCreateMediaType(&outputType); if (FAILED(hr)) { OutputDebugString(L"MFCreateMediaType outputType failed\n"); return; } hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); hr = outputType->SetGUID(MF_MT_SUBTYPE, outFormat); hr = outputType->SetUINT32(MF_MT_AVG_BITRATE, 10000000); hr = MFSetAttributeSize(outputType, MF_MT_FRAME_SIZE, width, height); hr = MFSetAttributeRatio(outputType, MF_MT_FRAME_RATE, fps, 1); hr = outputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); hr = outputType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_High); hr = outputType->SetUINT32(MF_MT_MPEG2_LEVEL, eAVEncH264VLevel3_1); hr = outputType->SetUINT32(CODECAPI_AVEncCommonRateControlMode, eAVEncCommonRateControlMode_CBR); hr = encoder->SetOutputType(outputId, outputType, 0); if (FAILED(hr)) { OutputDebugString(L"SetOutputType failed\n"); return; } IMFMediaType *inputType = NULL; hr = MFCreateMediaType(&inputType); if (FAILED(hr)) { OutputDebugString(L"MFCreateMediaType inputType failed\n"); return; } hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); hr = inputType->SetGUID(MF_MT_SUBTYPE, inFormat); hr = inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); hr = MFSetAttributeSize(inputType, MF_MT_FRAME_SIZE, width, height); hr = MFSetAttributeRatio(inputType, MF_MT_FRAME_RATE, fps, 1); hr = MFSetAttributeRatio(inputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1); hr = encoder->SetInputType(inputId, inputType, 0); if (FAILED(hr)) { OutputDebugString(L"SetInputType failed\n"); return; } hr = encoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0); hr = encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); hr = encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); OutputDebugString(L"Start encoding\n"); uint32_t frame = 1; IMFMediaEvent *event = NULL; MediaEventType type; do { hr = eventGenerator->GetEvent(0, &event); hr = event->GetType(&type); switch (type) { case METransformNeedInput: { IMFSample *newSample = NULL; IMFMediaBuffer *buffer; hr = MFCreateMemoryBuffer(len, &buffer); byte *bufferData; hr = buffer->Lock(&bufferData, NULL, NULL); memset(bufferData, 0, len); hr = buffer->Unlock(); hr = buffer->SetCurrentLength(len); hr = MFCreateSample(&newSample); hr = newSample->AddBuffer(buffer); uint64_t sampleDuration = 0; MFFrameRateToAverageTimePerFrame(fps, 1, &sampleDuration); newSample->SetSampleDuration(sampleDuration); hr = encoder->ProcessInput(0, newSample, 0); if (FAILED(hr)) { OutputDebugString(L"ProcessInput failed\n"); return; } else { WCHAR outMessage[128]; memset(outMessage, 0, 128 * sizeof(WCHAR)); wsprintf(outMessage, L"ProcessInput frame %u\n", frame); OutputDebugString(outMessage); ++frame; } break; } case METransformHaveOutput: { MFT_OUTPUT_DATA_BUFFER data = { outputId, NULL, 0, NULL }; MFT_OUTPUT_STREAM_INFO outInfo; hr = encoder->GetOutputStreamInfo(outputId, &outInfo); if (!(outInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)) { OutputDebugString(L"!MFT_OUTPUT_STREAM_PROVIDES_SAMPLES not handled\n"); return; } DWORD status = 0; hr = encoder->ProcessOutput(MFT_OUTPUT_STREAM_PROVIDES_SAMPLES, 1, &data, &status); if (FAILED(hr)) { OutputDebugString(L"ProcessOutput failed\n"); return; } if (data.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE) { OutputDebugString(L"ProcessOutput MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE\n"); return; } break; } default: break; } } while (true); }
Also, here is the output from mediasdk_ss_analyzer:
The following versions of Media SDK API are supported by platform/driver
[opportunistic detection of MSDK API > 1.16]:
Version Target Supported Dec Enc
1.0 HW Yes X X
1.0 SW Yes X X
1.1 HW Yes X X
1.1 SW Yes X X
1.2 HW Yes X X
1.2 SW Yes X X
1.3 HW Yes X X
1.3 SW Yes X X
1.4 HW Yes X X
1.4 SW Yes X X
1.5 HW Yes X X
1.5 SW Yes X X
1.6 HW Yes X X
1.6 SW Yes X X
1.7 HW Yes X X
1.7 SW Yes X X
1.8 HW Yes X X
1.8 SW Yes X X
1.9 HW Yes X X
1.9 SW Yes X X
1.10 HW Yes X X
1.10 SW Yes X X
1.11 HW Yes X X
1.11 SW Yes X X
1.12 HW Yes X X
1.12 SW Yes X X
1.13 HW Yes X X
1.13 SW Yes X X
1.14 HW Yes X X
1.14 SW Yes X X
1.15 HW Yes X X
1.15 SW Yes X X
1.16 HW Yes X X
1.16 SW Yes X X
1.17 HW Yes X X
1.17 SW Yes X X
Graphics Devices:
Name Version State
Intel(R) HD Graphics 20.19.15.4320 Active
System info:
CPU: Intel(R) Pentium(R) CPU N3700 @ 1.60GHz
OS: Microsoft Windows 10 Home Single Language
Arch: 64-bit
Installed Media SDK packages (be patient...processing takes some time):
Intel(R) Media Samples 6.0.0.68
Intel(R) Media SDK 2016
Analysis complete... [press ENTER]
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bogdan,
Thank you for sharing the detailed log of your system. Looking into issue and based on our investigation, the status returned "MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE" is not specifically due to hardware MFT (Intel® Quick Sync Video H.264 Encoder MFT) but due to no MFT sample ready for this stream.
For MSFT website reference here: https://technet.microsoft.com/es-es/ms704014, "If the MFT has multiple output streams, the streams might produce output at different rates, so some streams might have output while other streams do not. If a stream did not any produce output, the MFT sets the MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE flag in the dwStatus member of the MFT_OUTPUT_DATA_BUFFER structure for that stream". I suggest checking with MSFT support team on this issue. Hope this information helps.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Harsh,
Thank you for your answer.
The MFT has only 1 output stream (only 1 input stream too).
Also, running the same code with an NVIDIA hardware MFT, I have no issues on getting encoded frames (below is the output from it):
NVIDIA H.264 Encoder MFT
Start encoding
ProcessInput frame 1
ProcessOutput Got output
ProcessInput frame 2
ProcessOutput Got output
ProcessInput frame 3
.....
Thanks,
Bogdan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bogdan,
Thank you for sharing this information. If the MFT has only 1 output stream, then further investigation is needed. Can you please share a log from mediasdk_tracer (https://software.intel.com/en-us/articles/media-sdk-tools). Also, I have shared a tool via private message. Please share the logs from the tools, where logs could provide us more visibility into this issue.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bogdan,
Thank you for the log. Please check you inbox for Intel forum messages and I did re-send the message again too. Also, after brief look at the code (above) I suspect the issue is caused by MFT_OUTPUT_STREAM_PROVIDES_SAMPLES flag as it is not supported by Intel H.264 Encoder HMFT. Please try and remove this flag to isolate the problem, let me know how it goes.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
EDIT: Never mind. In my case it was a problem with the encoder wanting to renegotiate the output format and my code miscounting the METransformHaveOutput callbacks.
Hey,
I have the exact same problem, and it's clearly not related to the MFT_OUTPUT_STREAM_PROVIDES_SAMPLES flag - providing a sample in the MFT_OUTPUT_DATA_BUFFER structure doesn't help.
My code is completely independent from Bogdan's, and it's working flawlessly on NVidia/AMD GPUs and Microsoft's software encoder MFT, so there's definitely something fishy going on there.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page