IMFSinkWriter can't export a large size video

2019-05-10 04:46发布

问题:

My Windows MFC application has a function to export a video file.
And it can select encoding format (via WMV or MP4) and frame size.
But, Unfortunately when i tried to export MP4 file which is set large frame size, everytime MF_E_INVALIDMEDIATYPE happened.

Simply put, here is the result when i tested in each case.

WMV

  • 640 x 480 ... OK
  • 640 x 576 ... OK
  • 1280 x 720 ... OK
  • 1280 x 720 ... OK
  • 1920 x 1080 ... OK
  • 2048 x 1556 ... OK
  • 4096 x 2160 ... OK

MP4

  • 640 x 480 ... OK
  • 640 x 576 ... OK
  • 1280 x 720 ... OK
  • 1280 x 720 ... OK
  • 1920 x 1080 ... OK
  • 2048 x 1556 ... MF_E_INVALIDMEDIATYPE
  • 4096 x 2160 ... MF_E_INVALIDMEDIATYPE

And here is my code.

HRESULT hr = S_OK;
TIFF *out;
IMFSinkWriter   *pWriter = NULL;
IMFMediaType    *pMediaTypeOut = NULL;   
IMFMediaType    *pMediaTypeIn = NULL;   
DWORD           streamIndex;     

hr = MFCreateSinkWriterFromURL(filename, NULL, NULL, &pWriter);

// Set the output media type.
if (SUCCEEDED(hr))
{
  hr = MFCreateMediaType(&pMediaTypeOut);   
}
if (SUCCEEDED(hr))
{
  hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);     
}
if (SUCCEEDED(hr))
{
  if (exportMethod == ExportFormatWAV) {
    hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_WVC1);
  }
  else if (exportMethod == ExportFormatMP4) {
    hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);   
  }
}
if (SUCCEEDED(hr))
{
  hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, 12 * 1000 * 1000); // 12M   
}
if (SUCCEEDED(hr))
{
  hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);   
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, m_width, m_height);   // e.g. 4096 x 2160
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, m_fps * 100, 100);   
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);   
}
if (SUCCEEDED(hr))
{
  hr = pWriter->AddStream(pMediaTypeOut, &streamIndex);   
}

// Set the input media type.
if (SUCCEEDED(hr))
{
  hr = MFCreateMediaType(&pMediaTypeIn);   
}
if (SUCCEEDED(hr))
{
  hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);   
}
if (SUCCEEDED(hr))
{
  if (exportMethod == ExportFormatWAV) {
    hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24);   
  }
  else if (exportMethod == ExportFormatMP4) {
    hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);     // Because H264 requires
  }
}
if (SUCCEEDED(hr))
{
  hr = pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);   
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, m_width, m_height);   // e.g. 4096 x 2160
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, m_fps * 100, 100);   
}
if (SUCCEEDED(hr))
{
  hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);   
}
if (SUCCEEDED(hr))
{
  hr = pWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);   // This line returns MF_E_INVALIDMEDIATYPE
}

// Tell the sink writer to start accepting data.
if (SUCCEEDED(hr))
{
  hr = pWriter->BeginWriting();
}

I want to export a large sized video of MP4 as well.
Does anyone know a solution against this problem?

References
https://msdn.microsoft.com/en-us/library/windows/desktop/ff819477(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ff819476(v=vs.85).aspx

Oct 13th 2015

Same question has already posted msdn.
https://social.msdn.microsoft.com/Forums/en-US/ac5b71e4-e94a-4d18-bc92-8b44fa5280b6/the-max-resolution-for-mp4h264-encoder

回答1:

Media Foundation's MPEG-4 File Sink has no resolution restrictions. It multiplexes already encoded data and is not sensitive to video resolution.

If/when you, however, are encoding H.264 context, the encoders typically do have the limitations. For example, Intel(R) HD Graphics 4600's Intel® Quick Sync Video H.264 Encoder MFT can produce 4096 x 4096 H.264 content, and MP4 sink writes it correctly to file.

In your case you are likely to hit resolution limit in encoder, and since encoder rejects unsupported resolution with generic error code, you don't have anything more helpful than MF_E_INVALIDMEDIATYPE. You might have better luck with an alternate encoder.