如何检查媒体基础是否真的可以播放文件而不仅仅是加载它

How to check if Media Foundation can actually play a file and not just load it

我在使用 MPEG1 视频和 Media Foundation 时遇到了一些问题:因此 Media Foundation 不支持播放 MPEG1 视频流 (see here),但出于某种原因它仍会打开它们并且它将甚至报告正确的持续时间和帧大小。所以在开放时间一切看起来都可以播放这些文件。

但是不能!一旦您尝试实际播放 MPEG1 视频文件,IMFAsyncCallback::Invoke() 将以 MESessionTopologySet 的状态被调用,然后 IMFMediaEvent::GetStatus() 将 return 0xc004f011 就是这样。

那么有什么方法可以检查 Media Foundation 打开视频格式后是否真的可以播放视频格式,或者有什么方法可以让 Media Foundation 只打开它可以打开的文件真的可以玩吗?目前我只能通过尝试开始播放来判断一个文件是否可以播放,然后看看它是否有效,这有点不方便。我希望能够判断一个文件是否可以更早播放。

我现在已经使用 IMFSourceReader 解决了这个问题。我发现尝试将媒体类型设置为 MFVideoFormat_RGB32 将对 MPEG1 视频流失败,但它对 MPEG4 可以正常工作,因此这可能是检查 Media Foundation 是否可以实际播放文件的可行方法。在代码中,解决方案如下所示:

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);
}