DirectShowHelper.cpp

Go to the documentation of this file.
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))  // Already connected, not the pin we want.
00061                         {
00062                                 pTmp->Release();
00063                         }
00064                         else  // Unconnected, this is the pin we want.
00065                         {
00066                                 pEnum->Release();
00067                                 *ppPin = pPin;
00068                                 return S_OK;
00069                         }
00070                 }
00071                 pPin->Release();
00072         }
00073         pEnum->Release();
00074         // Did not find a matching pin.
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         // Find an input pin on the downstream filter.
00086         IPin *pIn = 0;
00087         HRESULT hr = CDirectShowHelper::GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
00088         if (FAILED(hr))
00089         {
00090                 return hr;
00091         }
00092         // Try to connect them.
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         // Find an output pin on the first filter.
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 //HRESULT CDirectShowHelper::GetFilterByCategory( IBaseFilter** gottaFilter, wchar_t* matchName, GUID Category )
00118 HRESULT CDirectShowHelper::GetFilterByCategory( IBaseFilter** gottaFilter, LPCWSTR matchName, GUID Category )
00119 {
00120         BOOL done = false;
00121 
00122         // Create the System Device Enumerator.
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         // Obtain a class enumerator for the audio input category.
00132         IEnumMoniker *pEnumCat = NULL;
00133         hr = pSysDevEnum->CreateClassEnumerator(Category, &pEnumCat, 0);
00134 
00135         if (hr == S_OK) 
00136         {
00137                 // Enumerate the monikers.
00138                 IMoniker *pMoniker = NULL;
00139                 ULONG cFetched;
00140                 while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done))
00141                 {
00142                         // Bind the first moniker to an object
00143                         IPropertyBag *pPropBag;
00144                         hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
00145                                 (void **)&pPropBag);
00146                         if (SUCCEEDED(hr))
00147                         {
00148                                 // To retrieve the filter's friendly name, do the following:
00149                                 VARIANT varName;
00150                                 VariantInit(&varName);
00151                                 hr = pPropBag->Read(L"FriendlyName", &varName, 0);
00152                                 if (SUCCEEDED(hr))
00153                                 {
00154                                         //wprintf(L"Testing Device: %s\n", varName.bstrVal);
00155 
00156                                         // Do a comparison, find out if it's the right one
00157                                         if (wcsncmp(varName.bstrVal, matchName, 
00158                                                 wcslen(matchName)) == 0) {
00159 
00160                                                         // We found it, so send it back to the caller
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;      // found it, return native error
00175         } else {
00176                 return VFW_E_NOT_FOUND; // didn't find it error
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         // First, create a document file which will hold the GRF file
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         // Next, create a stream to store.
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         // The IPersistStream converts a stream into a persistent object.
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         /* Obtain the filter's IBaseFilter interface. (Not shown) */
00251         ISpecifyPropertyPages *pProp;
00252         HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
00253         if (SUCCEEDED(hr)) 
00254         {
00255                 // Get the filter's name and IUnknown pointer.
00256                 FILTER_INFO FilterInfo;
00257                 hr = pFilter->QueryFilterInfo(&FilterInfo); 
00258                 IUnknown *pFilterUnk;
00259                 pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
00260 
00261                 // Show the page. 
00262                 CAUUID caGUID;
00263                 pProp->GetPages(&caGUID);
00264                 pProp->Release();
00265                 OleCreatePropertyFrame(
00266                         NULL,                   // Parent window
00267                         0, 0,                   // Reserved
00268                         FilterInfo.achName,     // Caption for the dialog box
00269                         1,                      // Number of objects (just the filter)
00270                         &pFilterUnk,            // Array of object pointers. 
00271                         caGUID.cElems,          // Number of property pages
00272                         caGUID.pElems,          // Array of property page CLSIDs
00273                         0,                      // Locale identifier
00274                         0, NULL                 // Reserved
00275                         );
00276 
00277                 // Clean up.
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         // Create the System Device Enumerator.
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         // Obtain a class enumerator for the audio input category.
00298         IEnumMoniker *pEnumCat = NULL;
00299         hr = pSysDevEnum->CreateClassEnumerator(Category, &pEnumCat, 0);
00300 
00301         if (hr == S_OK) 
00302         {
00303                 // Enumerate the monikers.
00304                 IMoniker *pMoniker = NULL;
00305                 ULONG cFetched;
00306                 while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done))
00307                 {
00308                         // Bind the first moniker to an object
00309                         IPropertyBag *pPropBag;
00310                         hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
00311                                 (void **)&pPropBag);
00312                         if (SUCCEEDED(hr))
00313                         {
00314                                 // To retrieve the filter's friendly name, do the following:
00315                                 VARIANT varName;
00316                                 VariantInit(&varName);
00317                                 hr = pPropBag->Read(L"FriendlyName", &varName, 0);
00318                                 if (SUCCEEDED(hr))
00319                                 {
00320                                         LPCWSTR mychar; // narrow string
00321                                         mychar = (LPCWSTR) (varName.bstrVal);
00322                                         //TODO
00323                                         vFilters.push_back(StringUtil::wideToStl(mychar));
00324                                         //USES_CONVERSION;
00325                                         //char* szTempBuffer = W2A(mychar);
00326                                         //szTempBuffer  = W2A(mychar);
00327                                         //vFilters.push_back(std::string(szTempBuffer));
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                         // Found a match. Return the IPin pointer to the caller.
00401                         *ppPin = pPin;
00402                         pEnum->Release();
00403                         return S_OK;
00404                 }
00405                 // Release the pin for the next time through the loop.
00406                 pPin->Release();
00407         }
00408         // No more pins. We did not find a match.
00409         pEnum->Release();
00410         return E_FAIL;
00411 }

Generated on Fri Mar 13 14:12:38 2009 for RTVC by  doxygen 1.5.3