I'm having some problems with MPEG1 videos and Media Foundation: So Media Foundation doesn't support playback of MPEG1 video streams (see here), but for some reason it will still open them and it will even report the correct duration and frame size. So at opening time everything looks like it can play those files.
But it can't! Once you try to actually play the MPEG1 video file, IMFAsyncCallback::Invoke()
will be called with a status of MESessionTopologySet
and then IMFMediaEvent::GetStatus()
will return 0xc004f011 and that's about it.
So is there any way to check if a video format can actually be played by Media Foundation after opening it or is there any way to make Media Foundation only open files that it can actually play? Currently I can only tell if a file can be played or not by attempting to start playback and then see if it works or not which is somewhat inconvenient. I'd like to be able to tell if a file can be played or not much earlier.
I have solved this now by using IMFSourceReader
. I have found out that trying to set the media type to MFVideoFormat_RGB32
will fail with MPEG1 video streams but it will work fine with MPEG4 so this is probably a feasible way to check if Media Foundation can actually play a file. In code, the solution looks like this:
hr = MFCreateAttributes(&pAttr, 1);
if(SUCCEEDED(hr)) {
IMFAttributes_SetUINT32(pAttr, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
IMFAttributes_SetUINT32(pAttr, &MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE);
hr = MFCreateSourceReaderFromURL(filename, pAttr, &pReader);
if(SUCCEEDED(hr)) {
hr = IMFSourceReader_GetCurrentMediaType(pReader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pFileVideoMediaType);
if(SUCCEEDED(hr)) {
hr = MFCreateMediaType(&pTypeUncomp);
if(SUCCEEDED(hr)) {
IMFMediaType_CopyAllItems(pFileVideoMediaType, (IMFAttributes *) pTypeUncomp);
IMFMediaType_SetGUID(pTypeUncomp, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
IMFMediaType_SetUINT32(pTypeUncomp, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
IMFMediaType_SetUINT32(pTypeUncomp, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
hr = IMFSourceReader_SetCurrentMediaType(pReader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, pTypeUncomp);
if(SUCCEEDED(hr)) printf("NOT AN MPEG1 STREAM!\n");
}
}
}
SAFERELEASE(&pAttr);
}
User contributions licensed under CC BY-SA 3.0