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