00001
00034 #include "stdafx.h"
00035 #include "DirectShowHelper.h"
00036 #include <Shared/StringUtil.h>
00037
00038
00039 CDirectShowHelper::CDirectShowHelper()
00040 {;}
00041
00042 HRESULT CDirectShowHelper::GetUnconnectedPin( IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
00043 {
00044 *ppPin = 0;
00045 IEnumPins *pEnum = 0;
00046 IPin *pPin = 0;
00047 HRESULT hr = pFilter->EnumPins(&pEnum);
00048 if (FAILED(hr))
00049 {
00050 return hr;
00051 }
00052 while (pEnum->Next(1, &pPin, NULL) == S_OK)
00053 {
00054 PIN_DIRECTION ThisPinDir;
00055 pPin->QueryDirection(&ThisPinDir);
00056 if (ThisPinDir == PinDir)
00057 {
00058 IPin *pTmp = 0;
00059 hr = pPin->ConnectedTo(&pTmp);
00060 if (SUCCEEDED(hr))
00061 {
00062 pTmp->Release();
00063 }
00064 else
00065 {
00066 pEnum->Release();
00067 *ppPin = pPin;
00068 return S_OK;
00069 }
00070 }
00071 pPin->Release();
00072 }
00073 pEnum->Release();
00074
00075 return E_FAIL;
00076 }
00077
00078 HRESULT CDirectShowHelper::ConnectFilters( IGraphBuilder *pGraph, IPin *pOut, IBaseFilter *pDest )
00079 {
00080 if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
00081 {
00082 return E_POINTER;
00083 }
00084
00085
00086 IPin *pIn = 0;
00087 HRESULT hr = CDirectShowHelper::GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
00088 if (FAILED(hr))
00089 {
00090 return hr;
00091 }
00092
00093 hr = pGraph->Connect(pOut, pIn);
00094 pIn->Release();
00095 return hr;
00096 }
00097
00098 HRESULT CDirectShowHelper::ConnectFilters( IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest )
00099 {
00100 if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
00101 {
00102 return E_POINTER;
00103 }
00104
00105
00106 IPin *pOut = 0;
00107 HRESULT hr = CDirectShowHelper::GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
00108 if (FAILED(hr))
00109 {
00110 return hr;
00111 }
00112 hr = ConnectFilters(pGraph, pOut, pDest);
00113 pOut->Release();
00114 return hr;
00115 }
00116
00117
00118 HRESULT CDirectShowHelper::GetFilterByCategory( IBaseFilter** gottaFilter, LPCWSTR matchName, GUID Category )
00119 {
00120 BOOL done = false;
00121
00122
00123 ICreateDevEnum *pSysDevEnum = NULL;
00124 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
00125 IID_ICreateDevEnum, (void **)&pSysDevEnum);
00126 if (FAILED(hr))
00127 {
00128 return hr;
00129 }
00130
00131
00132 IEnumMoniker *pEnumCat = NULL;
00133 hr = pSysDevEnum->CreateClassEnumerator(Category, &pEnumCat, 0);
00134
00135 if (hr == S_OK)
00136 {
00137
00138 IMoniker *pMoniker = NULL;
00139 ULONG cFetched;
00140 while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done))
00141 {
00142
00143 IPropertyBag *pPropBag;
00144 hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
00145 (void **)&pPropBag);
00146 if (SUCCEEDED(hr))
00147 {
00148
00149 VARIANT varName;
00150 VariantInit(&varName);
00151 hr = pPropBag->Read(L"FriendlyName", &varName, 0);
00152 if (SUCCEEDED(hr))
00153 {
00154
00155
00156
00157 if (wcsncmp(varName.bstrVal, matchName,
00158 wcslen(matchName)) == 0) {
00159
00160
00161 hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**) gottaFilter);
00162 done = true;
00163 }
00164 }
00165 VariantClear(&varName);
00166 pPropBag->Release();
00167 }
00168 pMoniker->Release();
00169 }
00170 pEnumCat->Release();
00171 }
00172 pSysDevEnum->Release();
00173 if (done) {
00174 return hr;
00175 } else {
00176 return VFW_E_NOT_FOUND;
00177 }
00178 }
00179
00180 HRESULT CDirectShowHelper::GetFilterByCategory( IBaseFilter** gottaFilter, std::string sMatchName, GUID Category )
00181 {
00182 WCHAR* wszName = StringUtil::stlToWide(sMatchName);
00183 HRESULT hr = CDirectShowHelper::GetFilterByCategory(gottaFilter, wszName, Category);
00184 delete wszName;
00185 return hr;
00186 }
00187
00188 HRESULT CDirectShowHelper::SaveGraphFile( IGraphBuilder *pGraph, WCHAR *wszPath )
00189 {
00190 const WCHAR wszStreamName[] = L"ActiveMovieGraph";
00191 HRESULT hr;
00192 IStorage *pStorage = NULL;
00193
00194
00195 hr = StgCreateDocfile(
00196 wszPath,
00197 STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
00198 0, &pStorage);
00199 if(FAILED(hr))
00200 {
00201 return hr;
00202 }
00203
00204
00205 IStream *pStream;
00206 hr = pStorage->CreateStream(
00207 wszStreamName,
00208 STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
00209 0, 0, &pStream);
00210 if (FAILED(hr))
00211 {
00212 pStorage->Release();
00213 return hr;
00214 }
00215
00216
00217 IPersistStream *pPersist = NULL;
00218 pGraph->QueryInterface(IID_IPersistStream, reinterpret_cast<void**>(&pPersist));
00219 hr = pPersist->Save(pStream, TRUE);
00220 pStream->Release();
00221 pPersist->Release();
00222 if (SUCCEEDED(hr))
00223 {
00224 hr = pStorage->Commit(STGC_DEFAULT);
00225 }
00226 pStorage->Release();
00227 return hr;
00228 }
00229
00230 HRESULT CDirectShowHelper::AddFilterByCLSID( IGraphBuilder *pGraph, const GUID& clsid, LPCWSTR wszName, IBaseFilter **ppF )
00231 {
00232 if (!pGraph || ! ppF) return E_POINTER;
00233 *ppF = 0;
00234 IBaseFilter *pF = 0;
00235 HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
00236 IID_IBaseFilter, reinterpret_cast<void**>(&pF));
00237 if (SUCCEEDED(hr))
00238 {
00239 hr = pGraph->AddFilter(pF, wszName);
00240 if (SUCCEEDED(hr))
00241 *ppF = pF;
00242 else
00243 pF->Release();
00244 }
00245 return hr;
00246 }
00247
00248 HRESULT CDirectShowHelper::ShowFilterPropertyPages( IBaseFilter *pFilter )
00249 {
00250
00251 ISpecifyPropertyPages *pProp;
00252 HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
00253 if (SUCCEEDED(hr))
00254 {
00255
00256 FILTER_INFO FilterInfo;
00257 hr = pFilter->QueryFilterInfo(&FilterInfo);
00258 IUnknown *pFilterUnk;
00259 pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
00260
00261
00262 CAUUID caGUID;
00263 pProp->GetPages(&caGUID);
00264 pProp->Release();
00265 OleCreatePropertyFrame(
00266 NULL,
00267 0, 0,
00268 FilterInfo.achName,
00269 1,
00270 &pFilterUnk,
00271 caGUID.cElems,
00272 caGUID.pElems,
00273 0,
00274 0, NULL
00275 );
00276
00277
00278 pFilterUnk->Release();
00279 FilterInfo.pGraph->Release();
00280 CoTaskMemFree(caGUID.pElems);
00281 }
00282 return hr;
00283 }
00284
00285 HRESULT CDirectShowHelper::GetFilterNamesByCategory( GUID Category, FILTER_NAME_LIST& vFilters )
00286 {
00287 BOOL done = false;
00288
00289 ICreateDevEnum *pSysDevEnum = NULL;
00290 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
00291 IID_ICreateDevEnum, (void **)&pSysDevEnum);
00292 if (FAILED(hr))
00293 {
00294 return hr;
00295 }
00296
00297
00298 IEnumMoniker *pEnumCat = NULL;
00299 hr = pSysDevEnum->CreateClassEnumerator(Category, &pEnumCat, 0);
00300
00301 if (hr == S_OK)
00302 {
00303
00304 IMoniker *pMoniker = NULL;
00305 ULONG cFetched;
00306 while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done))
00307 {
00308
00309 IPropertyBag *pPropBag;
00310 hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
00311 (void **)&pPropBag);
00312 if (SUCCEEDED(hr))
00313 {
00314
00315 VARIANT varName;
00316 VariantInit(&varName);
00317 hr = pPropBag->Read(L"FriendlyName", &varName, 0);
00318 if (SUCCEEDED(hr))
00319 {
00320 LPCWSTR mychar;
00321 mychar = (LPCWSTR) (varName.bstrVal);
00322
00323 vFilters.push_back(StringUtil::wideToStl(mychar));
00324
00325
00326
00327
00328 }
00329 VariantClear(&varName);
00330 pPropBag->Release();
00331 }
00332 pMoniker->Release();
00333 }
00334 pEnumCat->Release();
00335 }
00336 pSysDevEnum->Release();
00337 return S_OK;
00338 }
00339
00340
00341 HRESULT CDirectShowHelper::GetVideoInputs(FILTER_NAME_LIST& vList )
00342 {
00343 return GetFilterNamesByCategory(CLSID_VideoInputDeviceCategory, vList);
00344 }
00345
00346 HRESULT CDirectShowHelper::GetAudioInputs(FILTER_NAME_LIST& vList)
00347 {
00348 return GetFilterNamesByCategory(CLSID_AudioInputDeviceCategory, vList);
00349 }
00350
00351 HRESULT CDirectShowHelper::AddFilterByCategoryAndName( IGraphBuilder *pGraph, const GUID& category, LPCWSTR wszName, IBaseFilter **ppF )
00352 {
00353 HRESULT hr = CDirectShowHelper::GetFilterByCategory(ppF, wszName, category);
00354 if (SUCCEEDED(hr))
00355 {
00356 hr = pGraph->AddFilter(*ppF, wszName);
00357 }
00358 else
00359 {
00360 return hr;
00361 }
00362 }
00363
00364 HRESULT CDirectShowHelper::AddFilterByCategoryAndName( IGraphBuilder *pGraph, const GUID& category, std::string sName, IBaseFilter **ppF )
00365 {
00366 WCHAR* wszName = StringUtil::stlToWide(sName);
00367 HRESULT hr = CDirectShowHelper::AddFilterByCategoryAndName(pGraph, category, wszName, ppF);
00368 delete[] wszName;
00369 return hr;
00370 }
00371
00372 HRESULT CDirectShowHelper::GetPin( IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin )
00373 {
00374 IEnumPins *pEnum = NULL;
00375 IPin *pPin = NULL;
00376 HRESULT hr;
00377
00378 if (ppPin == NULL)
00379 {
00380 return E_POINTER;
00381 }
00382
00383 hr = pFilter->EnumPins(&pEnum);
00384 if (FAILED(hr))
00385 {
00386 return hr;
00387 }
00388 while(pEnum->Next(1, &pPin, 0) == S_OK)
00389 {
00390 PIN_DIRECTION PinDirThis;
00391 hr = pPin->QueryDirection(&PinDirThis);
00392 if (FAILED(hr))
00393 {
00394 pPin->Release();
00395 pEnum->Release();
00396 return hr;
00397 }
00398 if (PinDir == PinDirThis)
00399 {
00400
00401 *ppPin = pPin;
00402 pEnum->Release();
00403 return S_OK;
00404 }
00405
00406 pPin->Release();
00407 }
00408
00409 pEnum->Release();
00410 return E_FAIL;
00411 }