home *** CD-ROM | disk | FTP | other *** search
- //------------------------------------------------------------------------------
- // File: Graph.cpp
- //
- // Desc: Sample code for BDA graph building.
- //
- // Copyright (c) 2000, Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------------------------
-
- #include "graph.h"
-
- // Constructor, initializes member variables
- // and calls InitializeGraphBuilder
- CBDAFilterGraph::CBDAFilterGraph() :
- m_pFilterGraph(NULL),
- m_pITuningSpace(NULL),
- m_pITuner(NULL),
- m_pITuneRequest(NULL),
- m_pIMediaControl(NULL),
- m_pNetworkProvider(NULL),
- m_pTunerDevice(NULL),
- m_pCaptureDevice(NULL),
- m_pDemux(NULL),
- m_pVideoDecoder(NULL),
- m_pAudioDecoder(NULL),
- m_pMPE(NULL),
- m_pIPSink(NULL),
- m_pTIF(NULL),
- m_pOVMixer(NULL),
- m_pVRenderer(NULL),
- m_pDDSRenderer(NULL),
- m_fGraphBuilt(FALSE),
- m_fGraphRunning(FALSE),
- m_NetworkType(ATSC),
- m_MajorChannel(46L), // 46 is an in house test channel - go ahead and change it
- m_MinorChannel(-1L)
- {
- if(FAILED(InitializeGraphBuilder()))
- {
- m_fGraphFailure = TRUE;
- }
- else
- m_fGraphFailure = FALSE;
- }
-
- // Destructor
- CBDAFilterGraph::~CBDAFilterGraph()
- {
- if(m_fGraphRunning)
- {
- StopGraph();
- }
-
- if(m_fGraphBuilt || m_fGraphFailure)
- {
- TearDownGraph();
- }
-
- SAFE_RELEASE(m_pFilterGraph);
-
- CoUninitialize();
- }
-
-
- // Instantiate graph object for filter graph building
- HRESULT
- CBDAFilterGraph::InitializeGraphBuilder()
- {
- HRESULT hr = S_OK;
-
- // we have a graph already, bail
- if(m_pFilterGraph)
- return hr;
-
- // initialize com library.
- if (hr = CoInitialize(NULL) != S_OK)
- {
- OutputDebugString("BDASampl cannot initialize COM library\n");
- goto err;
- }
-
- // create the filter graph
- if(hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder, reinterpret_cast<void**>(&m_pFilterGraph)) != S_OK)
- {
- OutputDebugString("Couldn't CoCreate IGraphBuilder\n");
- goto err;
- }
-
- return hr;
-
- err:
- SAFE_RELEASE(m_pFilterGraph);
- m_fGraphFailure = TRUE;
-
- return hr;
- }
-
- // BuildGraph sets up devices, adds and connects filters
- HRESULT
- CBDAFilterGraph::BuildGraph(NETWORK_TYPE NetType)
- {
- m_NetworkType = NetType;
-
- // if we have already have a filter graph, tear it down
- if(m_fGraphBuilt)
- {
- if(m_fGraphRunning)
- {
- StopGraph();
- }
-
- TearDownGraph();
- }
-
- // load network provider first so that it can configure other
- // filters such as configuring the demux to sprout output pins
- if(FAILED(LoadNetworkProvider()))
- {
- OutputDebugString("Cannot load network provider\n");
- goto err;
- }
-
- // create a tune request to initialize the network provider
- // before connecting other filters
- if(FAILED(CreateATSCTuneRequest(m_MajorChannel, m_MinorChannel)))
- {
- OutputDebugString("Cannot create tune request\n");
- goto err;
- }
-
- // load tuner device and connect to network provider
- if(FAILED(LoadFilter(KSCATEGORY_BDA_RECEIVER_COMPONENT, &m_pTunerDevice,
- m_pNetworkProvider, TRUE)))
- {
- OutputDebugString("Cannot load tuner device and connect network provider\n");
- goto err;
- }
-
- // load capture device and connect to tuner device
- if(FAILED(LoadFilter(CLSID_VideoInputDeviceCategory, &m_pCaptureDevice,
- m_pTunerDevice, TRUE)))
- {
- OutputDebugString("Cannot load capture device and connect tuner\n");
- goto err;
- }
-
- // load demux
- if(FAILED(LoadDemux()))
- {
- OutputDebugString("Cannot load demux\n");
- goto err;
- }
-
- // 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
-
-
- // render demux pins
- if(FAILED(RenderDemux()))
- {
- OutputDebugString("Cannot load demux\n");
- goto err;
- }
-
- m_fGraphBuilt = TRUE;
-
- return S_OK;
-
- err:
- TearDownGraph();
-
- m_fGraphFailure = TRUE;
-
- return E_FAIL;
- }
-
-
- // Loads the correct tuning space based on NETWORK_TYPE that got
- // passed into BuildGraph()
- HRESULT
- CBDAFilterGraph::LoadTuningSpace()
- {
- HRESULT hr = S_OK;
- ITuningSpaceContainer* pITuningSpaceContainer = NULL;
-
- // get the tuningspace container for all the tuning spaces from SYSTEM_TUNING_SPACES
- hr = CoCreateInstance(CLSID_SystemTuningSpaces, NULL, CLSCTX_INPROC_SERVER,
- IID_ITuningSpaceContainer, reinterpret_cast<void**>(&pITuningSpaceContainer));
-
- if(SUCCEEDED(hr) && pITuningSpaceContainer)
- {
- VARIANT var;
- var.vt = VT_I2;
-
- var.iVal = m_NetworkType;
-
- hr = pITuningSpaceContainer->get_Item(var, &m_pITuningSpace);
-
- if(FAILED(hr) || !m_pITuningSpace)
- {
- OutputDebugString("Unable to retrieve Tuning Space\n");
- }
- }
- else
- {
- OutputDebugString("Could not CoCreate SystemTuningSpaces\n");
- }
-
- SAFE_RELEASE(pITuningSpaceContainer);
-
- return hr;
- }
-
-
- // Creates and puts an ATSC Tune Request
- HRESULT
- CBDAFilterGraph::CreateATSCTuneRequest(LONG lMajorChannel, LONG lMinorChannel)
- {
- HRESULT hr = S_OK;
- IATSCTuningSpace* pATSCTuningSpace;
- IATSCChannelTuneRequest* pATSCTuneRequest;
-
- // Making sure we have a valid tuning space
- if(m_pITuningSpace == NULL)
- {
- OutputDebugString("Tuning Space is NULL\n");
- hr = LoadTuningSpace();
-
- if(FAILED(hr))
- {
- goto err;
- }
- }
-
- hr = m_pNetworkProvider->QueryInterface(IID_ITuner, reinterpret_cast<void**>(&m_pITuner));
-
- if(FAILED(hr) || !m_pITuner)
- {
- OutputDebugString("pNetworkProvider->QI: Can't QI for ITuner.\n");
- hr = E_NOINTERFACE;
- goto err;
- }
-
- // Create an instance of the ATSC tuning space
- hr = m_pITuningSpace->QueryInterface(IID_IATSCTuningSpace,
- reinterpret_cast<void**>(&pATSCTuningSpace));
-
- if(FAILED(hr) || !pATSCTuningSpace)
- {
- OutputDebugString("pITuningSpace->QI: Can't QI for ATSC Tuning Space.\n");
- hr = E_NOINTERFACE;
- goto err;
- }
-
- // Create an empty tune request.
- hr = pATSCTuningSpace->CreateTuneRequest(&m_pITuneRequest);
-
- if(FAILED(hr) || !m_pITuneRequest)
- {
- OutputDebugString("CreateTuneRequest: Can't create tune request.\n");
- hr = E_NOINTERFACE;
- goto err;
- }
-
- hr = m_pITuneRequest->QueryInterface(IID_IATSCChannelTuneRequest,
- reinterpret_cast<void**>(&pATSCTuneRequest));
-
- if(FAILED(hr) || !pATSCTuneRequest)
- {
- OutputDebugString("CreateATSCTuneRequest: Can't create ATSC tune request.\n");
- hr = E_NOINTERFACE;
- goto err;
- }
-
- // Set the initial major and minor channels
- hr = pATSCTuneRequest->put_Channel(lMajorChannel);
-
- if(FAILED(hr))
- {
- OutputDebugString("put_Channel failed\n");
- goto err;
- }
-
- hr = pATSCTuneRequest->put_MinorChannel(lMinorChannel);
-
- if(FAILED(hr))
- {
- OutputDebugString("put_MinorChannel failed\n");
- goto err;
- }
-
- hr = m_pITuner->put_TuneRequest(pATSCTuneRequest);
-
- if(FAILED(hr))
- {
- OutputDebugString("Tune Request failed\n");
- goto err;
- }
-
- err:
- SAFE_RELEASE(pATSCTuningSpace);
- SAFE_RELEASE(pATSCTuneRequest);
- SAFE_RELEASE(m_pITuneRequest);
- SAFE_RELEASE(pATSCTuneRequest);
- SAFE_RELEASE(m_pITuner);
-
- return hr;
- }
-
- /*
- DVB not implemented for DX8 RC0
-
- // Creates and puts a DVB Tune Request
- HRESULT
- CBDAFilterGraph::CreateDVBTuneRequest()
- {
- HRESULT hr = S_OK;
-
- return hr;
- }
- */
-
- // LoadNetworkProvider loads network provider
- HRESULT
- CBDAFilterGraph::LoadNetworkProvider()
- {
- HRESULT hr = S_OK;
- BSTR bstrNetworkType = NULL;
- CLSID CLSIDNetworkType;
-
- // obtain tuning space then load network provider
- if(m_pITuningSpace == NULL)
- {
- hr = LoadTuningSpace();
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot load TuningSpace\n");
- goto err;
- }
- }
-
- // Get the current Network Type clsid
- hr = m_pITuningSpace->get_NetworkType(&bstrNetworkType);
-
- if(SUCCEEDED(hr) && bstrNetworkType)
- {
- if(FAILED(CLSIDFromString(bstrNetworkType, &CLSIDNetworkType)))
- {
- OutputDebugString("Couldn't get CLSIDFromString\n");
- goto err;
- }
-
- SysFreeString(bstrNetworkType);
- }
- else
- {
- OutputDebugString("ITuningSpace::Get Network Type failed\n");
- goto err;
- }
-
- // 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(SUCCEEDED(hr) && m_pNetworkProvider)
- {
- hr = m_pFilterGraph->AddFilter(m_pNetworkProvider, L"Network Provider");
- }
- else
- {
- OutputDebugString("Couldn't CoCreate Network Provider\n");
- goto err;
- }
-
- return hr;
-
- err:
- SysFreeString(bstrNetworkType);
- SAFE_RELEASE(m_pNetworkProvider);
-
- 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
- CBDAFilterGraph::LoadFilter(REFCLSID clsid, IBaseFilter** ppFilter,
- IBaseFilter* pConnectFilter, BOOL fIsUpstream)
- {
-
- HRESULT hr;
- BOOL fFoundFilter = FALSE;
- IMoniker* pIMoniker = NULL;
- IEnumMoniker* pIEnumMoniker = NULL;
- IBaseFilter* pFilter = NULL;
- IPropertyBag* pBag = NULL;
-
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, reinterpret_cast<void**>(&m_pICreateDevEnum));
-
- if(FAILED(hr))
- {
- OutputDebugString("LoadFilter(): Cannot CoCreate ICreateDevEnum");
- goto err;
- }
-
- // obtain the enumerator
- hr = m_pICreateDevEnum->CreateClassEnumerator(clsid, &pIEnumMoniker, 0);
-
- if(FAILED(hr))
- {
- OutputDebugString("LoadFilter(): Cannot CreateClassEnumerator");
- goto err;
- }
-
- // next filter
- while(pIEnumMoniker->Next(1, &pIMoniker, 0) == S_OK)
- {
- // obtain filter's friendly name
- hr = pIMoniker->BindToStorage(NULL, NULL, IID_IPropertyBag,
- reinterpret_cast<void**>(&pBag));
-
- if(FAILED(hr) && !pBag)
- {
- goto err;
- }
-
- VARIANT var;
- var.vt = VT_BSTR;
- hr = pBag->Read(L"FriendlyName", &var, NULL);
-
- if(FAILED(hr))
- {
- goto err;
- }
-
- SAFE_RELEASE(pBag);
-
- // bind the filter
- hr = pIMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
- reinterpret_cast<void**>(&pFilter));
-
- SAFE_RELEASE(pIMoniker);
-
- if(FAILED(hr) || !pFilter)
- {
- SAFE_RELEASE(pIMoniker);
- SAFE_RELEASE(pFilter);
- continue;
- }
-
- hr = m_pFilterGraph->AddFilter(pFilter, var.bstrVal);
-
- SysFreeString(var.bstrVal);
-
- if(FAILED(hr))
- {
- OutputDebugString("Can not add filter\n");
- goto err;
- }
-
- // test connections
- // to upstream filter
- if(pConnectFilter)
- {
- if(fIsUpstream)
- {
- hr = ConnectFilters(pConnectFilter, pFilter);
- }
- else
- {
- hr = ConnectFilters(pFilter, pConnectFilter);
- }
-
- if(SUCCEEDED(hr))
- {
- // that's the filter we want
- fFoundFilter = TRUE;
- *ppFilter = pFilter;
- break;
- }
- else
- {
- fFoundFilter = FALSE;
- // that wasn't the the filter we wanted
- // so unload and try the next one
- hr = m_pFilterGraph->RemoveFilter(pFilter);
-
- if(FAILED(hr))
- {
- OutputDebugString("Failed unloading Filter\n");
- }
- }
- }
- else
- {
- fFoundFilter = TRUE;
- *ppFilter = pFilter;
- break;
- }
-
- SAFE_RELEASE(pFilter);
- } // while
-
- SAFE_RELEASE(pIEnumMoniker);
-
- err:
- SAFE_RELEASE(pBag);
- SAFE_RELEASE(m_pICreateDevEnum);
-
- if(fFoundFilter)
- {
- return S_OK;
- }
- else
- {
- return hr;
- }
- }
-
- // loads the demux into the FilterGraph
- HRESULT
- CBDAFilterGraph::LoadDemux()
- {
- HRESULT hr;
-
- hr = CoCreateInstance(CLSID_MPEG2Demultiplexer, NULL, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter, reinterpret_cast<void**>(&m_pDemux));
-
- if(SUCCEEDED(hr) && m_pDemux)
- {
- hr = m_pFilterGraph->AddFilter(m_pDemux, L"Demux");
-
- if(FAILED(hr))
- {
- OutputDebugString("Unable to add demux filter to graph\n");
- }
- }
- else
- {
- OutputDebugString("Could not CoCreateInstance CLSID_MPEG2Demultiplexer\n");
- }
-
- return hr;
- }
-
-
- // renders demux output pins
- HRESULT
- CBDAFilterGraph::RenderDemux()
- {
-
- HRESULT hr;
- IPin* pIPin;
- IPin* pDownstreamPin;
- IEnumPins* pIEnumPins;
- PIN_DIRECTION direction;
-
- if(!m_pDemux)
- {
- goto err;
- }
-
- // connect the demux to the capture device
- hr = ConnectFilters(m_pCaptureDevice, m_pDemux);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot connect demux to capture filter\n");
- goto err;
- }
-
- // load transform information filter and connect it to the demux
- hr = LoadFilter(KSCATEGORY_BDA_TRANSPORT_INFORMATION, &m_pTIF, m_pDemux, TRUE);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot load TIF\n");
- goto err;
- }
-
- // load multi protocol encapsulator
- hr = LoadFilter(KSCATEGORY_BDA_RECEIVER_COMPONENT, &m_pMPE, m_pDemux, TRUE);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot load MPE\n");
- goto err;
- }
-
- // load IP Sink
- hr = LoadFilter(KSCATEGORY_IP_SINK, &m_pIPSink, m_pMPE, TRUE);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot load IP Sink\n");
- goto err;
- }
-
- // render/connect the rest of the demux pins
- hr = m_pDemux->EnumPins(&pIEnumPins);
-
- ASSERT(pIEnumPins);
-
- while(pIEnumPins->Next(1, &pIPin, 0) == S_OK)
- {
- hr = pIPin->QueryDirection(&direction);
-
- if(direction == PINDIR_OUTPUT)
- {
- pIPin->ConnectedTo(&pDownstreamPin);
-
- if(pDownstreamPin == NULL)
- {
- m_pFilterGraph->Render(pIPin);
- }
-
- SAFE_RELEASE(pDownstreamPin);
- }
-
- SAFE_RELEASE(pIPin);
- }
-
- SAFE_RELEASE(pIEnumPins);
-
- return hr;
-
- err:
- m_pFilterGraph->RemoveFilter(m_pDemux);
- m_pFilterGraph->RemoveFilter(m_pMPE);
- m_pFilterGraph->RemoveFilter(m_pTIF);
- m_pFilterGraph->RemoveFilter(m_pIPSink);
-
- return hr;
- }
-
-
- // removes each filter from the graph
- HRESULT
- CBDAFilterGraph::TearDownGraph()
- {
- HRESULT hr = S_OK;
-
- IBaseFilter *pFilter = NULL;
- IEnumFilters *pIFilterEnum = NULL;
-
- SAFE_RELEASE(m_pITuningSpace);
-
- if(m_fGraphBuilt || m_fGraphFailure)
- {
- // unload manually added filters
- m_pFilterGraph->RemoveFilter(m_pIPSink);
- m_pFilterGraph->RemoveFilter(m_pMPE);
- m_pFilterGraph->RemoveFilter(m_pTIF);
- m_pFilterGraph->RemoveFilter(m_pDemux);
- m_pFilterGraph->RemoveFilter(m_pNetworkProvider);
- m_pFilterGraph->RemoveFilter(m_pTunerDevice);
- m_pFilterGraph->RemoveFilter(m_pCaptureDevice);
-
- SAFE_RELEASE(m_pIPSink);
- SAFE_RELEASE(m_pMPE);
- SAFE_RELEASE(m_pTIF);
- SAFE_RELEASE(m_pDemux);
- SAFE_RELEASE(m_pNetworkProvider);
- SAFE_RELEASE(m_pTunerDevice);
- SAFE_RELEASE(m_pCaptureDevice);
-
- // now go unload rendered filters
- hr = m_pFilterGraph->EnumFilters(&pIFilterEnum);
-
- if(FAILED(hr))
- {
- OutputDebugString("TearDownGraph: cannot EnumFilters\n");
- goto err;
- }
-
- pIFilterEnum->Reset();
-
- while(pIFilterEnum->Next(1, &pFilter, 0) == S_OK) // addrefs filter
- {
- if(hr = m_pFilterGraph->RemoveFilter(pFilter) != S_OK)
- {
- goto err;
- }
-
- SAFE_RELEASE(pFilter);
- pIFilterEnum->Reset();
- }
- }
-
- m_fGraphBuilt = FALSE;
-
- err:
- SAFE_RELEASE(pFilter);
- SAFE_RELEASE(pIFilterEnum);
-
- return hr;
- }
-
-
- //ConnectFilters is called from BuildGraph
- //it enumerates and connects pins
- HRESULT
- CBDAFilterGraph::ConnectFilters(IBaseFilter* pFilterUpstream, IBaseFilter* pFilterDownstream)
- {
- HRESULT hr = E_FAIL;
-
- IPin* pIPinUpstream = NULL;
- IPin* pPinDown = NULL;
- IPin* pIPinDownstream = NULL;
- IPin* pPinUp = NULL;
-
- IEnumPins* pIEnumPinsUpstream = NULL;
- IEnumPins* pIEnumPinsDownstream = NULL;
-
- PIN_INFO PinInfoUpstream;
- PIN_INFO PinInfoDownstream;
-
- BOOL bConnected = FALSE;
-
- // validate passed in filters
- ASSERT(pFilterUpstream);
- ASSERT(pFilterDownstream);
-
- // grab upstream filter's enumerator
- hr = pFilterUpstream->EnumPins(&pIEnumPinsUpstream);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot Enumerate Upstream Filter's Pins\n");
- goto err;
- }
-
- // iterate through upstream filter's pins
- while(pIEnumPinsUpstream->Next(1, &pIPinUpstream, 0) == S_OK)
- {
- hr = pIPinUpstream->QueryPinInfo(&PinInfoUpstream);
-
- if(FAILED(hr))
- {
- OutputDebugString("Cannot Obtain Upstream Filter's PIN_INFO\n");
- goto err;
- }
-
- pIPinUpstream->ConnectedTo(&pPinDown);
-
- // bail if pins are connected
- // otherwise check direction and connect
- if(PINDIR_OUTPUT == PinInfoUpstream.dir && pPinDown == NULL)
- {
- // grab downstream filter's enumerator
- hr = pFilterDownstream->EnumPins(&pIEnumPinsDownstream);
-
- // iterate through downstream filter's pins
- while(pIEnumPinsDownstream->Next(1, &pIPinDownstream, 0) == S_OK)
- {
- // make sure it is an input pin
- hr = pIPinDownstream->QueryPinInfo(&PinInfoDownstream);
-
- if(SUCCEEDED(hr))
- {
- pIPinDownstream->ConnectedTo(&pPinUp);
-
- if(PINDIR_INPUT == PinInfoDownstream.dir && pPinUp == NULL)
- {
- if(SUCCEEDED(m_pFilterGraph->Connect(pIPinUpstream,
- pIPinDownstream)))
- {
- PinInfoDownstream.pFilter->Release();
- PinInfoUpstream.pFilter->Release();
- bConnected = TRUE;
- SAFE_RELEASE(pIPinDownstream);
-
- break;
- }
- }
- SAFE_RELEASE(pPinUp);
- }
-
- PinInfoDownstream.pFilter->Release();
- SAFE_RELEASE(pIPinDownstream);
- } // while next downstream filter pin
-
- SAFE_RELEASE(pIEnumPinsDownstream);
- SAFE_RELEASE(pPinUp);
- SAFE_RELEASE(pIPinDownstream);
- SAFE_RELEASE(pIPinUpstream);
- //We are now back into the upstream pin loop
- if(bConnected)
- {
- break;
- }
- } // if output pin
-
- PinInfoUpstream.pFilter->Release();
- SAFE_RELEASE(pIPinUpstream);
- SAFE_RELEASE(pPinDown);
- SAFE_RELEASE(pPinUp);
- SAFE_RELEASE(pIPinDownstream);
- SAFE_RELEASE(pIEnumPinsDownstream);
-
- } // while next upstream filter pin
-
- SAFE_RELEASE(pIEnumPinsUpstream);
-
- if(bConnected)
- {
- hr = S_OK;
- }
- else
- {
- hr = E_FAIL;
- }
-
- err:
-
- SAFE_RELEASE(pPinDown);
- SAFE_RELEASE(pPinUp);
- SAFE_RELEASE(pIPinUpstream);
- SAFE_RELEASE(pIPinDownstream);
- SAFE_RELEASE(pIEnumPinsDownstream);
- SAFE_RELEASE(pIEnumPinsUpstream);
-
- return hr;
- }
-
-
- // RunGraph checks to see if a graph has been built
- // if not it calls BuildGraph
- // RunGraph then calls MediaCtrl-Run
- HRESULT
- CBDAFilterGraph::RunGraph()
- {
- HRESULT hr = S_OK;
-
- // check to see if the graph is already running
- if(m_fGraphRunning)
- {
- return hr;
- }
-
- hr = m_pFilterGraph->QueryInterface(IID_IMediaControl,
- reinterpret_cast<void**>(&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();
- OutputDebugString("Cannot run graph\n");
- }
- }
-
- SAFE_RELEASE(m_pIMediaControl);
-
- return hr;
- }
-
-
- // StopGraph calls MediaCtrl - Stop
- HRESULT
- CBDAFilterGraph::StopGraph()
- {
- HRESULT hr = S_OK;
-
- // check to see if the graph is already stopped
- if(!m_fGraphRunning)
- {
- return hr;
- }
-
- hr = m_pFilterGraph->QueryInterface(IID_IMediaControl,
- reinterpret_cast<void**>(&m_pIMediaControl));
-
- if(SUCCEEDED(hr))
- {
- // pause before stopping
- hr = m_pIMediaControl->Pause();
-
- // stop the graph
- hr = m_pIMediaControl->Stop();
-
- if(SUCCEEDED(hr))
- {
- m_fGraphRunning = FALSE;
- }
- else
- {
- OutputDebugString("Cannot stop graph\n");
- }
- }
-
- SAFE_RELEASE(m_pIMediaControl);
-
- return hr;
- }
-
- // Set our client area for viewing
- //
- // Note, what your 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)
- {
- HRESULT hr = S_OK;
-
- IVideoWindow* pVideoWindow = NULL;
- RECT rc;
- INT cyBorder;
- INT cy;
-
- // get IVideoWindow interface
- hr = m_pFilterGraph->QueryInterface(IID_IVideoWindow,
- reinterpret_cast<void**>(&pVideoWindow));
-
- if(FAILED(hr))
- {
- OutputDebugString("QueryInterface IVideoWindow Failed\n");
- goto err;
- }
-
- hr = pVideoWindow->put_Owner((LONG) hwndMain);
-
- if(FAILED(hr))
- {
- OutputDebugString("Unable to set video window\n");
- goto err;
- }
-
- hr = pVideoWindow->put_WindowStyle(WS_CHILD);
-
- GetClientRect(hwndMain, &rc);
- cyBorder = GetSystemMetrics(SM_CYBORDER);
- cy = cyBorder;
- rc.bottom -= cy;
- pVideoWindow->SetWindowPosition(0, 0, rc.right, rc.bottom);
- pVideoWindow->put_Visible(OATRUE);
-
- err:
- SAFE_RELEASE(pVideoWindow);
-
- return hr;
- }
-
- HRESULT
- CBDAFilterGraph::ChangeChannel(LONG lMajorChannel, LONG lMinorChannel)
- {
- HRESULT hr = E_FAIL;
- IScanningTuner* pIScanningTuner = NULL;
-
- if(!m_pNetworkProvider)
- {
- OutputDebugString("The FilterGraph is not Built Yet\n");
- hr = E_NOINTERFACE;
- goto err;
- }
-
- hr = m_pNetworkProvider->QueryInterface(IID_IScanningTuner,
- reinterpret_cast<void**>(&pIScanningTuner));
-
- if(FAILED(hr) && !pIScanningTuner)
- {
- OutputDebugString("Cannot QI for IScanningTuner\n");
- goto err;
- }
-
- // check to see if we're going for major channel change
- // if so, set minor channel to -1, unless the minor has changed as well
- if(lMajorChannel == m_MajorChannel)
- {
- switch(lMinorChannel)
- {
- case CHANNEL_UP: // up channel
- m_MinorChannel++;
-
- break;
-
- case CHANNEL_DOWN: // down channel
- m_MinorChannel--;
-
- break;
-
- default:
- if(lMajorChannel < CHANNEL_UPPER_LIMIT &&
- lMajorChannel > CHANNEL_LOWER_LIMIT &&
- lMinorChannel < MINOR_CHANNEL_UPPER_LIMIT &&
- lMinorChannel > MINOR_CHANNEL_LOWER_LIMIT)
-
- {
- m_MinorChannel = lMinorChannel;
- }
-
- break;
- }
- }
- else
- {
- // major channel change, and did minor change?
- // if not set it to "unset" (-1)
- if(m_MinorChannel == lMinorChannel)
- {
- m_MinorChannel = -1;
- }
- else
- {
- m_MinorChannel = lMinorChannel;
- }
- }
-
- switch(lMajorChannel)
- {
- case CHANNEL_UP: // up channel
- hr = pIScanningTuner->SeekUp();
-
- if(SUCCEEDED(hr))
- {
- m_MajorChannel++;
- }
- else
- {
- OutputDebugString("pIScanningTuner->SeekUp Failed\n");
- }
-
- break;
-
- case CHANNEL_DOWN: // down channel
- hr = pIScanningTuner->SeekDown();
-
- if(SUCCEEDED(hr))
- {
- m_MajorChannel--;
- }
- else
- {
- OutputDebugString("pIScanningTuner->SeekDown Failed\n");
- }
-
- break;
-
- default:
- if( lMajorChannel < CHANNEL_UPPER_LIMIT &&
- lMajorChannel > CHANNEL_LOWER_LIMIT &&
- m_MinorChannel < MINOR_CHANNEL_UPPER_LIMIT &&
- m_MinorChannel > MINOR_CHANNEL_LOWER_LIMIT)
-
- {
- // create tune request
- hr = CreateATSCTuneRequest(lMajorChannel, m_MinorChannel);
-
- if(SUCCEEDED(hr))
- {
- m_MajorChannel = lMajorChannel;
- }
- else
- {
- OutputDebugString("Cannot Change Channels\n");
- }
- }
-
- break;
- }
-
- err:
- SAFE_RELEASE(pIScanningTuner);
-
- return hr;
- }
-
-
- void
- CBDAFilterGraph::Refresh(HWND hDlg)
- {
- if(hDlg)
- {
- SetDlgItemInt(hDlg, IDC_MAJOR_CHANNEL, m_MajorChannel, FALSE);
- SetDlgItemInt(hDlg, IDC_MINOR_CHANNEL, m_MinorChannel, TRUE);
- }
- }
-
-
-
- // USE THE BELOW CODE 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))
- {
- OutputDebugString("Connecting Demux & Video Decoder Failed\n");
- goto err;
- }
- }
- else
- {
- //OutputDebugString("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))
- {
- OutputDebugString("Connecting Deumx & Audio Decoder Failed\n");
- goto err;
- }
- }
- else
- {
- OutputDebugString("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))
- {
- OutputDebugString("Adding OVMixer to the FilterGraph Failed\n");
- goto err;
- }
- }
- else
- {
- OutputDebugString("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))
- {
- OutputDebugString("Adding Video Renderer to the FilterGraph Failed\n");
- goto err;
- }
- }
- else
- {
- OutputDebugString("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))
- {
- OutputDebugString("Adding DirectSound Device to the FilterGraph Failed\n");
- goto err;
- }
- }
- else
- {
- OutputDebugString("Loading DirectSound Device Failed\n");
- goto err;
- }
- }
-
- hr = ConnectFilters(m_pVideoDecoder, m_pOVMixer);
-
- if(FAILED(hr))
- {
- OutputDebugString("Connecting Capture & OVMixer Failed\n");
- goto err;
- }
-
- hr = ConnectFilters(m_pOVMixer, m_pVRenderer);
-
- if(FAILED(hr))
- {
- OutputDebugString("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))
- {
- OutputDebugString("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))
- {
- OutputDebugString("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))
- {
- OutputDebugString("Unable to add Audio filter to graph\n");
- }
- }
-
- return hr;
- }
-
- */
-
-