We have existing functionality in an application for writing uncompressed images generated from a screen capture to an mp4 file. The functionality is largely based on the Sink Writer tutorial. The functionality has worked well on any Windows 7 machine, but seems to be failing consistently on Windows 8.1 or Windows 10. The failure occurs when calling SetMediaInputType on the IMFSinkWriter, where MF_E_INVALIDMEDIATYPE is always returned. This result persists if the encoding format is changed (to MFVideoFormat_WMV3 for instance), if the size of the image to be written to file is reduced, if frame rate is modified, etc. A snapshot of the code where the IMFSinkWriter is initialized follows:
const UINT32 VIDEO_FPS = 30;
const UINT64 VIDEO_FRAME_DURATION = 10 * 1000 * 1000 / VIDEO_FPS;
const UINT32 VIDEO_BIT_RATE = 800000;
const GUID VIDEO_ENCODING_FORMAT = MFVideoFormat_H264;
const GUID VIDEO_INPUT_FORMAT = MFVideoFormat_RGB32;
HRESULT CMP4Writer::InitializeMFWriter(WCHAR * filename, int frameWidth, int frameHeight, int frameRate)
{
IMFMediaType *pMediaTypeOut = NULL;
IMFMediaType *pMediaTypeIn = NULL;
DWORD streamIndex;
wchar_t * pBuffer = 0;
HRESULT hr = S_OK;
CHECK_HR(hr = MFCreateSinkWriterFromURL(filename, NULL, NULL, &m_pWriter));
CHECK_HR(hr = MFCreateMediaType(&pMediaTypeOut));
CHECK_HR(hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
CHECK_HR(hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, VIDEO_ENCODING_FORMAT));
CHECK_HR(hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, frameHeight * frameWidth * VIDEO_FPS * 4 * 32));
CHECK_HR(hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
CHECK_HR(hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, frameWidth, frameHeight));
CHECK_HR(hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1));
CHECK_HR(hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
CHECK_HR(hr = pMediaTypeOut->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Main));
CHECK_HR(hr = m_pWriter->AddStream(pMediaTypeOut, &streamIndex));
CHECK_HR(hr = MFCreateMediaType(&pMediaTypeIn));
CHECK_HR(hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
CHECK_HR(hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT));
CHECK_HR(hr = pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
CHECK_HR(hr = pMediaTypeIn->SetUINT32(MF_MT_DEFAULT_STRIDE, 4 * frameWidth));
UINT cbImage = 0;
CHECK_HR(hr = MFCalculateImageSize(VIDEO_INPUT_FORMAT, frameWidth, frameHeight, &cbImage));
CHECK_HR(hr = pMediaTypeIn->SetUINT32(MF_MT_SAMPLE_SIZE, cbImage));
CHECK_HR(hr = pMediaTypeIn->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE));
CHECK_HR(hr = pMediaTypeIn->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE));
CHECK_HR(hr = MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, frameWidth, frameHeight));
CHECK_HR(hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, VIDEO_FPS, 1));
CHECK_HR(hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
CHECK_HR(hr = m_pWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL));
CHECK_HR(hr = m_pWriter->BeginWriting());
SafeRelease(&pMediaTypeOut);
SafeRelease(&pMediaTypeIn);
return 0;
}
Frankle