#include "FilterGraphWrapper.h"
BOOL SelectFilterFromCategory(GUID CategorytoList, IBaseFilter** ppFilter, LPCWSTR pSelectedName)
{
BOOL bCaptureSelected = FALSE;
HRESULT hr = E_FAIL;
VARIANT varFiltername;
int UserChoice = 0;
(*ppFilter) = NULL;
while (UserChoice == 0)
{
CComPtr<ICreateDevEnum> pDevEnum = NULL;
CComPtr<IEnumMoniker> pEnumCapture = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CategorytoList, &pEnumCapture, 0);
}
pDevEnum = NULL;
if (hr == S_OK)
{
char UserInput[32] = {0};
int devCounter = 0;
CComPtr<IMoniker> pFilterMoniker = NULL;
while (pEnumCapture->Next(1, &pFilterMoniker, NULL) == S_OK)
{
devCounter++;
CComPtr<IPropertyBag> pPropBag;
HRESULT hr = pFilterMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (SUCCEEDED(hr))
{
VariantInit(&varFiltername);
hr = pPropBag->Read(L"FriendlyName", &varFiltername, 0);
if (SUCCEEDED(hr))
{
MosPrintf(MIL_TEXT(" %d: %s\n"), devCounter, varFiltername.bstrVal);
VariantClear(&varFiltername);
}
}
pFilterMoniker = NULL;
}
MosPrintf(MIL_TEXT("\nEnter the number corresponding to the desired filter:\n"));
MosPrintf(MIL_TEXT("Valid entries are from 1 to %d, (Q)uit: "), (devCounter));
scanf_s("%s", UserInput, (int)_countof(UserInput));
sscanf_s(UserInput, "%d", &UserChoice);
if (UserChoice < 1 || UserChoice >(int)devCounter)
{
char inputChar;
sscanf_s(UserInput, "%c", &inputChar, 1);
if (inputChar == 'q' ||
inputChar == 'Q')
{
UserChoice = -1;
}
else
{
MosPrintf(MIL_TEXT("Invalid selection. Select another filter.\n"));
UserChoice = 0;
}
}
else
{
bCaptureSelected = TRUE;
}
if (UserChoice > 0)
{
pEnumCapture->Reset();
devCounter = 0;
while (pEnumCapture->Next(1, &pFilterMoniker, NULL) == S_OK)
{
devCounter++;
if (devCounter == UserChoice)
{
CComPtr<IPropertyBag> pPropBag;
HRESULT hr = pFilterMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (SUCCEEDED(hr))
{
VariantInit(&varFiltername);
hr = pPropBag->Read(L"FriendlyName", &varFiltername, 0);
if (SUCCEEDED(hr))
{
MosPrintf(MIL_TEXT("The selected filter is: %s\n"), varFiltername.bstrVal);
size_t filterNameLen = MosStrlen(varFiltername.bstrVal) + 2;
MosSprintf(((wchar_t*)pSelectedName), filterNameLen, MIL_TEXT("%s"), varFiltername.bstrVal);
}
}
pFilterMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppFilter);
break;
}
pFilterMoniker = NULL;
}
}
VariantClear(&varFiltername);
pEnumCapture = NULL;
}
else
{
UserChoice = -1;
MosPrintf(MIL_TEXT("No filter available in this category.\n"));
}
}
MosPrintf(MIL_TEXT("\n"));
return bCaptureSelected;
}
MIL_INT FilterFormCategoryCount(GUID CategorytoList)
{
HRESULT hr = E_FAIL;
MIL_INT devCounter = 0;
CComPtr<ICreateDevEnum> pDevEnum = NULL;
CComPtr<IEnumMoniker> pEnumCapture = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CategorytoList, &pEnumCapture, 0);
}
pDevEnum = NULL;
if (hr == S_OK)
{
CComPtr<IMoniker> pFilterMoniker = NULL;
while (pEnumCapture->Next(1, &pFilterMoniker, NULL) == S_OK)
{
devCounter++;
pFilterMoniker = NULL;
}
}
return devCounter;
}
FilterGraphWrapper::FilterGraphWrapper()
{
}
FilterGraphWrapper::~FilterGraphWrapper()
{
}
HRESULT FilterGraphWrapper::InitGraph(const CLSID RendererGUID)
{
HRESULT hr = E_FAIL;
hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,
(void**)&m_pGraphBuilder);
}
else
{
MosPrintf(MIL_TEXT("\nERROR\n\nFailed to initialize Directshow Graph Builder\n"));
}
if (m_pGraphBuilder)
{
#if REGISTER_GRAPH
AddToRot(m_pGraphBuilder, &m_dwGraphRegister);
#endif
hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);
if (FAILED(hr))
{
MosPrintf(MIL_TEXT("\nERROR\n\nFailed to initialize IMediaControl Interface\n"));
}
}
if (SUCCEEDED(hr) && RendererGUID != CLSID_NULL)
{
CComPtr<IBaseFilter> pRendererfilter;
hr = CoCreateInstance(RendererGUID,
NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void**)&pRendererfilter);
if (SUCCEEDED(hr))
{
m_pGraphBuilder->AddFilter(pRendererfilter, L"Renderer");
}
pRendererfilter = NULL;
}
if (SUCCEEDED(hr))
{
m_bGraphInitialized = true;
}
return hr;
}
HRESULT FilterGraphWrapper::UninitGraph()
{
#if REGISTER_GRAPH
RemoveFromRot(m_dwGraphRegister);
#endif
m_pMediaControl = NULL;
m_pGraphBuilder = NULL;
CoUninitialize();
m_bGraphInitialized = false;
return S_OK;
}
HRESULT FilterGraphWrapper::InsertFilter(IBaseFilter* pFilter, LPCWSTR pFilterName, IPin** ppOutputPin)
{
HRESULT hr = E_FAIL;
if (pFilter != NULL)
{
hr = m_pGraphBuilder->AddFilter(pFilter, pFilterName);
if (SUCCEEDED(hr) && ppOutputPin)
hr = FindUnconnectedPin(pFilter, PINDIR_OUTPUT, ppOutputPin);
}
return hr;
}
HRESULT FilterGraphWrapper::Connect(IPin* pOutputPin, IBaseFilter* pDownstreamFilter)
{
HRESULT hr = S_FALSE;
if (pOutputPin && pDownstreamFilter)
hr = ConnectFilters(m_pGraphBuilder, pOutputPin, pDownstreamFilter);
return hr;
}
HRESULT FilterGraphWrapper::Connect(IBaseFilter* pUpstreamFilter, IBaseFilter* pDownstreamFilter)
{
HRESULT hr = S_OK;
CComPtr<IPin> pOutputPin = NULL;
if (pUpstreamFilter != NULL)
{
hr = FindUnconnectedPin(pUpstreamFilter, PINDIR_OUTPUT, &pOutputPin);
if (SUCCEEDED(hr) && pDownstreamFilter)
{
hr = Connect(pOutputPin, pDownstreamFilter);
}
}
return hr;
}
void FilterGraphWrapper::Render(IPin* pOutputPin)
{
if (pOutputPin)
m_pGraphBuilder->Render(pOutputPin);
}
void FilterGraphWrapper::Render(IBaseFilter* pFilter)
{
HRESULT hr = S_OK;
CComPtr<IPin> pOutputPin = NULL;
if (pFilter != NULL)
{
hr = FindUnconnectedPin(pFilter, PINDIR_OUTPUT, &pOutputPin);
if (SUCCEEDED(hr) && pOutputPin)
{
Render(pOutputPin);
}
}
}
HRESULT FilterGraphWrapper::StartGraph()
{
HRESULT hr = S_OK;
if (m_pMediaControl)
hr = m_pMediaControl->Run();
if (hr != S_OK)
{
OAFilterState filterGraphState = State_Stopped;
hr = m_pMediaControl->GetState(5000, &filterGraphState);
if (hr == VFW_S_STATE_INTERMEDIATE && filterGraphState == State_Running)
{
MosPrintf(MIL_TEXT("Some filters are still in an intermediate state.\n"));
}
else if(hr != S_OK || filterGraphState != State_Running)
{
MosPrintf(MIL_TEXT("ERROR\n\n"));
MosPrintf(MIL_TEXT("Failed to start all the filter in the graph.\n"));
}
}
return hr;
}
HRESULT FilterGraphWrapper::StopGraph()
{
HRESULT hr = S_OK;
if (m_pMediaControl)
hr = m_pMediaControl->Stop();
return hr;
}