首页 > 解决方案 > 如何检查 Media Foundation 是否可以实际播放文件而不仅仅是加载它

问题描述

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

但它不能!一旦您尝试实际播放 MPEG1 视频文件,IMFAsyncCallback::Invoke()将调用状态为MESessionTopologySet,然后IMFMediaEvent::GetStatus()将返回 0xc004f011,仅此而已。

那么有没有办法检查媒体基金会打开后是否可以真正播放视频格式,或者有没有办法让媒体基金会只打开它实际可以播放的文件?目前我只能通过尝试开始播放来判断文件是否可以播放,然后查看它是否有效,这有点不方便。我希望能够更早地判断文件是否可以播放。

标签: c++windowswinapivideoms-media-foundation

解决方案


我现在已经通过使用解决了这个问题IMFSourceReader。我发现尝试将媒体类型设置为MFVideoFormat_RGB32MPEG1 视频流会失败,但它会在 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);
}

推荐阅读