📄 mmsgraph.cpp
字号:
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, wstrFilterName);
}
else
{
// No filter name specified, cannot convert
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, NULL);
}
#else
// already unicode, no need to change anything
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, pstrFilterName);
#endif
// check the result of the operation
if(FAILED(hr))
{
TRACE("Could not add filter to filter graph\n");
// free the filter definitely
(*ppIFilter)->Release();
(*ppIFilter) = NULL;
return hr;
}
// that's it
return hr;
}
STDMETHODIMP CMMSGraph::RemoveFilter(IBaseFilter* pIFilter)
{
HRESULT hr;
// Parameters...
if(!pIFilter)
// DON'T return an error, this is expected
return NOERROR;
ASSERT(m_pGB);
// Just remove it from the graph
hr = m_pGB->RemoveFilter(pIFilter);
// Check the result
if(FAILED(hr))
TRACE("Could not remove filter from filter graph\n");
return hr;
}
STDMETHODIMP CMMSGraph::ConnectPins(IBaseFilter* pIFilterOutput,
LPCTSTR pstrPinNameOutput,
IBaseFilter* pIFilterInput,
LPCTSTR pstrPinNameInput,
AM_MEDIA_TYPE* pmt)
{
HRESULT hr;
ASSERT(m_pGB);
// Parameters...
if((!pIFilterOutput) || (!pIFilterInput))
{
//ASSERT(pIFilterOutput && pIFilterInput);
TRACE("ConnectPins called with NULL parameter\n");
return E_INVALIDARG;
}
// Find the first pin
IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput,
pstrPinNameOutput,
PINDIR_OUTPUT);
if(!pIPinOutput)
{
// ASSERT(pIPinOutput);
return E_FAIL;
}
// Find the second pin
IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
pstrPinNameInput,
PINDIR_INPUT);
if(!pIPinInput)
{
//ASSERT(pIPinInput);
// release the other pin
pIPinOutput->Release();
return E_FAIL;
}
if(FAILED(pIPinOutput->Disconnect()))
{
//ASSERT(FALSE);
return E_FAIL;
}
if(FAILED(pIPinInput->Disconnect()))
{
//ASSERT(FALSE);
return E_FAIL;
}
// Now just connect the two pins
if(NULL == pmt || pmt->cbFormat == 0)
hr = m_pGB->Connect(pIPinOutput, pIPinInput);
else
hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt);
if(FAILED(hr))
TRACE("Could not connect pins!");
// Release the two pins and return the result
pIPinOutput->Release();
pIPinInput->Release();
return hr;
}
STDMETHODIMP CMMSGraph::DisconnectPin(IBaseFilter *pIFilter,
LPCTSTR pstrPinName,
PIN_DIRECTION dir)
{
HRESULT hr;
ASSERT(m_pGB);
// Parameters...
if(!pIFilter)
// DON'T fail on this, it is expected
return NOERROR;
// Find the pin
IPin* pIPin = FindPinOnFilter(pIFilter, pstrPinName, dir);
if(!pIPin)
{
TRACE("Could not find specified filter pin\n");
return E_FAIL;
}
// Find the pin it's connected to
IPin* pIPinConnected;
hr = pIPin->ConnectedTo(&pIPinConnected);
if((FAILED(hr)) || (!pIPinConnected))
{
// Function call failed, pin not connected, nothing to do!
pIPin->Release();
return NOERROR;
}
// Try to disconnect the input pin first
if (dir == PINDIR_INPUT)
{
// ok now disconnect both of them
hr = m_pGB->Disconnect(pIPin);
if(FAILED(hr))
{
// just forget everything
ASSERT(SUCCEEDED(hr));
pIPin->Release();
pIPinConnected->Release();
TRACE("Disconnect failed on input pin\n");
return hr;
}
hr = m_pGB->Disconnect(pIPinConnected);
if(FAILED(hr))
{
ASSERT(SUCCEEDED(hr));
TRACE("Disconnect failed on output pin\n");
}
}
else
{
// ok now disconnect both of them
hr = m_pGB->Disconnect(pIPinConnected);
if(FAILED(hr))
{
ASSERT(SUCCEEDED(hr));
// just forget everything
pIPin->Release();
pIPinConnected->Release();
TRACE("Disconnect failed on input pin\n");
return hr;
}
hr = m_pGB->Disconnect(pIPin);
if(FAILED(hr))
{
ASSERT(SUCCEEDED(hr));
TRACE("Disconnect failed on output pin\n");
}
}
// Just release the two pins and return last result
pIPin->Release();
pIPinConnected->Release();
return hr;
}
STDMETHODIMP_(BOOL) CMMSGraph::IsConnected(IBaseFilter *pFilter,
LPCTSTR pstrPinName,
PIN_DIRECTION pd)
{
ASSERT(m_pGB);
// Parameters...
if((!pFilter))
{
ASSERT(pFilter);
TRACE("ConnectPins called with NULL parameter\n");
return FALSE;
}
// Find the pin
IPin* pIPin = FindPinOnFilter(pFilter,
pstrPinName,
pd);
if(!pIPin)
{
ASSERT(pIPin);
return FALSE;
}
IPin *pNextPin = NULL;
pIPin->ConnectedTo(&pNextPin);
if(!pNextPin)
{
return FALSE;
}
pIPin->Release();
pNextPin->Release();
//That's it...
return TRUE;
}
STDMETHODIMP_(IPin*) CMMSGraph::FindPinOnFilter(IBaseFilter* pIFilter,
LPCTSTR pstrPinName,
PIN_DIRECTION dir)
{
HRESULT hr;
IEnumPins* pIEnumPins;
IPin* pIPin;
PIN_INFO pi;
ASSERT(m_pGB);
// Parameters...
if(!pIFilter)
return NULL;
// Enumerate pins on the filter
hr = pIFilter->EnumPins(&pIEnumPins);
if(FAILED(hr))
// pin was not found!
return NULL;
// Loop till we find no more pins
IPin* pIPinFound = NULL;
while( (!pIPinFound) && (pIEnumPins->Next(1, &pIPin, NULL)==S_OK) )
{
// Is this the pin?
hr = pIPin->QueryPinInfo(&pi);
if(!FAILED(hr))
{
// check if it is the right direction
if(pi.dir == dir)
{
// Let the graph builder find the right filter
TCHAR strFoundPinName[256];
#ifndef _UNICODE
// not unicode, we need to de-unicodify the returned pin name
WideCharToMultiByte(CP_ACP, NULL,
pi.achName, -1,
strFoundPinName, sizeof(strFoundPinName),
NULL, NULL);
#else
// just make a copy of the string
lstrcpyn(strFoundPinName, pi.achName, sizeof(strFoundPinName));
#endif
// check if there is a pin name specified
if(!pstrPinName)
{
// no name specified, take the first pin found
pIPinFound = pIPin;
pIPinFound->AddRef();
}
// check if we have the right pin name
else if(lstrcmp(strFoundPinName, pstrPinName)==0)
{
// yes we have!
pIPinFound = pIPin;
pIPinFound->AddRef();
}
}
// release the PIN_INFO data
pi.pFilter->Release();
}
// release the IPin pointer
pIPin->Release();
}
// Finished with the enumerator, let it go (be free)
pIEnumPins->Release();
// Return whatever we have found
return pIPinFound;
}
HRESULT CMMSGraph::FindASFHandler(string strFilterName)
{
HRESULT hr;
IMoniker *pMoniker =NULL;
ULONG cFetched;
// Create the system device enumerator
ICreateDevEnum* pDevEnum = NULL;
hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **) &pDevEnum);
if (FAILED(hr))
{
TRACE1(TEXT("Couldn't create system enumerator! hr=0x%x"), hr);
return hr;
}
IEnumMoniker *pClassEnum = NULL;
hr = pDevEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory, &pClassEnum, 0);
if (FAILED(hr))
{
pDevEnum->Release();
TRACE1(TEXT("Couldn't create class enumerator! hr=0x%x"), hr);
return hr;
}
if (pClassEnum == NULL)
{
pDevEnum->Release();
return E_FAIL;
}
BOOL bFinded = FALSE;
while (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
int cch = lstrlenW(varName.bstrVal) + 1;
CHAR* lpszFilterName = new char[cch * 2];
if (!lpszFilterName)
return E_OUTOFMEMORY;
WideCharToMultiByte(GetACP(), 0, varName.bstrVal, -1,
lpszFilterName, cch, NULL, NULL);
string str;
str.append(lpszFilterName);
if(strFilterName == str)
{
if(str == "ASF ACM Handler")
{
pMoniker->BindToObject(NULL, NULL,
IID_IBaseFilter,
(VOID**)&m_pAsfAcmHandler);
bFinded = TRUE;
}
else if(str == "ASF ICM Handler")
{
pMoniker->BindToObject(NULL, NULL,
IID_IBaseFilter,
(VOID**)&m_pAsfIcmHandler);
bFinded = TRUE;
}
else
ASSERT(FALSE);
delete [] lpszFilterName;
VariantClear(&varName);
pPropBag->Release();
pMoniker->Release();
break;
}
delete [] lpszFilterName;
}
VariantClear(&varName);
pPropBag->Release();
}
pMoniker->Release();
}
pClassEnum->Release();
pDevEnum->Release();
if(bFinded)
return S_OK;
return E_FAIL;
}
STDMETHODIMP CMMSGraph::Initialize()
{
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
TRACE0("ERROR - Could not initialize COM library");
return hr;
}
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,
(void **)&m_pGB);
if (FAILED(hr))
{
TRACE0("ERROR - Could not create the Filter Graph Manager.");
return hr;
}
hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
if (FAILED(hr))
{
TRACE0("ERROR - Could not Get IMediaControl");
return hr;
}
AddGraphToRot(m_pGB, &g_dwRegister);
if(!BuildGraph())
{
return -1 ;
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -