?? graph.cpp
字號:
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 filter\n"));
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 Filter\n"));
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_MPEG2Demultiplexer\n"));
return hr;
}
hr = m_pFilterGraph->AddFilter(m_pDemux, L"Demux");
if(FAILED(hr))
{
ErrorMessageBox(TEXT("Unable to add demux filter to graph\n"));
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 filter\n"));
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 TIF\n"));
return hr;
}
// load multi protocol encapsulator
hr = LoadFilter (
KSCATEGORY_BDA_RECEIVER_COMPONENT,
&m_pMPE,
m_pDemux,
TRUE
);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Cannot load MPE\n"));
return hr;
}
// load IP Sink
hr = LoadFilter (
KSCATEGORY_IP_SINK,
&m_pIPSink,
m_pMPE,
TRUE
);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Cannot load IP Sink\n"));
return hr;
}
// render/connect the rest of the demux pins
hr = m_pDemux->EnumPins (&pIEnumPins);
if (FAILED (hr))
{
ErrorMessageBox(TEXT("Cannot get the enumpins\n"));
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 EnumFilters\n"));
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 Pins\n"));
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_INFO\n"));
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();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -