graph.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:34k
- //------------------------------------------------------------------------------
- // 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 IGraphBuildern"));
- 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 providern"));
- 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 requestn"));
- 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 requestn"));
- 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 providern"));
- 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 tunern"));
- 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 tunern"));
- TearDownGraph();
- m_fGraphFailure = true;
- return hr;
- }
- // Step5: Load demux
- if(FAILED (hr = LoadDemux()))
- {
- ErrorMessageBox(TEXT("Cannot load demuxn"));
- 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 demuxn"));
- 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 SystemTuningSpacesn"));
- return hr;
- }
- CComVariant var (m_NetworkType);
- hr = pITuningSpaceContainer->get_Item(var, &m_pITuningSpace);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("Unable to retrieve Tuning Spacen"));
- }
- 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 pointern"));
- return E_POINTER;
- }
- // Making sure we have a valid tuning space
- if (m_pITuningSpace == NULL)
- {
- ErrorMessageBox(TEXT("Tuning Space is NULLn"));
- return E_FAIL;
- }
- // Create an instance of the ATSC tuning space
- CComQIPtr <IATSCTuningSpace> pATSCTuningSpace (m_pITuningSpace);
- if (!pATSCTuningSpace)
- {
- ErrorMessageBox(TEXT("Cannot QI for an IATSCTuningSpacen"));
- 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 failedn"));
- return hr;
- }
- hr = pATSCTuneRequest->put_MinorChannel(lMinorChannel);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("put_MinorChannel failedn"));
- return hr;
- }
- CComPtr <IATSCLocator> pATSCLocator;
- hr = pATSCLocator.CoCreateInstance (CLSID_ATSCLocator);
- if (FAILED( hr))
- {
- ErrorMessageBox(TEXT("Cannot create the ATSC locator failedn"));
- return hr;
- }
- // Set the initial physical channel.
- //
- hr = pATSCLocator->put_PhysicalChannel (lPhysicalChannel);
- if (FAILED( hr))
- {
- ErrorMessageBox(TEXT("Cannot put the physical channeln"));
- return hr;
- }
- hr = pATSCTuneRequest->put_Locator (pATSCLocator);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot put the locatorn"));
- 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 TuningSpacen"));
- return hr;
- }
- }
- // Get the current Network Type clsid
- hr = m_pITuningSpace->get_NetworkType(&bstrNetworkType);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("ITuningSpace::Get Network Type failedn"));
- return hr;
- }
- hr = CLSIDFromString(bstrNetworkType, &CLSIDNetworkType);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Couldn't get CLSIDFromStringn"));
- 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 Providern"));
- 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
- CBDAFilterGraph::LoadFilter(
- REFCLSID clsid,
- IBaseFilter** ppFilter,
- IBaseFilter* pConnectFilter,
- BOOL fIsUpstream
- )
- {
- HRESULT hr = S_OK;
- BOOL fFoundFilter = FALSE;
- CComPtr <IMoniker> pIMoniker;
- CComPtr <IEnumMoniker> pIEnumMoniker;
- if (!m_pICreateDevEnum)
- {
- hr = m_pICreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("LoadFilter(): Cannot CoCreate ICreateDevEnum"));
- return hr;
- }
- }
- // obtain the enumerator
- hr = m_pICreateDevEnum->CreateClassEnumerator(clsid, &pIEnumMoniker, 0);
- // the call can return S_FALSE if no moniker exists, so explicitly check S_OK
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("LoadFilter(): Cannot CreateClassEnumerator"));
- return hr;
- }
- if (S_OK != hr) // Class not found
- {
- ErrorMessageBox(TEXT("LoadFilter(): Class not found, CreateClassEnumerator returned S_FALSE"));
- return E_UNEXPECTED;
- }
- // next filter
- while(pIEnumMoniker->Next(1, &pIMoniker, 0) == S_OK)
- {
- // obtain filter's friendly name
- CComPtr <IPropertyBag> pBag;
- hr = pIMoniker->BindToStorage(
- NULL,
- NULL,
- IID_IPropertyBag,
- reinterpret_cast<void**>(&pBag)
- );
- if(FAILED(hr))
- {
- OutputDebugString (TEXT("LoadFilter(): Cannot BindToStorage"));
- return hr;
- }
- CComVariant varBSTR;
- hr = pBag->Read(L"FriendlyName", &varBSTR, NULL);
- if(FAILED(hr))
- {
- OutputDebugString (TEXT("LoadFilter(): IPropertyBag->Read method failed"));
- pIMoniker = NULL;
- continue;
- }
- // bind the filter
- CComPtr <IBaseFilter> pFilter;
- hr = pIMoniker->BindToObject(
- NULL,
- NULL,
- IID_IBaseFilter,
- reinterpret_cast<void**>(&pFilter)
- );
- if (FAILED(hr))
- {
- pIMoniker = NULL;
- pFilter = NULL;
- continue;
- }
- hr = m_pFilterGraph->AddFilter (pFilter, varBSTR.bstrVal);
- if (FAILED(hr))
- {
- OutputDebugString (TEXT("Cannot add filtern"));
- return hr;
- }
- //MessageBox (NULL, _T(""), _T(""), MB_OK);
- // 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;
- pFilter.QueryInterface (ppFilter);
- 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(TEXT("Failed unloading Filtern"));
- return hr;
- }
- }
- }
- else
- {
- fFoundFilter = TRUE;
- pFilter.QueryInterface (ppFilter);
- break;
- }
- pIMoniker = NULL;
- pFilter = NULL;
- } // while
- return S_OK;
- }
- // loads the demux into the FilterGraph
- HRESULT
- CBDAFilterGraph::LoadDemux()
- {
- HRESULT hr = S_OK;
-
- hr = CoCreateInstance(
- CLSID_MPEG2Demultiplexer,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- reinterpret_cast<void**>(&m_pDemux)
- );
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Could not CoCreateInstance CLSID_MPEG2Demultiplexern"));
- return hr;
- }
- hr = m_pFilterGraph->AddFilter(m_pDemux, L"Demux");
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("Unable to add demux filter to graphn"));
- return hr;
- }
- return hr;
- }
- // renders demux output pins
- HRESULT
- CBDAFilterGraph::RenderDemux()
- {
- HRESULT hr = S_OK;
- CComPtr <IPin> pIPin;
- CComPtr <IPin> pDownstreamPin;
- CComPtr <IEnumPins> pIEnumPins;
- PIN_DIRECTION direction;
- if (!m_pDemux)
- {
- return E_FAIL;
- }
- // connect the demux to the capture device
- hr = ConnectFilters (m_pCaptureDevice, m_pDemux);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot connect demux to capture filtern"));
- return hr;
- }
- // load transform information filter and connect it to the demux
- hr = LoadFilter (
- KSCATEGORY_BDA_TRANSPORT_INFORMATION,
- &m_pTIF,
- m_pDemux,
- TRUE
- );
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot load TIFn"));
- return hr;
- }
- // load multi protocol encapsulator
- hr = LoadFilter (
- KSCATEGORY_BDA_RECEIVER_COMPONENT,
- &m_pMPE,
- m_pDemux,
- TRUE
- );
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot load MPEn"));
- return hr;
- }
- // load IP Sink
- hr = LoadFilter (
- KSCATEGORY_IP_SINK,
- &m_pIPSink,
- m_pMPE,
- TRUE
- );
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot load IP Sinkn"));
- return hr;
- }
- // render/connect the rest of the demux pins
- hr = m_pDemux->EnumPins (&pIEnumPins);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Cannot get the enumpinsn"));
- return hr;
- }
- 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);
- }
- pDownstreamPin = NULL;
- }
- pIPin = NULL;
- }
- return hr;
- }
- // removes each filter from the graph
- HRESULT
- CBDAFilterGraph::TearDownGraph()
- {
- HRESULT hr = S_OK;
- CComPtr <IBaseFilter> pFilter;
- CComPtr <IEnumFilters> pIFilterEnum;
- m_pITuningSpace = NULL;
- 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);
- m_pIPSink = NULL;
- m_pMPE = NULL;
- m_pTIF = NULL;
- m_pDemux = NULL;
- m_pNetworkProvider = NULL;
- m_pTunerDevice = NULL;
- m_pDemodulatorDevice = NULL;
- m_pCaptureDevice = NULL;
- // now go unload rendered filters
- hr = m_pFilterGraph->EnumFilters(&pIFilterEnum);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("TearDownGraph: cannot EnumFiltersn"));
- return E_FAIL;
- }
- pIFilterEnum->Reset();
- while(pIFilterEnum->Next(1, &pFilter, 0) == S_OK) // addrefs filter
- {
- hr = m_pFilterGraph->RemoveFilter(pFilter);
- if (FAILED (hr))
- return hr;
- pIFilterEnum->Reset();
- pFilter.Release ();
- }
- }
- #ifdef REGISTER_FILTERGRAPH
- if (m_dwGraphRegister)
- {
- RemoveGraphFromRot(m_dwGraphRegister);
- m_dwGraphRegister = 0;
- }
- #endif
- m_fGraphBuilt = FALSE;
- return S_OK;
- }
- // ConnectFilters is called from BuildGraph
- // to enumerate and connect pins
- HRESULT
- CBDAFilterGraph::ConnectFilters(
- IBaseFilter* pFilterUpstream,
- IBaseFilter* pFilterDownstream
- )
- {
- HRESULT hr = E_FAIL;
- CComPtr <IPin> pIPinUpstream;
- PIN_INFO PinInfoUpstream;
- PIN_INFO PinInfoDownstream;
- // validate passed in filters
- ASSERT (pFilterUpstream);
- ASSERT (pFilterDownstream);
- // grab upstream filter's enumerator
- CComPtr <IEnumPins> pIEnumPinsUpstream;
- hr = pFilterUpstream->EnumPins(&pIEnumPinsUpstream);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("Cannot Enumerate Upstream Filter's Pinsn"));
- return hr;
- }
- // iterate through upstream filter's pins
- while (pIEnumPinsUpstream->Next (1, &pIPinUpstream, 0) == S_OK)
- {
- hr = pIPinUpstream->QueryPinInfo (&PinInfoUpstream);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("Cannot Obtain Upstream Filter's PIN_INFOn"));
- return hr;
- }
- CComPtr <IPin> pPinDown;
- 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
- CComPtr <IEnumPins> pIEnumPinsDownstream;
- hr = pFilterDownstream->EnumPins (&pIEnumPinsDownstream);
- if(FAILED(hr))
- {
- ErrorMessageBox(TEXT("Cannot enumerate pins on downstream filter!n"));
- return hr;
- }
- // iterate through downstream filter's pins
- CComPtr <IPin> pIPinDownstream;
- while (pIEnumPinsDownstream->Next (1, &pIPinDownstream, 0) == S_OK)
- {
- // make sure it is an input pin
- hr = pIPinDownstream->QueryPinInfo(&PinInfoDownstream);
- if(SUCCEEDED(hr))
- {
- CComPtr <IPin> pPinUp;
- // Determine if the pin is already connected. Note that
- // VFW_E_NOT_CONNECTED is expected if the pin isn't yet connected.
- hr = pIPinDownstream->ConnectedTo (&pPinUp);
- if(FAILED(hr) && hr != VFW_E_NOT_CONNECTED)
- {
- ErrorMessageBox(TEXT("Failed in pIPinDownstream->ConnectedTo()!n"));
- continue;
- }
- if ((PINDIR_INPUT == PinInfoDownstream.dir) && (pPinUp == NULL))
- {
- if (SUCCEEDED (m_pFilterGraph->Connect(
- pIPinUpstream,
- pIPinDownstream))
- )
- {
- PinInfoDownstream.pFilter->Release();
- PinInfoUpstream.pFilter->Release();
- return S_OK;
- }
- }
- }
- PinInfoDownstream.pFilter->Release();
- 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 graphn"));
- }
- }
- 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 Failedn"));
- return hr;
- }
- hr = pVideoWindow->put_Owner (reinterpret_cast <LONG> (hwndMain));
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Unable to set video windown"));
- return hr;
- }
- hr = pVideoWindow->put_WindowStyle (WS_CHILD);
- if (FAILED (hr))
- {
- ErrorMessageBox(TEXT("Unable to set the style for the video windown"));
- 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 requestn"));
- }
- else
- {
- ErrorMessageBox(TEXT("Cannot Change Channelsn"));
- }
- 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 ", (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 Failedn");
- goto err;
- }
- }
- else
- {
- //ErrorMessageBox("Unable to load Video Decodern");
- goto err;
- }
- //Audio
- hr = LoadAudioDecoder();
- if(SUCCEEDED(hr) && m_pAudioDecoder)
- {
- hr = ConnectFilters(m_pDemux, m_pAudioDecoder);
- if(FAILED(hr))
- {
- ErrorMessageBox("Connecting Deumx & Audio Decoder Failedn");
- goto err;
- }
- }
- else
- {
- ErrorMessageBox("Unable to load Audio Decodern");
- 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 Failedn");
- goto err;
- }
- }
- else
- {
- ErrorMessageBox("Loading OVMixer Failedn");
- 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 Failedn");
- goto err;
- }
- }
- else
- {
- ErrorMessageBox("Loading Video Renderer Failedn");
- 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 Failedn");
- goto err;
- }
- }
- else
- {
- ErrorMessageBox("Loading DirectSound Device Failedn");
- goto err;
- }
- }
- hr = ConnectFilters(m_pVideoDecoder, m_pOVMixer);
- if(FAILED(hr))
- {
- ErrorMessageBox("Connecting Capture & OVMixer Failedn");
- goto err;
- }
- hr = ConnectFilters(m_pOVMixer, m_pVRenderer);
- if(FAILED(hr))
- {
- ErrorMessageBox("Connecting OVMixer & Video Renderer Failedn");
- 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 Failedn");
- 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 graphn");
- }
- }
- 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 graphn");
- }
- }
- return hr;
- }
- */