📄 graph.cpp
字号:
//------------------------------------------------------------------------------
// File: Graph.cpp
//
// Desc: Sample code for BDA graph building.
//
// Copyright (c) 2000-2002, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "graph.h"
//
// NOTE: In this sample, text strings are hard-coded for
// simplicity and for readability. For product code, you should
// use string tables and LoadString().
//
//
// An application can advertise the existence of its filter graph
// by registering the graph with a global Running Object Table (ROT).
// The GraphEdit application can detect and remotely view the running
// filter graph, allowing you to 'spy' on the graph with GraphEdit.
//
// To enable registration in this sample, define REGISTER_FILTERGRAPH.
//
#define REGISTER_FILTERGRAPH
// We use channel 46 internally for testing. Change this constant to any value.
#define DEFAULT_PHYSICAL_CHANNEL 46L
// Constructor, initializes member variables
// and calls InitializeGraphBuilder
CBDAFilterGraph::CBDAFilterGraph() :
m_fGraphBuilt(FALSE),
m_fGraphRunning(FALSE),
m_NetworkType(ATSC),
m_lMajorChannel(-1),
m_lMinorChannel(-1),
m_lPhysicalChannel(DEFAULT_PHYSICAL_CHANNEL),
m_dwGraphRegister (0)
{
if(FAILED(InitializeGraphBuilder()))
m_fGraphFailure = TRUE;
else
m_fGraphFailure = FALSE;
}
// Destructor
CBDAFilterGraph::~CBDAFilterGraph()
{
if(m_fGraphRunning)
{
StopGraph();
}
if(m_fGraphBuilt || m_fGraphFailure)
{
TearDownGraph();
}
}
// Instantiate graph object for filter graph building
HRESULT
CBDAFilterGraph::InitializeGraphBuilder()
{
HRESULT hr = S_OK;
// we have a graph already
if (m_pFilterGraph)
return S_OK;
// create the filter graph
if (FAILED (hr = m_pFilterGraph.CoCreateInstance (CLSID_FilterGraph)))
{
ErrorMessageBox(TEXT("Couldn't CoCreate IGraphBuilder\n"));
m_fGraphFailure = true;
return hr;
}
return hr;
}
// BuildGraph sets up devices, adds and connects filters
HRESULT
CBDAFilterGraph::BuildGraph(NETWORK_TYPE NetType)
{
HRESULT hr = S_OK;
m_NetworkType = NetType;
// if we have already have a filter graph, tear it down
if(m_fGraphBuilt)
{
if(m_fGraphRunning)
{
hr = StopGraph ();
}
hr = TearDownGraph ();
}
// STEP 1: load network provider first so that it can configure other
// filters, such as configuring the demux to sprout output pins.
// We also need to submit a tune request to the Network Provider so it will
// tune to a channel
if(FAILED (hr = LoadNetworkProvider()))
{
ErrorMessageBox(TEXT("Cannot load network provider\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
hr = m_pNetworkProvider->QueryInterface(__uuidof (ITuner), reinterpret_cast <void**> (&m_pITuner));
if(FAILED (hr))
{
ErrorMessageBox(TEXT("pNetworkProvider->QI: Can't QI for ITuner.\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
// create a tune request to initialize the network provider
// before connecting other filters
CComPtr <IATSCChannelTuneRequest> pATSCTuneRequest;
if(FAILED (hr = CreateATSCTuneRequest(
m_lPhysicalChannel,
m_lMajorChannel,
m_lMinorChannel,
&pATSCTuneRequest
)))
{
ErrorMessageBox(TEXT("Cannot create tune request\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
//submit the tune request to the network provider
hr = m_pITuner->put_TuneRequest(pATSCTuneRequest);
if(FAILED(hr))
{
ErrorMessageBox(TEXT("Cannot submit the tune request\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
// STEP2: Load tuner device and connect to network provider
if(FAILED (hr = LoadFilter (
KSCATEGORY_BDA_NETWORK_TUNER,
&m_pTunerDevice,
m_pNetworkProvider,
TRUE
)))
{
ErrorMessageBox(TEXT("Cannot load tuner device and connect network provider\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
// STEP3: Load tuner device and connect to demodulator device
if(FAILED (hr = LoadFilter (
KSCATEGORY_BDA_RECEIVER_COMPONENT,
&m_pDemodulatorDevice,
m_pTunerDevice,
TRUE
)))
{
ErrorMessageBox(TEXT("Cannot load capture device and connect tuner\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
// Step4: Load capture device and connect to tuner device
if(FAILED (hr = LoadFilter (
KSCATEGORY_BDA_RECEIVER_COMPONENT,
&m_pCaptureDevice,
m_pDemodulatorDevice,
TRUE
)))
{
ErrorMessageBox(TEXT("Cannot load capture device and connect tuner\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
// Step5: Load demux
if(FAILED (hr = LoadDemux()))
{
ErrorMessageBox(TEXT("Cannot load demux\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
//
// this next call loads and connects filters associated with
// the demultiplexor. if you want to manually load individual
// filters such as audio and video decoders, use the code at
// the bottom of this file
//
#ifdef REGISTER_FILTERGRAPH
hr = AddGraphToRot (m_pFilterGraph, &m_dwGraphRegister);
if (FAILED(hr))
{
///ErrorMessageBox(TEXT("Failed to register filter graph with ROT! hr=0x%x"), hr);
m_dwGraphRegister = 0;
}
#endif
// Step6: Render demux pins
if(FAILED (hr = RenderDemux()))
{
ErrorMessageBox(TEXT("Cannot load demux\n"));
TearDownGraph();
m_fGraphFailure = true;
return hr;
}
m_fGraphBuilt = true;
m_fGraphFailure = false;
return S_OK;
}
// Loads the correct tuning space based on NETWORK_TYPE that got
// passed into BuildGraph()
HRESULT
CBDAFilterGraph::LoadTuningSpace()
{
CComPtr <ITuningSpaceContainer> pITuningSpaceContainer;
// get the tuningspace container for all the tuning spaces from SYSTEM_TUNING_SPACES
HRESULT hr = pITuningSpaceContainer.CoCreateInstance(CLSID_SystemTuningSpaces);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Could not CoCreate SystemTuningSpaces\n"));
return hr;
}
CComVariant var (m_NetworkType);
hr = pITuningSpaceContainer->get_Item(var, &m_pITuningSpace);
if(FAILED(hr))
{
ErrorMessageBox(TEXT("Unable to retrieve Tuning Space\n"));
}
return hr;
}
// Creates an ATSC Tune Request
HRESULT
CBDAFilterGraph::CreateATSCTuneRequest(
LONG lPhysicalChannel,
LONG lMajorChannel,
LONG lMinorChannel,
IATSCChannelTuneRequest** pTuneRequest
)
{
HRESULT hr = S_OK;
if (pTuneRequest == NULL)
{
ErrorMessageBox (TEXT("Invalid pointer\n"));
return E_POINTER;
}
// Making sure we have a valid tuning space
if (m_pITuningSpace == NULL)
{
ErrorMessageBox(TEXT("Tuning Space is NULL\n"));
return E_FAIL;
}
// Create an instance of the ATSC tuning space
CComQIPtr <IATSCTuningSpace> pATSCTuningSpace (m_pITuningSpace);
if (!pATSCTuningSpace)
{
ErrorMessageBox(TEXT("Cannot QI for an IATSCTuningSpace\n"));
return E_FAIL;
}
// Create an empty tune request.
CComPtr <ITuneRequest> pNewTuneRequest;
hr = pATSCTuningSpace->CreateTuneRequest(&pNewTuneRequest);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("CreateTuneRequest: Can't create tune request.\n"));
return hr;
}
//query for an IATSCChannelTuneRequest interface pointer
CComQIPtr <IATSCChannelTuneRequest> pATSCTuneRequest (pNewTuneRequest);
if (!pATSCTuneRequest)
{
ErrorMessageBox(TEXT("CreateATSCTuneRequest: Can't QI for IATSCChannelTuneRequest.\n"));
return E_FAIL;
}
// Set the initial major and minor channels
hr = pATSCTuneRequest->put_Channel(lMajorChannel);
if(FAILED(hr))
{
ErrorMessageBox(TEXT("put_Channel failed\n"));
return hr;
}
hr = pATSCTuneRequest->put_MinorChannel(lMinorChannel);
if(FAILED(hr))
{
ErrorMessageBox(TEXT("put_MinorChannel failed\n"));
return hr;
}
CComPtr <IATSCLocator> pATSCLocator;
hr = pATSCLocator.CoCreateInstance (CLSID_ATSCLocator);
if (FAILED( hr))
{
ErrorMessageBox(TEXT("Cannot create the ATSC locator failed\n"));
return hr;
}
// Set the initial physical channel.
//
hr = pATSCLocator->put_PhysicalChannel (lPhysicalChannel);
if (FAILED( hr))
{
ErrorMessageBox(TEXT("Cannot put the physical channel\n"));
return hr;
}
hr = pATSCTuneRequest->put_Locator (pATSCLocator);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Cannot put the locator\n"));
return hr;
}
hr = pATSCTuneRequest.QueryInterface (pTuneRequest);
return hr;
}
// LoadNetworkProvider loads network provider
HRESULT
CBDAFilterGraph::LoadNetworkProvider()
{
HRESULT hr = S_OK;
CComBSTR bstrNetworkType;
CLSID CLSIDNetworkType;
// obtain tuning space then load network provider
if(m_pITuningSpace == NULL)
{
hr = LoadTuningSpace();
if(FAILED(hr))
{
ErrorMessageBox(TEXT("Cannot load TuningSpace\n"));
return hr;
}
}
// Get the current Network Type clsid
hr = m_pITuningSpace->get_NetworkType(&bstrNetworkType);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("ITuningSpace::Get Network Type failed\n"));
return hr;
}
hr = CLSIDFromString(bstrNetworkType, &CLSIDNetworkType);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Couldn't get CLSIDFromString\n"));
return hr;
}
// create the network provider based on the clsid obtained from the tuning space
hr = CoCreateInstance(CLSIDNetworkType, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
reinterpret_cast<void**>(&m_pNetworkProvider));
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Couldn't CoCreate Network Provider\n"));
return hr;
}
//add the Network Provider filter to the graph
hr = m_pFilterGraph->AddFilter(m_pNetworkProvider, L"Network Provider");
return hr;
}
// enumerates through registered filters
// instantiates the the filter object and adds it to the graph
// it checks to see if it connects to upstream filter
// if not, on to the next enumerated filter
// used for tuner, capture, MPE Data Filters and decoders that
// could have more than one filter object
// if pUpstreamFilter is NULL don't bother connecting
HRESULT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -