Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 配置MPEG4MediaSink_C++_Windows_Ms Media Foundation - Fatal编程技术网

C++ 配置MPEG4MediaSink

C++ 配置MPEG4MediaSink,c++,windows,ms-media-foundation,C++,Windows,Ms Media Foundation,我正在尝试构建一个简单的WMF演示应用程序,它使用媒体源、管道和媒体接收器来复制MP4文件。以下是基本程序 创建媒体源,并从中获取表示描述符 从中获取第一个活动视频和音频流描述符 表示描述符 从每个流中获取当前视频和音频IMFMediaTypes 描述符。检查表明视频媒体子类型为H264 音频媒体子类型为AAC 使用两种介质MFCreateMPEG4MediaSink打开介质接收器 类型和输出文件名 使用流和流设置视频和音频源节点 表示描述符 使用媒体接收器设置视频和音频接收器节点 将所有节点添

我正在尝试构建一个简单的WMF演示应用程序,它使用媒体源、管道和媒体接收器来复制MP4文件。以下是基本程序

  • 创建媒体源,并从中获取表示描述符
  • 从中获取第一个活动视频和音频流描述符 表示描述符
  • 从每个流中获取当前视频和音频IMFMediaTypes 描述符。检查表明视频媒体子类型为H264 音频媒体子类型为AAC
  • 使用两种介质MFCreateMPEG4MediaSink打开介质接收器 类型和输出文件名
  • 使用流和流设置视频和音频源节点 表示描述符
  • 使用媒体接收器设置视频和音频接收器节点
  • 将所有节点添加到拓扑中
  • 将源节点连接到接收器节点
  • 构建拓扑并运行
  • 在媒体会话回调中,我得到的错误是MF_E_INVALIDMEDIATYPE。如果我注释掉音频流,将空值输入到音频类型的MFCreateMPEG4MediaSink调用中,并且不为其设置任何节点,则复制工作正常–我可以播放生成的mp4文件,该文件仅包含视频

    MPEG4MediaSink应该能够处理AAC音频。但是,我怀疑媒体类型中存在它不喜欢的内容(请记住,它是直接从源流派生而来的,没有任何更改)

    如果您能就如何使音频流正常工作提出见解或建议,我将不胜感激


    我已经使用MFCreateMP3MediaSink成功地对MP3文件进行了类似的复制,但这种情况下的媒体类型是MP3。

    在Mediafoundation示例中,您有LogMediaType函数

    你能给我们看一下AAC音频的MediaType日志吗

    通常,以下是AAC所需的一些属性(某些值可能不同):

    • MF\U MT\U主要类型:MFMediaType\U音频
    • MF\U MT\U子类型:MFAudioFormat\U AAC或MEDIASUBTYPE\U RAW\U AAC1
    • MF\u MT\u音频\u首选\u波形:正确
    • MF\U MT\U AAC\U有效负载类型:0
    • MF\U MT\U AAC\U音频配置文件\U电平\U指示:0
    • 音频频道:6个
    • 音频采样率:每秒48000
    • 音频块对齐:24
    • 音频平均字节/秒:1152000
    • MF\u MT\u音频\u位\u每个样本:32
    • 音频通道屏蔽:63
    • MF_MT_USER_DATA:byte array==AudioSpecificConfig(取决于MFAudioFormat_AAC或MEDIASUBTYPE_RAW_AAC1)
    在SourceResolver中,您还可以看到以下属性:

    • MF\u MT\u MPEG4\u示例\u说明:字节数组
    • MF\U MT\U MPEG4\u当前\u样本\u条目:0
    • MF\u MT\u平均比特率:x
    • MF\U MT\U AM\U格式\U类型:clsid
    • MF\u MT\u所有样本\u独立:1
    • MF\U MT\U固定尺寸\U样品:1
    • MF\U MT\U样本大小:1
    使用Microsoft提供的对象时,MF_MT_USER_数据非常重要。如果缺少某些属性,请尝试手动添加它们

    EDIT1


    是否将音频源节点连接到右侧IMFStreamLink。您是否使用了IMFMediaSink中的正确索引?

    谢谢大家的帮助!!本例中的问题是在创建输出节点时使用了硬编码流索引0。在我的辩护中,各种WMF样本似乎只演示了每个接收器一个流,因此使用硬编码流索引0。我的代码基于这些示例,并将该部分分解到实用程序库中,但很快就忘记了它是一个特例。当然,MP4接收器使用两个流,在解析拓扑时,流索引0用于音频中断

    这里是我的音频媒体类型的设置。一旦我对streamsink问题进行了分类,这种媒体类型配置就可以正常工作。这些问题被分解为与上述示例音频媒体类型内容相同、不同、额外和缺失的项目

    相同

    MF_MT_MAJOR_TYPE=MFMediaType_Audio (73647561-0000-0010-8000-00aa00389b71)
    MF_MT_SUBTYPE=AAC (00001610-0000-0010-8000-00aa00389b71)
    MF_MT_AUDIO_PREFER_WAVEFORMATEX=1
    MF_MT_AAC_PAYLOAD_TYPE=0
    MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION=0
    MF_MT_AUDIO_NUM_CHANNELS=6
    MF_MT_AUDIO_SAMPLES_PER_SECOND=48000
    
    不同

    MF_MT_AUDIO_BLOCK_ALIGNMENT=1
    MF_MT_AUDIO_AVG_BYTES_PER_SECOND=47995
    MF_MT_AUDIO_BITS_PER_SAMPLE=16
    
    未知

    MF_MT_USER_DATA=00,00,00,00,00,00,00,00,00,00,00,00,11,b0
    
    额外的

    MF_MT_AVG_BITRATE=383960
    MF_MT_MPEG4_SAMPLE_DESCRIPTION=00,00,00,67,73,74,73,64,00,00,00,00,00,00,00,01...
    MF_MT_AM_FORMAT_TYPE=Unknown (05589f81-c356-11ce-bf01-00aa0055595a)
    MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY=0
    MF_MT_FIXED_SIZE_SAMPLES=1
    MF_MT_ALL_SAMPLES_INDEPENDENT=1
    MF_MT_SAMPLE_SIZE=1
    
    缺失

    MF_MT_AUDIO_CHANNEL_MASK : 63
    

    只是为了好玩,我以一种快速的方式重写了您的程序:

    //----------------------------------------------------------------------------------------------
    // Main.cpp
    //----------------------------------------------------------------------------------------------
    #pragma once
    #define WIN32_LEAN_AND_MEAN
    #define STRICT
    
    #pragma comment(lib, "mf")
    #pragma comment(lib, "mfplat")
    #pragma comment(lib, "mfuuid")
    
    #include <WinSDKVer.h>
    #include <new>
    #include <windows.h>
    
    #include <mfapi.h>
    #include <mfidl.h>
    #include <wchar.h>
    
    #define MP4_SOURCE_VIDEO_MEDIA_FILE L"big_buck_bunny_720p_50mb.mp4"
    #define MP4_FINAL_VIDEO_MEDIA_FILE L"final.mp4"
    
    HRESULT ProcessConverter(LPCWSTR);
    HRESULT ConfigureSource(LPCWSTR, IMFMediaSource**, IMFMediaType**, IMFMediaType**, IMFTopologyNode**, IMFTopologyNode**);
    HRESULT CreateMediaSource(LPCWSTR, IMFMediaSource**);
    HRESULT ConfigureMediaTypeSource(IMFMediaSource*, IMFPresentationDescriptor*, IMFStreamDescriptor*, IMFMediaType**, IMFMediaType**, IMFTopologyNode**, IMFTopologyNode**);
    HRESULT CreateTopologyNodeSink(IMFMediaSink*, IMFTopologyNode**, IMFTopologyNode**, IMFMediaType*, IMFMediaType*);
    HRESULT CreateSourceStreamNode(IMFMediaSource*, IMFPresentationDescriptor*, IMFStreamDescriptor*, IMFTopologyNode**);
    HRESULT ConfigureSinkNode(IMFMediaTypeHandler*, IMFStreamSink*, IMFTopologyNode**, IMFMediaType*);
    HRESULT ConfigureTopologyNode(IMFTopology*, IMFTopologyNode*, IMFTopologyNode*, IMFTopologyNode*, IMFTopologyNode*);
    HRESULT RunMediaSession(IMFMediaSession*);
    
    template <class T> inline void SAFE_RELEASE(T*& p){
    
        if(p){
            p->Release();
            p = NULL;
        }
    }
    
    void main() {
    
        HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    
        if(SUCCEEDED(hr)) {
    
            hr = MFStartup(MF_VERSION, MFSTARTUP_LITE);
    
            if(SUCCEEDED(hr)) {
    
                hr = ProcessConverter(MP4_SOURCE_VIDEO_MEDIA_FILE);
    
                hr = MFShutdown();
            }
    
            CoUninitialize();
        }
    }
    
    HRESULT ProcessConverter(LPCWSTR wszVideoFile){
    
        HRESULT hr = S_OK;
        IMFMediaSource* pSource = NULL;
        IMFMediaType* pVideoMediaType = NULL;
        IMFMediaType* pAudioMediaType = NULL;
        IMFByteStream* pByteStream = NULL;
        IMFMediaSink* pMediaSink = NULL;
        IMFTopology* pTopology = NULL;
        IMFTopologyNode* pVideoSourceNode = NULL;
        IMFTopologyNode* pAudioSourceNode = NULL;
        IMFTopologyNode* pVideoSinkNode = NULL;
        IMFTopologyNode* pAudioSinkNode = NULL;
        IMFMediaSession* pSession = NULL;
    
        hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, MP4_FINAL_VIDEO_MEDIA_FILE, &pByteStream);
    
        if(FAILED(hr)){ goto done; }
    
        hr = ConfigureSource(wszVideoFile, &pSource, &pVideoMediaType, &pAudioMediaType, &pVideoSourceNode, &pAudioSourceNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = MFCreateMPEG4MediaSink(pByteStream, pVideoMediaType, pAudioMediaType, &pMediaSink);
    
        if(FAILED(hr)){ goto done; }
    
        hr = CreateTopologyNodeSink(pMediaSink, &pVideoSinkNode, &pAudioSinkNode, pVideoMediaType, pAudioMediaType);
    
        if(FAILED(hr)){ goto done; }
    
        hr = MFCreateTopology(&pTopology);
    
        if(FAILED(hr)){ goto done; }
    
        hr = ConfigureTopologyNode(pTopology, pVideoSourceNode, pAudioSourceNode, pVideoSinkNode, pAudioSinkNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = MFCreateMediaSession(NULL, &pSession);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pSession->SetTopology(0, pTopology);
    
        if(FAILED(hr)){ goto done; }
    
        hr = RunMediaSession(pSession);
    
    done:
    
        if(pSession){
    
            hr = pSession->Close();
    
            // todo : normally wait for close event, here just Sleep
            Sleep(1000);
        }
    
        if(pMediaSink){
    
            hr = pMediaSink->Shutdown();
            SAFE_RELEASE(pMediaSink);
        }
    
        if(pSource){
    
            hr = pSource->Shutdown();
            SAFE_RELEASE(pSource);
        }
    
        if(pSession){
    
            hr = pSession->Shutdown();
            SAFE_RELEASE(pSession);
        }
    
        SAFE_RELEASE(pByteStream);
        SAFE_RELEASE(pAudioMediaType);
        SAFE_RELEASE(pVideoMediaType);
    
        SAFE_RELEASE(pAudioSinkNode);
        SAFE_RELEASE(pVideoSinkNode);
        SAFE_RELEASE(pAudioSourceNode);
        SAFE_RELEASE(pVideoSourceNode);
    
        SAFE_RELEASE(pTopology);
    
        return hr;
    }
    
    HRESULT ConfigureSource(LPCWSTR wszVideoFile, IMFMediaSource** ppSource, IMFMediaType** ppVideoMediaType, IMFMediaType** ppAudioMediaType, IMFTopologyNode** ppVideoSourceNode, IMFTopologyNode** ppVAudioSourceNode){
    
        HRESULT hr = S_OK;
        IMFPresentationDescriptor* pPresentationDescriptor = NULL;
        IMFStreamDescriptor* pStreamDescriptor = NULL;
        DWORD dwStreamCount = 0;
        BOOL bSelected = FALSE;
    
        hr = CreateMediaSource(wszVideoFile, ppSource);
    
        if(FAILED(hr)){ goto done; }
    
        hr = (*ppSource)->CreatePresentationDescriptor(&pPresentationDescriptor);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pPresentationDescriptor->GetStreamDescriptorCount(&dwStreamCount);
    
        if(FAILED(hr)){ goto done; }
    
        for(DWORD dwStream = 0; dwStream < dwStreamCount; dwStream++){
    
            hr = pPresentationDescriptor->GetStreamDescriptorByIndex(dwStream, &bSelected, &pStreamDescriptor);
    
            if(FAILED(hr)){
                break;
            }
    
            if(bSelected){
    
                hr = ConfigureMediaTypeSource(*ppSource, pPresentationDescriptor, pStreamDescriptor, ppVideoMediaType, ppAudioMediaType, ppVideoSourceNode, ppVAudioSourceNode);
            }
    
            SAFE_RELEASE(pStreamDescriptor);
    
            if(FAILED(hr) || ((*ppVideoMediaType) && (*ppAudioMediaType))){
                break;
            }
        }
    
    done:
    
        SAFE_RELEASE(pStreamDescriptor);
        SAFE_RELEASE(pPresentationDescriptor);
    
        // We just only if video and audio stream are presents
        if((*ppVideoMediaType) == NULL && (*ppAudioMediaType) == NULL)
            hr = E_FAIL;
    
        return hr;
    }
    
    HRESULT CreateMediaSource(LPCWSTR wszVideoFile, IMFMediaSource** ppSource){
    
        MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
    
        IMFSourceResolver* pSourceResolver = NULL;
        IUnknown* pSource = NULL;
    
        HRESULT hr = MFCreateSourceResolver(&pSourceResolver);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pSourceResolver->CreateObjectFromURL(wszVideoFile, MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, &pSource);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pSource->QueryInterface(IID_PPV_ARGS(ppSource));
    
    done:
    
        SAFE_RELEASE(pSourceResolver);
        SAFE_RELEASE(pSource);
    
        return hr;
    }
    
    HRESULT ConfigureMediaTypeSource(IMFMediaSource* pSource, IMFPresentationDescriptor* pPresentationDescriptor, IMFStreamDescriptor* pStreamDescriptor, IMFMediaType** ppVideoMediaType,
        IMFMediaType** ppAudioMediaType, IMFTopologyNode** ppVideoSourceNode, IMFTopologyNode** ppAudioSourceNode){
    
        HRESULT hr = S_OK;
        IMFMediaTypeHandler* pHandler = NULL;
        IMFMediaType* pMediaType = NULL;
        DWORD dwTypeCount = 0;
        GUID MajorType = GUID_NULL;
    
        hr = pStreamDescriptor->GetMediaTypeHandler(&pHandler);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pHandler->GetMediaTypeCount(&dwTypeCount);
    
        if(FAILED(hr)){ goto done; }
    
        for(DWORD dwType = 0; dwType < dwTypeCount; dwType++){
    
            hr = pHandler->GetMediaTypeByIndex(dwType, &pMediaType);
    
            if(hr == S_OK){
    
                hr = pMediaType->GetMajorType(&MajorType);
    
                if(hr == S_OK){
    
                    if(MajorType == MFMediaType_Video && (*ppVideoMediaType) == NULL){
    
                        hr = pHandler->SetCurrentMediaType(pMediaType);
    
                        if(hr == S_OK){
    
                            //LogMediaType(pMediaType);
    
                            hr = CreateSourceStreamNode(pSource, pPresentationDescriptor, pStreamDescriptor, ppVideoSourceNode);
    
                            if(hr == S_OK){
                                *ppVideoMediaType = pMediaType;
                                (*ppVideoMediaType)->AddRef();
                                break;
                            }
                        }
                    }
                    else if(MajorType == MFMediaType_Audio && (*ppAudioMediaType) == NULL){
    
                        hr = pHandler->SetCurrentMediaType(pMediaType);
    
                        if(hr == S_OK){
    
                            //LogMediaType(pMediaType);
    
                            hr = CreateSourceStreamNode(pSource, pPresentationDescriptor, pStreamDescriptor, ppAudioSourceNode);
    
                            if(hr == S_OK){
                                *ppAudioMediaType = pMediaType;
                                (*ppAudioMediaType)->AddRef();
                                break;
                            }
                        }
                    }
                }
            }
    
            SAFE_RELEASE(pMediaType);
        }
    
    done:
    
        SAFE_RELEASE(pMediaType);
        SAFE_RELEASE(pHandler);
    
        return hr;
    }
    
    HRESULT CreateSourceStreamNode(IMFMediaSource* pSource, IMFPresentationDescriptor* pPresentationDescriptor, IMFStreamDescriptor* pStreamDescriptor, IMFTopologyNode** ppNode){
    
        HRESULT hr = S_OK;
        IMFTopologyNode* pNode = NULL;
    
        hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPresentationDescriptor);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pStreamDescriptor);
    
        if(FAILED(hr)){ goto done; }
    
        *ppNode = pNode;
        (*ppNode)->AddRef();
    
    done:
    
        SAFE_RELEASE(pNode);
    
        return hr;
    }
    
    HRESULT CreateTopologyNodeSink(IMFMediaSink* pMediaSink, IMFTopologyNode** ppVideoSinkNode, IMFTopologyNode** ppAudioSinkNode, IMFMediaType* pVideoMediaType, IMFMediaType* pAudioMediaType){
    
        HRESULT hr = S_OK;
        DWORD dwCount = 0;
        IMFStreamSink* pStreamSink = NULL;
        IMFMediaTypeHandler* pHandler = NULL;
        GUID MajorType = GUID_NULL;
    
        hr = pMediaSink->GetStreamSinkCount(&dwCount);
    
        if(FAILED(hr)){ goto done; }
    
        for(DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++){
    
            hr = pMediaSink->GetStreamSinkByIndex(dwIndex, &pStreamSink);
    
            if(hr == S_OK){
    
                hr = pStreamSink->GetMediaTypeHandler(&pHandler);
    
                if(hr == S_OK){
    
                    hr = pHandler->GetMajorType(&MajorType);
    
                    if(hr == S_OK){
    
                        if(MajorType == MFMediaType_Video)
                            hr = ConfigureSinkNode(pHandler, pStreamSink, ppVideoSinkNode, pVideoMediaType);
                        else if(MajorType == MFMediaType_Audio)
                            hr = ConfigureSinkNode(pHandler, pStreamSink, ppAudioSinkNode, pAudioMediaType);
                    }
    
                    if(hr == S_OK && (*ppVideoSinkNode) != NULL && (*ppAudioSinkNode) != NULL){
                        break;
                    }
                }
    
                SAFE_RELEASE(pHandler);
            }
    
            SAFE_RELEASE(pStreamSink);
        }
    
    done:
    
        SAFE_RELEASE(pHandler);
        SAFE_RELEASE(pStreamSink);
    
        if((*ppVideoSinkNode) == NULL || (*ppAudioSinkNode) == NULL)
                hr = E_FAIL;
    
        return hr;
    }
    
    HRESULT ConfigureSinkNode(IMFMediaTypeHandler* pHandler, IMFStreamSink* pStreamSink, IMFTopologyNode** ppSinkNode, IMFMediaType* pMediaType){
    
        HRESULT hr = S_OK;
        IMFTopologyNode* pNode = NULL;
    
        hr = pHandler->SetCurrentMediaType(pMediaType);
    
        if(FAILED(hr)){ goto done; }
    
        hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pNode->SetObject(pStreamSink);
    
        if(FAILED(hr)){ goto done; }
    
        *ppSinkNode = pNode;
        (*ppSinkNode)->AddRef();
    
    done:
    
        SAFE_RELEASE(pNode);
    
        return hr;
    }
    
    HRESULT ConfigureTopologyNode(IMFTopology* pTopology, IMFTopologyNode* pVideoSourceNode, IMFTopologyNode* pAudioSourceNode, IMFTopologyNode* pVideoSinkNode, IMFTopologyNode* pAudioSinkNode){
    
        HRESULT hr = S_OK;
    
        hr = pTopology->AddNode(pVideoSourceNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pTopology->AddNode(pAudioSourceNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pTopology->AddNode(pVideoSinkNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pTopology->AddNode(pAudioSinkNode);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pVideoSourceNode->ConnectOutput(0, pVideoSinkNode, 0);
    
        if(FAILED(hr)){ goto done; }
    
        hr = pAudioSourceNode->ConnectOutput(0, pAudioSinkNode, 0);
    
    done:
    
        return hr;
    }
    
    HRESULT RunMediaSession(IMFMediaSession* pSession){
    
        HRESULT hr = S_OK;
    
        BOOL bSessionEvent = TRUE;
    
        while(bSessionEvent){
    
            HRESULT hrStatus = S_OK;
            IMFMediaEvent* pEvent = NULL;
            MediaEventType meType = MEUnknown;
    
            MF_TOPOSTATUS TopoStatus = MF_TOPOSTATUS_INVALID;
    
            hr = pSession->GetEvent(0, &pEvent);
    
            if(SUCCEEDED(hr)){
                hr = pEvent->GetStatus(&hrStatus);
            }
    
            if(SUCCEEDED(hr)){
                hr = pEvent->GetType(&meType);
            }
    
            if(SUCCEEDED(hr) && SUCCEEDED(hrStatus)){
    
                switch(meType){
    
                    case MESessionTopologySet:
                        wprintf(L"MESessionTopologySet\n");
                        break;
    
                    case MESessionTopologyStatus:
    
                        hr = pEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, (UINT32*)&TopoStatus);
    
                        if(SUCCEEDED(hr)){
    
                            switch(TopoStatus){
    
                                case MF_TOPOSTATUS_READY:
                                {
                                    wprintf(L"MESessionTopologyStatus: MF_TOPOSTATUS_READY\n");
                                    PROPVARIANT varStartPosition;
                                    PropVariantInit(&varStartPosition);
                                    hr = pSession->Start(&GUID_NULL, &varStartPosition);
                                    PropVariantClear(&varStartPosition);
                                }
                                break;
    
                                case MF_TOPOSTATUS_STARTED_SOURCE:
                                    wprintf(L"MESessionTopologyStatus: MF_TOPOSTATUS_STARTED_SOURCE\n");
                                    break;
    
                                case MF_TOPOSTATUS_ENDED:
                                    wprintf(L"MESessionTopologyStatus: MF_TOPOSTATUS_ENDED\n");
                                    break;
    
                                default:
                                    wprintf(L"MESessionTopologyStatus: %d\n", TopoStatus);
                                    break;
                            }
                        }
                        break;
    
                    case MESessionStarted:
                        wprintf(L"MESessionStarted\n");
                        break;
    
                    case MESessionEnded:
                        wprintf(L"MESessionEnded\n");
                        hr = pSession->Stop();
                        break;
    
                    case MESessionStopped:
                        wprintf(L"MESessionStopped\n");
                        hr = pSession->Close();
                        break;
    
                    case MESessionClosed:
                        wprintf(L"MESessionClosed\n");
                        bSessionEvent = FALSE;
                        break;
    
                    case MESessionNotifyPresentationTime:
                        wprintf(L"MESessionNotifyPresentationTime\n");
                        break;
    
                    case MESessionCapabilitiesChanged:
                        wprintf(L"MESessionCapabilitiesChanged\n");
                        break;
    
                    case MEEndOfPresentation:
                        wprintf(L"MEEndOfPresentation\n");
                        break;
    
                    default:
                        wprintf(L"Media session event: %d\n", meType);
                        break;
                }
    
                SAFE_RELEASE(pEvent);
    
                if(FAILED(hr) || FAILED(hrStatus)){
                    bSessionEvent = FALSE;
                }
            }
        }
    
        return hr;
    }
    
    //----------------------------------------------------------------------------------------------
    //Main.cpp
    //----------------------------------------------------------------------------------------------
    #布拉格语一次
    #定义WIN32_精益_和_平均值
    #定义严格
    #pragma注释(lib,“mf”)
    #pragma注释(lib,“mfplat”)
    #pragma注释(lib,“mfuuid”)
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #定义MP4\u源\u视频\u媒体\u文件L“big\u buck\u bunny\u 720p\u 50mb.MP4”
    #定义MP4\u FINAL\u VIDEO\u MEDIA\u文件L“FINAL.MP4”
    HRESULT进程转换器(LPCWSTR);
    HRESULT配置源(LPCWSTR、IMFMediaSource**、IMFMediaType**、IMFMediaType**、IMFTopologyNode**、IMFTopologyNode**);
    HRESULT CreateMediaSource(LPCWSTR、IMFMediaSource**);
    HRESULT配置MediaTypeSource(IMFMediaSource*、IMFPresentationDescriptor*、IMFStreamDescriptor*、IMFMediaType**、IMFMediaType**、IMFTopologyNode**、IMFTopologyNode**);
    HRESULT CreateTopologyNodeLink(IMFMediaSink*、IMFTopologyNode**、IMFTopologyNode**、IMFMediaType*、IMFMediaType*);
    HRESULT CreateSourceStreamNode(IMFMediaSource*、IMFPresentationDescriptor*、IMFStreamDescriptor*、IMFTopologyNode**);
    HRESULT ConfigureSinkNode(IMFMediaTypeHandler*、IMFStreamSink*、IMFTopologyNode**、IMFMediaType*);
    HRESULT配置拓扑节点(IMFTopology*、IMFTopologyNode*、IMFTopologyNode*、IMFTopologyNode*、IMFTopologyNode*);
    HRESULT RunMediaSession(IMFMediaSession*);
    模板内联作废安全发布(T*&p){
    如果(p){
    p->Release();
    p=零;
    }
    }
    void main(){
    HRESULT hr=coinitializex(NULL,COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    如果(成功(hr)){
    hr=MFS