MediaFoundation uses IMFTopology, IMFTopologyNode, IMFTopoLoader to create playback topology

53 views Asked by At
HRESULT hr;
IMFAttributes *pMFAttributes = nullptr;
hr = MFCreateAttributes(&pMFAttributes, 0);
if (hr != S_OK)
    return -1;

// Create Media Session
IMFMediaSession *pMediaSession = nullptr;
hr = MFCreateMediaSession(pMFAttributes, &pMediaSession);
if (hr != S_OK)
    return -1;

// Create Topology
IMFTopology *pTopology = nullptr;
hr = MFCreateTopology(&pTopology);
if (hr != S_OK)
    return -1;

// Create Output Topology Node
IMFTopologyNode *pOutputTopologyNode = nullptr;
hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pOutputTopologyNode);
if (hr != S_OK)
    return -1;
    
IMFMediaSink *pMediaSink = nullptr;
hr = MFCreateVideoRenderer(IID_PPV_ARGS(&pMediaSink));
if (hr != S_OK)
    return -1;
    
DWORD cStreamSinkCount = 0;
hr = pMediaSink->GetStreamSinkCount(&cStreamSinkCount);
if (hr != S_OK)
    return -1;

I want to use MediaFoundation's IMFMediaSession, IMFTopology, IMFTopologyNode, and IMFTopoLoader to create a playback topology, then connect Topology's SourceNode and OutputNode, and use the IMFTopology::Load function to generate a complete topology to achieve the preview of the UVC camera.

When I use VisualStudio2022 to single-step debug this part of the code, whenever I run

"hr = pMediaSink->GetStreamSinkCount(&cStreamSinkCount);" after this line of code ends, some errors will appear in the output window of VisualStudio, although the return result of hr is S_OK.

'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\shell32.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\windows.storage.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\shlwapi.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\nvspcap64.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\profapi.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\ntmarta.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\gpapi.dll'.
'DDemo.exe' (Win32): Loaded 'C:\Windows\System32\DriverStore\FileRepository\nvhmsi.inf_amd64_c4a5dbc0d2a257c5\NvCamera\NvCameraAllowlisting64.dll'.
'DDemo.exe' (Win32): Uninstalled 'C:\Windows\System32\DriverStore\FileRepository\nvhmsi.inf_amd64_c4a5dbc0d2a257c5\NvCamera\NvCameraAllowlisting64.dll'
Exception thrown at 0x00007FFF0BF7565C in DDemo.exe: Microsoft C++ exception: bad_hresult at memory location 0x000000183F8FEFA0.

Why this problem occurs and how to solve it, thank you very much.

INT CreateTopology()
{
    HRESULT hr;
    // Create MediaSession
    IMFMediaSession *m_pMediaSession = nullptr;
    hr = MFCreateMediaSession(m_pMFAttributes, &m_pMediaSession);
    if (hr != S_OK)
        return -1;

    // Create Topology
    IMFTopology *m_pTopology = nullptr;
    hr = MFCreateTopology(&m_pTopology);
    if (hr != S_OK)
        return -1;

    // Source Topology Node - Create
    IMFTopologyNode *m_pSourceTopologyNode = nullptr;
    hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &m_pSourceTopologyNode);
    if (hr != S_OK)
        return -1;

    IMFPresentationDescriptor *m_pMediaSourcePD = nullptr;
    hr = m_pMediaSource->CreatePresentationDescriptor(&m_pMediaSourcePD);
    if (hr != S_OK)
        return -1;

    DWORD sourceStreams = 0;
    // hr = m_pMediaSourcePD->GetStreamDescriptorCount(&sourceStreams);
    // if (hr != S_OK)
    //     return -1;

    sourceStreams = 0;
    BOOL fSelected;
    IMFStreamDescriptor *m_pMediaSourceSD = nullptr;
    hr = m_pMediaSourcePD->GetStreamDescriptorByIndex(sourceStreams, &fSelected, &m_pMediaSourceSD);
    if (hr != S_OK || fSelected == FALSE)
        return -1;

    hr = m_pSourceTopologyNode->SetUnknown(MF_TOPONODE_SOURCE, m_pMediaSource);
    if (hr != S_OK)
        return -1;

    hr = m_pSourceTopologyNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, m_pMediaSourcePD);
    if (hr != S_OK)
        return -1;

    hr = m_pSourceTopologyNode->SetUnknown( MF_TOPONODE_STREAM_DESCRIPTOR, m_pMediaSourceSD);
    if (hr != S_OK)
        return -1;

    // Output Topology Node - Create
    hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &m_pOutputTopologyNode);
    if (hr != S_OK)
        return -1;

    // IMFActivate* pEVRActivate = nullptr;
    // hr = MFCreateVideoRendererActivate(nullptr, &pEVRActivate); ////m_hWnd
    // if (hr != S_OK)
    //     return -1;

    IMFMediaSink *m_pMediaSink = nullptr;
    hr = MFCreateVideoRenderer(IID_PPV_ARGS(&m_pMediaSink));
    if (hr != S_OK)
        return -1;

    DWORD cStreamSinkCount = 0;
    // hr = m_pMediaSink->GetStreamSinkCount(&cStreamSinkCount);
    // if (hr != S_OK)
    //     return -1;

    cStreamSinkCount = 0;
    IMFStreamSink *m_pStreamSink = nullptr;
    hr = m_pMediaSink->GetStreamSinkByIndex(cStreamSinkCount, &m_pStreamSink);
    if (hr != S_OK)
        return -1;

    hr = m_pOutputTopologyNode->SetObject(m_pStreamSink);
    if (hr != S_OK)
        return -1;

    hr = m_pOutputTopologyNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, TRUE);
    if (hr != S_OK)
        return -1;

    IMFGetService* pService = nullptr;
    hr = m_pStreamSink->QueryInterface(IID_PPV_ARGS(&pService));
    if (hr != S_OK)
        return -1;

    IMFVideoDisplayControl *m_pVideoDisplayControl = nullptr;
    hr = pService->GetService(MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_pVideoDisplayControl)); // IID_IMFVideoDisplayControl
    if (hr != S_OK)
        return -1;

    // Source Topology Node - Add to topology
    hr = m_pTopology->AddNode(m_pSourceTopologyNode);
    if (hr != S_OK)
        return -1;

    // Output Topology Node - Add to topology
    hr = m_pTopology->AddNode(m_pOutputTopologyNode);
    if (hr != S_OK)
        return -1;

    // Source Topology Node -> Output Topology Node
    hr = m_pSourceTopologyNode->ConnectOutput(0, m_pOutputTopologyNode, 0);
    if (hr != S_OK)
        return -1;

    IMFTopoLoader *pTopoLoader = nullptr;
    hr = MFCreateTopoLoader(&pTopoLoader);
    if (hr != S_OK)
        return -1;

    IMFTopology *pFullTopology = nullptr;
    // MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
    hr = pTopoLoader->Load(m_pTopology, &pFullTopology, nullptr);
    if (hr != S_OK)
        return -1;

    hr = m_pMediaSession->SetTopology(0, m_pTopology);
    if (hr != S_OK)
        return -1;

    hr = m_pVideoDisplayControl->SetVideoWindow(m_hWnd);
    if (hr != S_OK)
        return -1;

    hr = m_pVideoDisplayControl->SetBorderColor(RGB(255, 0, 0));
    if (hr != S_OK)
        return -1;

    RECT rect;
    rect.left = 0;
    rect.top  = 0;
    rect.right = 320;
    rect.bottom = 180;
    hr = m_pVideoDisplayControl->SetVideoPosition(nullptr, &rect);
    if (hr != S_OK)
        return -1;

    PROPVARIANT startPosition;
    PropVariantInit(&startPosition);
    hr = m_pMediaSession->Start(&GUID_NULL, &startPosition);
    // hr = m_pMediaSession->Start(NULL, NULL);
    if (hr != S_OK)
        return -1;

    return 0;
}
0

There are 0 answers