ms-media-foundation

MFCreateSinkWriterFromURL fails when MFCreateMPEG4MediaSink succeeds


There are two ways to create a IMFSinkWriter:

With MFCreateMPEG4MediaSink

winrt::com_ptr<IMFByteStream> outputStream;
winrt::check_hresult(MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, L"D:\\Documents\\test.mp4", outputStream.put()));
winrt::com_ptr<IMFMediaSink> mp4StreamSink;
winrt::check_hresult(MFCreateMPEG4MediaSink(outputStream.get(), m_videoOut.get(), NULL, mp4StreamSink.put()));
winrt::com_ptr<IMFSinkWriter> sinkWriter;
winrt::check_hresult(MFCreateSinkWriterFromMediaSink(mp4StreamSink.get(), m_containter_attributes.get(), sinkWriter.put()));
sinkWriter->SetInputMediaType(0, m_videoIn.get(), nullptr);

With MFCreateSinkWriterFromURL

winrt::com_ptr<IMFSinkWriter> pSinkWriterVideo;
winrt::check_hresult(MFCreateSinkWriterFromURL(L"D:\\Documents\\test2.mp4", NULL, m_containter_attributes.get(), pSinkWriterVideo.put()));
winrt::check_hresult(pSinkWriterVideo->AddStream(m_videoOut.get(), &m_videoStreamIndex));
// BOOM! when size is irregular
winrt::check_hresult(pSinkWriterVideo->SetInputMediaType(m_videoStreamIndex, m_videoIn.get(), nullptr /*encoder attributes*/));

If MF_MT_FRAME_SIZE is set to {1920, 1080} both succeed. But if set to {1922, 1089} then just the MFCreateSinkWriterFromURL alternative fails. To be clear it fails at IMFSinkWriter::SetInputMediaType.

Repro: https://github.com/tom-huntington/ConsoleApplication13MediaStreamSource


Solution

  • IMFSinkWriter::WriteSample fails when writing with an odd height.

    It's probably about 1089 being odd. Note that U, V components of H.264 are normally subsampled 4:2:0 and hence odd heights might be a problem.