📄 graph.cpp
字号:
pIPinDownstream = NULL;
} // while next downstream filter pin
//We are now back into the upstream pin loop
} // if output pin
pIPinUpstream = NULL;
PinInfoUpstream.pFilter->Release();
} // while next upstream filter pin
return E_FAIL;
}
// RunGraph checks to see if a graph has been built
// if not it calls BuildGraph
// RunGraph then calls MediaCtrl-Run
HRESULT
CBDAFilterGraph::RunGraph()
{
// check to see if the graph is already running
if(m_fGraphRunning)
return S_OK;
HRESULT hr = S_OK;
if (m_pIMediaControl == NULL)
hr = m_pFilterGraph.QueryInterface (&m_pIMediaControl);
if (SUCCEEDED (hr))
{
// run the graph
hr = m_pIMediaControl->Run();
if(SUCCEEDED(hr))
{
m_fGraphRunning = true;
}
else
{
// stop parts of the graph that ran
m_pIMediaControl->Stop();
ErrorMessageBox(TEXT("Cannot run graph\n"));
}
}
return hr;
}
// StopGraph calls MediaCtrl - Stop
HRESULT
CBDAFilterGraph::StopGraph()
{
// check to see if the graph is already stopped
if(m_fGraphRunning == false)
return S_OK;
HRESULT hr = S_OK;
ASSERT (m_pIMediaControl);
// pause before stopping
hr = m_pIMediaControl->Pause();
// stop the graph
hr = m_pIMediaControl->Stop();
m_fGraphRunning = (FAILED (hr))?true:false;
return hr;
}
// Set our client area for viewing
//
// Note, what you're not seeing here is a call to
// IAMSreamCconfig's GetFormat to obtain the video
// format properties that would enable us to set
// the viewing window's size
HRESULT
CBDAFilterGraph::SetVideoWindow(
HWND hwndMain
)
{
CComPtr <IVideoWindow> pVideoWindow;
RECT rc;
INT cyBorder;
INT cy;
HRESULT hr = S_OK;
// get IVideoWindow interface
hr = m_pFilterGraph->QueryInterface (&pVideoWindow);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("QueryInterface IVideoWindow Failed\n"));
return hr;
}
hr = pVideoWindow->put_Owner (reinterpret_cast <LONG> (hwndMain));
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Unable to set video window\n"));
return hr;
}
hr = pVideoWindow->put_WindowStyle (WS_CHILD);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Unable to set the style for the video window\n"));
return hr;
}
GetClientRect(hwndMain, &rc);
cyBorder = GetSystemMetrics(SM_CYBORDER);
cy = cyBorder;
rc.bottom -= cy;
hr = pVideoWindow->SetWindowPosition(0, 0, rc.right, rc.bottom);
hr = pVideoWindow->put_Visible (OATRUE);
return hr;
}
HRESULT
CBDAFilterGraph::ChangeChannel(
LONG lPhysicalChannel,
LONG lMajorChannel,
LONG lMinorChannel
)
{
HRESULT hr = S_OK;
m_lMajorChannel = lMajorChannel;
m_lMinorChannel = lMinorChannel;
m_lPhysicalChannel = lPhysicalChannel;
if (!m_pNetworkProvider)
{
ErrorMessageBox(TEXT("The FilterGraph is not yet built.\n"));
return E_FAIL;
}
// create tune request
CComPtr <IATSCChannelTuneRequest> pTuneRequest;
hr = CreateATSCTuneRequest(
m_lPhysicalChannel,
lMajorChannel,
lMinorChannel,
&pTuneRequest
);
if(SUCCEEDED(hr))
{
hr = m_pITuner->put_TuneRequest (pTuneRequest);
if (FAILED (hr))
ErrorMessageBox(TEXT("Cannot submit tune request\n"));
}
else
{
ErrorMessageBox(TEXT("Cannot Change Channels\n"));
}
return hr;
}
#ifdef REGISTER_FILTERGRAPH
// Adds a DirectShow filter graph to the Running Object Table,
// allowing GraphEdit to "spy" on a remote filter graph.
HRESULT CBDAFilterGraph::AddGraphToRot(
IUnknown *pUnkGraph,
DWORD *pdwRegister
)
{
CComPtr <IMoniker> pMoniker;
CComPtr <IRunningObjectTable> pROT;
WCHAR wsz[128];
HRESULT hr;
if (FAILED(GetRunningObjectTable(0, &pROT)))
return E_FAIL;
wsprintfW(wsz, L"FilterGraph %08x pid %08x\0", (DWORD_PTR) pUnkGraph,
GetCurrentProcessId());
hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr))
hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,
pMoniker, pdwRegister);
return hr;
}
// Removes a filter graph from the Running Object Table
void CBDAFilterGraph::RemoveGraphFromRot(
DWORD pdwRegister
)
{
CComPtr <IRunningObjectTable> pROT;
if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
pROT->Revoke(pdwRegister);
}
#endif
//
// USE THE CODE BELOW IF YOU WANT TO MANUALLY LOAD AND
// CONNECT A/V DECODERS TO THE DEMUX OUTPUT PINS
//
/*
To use this code:
1) in LoadAudioDecoder() and LoadVideoDecoder(), fill in decoder specific information (clsid)
2) goto BuildGraph() and replace RenderDemux() with BuildAVSegment()
*/
/*
// Builds the Audio, Video segment of the digital TV graph.
// Demux -> AV Decoder -> OVMixer -> Video Renderer
HRESULT
CBDAFilterGraph::BuildAVSegment()
{
HRESULT hr = E_FAIL;
// connect the demux to the capture device
hr = ConnectFilters(m_pCaptureDevice, m_pDemux);
hr = LoadVideoDecoder();
if(SUCCEEDED(hr) && m_pVideoDecoder)
{
// Connect the demux & video decoder
hr = ConnectFilters(m_pDemux, m_pVideoDecoder);
if(FAILED(hr))
{
ErrorMessageBox("Connecting Demux & Video Decoder Failed\n");
goto err;
}
}
else
{
//ErrorMessageBox("Unable to load Video Decoder\n");
goto err;
}
//Audio
hr = LoadAudioDecoder();
if(SUCCEEDED(hr) && m_pAudioDecoder)
{
hr = ConnectFilters(m_pDemux, m_pAudioDecoder);
if(FAILED(hr))
{
ErrorMessageBox("Connecting Deumx & Audio Decoder Failed\n");
goto err;
}
}
else
{
ErrorMessageBox("Unable to load Audio Decoder\n");
goto err;
}
// Create the OVMixer & Video Renderer for the video segment
hr = CoCreateInstance(CLSID_OverlayMixer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, reinterpret_cast<void**>(&m_pOVMixer));
if(SUCCEEDED(hr) && m_pOVMixer)
{
hr = m_pFilterGraph->AddFilter(m_pOVMixer, L"OVMixer");
if(FAILED(hr))
{
ErrorMessageBox("Adding OVMixer to the FilterGraph Failed\n");
goto err;
}
}
else
{
ErrorMessageBox("Loading OVMixer Failed\n");
goto err;
}
hr = CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, reinterpret_cast<void**>(&m_pVRenderer));
if(SUCCEEDED(hr) && m_pVRenderer)
{
hr = m_pFilterGraph->AddFilter(m_pVRenderer, L"Video Renderer");
if(FAILED(hr))
{
ErrorMessageBox("Adding Video Renderer to the FilterGraph Failed\n");
goto err;
}
}
else
{
ErrorMessageBox("Loading Video Renderer Failed\n");
goto err;
}
// Split AV Decoder? Then add Default DirectSound Renderer to the filtergraph
if(m_pVideoDecoder != m_pAudioDecoder)
{
hr = CoCreateInstance(CLSID_DSoundRender, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
reinterpret_cast<void**>(&m_pDDSRenderer));
if(SUCCEEDED(hr) && m_pDDSRenderer)
{
hr = m_pFilterGraph->AddFilter(m_pDDSRenderer, L"Sound Renderer");
if(FAILED(hr))
{
ErrorMessageBox("Adding DirectSound Device to the FilterGraph Failed\n");
goto err;
}
}
else
{
ErrorMessageBox("Loading DirectSound Device Failed\n");
goto err;
}
}
hr = ConnectFilters(m_pVideoDecoder, m_pOVMixer);
if(FAILED(hr))
{
ErrorMessageBox("Connecting Capture & OVMixer Failed\n");
goto err;
}
hr = ConnectFilters(m_pOVMixer, m_pVRenderer);
if(FAILED(hr))
{
ErrorMessageBox("Connecting OVMixer & Video Renderer Failed\n");
goto err;
}
// Split AV Decoder & if you need audio too ?? then connect Audio decoder to Sound Renderer
if(m_pVideoDecoder != m_pAudioDecoder)
{
hr = ConnectFilters(m_pAudioDecoder, m_pDDSRenderer);
if(FAILED(hr))
{
ErrorMessageBox("Connecting AudioDecoder & DirectSound Device Failed\n");
goto err;
}
}
err:
return hr;
}
// placeholders for real decoders
DEFINE_GUID(CLSID_FILL_IN_NAME_AUDIO_DECODER, 0xFEEDFEED, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00);
DEFINE_GUID(CLSID_FILL_IN_NAME_VIDEO_DECODER, 0xFEEDFEED, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00);
HRESULT
CBDAFilterGraph::LoadVideoDecoder()
{
HRESULT hr = E_FAIL;
hr = CoCreateInstance(CLSID_FILL_IN_NAME_VIDEO_DECODER, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
reinterpret_cast<void**>(&m_pVideoDecoder));
if(SUCCEEDED(hr) && m_pVideoDecoder)
{
hr = m_pFilterGraph->AddFilter(m_pVideoDecoder, L"Video Decoder");
if(FAILED(hr))
{
ErrorMessageBox("Unable to add Video Decoder filter to graph\n");
}
}
return hr;
}
HRESULT
CBDAFilterGraph::LoadAudioDecoder()
{
HRESULT hr = E_FAIL;
hr = CoCreateInstance(CLSID_FILL_IN_NAME_AUDIO_DECODER, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
reinterpret_cast<void**>(&m_pAudioDecoder));
if(SUCCEEDED(hr) && m_pAudioDecoder)
{
hr = m_pFilterGraph->AddFilter(m_pAudioDecoder, L"Audio Decoder");
if(FAILED(hr))
{
ErrorMessageBox("Unable to add Audio filter to graph\n");
}
}
return hr;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -