The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Libraries/mputil/DirectShow/MPDirectShow.cpp

Go to the documentation of this file.
00001 /* 
00002  *  MPDirectShow.cpp
00003  *
00004  *  Created by Bret Fortenberry June 2004.
00005  *  Fixes: 
00006  * 
00007  *  Copyright (c) 2004 Machine Perception Laboratory 
00008  *  University of California San Diego.
00009  * 
00010  * Please read the disclaimer and notes about redistribution 
00011  * at the end of this file.
00012  *  
00013  */
00014 
00015 #include <windows.h>
00016 #include <stdlib.h>
00017 #include <malloc.h>
00018 #include <memory.h>
00019 #include <tchar.h>
00020 #include "MPDirectShow.h"
00021 #include "MPUFilter_uids.h"
00022 
00023 #define MAX_LOADSTRING 100
00024 #define FRAMERATE               30
00025 
00026 /*#define JIF(x) if (FAILED(hr=(x))) \
00027     { MessageBox(NULL, m_ErrMsg.GetBuffer(0), NULL, MB_OK); \
00028           m_ErrMsg = oldErr; \
00029           return hr;}*/
00030 #define JIF(x) if (FAILED(hr=(x))) \
00031     MessageBox(NULL, "failed",NULL,MB_OK);  
00032 #define JIF_NRTN(x) if (FAILED(hr=(x))) \
00033       MessageBox(NULL, "failed",NULL,MB_OK); 
00034 
00035 
00036 MPDirectShow::MPDirectShow()
00037 {
00038     HRESULT hr;
00039 
00040         //m_ErrMsg = "Could not initilize DirectShow";
00041 
00042         pGraph = NULL;
00043         pBuild = NULL;
00044         m_width = 320;
00045         m_height = 240;
00046         m_usingCompressor = FALSE;
00047         m_curProject = ds_mpisearch;
00048         m_recordMode = ds_stop;
00049         JIF_NRTN(CoInitialize(NULL));
00050 
00051         JIF(CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **) &pGraph));
00052         JIF(CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&pBuild));
00053         JIF(pBuild->SetFiltergraph(pGraph));
00054 
00055 //      m_ErrMsg = "Running MPDirectShow";
00056 }
00057 
00058 MPDirectShow::~MPDirectShow()
00059 {
00060         pControl->Stop();
00061         pEvent.Release();
00062         pWindow.Release();
00063         pControl.Release();
00064         if(pGraph) pGraph->Release();
00065         pBuild->Release();
00066 }
00067 
00068 void MPDirectShow::SetProject(ds_project curProject)
00069 {
00070         m_curProject = curProject;
00071 }
00072 
00073 void MPDirectShow::SetInput(int width, int height)
00074 {
00075         m_width = width;
00076         m_height = height;
00077 }
00078 
00079 
00080 HRESULT MPDirectShow::FindAllDevices( REFCLSID clsidDeviceClass, int* totalFound)
00081 {
00082     HRESULT hr;
00083         //CString oldErr = m_ErrMsg;
00084         //m_ErrMsg = "Error Finding Devices";
00085 
00086     // create an enumerator
00087     //
00088     CComPtr< ICreateDevEnum > pCreateDevEnum;
00089     JIF(pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum ));
00090     if( !pCreateDevEnum )
00091         return hr;
00092 
00093     // enumerate video capture devices
00094     //
00095     CComPtr< IEnumMoniker > pEm;
00096         JIF_NRTN(pCreateDevEnum->CreateClassEnumerator( clsidDeviceClass, &pEm, 0 ));
00097     if( !pEm )   {pCreateDevEnum.Release(); return hr;}
00098 
00099     pEm->Reset( );
00100 
00101     // go through and find first video capture device
00102     //
00103     CComPtr< IMoniker > pM;
00104     for( int i = 0; ; i++)
00105     {
00106 //              m_ErrMsg = "No Compressors found";
00107         ULONG ulFetched = 0;
00108 
00109         JIF_NRTN(pEm->Next( 1, &pM, &ulFetched ));
00110         if( hr != S_OK ) {
00111                         *totalFound = i;
00112                         break;
00113                 }
00114 
00115         // get the property bag interface from the moniker
00116         //
00117         CComPtr< IPropertyBag > pBag;
00118         hr = pM->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
00119         if( hr != S_OK )
00120                         continue; 
00121 
00122         // ask for the english-readable name
00123         //
00124         CComVariant var;
00125         var.vt = VT_BSTR;
00126         hr = pBag->Read( L"FriendlyName", &var, NULL ); 
00127         if( hr != S_OK )
00128                         continue;
00129 
00130         // set it in our UI
00131         //
00132         USES_CONVERSION;
00133                 char szName[256];
00134 
00135                 WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
00136                 strcpy(m_deviceNames[i], szName);
00137                 //MessageBox(NULL,szName, "Compressor name", MB_OK);
00138     }
00139 
00140         pCreateDevEnum.Release();
00141         pEm.Release();
00142 
00143         //m_ErrMsg = oldErr;
00144     return hr;
00145 }
00146 
00147 // ================================================================
00148 
00149 HRESULT MPDirectShow::GetDefaultCapDevice( IBaseFilter ** ppCap, REFCLSID clsidDeviceClass )
00150 {
00151     HRESULT hr;
00152         //CString oldErr = m_ErrMsg;
00153         //m_ErrMsg = "Error Loading Camera";
00154 
00155     *ppCap = NULL;
00156 
00157     // create an enumerator
00158     //
00159     CComPtr< ICreateDevEnum > pCreateDevEnum;
00160     JIF(pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum ));
00161     if( !pCreateDevEnum )
00162         return hr;
00163 
00164     // enumerate video capture devices
00165     //
00166     CComPtr< IEnumMoniker > pEm;
00167         JIF_NRTN(pCreateDevEnum->CreateClassEnumerator( clsidDeviceClass, &pEm, 0 ));
00168     if( !pEm )   {pCreateDevEnum.Release(); return hr;}
00169 
00170     pEm->Reset( );
00171 
00172     // go through and find first video capture device
00173     //
00174     CComPtr< IMoniker > pM;
00175     while( 1 )
00176     {
00177 //              m_ErrMsg = "No Cameras Connected";
00178         ULONG ulFetched = 0;
00179 
00180         JIF_NRTN(pEm->Next( 1, &pM, &ulFetched ));
00181         if( hr != S_OK ) break;
00182 
00183         // get the property bag interface from the moniker
00184         //
00185         CComPtr< IPropertyBag > pBag;
00186         hr = pM->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
00187         if( hr != S_OK )
00188                         continue; 
00189 
00190         // ask for the english-readable name
00191         //
00192         CComVariant var;
00193         var.vt = VT_BSTR;
00194         hr = pBag->Read( L"FriendlyName", &var, NULL );
00195         if( hr != S_OK )
00196                         continue;
00197 
00198         // set it in our UI
00199         //
00200         USES_CONVERSION;
00201         //SetDlgItemText( IDC_CAPOBJ, W2T( var.bstrVal ) );
00202 
00203         // ask for the actual filter
00204         //
00205         hr = pM->BindToObject( 0, 0, IID_IBaseFilter, (void**) ppCap );
00206         if( *ppCap ) break;
00207     }
00208 
00209         pCreateDevEnum.Release();
00210         pEm.Release();
00211 
00212         //m_ErrMsg = oldErr;
00213     return hr;
00214 }
00215 
00216 // ================================================================
00217 
00218 HRESULT MPDirectShow::GetListedDevice( IBaseFilter ** ppCom, REFCLSID clsidDeviceClass, char* deviceName)
00219 {
00220     HRESULT hr;
00221         //CString oldErr = m_ErrMsg;
00222         //m_ErrMsg = "Error Loading Device";
00223 
00224     *ppCom = NULL;
00225 
00226     // create an enumerator
00227     //
00228     CComPtr< ICreateDevEnum > pCreateDevEnum;
00229     JIF(pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum ));
00230     if( !pCreateDevEnum )
00231         return hr;
00232 
00233     // enumerate video capture devices
00234     //
00235     CComPtr< IEnumMoniker > pEm;
00236         JIF_NRTN(pCreateDevEnum->CreateClassEnumerator( clsidDeviceClass, &pEm, 0 ));
00237     if( !pEm )   {pCreateDevEnum.Release(); return hr;}
00238 
00239     pEm->Reset( );
00240 
00241     // go through and find first video capture device
00242     //
00243     CComPtr< IMoniker > pM;
00244     while( 1 )
00245     {
00246 //              m_ErrMsg = "No Devices found";
00247         ULONG ulFetched = 0;
00248 
00249         JIF_NRTN(pEm->Next( 1, &pM, &ulFetched ));
00250         if( hr != S_OK ) {
00251                         pCreateDevEnum.Release();
00252                         pEm.Release();
00253                         JIF(E_FAIL);
00254                 }
00255 
00256         // get the property bag interface from the moniker
00257         //
00258         CComPtr< IPropertyBag > pBag;
00259         hr = pM->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
00260         if( hr != S_OK )
00261                         continue; 
00262 
00263         // ask for the english-readable name
00264         //
00265         CComVariant var;
00266         var.vt = VT_BSTR;
00267         hr = pBag->Read( L"FriendlyName", &var, NULL );
00268         if( hr != S_OK )
00269                         continue;
00270 
00271         // set it in our UI
00272         //
00273         USES_CONVERSION;
00274                 char szName[256];
00275 
00276                 WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
00277                 //MessageBox(NULL,szName, "Compressor name", MB_OK);
00278 
00279         // ask for the actual filter
00280         //
00281                 if(!strcmp(szName, deviceName)) 
00282                 {
00283                         WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
00284                         //MessageBox(NULL,szName, "Device Found", MB_OK);
00285                         hr = pM->BindToObject( 0, 0, IID_IBaseFilter, (void**) ppCom );
00286                         if( *ppCom ) break;
00287                         else {
00288                                 pCreateDevEnum.Release();
00289                                 pEm.Release();
00290                                 JIF(E_FAIL);
00291                         }
00292                 }
00293     }
00294 
00295         pCreateDevEnum.Release();
00296         pEm.Release();
00297 
00298         //m_ErrMsg = oldErr;
00299     return hr;
00300 }
00301 
00302 // ================================================================
00303 
00304 HRESULT MPDirectShow::RunDirectShow(HWND hWnd)
00305 {
00306         HRESULT hr;
00307 //      CString oldErr = m_ErrMsg;
00308 //      m_ErrMsg = "MPDirectShow::RunDirectShow";
00309 
00310         //obtain a pointer to the MediaControl
00311         pControl = pGraph;
00312         pWindow = pGraph;
00313 
00314         // Build the graph manually
00315         JIF(CreateManualGraph(hWnd));
00316 
00317 
00318         SetDisplayWnd(hWnd);
00319 
00320         // run the graph
00321         pEvent = pGraph;
00322         JIF(pEvent->SetNotifyWindow(NULL, 0, 0));
00323 
00324         JIF(pControl->Run());
00325 
00326         //SaveVideo();
00327 //      m_ErrMsg = oldErr;
00328         return hr;
00329 }
00330 
00331 // ================================================================
00332 
00333 HRESULT MPDirectShow::CreateManualGraph(HWND hWnd)
00334 {
00335 
00336         HRESULT hr;
00337 //      CString oldErr = m_ErrMsg;
00338 //      m_ErrMsg = "Error Creating Graph";
00339 
00341         // Capture device
00342         CComPtr< IBaseFilter > pVideoCap;
00343 
00344         if(FAILED(pGraph->FindFilterByName(L"Video Camera", &pVideoCap)))
00345                         GetDefaultCapDevice( &pVideoCap, CLSID_VideoInputDeviceCategory );
00346         JIF(pGraph->AddFilter( pVideoCap, L"Video Camera" ));
00347 
00348         // Avi decompressor
00349         CComPtr< IBaseFilter > pAVIDecompressor;
00350         JIF(pAVIDecompressor.CoCreateInstance( CLSID_AVIDec ));
00351         JIF(pGraph->AddFilter(pAVIDecompressor, L"AVI Decompressor"));
00352 
00353         // MPLab Filter for running processes
00354         // Add any new filter to the list of struct **enum is defined in MPDirectShow.h
00355         CComPtr< IBaseFilter > pFaceFinder;
00356         switch (m_curProject) {
00357         case ds_mpisearch:
00358                 if (FAILED(hr = pFaceFinder.CoCreateInstance( CLSID_MPISearchFilter )))
00359                 {
00360                         MessageBox(NULL, (LPCTSTR)"The mpisearch filter is not registered", NULL, MB_OK); 
00361                         exit (-1);
00362                 }
00363                 break;
00364         case ds_eyefinder:
00365                 if (FAILED(hr = pFaceFinder.CoCreateInstance( CLSID_MPEyeFinderFilter )))
00366                 {
00367                         MessageBox(NULL, (LPCTSTR)"The EyeFinder filter is not registered", NULL, MB_OK); 
00368                         exit (-1);
00369                 }
00370                 break;
00371         case ds_colorTracker:
00372                 if (FAILED(hr = pFaceFinder.CoCreateInstance( CLSID_MPColorTrackerFilter )))
00373                 {
00374                         MessageBox(NULL, (LPCTSTR)"The ColorTracker filter is not registered", NULL, MB_OK); 
00375                         exit (-1);
00376                 }
00377                 break;
00378         case ds_blinkDetector:
00379                 if (FAILED(hr = pFaceFinder.CoCreateInstance( CLSID_MPBlinkDetectorFilter )))
00380                 {
00381                         MessageBox(NULL, (LPCTSTR)"The BlinkDetector filter is not registered", NULL, MB_OK); 
00382                         exit (-1);
00383                 }
00384                 break;
00385         case ds_mpisearchAda:
00386                 if (FAILED(hr = pFaceFinder.CoCreateInstance( CLSID_MPISearchAdaFilter )))
00387                 {
00388                         MessageBox(NULL, (LPCTSTR)"The mpisearch AdaBoost filter is not registered", NULL, MB_OK); 
00389                         exit (-1);
00390                 }
00391                 break;
00392         };
00393         JIF(pGraph->AddFilter(pFaceFinder, L"MPFilter"));
00394 
00395         // Smart Tee
00396         CComPtr< IBaseFilter > pSmartTee;
00397         JIF(pSmartTee.CoCreateInstance( CLSID_SmartTee ));
00398         JIF(pGraph->AddFilter(pSmartTee, L"Smart Tee"));
00399 
00400 
00402         CComQIPtr< IPin > pOutPin;
00403         CComQIPtr< IPin > pInPin;
00404 
00405         //get video dimensions
00406         JIF(GetPin(pVideoCap, PINDIR_OUTPUT, &pOutPin));
00407         JIF(GetPin(pAVIDecompressor, PINDIR_INPUT, &pInPin));
00408 
00409         CComQIPtr< IAMStreamConfig > pStreamConfig;
00410         pStreamConfig = pOutPin;
00411         AM_MEDIA_TYPE *pmt = NULL;
00412 
00413         JIF(GetMediaType(pOutPin, pInPin, pmt));
00414         JIF(pStreamConfig->SetFormat(pmt));
00415         JIF(pStreamConfig->GetFormat(&pmt));
00416 
00417         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER *) pmt->pbFormat;
00418         long lWidth  = vih->bmiHeader.biWidth;
00419         long lHeight = vih->bmiHeader.biHeight;
00420         lWidth = m_width;
00421         lHeight = m_height;
00422         vih->bmiHeader.biWidth = lWidth;
00423   vih->bmiHeader.biHeight = lHeight;
00424 
00425         vih->AvgTimePerFrame = (LONGLONG) 10000000/FRAMERATE;
00426 
00427         // Create video input interface
00428         ISpecifyPropertyPages *pProp;
00429         JIF(pVideoCap->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp));
00430         //if (SUCCEEDED(hr))
00431         {
00432                         // Get the filter's name and IUnknown pointer.
00433                         FILTER_INFO FilterInfo;
00434                         hr = pVideoCap->QueryFilterInfo(&FilterInfo);
00435                         IUnknown *pFilterUnk;
00436                         pVideoCap->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
00437 
00438                         // Show the page.
00439                         CAUUID caGUID;
00440                         pProp->GetPages(&caGUID);
00441                         pProp->Release();
00442                         OleCreatePropertyFrame(
00443                                         hWnd,                   // Parent window
00444                                         0, 0,                   // Reserved
00445                                         FilterInfo.achName,     // Caption for the dialog box
00446                                         1,                      // Number of objects (just the filter)
00447                                         &pFilterUnk,            // Array of object pointers.
00448                                         caGUID.cElems,          // Number of property pages
00449                                         caGUID.pElems,          // Array of property page CLSIDs
00450                                         0,                      // Locale identifier
00451                                         0, NULL                 // Reserved
00452                         );
00453 
00454                         // Clean up.
00455                         pFilterUnk->Release();
00456                         FilterInfo.pGraph->Release();
00457                         CoTaskMemFree(caGUID.pElems);
00458         }
00459 
00460         
00462         //  videoCapture -> aviDecompressor -> MPLabFilter 
00463         JIF(ConnectFilters(pVideoCap, pAVIDecompressor));
00464         JIF(ConnectFilters(pAVIDecompressor,pFaceFinder));
00465         JIF(ConnectFilters(pFaceFinder,pSmartTee));
00466 
00467 
00469         pOutPin.Release();
00470         GetPin_Name(pSmartTee, "Preview", &pOutPin);
00471         pGraph->Render(pOutPin);
00472 
00474         // input stream devices
00475         pOutPin.Release();
00476         pInPin.Release();
00477         pStreamConfig.Release();
00478         // graph devices
00479         pVideoCap.Release();
00480         pAVIDecompressor.Release();
00481         pFaceFinder.Release();
00482         pSmartTee.Release();
00483         
00484 //      m_ErrMsg = oldErr;
00485         return hr;
00486 
00487 }
00488 
00489 // ================================================================
00490 
00491 HRESULT MPDirectShow::SetDisplayWnd(HWND hWnd)
00492 {
00493         HRESULT hr;
00494 //      CString oldErr = m_ErrMsg;
00495 //      m_ErrMsg = "Error creating Display Graph";
00496 
00497         int nTitleHeight = GetSystemMetrics(SM_CYCAPTION);
00498         int nBorderWidth = GetSystemMetrics(SM_CXBORDER);
00499         int nMenuHeight= GetSystemMetrics(SM_CYMENU);
00500 
00501         int nBorderHeight = GetSystemMetrics(SM_CYBORDER);
00502         int screenMult = 3;
00503         SetWindowPos(hWnd, NULL, 0, 0, 640 + nBorderWidth, 480 + nTitleHeight + nBorderHeight + nMenuHeight, SWP_NOOWNERZORDER);
00504 
00505         RECT rect;
00506         GetClientRect(hWnd,&rect);
00507 
00508         JIF(pWindow->SetWindowPosition(rect.left, rect.top, rect.right, rect.bottom));
00509         JIF(pWindow->put_Owner( (OAHWND) hWnd )) ;
00510         JIF(pWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));
00511         //JIF(pWindow->put_Visible(TRUE));
00512 
00513 //      m_ErrMsg = oldErr;
00514         return hr;
00515 
00516 }
00517 
00518 // ================================================================
00519 
00520 HRESULT MPDirectShow::StopCapture()
00521 {
00522 
00523         HRESULT hr;
00524 //      CString oldErr = m_ErrMsg;
00525 //      m_ErrMsg = "Error trying to stop capture";
00526                 
00527         JIF(pControl->Stop());
00528 
00529         CComPtr< IBaseFilter > pAviMux;
00530         CComPtr< IBaseFilter > pFileWriter;
00531 
00532         JIF(pGraph->FindFilterByName(L"Mux", &pAviMux));
00533         JIF(pGraph->FindFilterByName(L"File Writer", &pFileWriter));
00534 
00535         JIF(pGraph->RemoveFilter(pFileWriter));
00536         JIF(pGraph->RemoveFilter(pAviMux));
00537 
00538         if(m_usingCompressor) {
00539                 CComPtr< IBaseFilter > pAviCom;
00540                 JIF(pGraph->FindFilterByName(L"AVI Compressor", &pAviCom));
00541                 JIF(pGraph->RemoveFilter(pAviCom));
00542                 pAviCom.Release();
00543         }
00544 
00545         JIF(pControl->Run());
00546 
00547         pAviMux.Release();
00548         pFileWriter.Release();
00549 
00550         m_recordMode = ds_stop;
00551 
00552 //      m_ErrMsg = oldErr;
00553         return hr;
00554 
00555 }
00556 
00557 // ================================================================
00558 
00559 HRESULT MPDirectShow::PauseFilter()
00560 {
00561         HRESULT hr;
00562 //      CString oldErr = m_ErrMsg;
00563 //      m_ErrMsg = "Error trying to pause capture";
00564 
00565         JIF(pControl->Pause());
00566         m_recordMode = ds_pause;
00567 
00568 //      m_ErrMsg = oldErr;
00569         return hr;
00570 }
00571 
00572 // ================================================================
00573 
00574 HRESULT MPDirectShow::RunFilter()
00575 {
00576         HRESULT hr;
00577 //      CString oldErr = m_ErrMsg;
00578 //      m_ErrMsg = "Error trying to restart capture";
00579 
00580         JIF(pControl->Run());
00581         if (m_recordMode == ds_pause)
00582                 m_recordMode = ds_capture;
00583 
00584 //      m_ErrMsg = oldErr;
00585         return hr;
00586 
00587 }
00588 
00589 // ================================================================
00590 
00591 HRESULT MPDirectShow::SaveVideo()
00592 {
00593         HRESULT hr;
00594 //      CString oldErr = m_ErrMsg;
00595 //      m_ErrMsg = "Error trying to start capture";
00596 
00597         /*JIF(pControl->Stop());
00598 
00599         CComPtr< IBaseFilter > pAviCom = NULL;
00600         CComPtr< IBaseFilter > pAviMux = NULL;
00601         CComPtr< IFileSinkFilter > pSink = NULL;
00602         CComPtr< IBaseFilter > pSmartTee;
00603         CComQIPtr< IPin > pOutPin;
00604 
00605         CFileDialog FileDlg (TRUE, "open file", "", OFN_ENABLESIZING, "AVI |*.avi||");
00606 
00607         POSITION im;
00608         CString pathname;
00609         if(FileDlg.DoModal() == IDOK){
00610                 im = FileDlg.GetStartPosition();
00611                 pathname = FileDlg.GetNextPathName(im);
00612         }
00613         else
00614                 return E_FAIL;
00615 
00616         LPWSTR outPath = new WCHAR[256];
00617         int nLen = MultiByteToWideChar(CP_ACP,0,pathname.GetBuffer(pathname.GetLength()),-1,NULL,NULL);
00618         MultiByteToWideChar(CP_ACP,0,pathname.GetBuffer(0),-1,outPath,nLen);
00619 
00620         JIF(pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, outPath, &pAviMux, &pSink));   
00621         JIF(pGraph->FindFilterByName(L"Smart Tee", &pSmartTee));
00622 
00623         JIF(GetPin_Name(pSmartTee, "Capture", &pOutPin));
00624         //Get Compressor if found add it
00625 
00626         int totalDevicesFound;
00627         hr = FindAllDevices( CLSID_VideoCompressorCategory, &totalDevicesFound);
00628         if(!FAILED(hr)) {
00629                 DeviceList deviceList;
00630                 deviceList.setDirectShow(this, totalDevicesFound, dl_compressor);
00631                 deviceList.DoModal();
00632         }
00633 
00634         hr = pGraph->FindFilterByName(L"AVI Compressor", &pAviCom);
00635         if(m_devicePos == totalDevicesFound || FAILED(hr)) {
00636                 JIF(ConnectFilters(pOutPin, pAviMux));
00637                 m_usingCompressor = FALSE;
00638         }
00639         else  {
00640                 JIF(pGraph->AddFilter( pAviCom, L"AVI Compressor" ));
00641                 JIF(ConnectFilters(pOutPin, pAviCom));
00642                 JIF(ConnectFilters(pAviCom, pAviMux));
00643                 m_usingCompressor = TRUE;
00644         }
00645 
00646         m_recordMode = ds_capture;
00647 
00648         pSink.Release();
00649         pAviMux.Release();
00650         pSmartTee.Release();
00651         pOutPin.Release();
00652         pAviCom.Release();
00653 
00654         JIF(pControl->Run());
00655 */
00656 //      m_ErrMsg = oldErr;
00657         return hr;
00658 }
00659 
00660 // ================================================================
00661 
00662 HRESULT MPDirectShow::ChangeMPFilter(HWND hWnd)
00663 {
00664         HRESULT hr;
00665 //      CString oldErr = m_ErrMsg;
00666 //      m_ErrMsg = "Error removing filters";
00667         OAFilterState pf;
00668 
00669         pControl->StopWhenReady();
00670 
00671         pControl->GetState(100, &pf);
00672         if(pf != State_Stopped)
00673                 return E_FAIL;
00674         CComPtr< IBaseFilter > pFaceFinder;
00675         CComPtr< IBaseFilter > pVideoRenderer;
00676         CComPtr< IBaseFilter > pAVIDecompressor;
00677         CComPtr< IBaseFilter > pVideoCap;
00678 
00679         pGraph->FindFilterByName(L"Video Renderer", &pVideoRenderer);
00680         pGraph->FindFilterByName(L"MPFilter", &pFaceFinder);
00681         pGraph->FindFilterByName(L"AVI Decompressor", &pAVIDecompressor);
00682         pGraph->FindFilterByName(L"Video Camera", &pVideoCap);
00683 
00684         hr = pGraph->RemoveFilter(pVideoRenderer);
00685         hr = pGraph->RemoveFilter(pFaceFinder);
00686         hr = pGraph->RemoveFilter(pAVIDecompressor);
00687         hr = pGraph->RemoveFilter(pVideoCap);
00688 
00689         pFaceFinder.Release();
00690         pVideoRenderer.Release();
00691         pAVIDecompressor.Release();
00692         pVideoCap.Release();
00693 
00694 //      m_ErrMsg = oldErr;
00695         return hr;
00696 }
00697 
00698 // ================================================================
00699 
00700 // Helper functions:
00701 HRESULT MPDirectShow::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
00702 {
00703         IEnumPins  *pEnum;
00704         IPin       *pPin;
00705         pFilter->EnumPins(&pEnum);
00706         while(pEnum->Next(1, &pPin, 0) == S_OK)
00707         {
00708                 PIN_DIRECTION PinDirThis;
00709                 pPin->QueryDirection(&PinDirThis);
00710                 if (PinDir == PinDirThis)
00711                 {
00712                         pEnum->Release();
00713                         *ppPin = pPin;
00714                         return S_OK;
00715                 }
00716                 pPin->Release();
00717         }
00718         pEnum->Release();
00719         return E_FAIL;
00720 }
00721 
00722 // ================================================================
00723 
00724 // Helper functions:
00725 HRESULT MPDirectShow::GetPin_Name(IBaseFilter *pFilter, char* name, IPin **ppPin)
00726 {
00727         IEnumPins  *pEnum;
00728         IPin       *pPin;
00729         pFilter->EnumPins(&pEnum);
00730         while(pEnum->Next(1, &pPin, 0) == S_OK)
00731         {
00732                 PIN_INFO PinInfo;
00733                 char szName[256];
00734 
00735                 pPin->QueryPinInfo(&PinInfo);
00736                 WideCharToMultiByte(CP_ACP,0,PinInfo.achName,-1,szName,256,0,0);
00737                 if (!strcmp(szName, name))
00738                 {
00739                         pEnum->Release();
00740                         PinInfo.pFilter->Release();
00741                         *ppPin = pPin;
00742                         return S_OK;
00743                 }
00744                 pPin->Release();
00745                 PinInfo.pFilter->Release();
00746         }
00747         pEnum->Release();
00748         return E_FAIL;
00749 }
00750 
00751 // ================================================================
00752 
00753 HRESULT MPDirectShow::ConnectFilters(IBaseFilter *pFirst, IBaseFilter *pSecond)
00754 {
00755         HRESULT hr;
00756 //      CString oldErr = m_ErrMsg;
00757 //      m_ErrMsg = "Error connecting filters";
00758 
00759         IPin *pOut = NULL, *pIn = NULL;
00760         JIF(GetPin(pFirst, PINDIR_OUTPUT, &pOut));
00761         hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
00762         if (FAILED(hr))
00763         {
00764                 pOut->Release();
00765                 JIF(hr);
00766         }
00767         JIF(pGraph->Connect(pOut, pIn));
00768         pIn->Release();
00769         pOut->Release();
00770 
00771 //      m_ErrMsg = oldErr;
00772         return hr;
00773 }
00774 
00775 // ================================================================
00776 
00777 HRESULT MPDirectShow::ConnectFilters(IPin *pOut, IBaseFilter *pSecond)
00778 {
00779         HRESULT hr;
00780 //      CString oldErr = m_ErrMsg;
00781 //      m_ErrMsg = "Error connecting filters";
00782 
00783         IPin *pIn = NULL;
00784         JIF(GetPin(pSecond, PINDIR_INPUT, &pIn));
00785 
00786         JIF(pGraph->Connect(pOut, pIn));
00787         pIn->Release();
00788 
00789 //      m_ErrMsg = oldErr;
00790         return hr;
00791 }
00792 
00793 // ================================================================
00794 
00795 HRESULT MPDirectShow::DisonnectFilters(IBaseFilter *pFilter, PIN_DIRECTION pindir)
00796 {
00797         HRESULT hr;
00798 //      CString oldErr = m_ErrMsg;
00799 //      m_ErrMsg = "Error disconnecting filters";
00800 
00801         IPin *pin = NULL;
00802         JIF(GetPin(pFilter, pindir, &pin));
00803         JIF(pGraph->Disconnect(pin));
00804         pin->Release();
00805 
00806 //      m_ErrMsg = oldErr;
00807         return hr;
00808 }
00809 
00810 // ================================================================
00811 
00812 void MPDirectShow::EnumFilters(void)
00813 {
00814         IEnumFilters *pEnum = NULL;
00815         IBaseFilter *pFilter;
00816         ULONG cFetched;
00817 
00818         pGraph->EnumFilters(&pEnum);
00819         while(pEnum->Next(1,&pFilter,&cFetched) == S_OK)
00820         {
00821                 FILTER_INFO FilterInfo;
00822                 char szName[256];
00823 
00824                 pFilter->QueryFilterInfo(&FilterInfo);
00825                 WideCharToMultiByte(CP_ACP,0,FilterInfo.achName,-1,szName,256,0,0);
00826                 MessageBox(NULL,szName, "Filter name", MB_OK);
00827                 FilterInfo.pGraph->Release();
00828                 pFilter->Release();
00829         }
00830         pEnum->Release();
00831 }
00832 
00833 // ================================================================
00834 
00835 void MPDirectShow::EnumPins(IBaseFilter *pFilter)
00836 {
00837         IEnumPins  *pEnum;
00838         IPin       *pPin;
00839         pFilter->EnumPins(&pEnum);
00840         while(pEnum->Next(1, &pPin, 0) == S_OK)
00841         {
00842                 PIN_INFO PinInfo;
00843                 char szName[256];
00844 
00845                 pPin->QueryPinInfo(&PinInfo);
00846                 WideCharToMultiByte(CP_ACP,0,PinInfo.achName,-1,szName,256,0,0);
00847                 MessageBox(NULL,szName, "Pin name", MB_OK);
00848                 PinInfo.pFilter->Release();
00849                 pPin->Release();
00850         }
00851         pEnum->Release();
00852 }
00853 
00854 // ================================================================
00855 
00856 // finds the first AM_MEDIA_TYPE from the input pin that correctly connects to the output pin
00857 HRESULT MPDirectShow::GetMediaType(IPin *outPin, IPin *inPin, AM_MEDIA_TYPE *ppMediaType)
00858 {
00859         IEnumMediaTypes *ppEnum;
00860         HRESULT hr;
00861 
00862         outPin->EnumMediaTypes(&ppEnum);
00863         while(ppEnum->Next(1, &ppMediaType, 0) == S_OK)
00864         {
00865 
00866                 if((hr = inPin->QueryAccept(ppMediaType)) == S_OK) {
00867                         ppEnum->Release();
00868                         return hr;
00869                 }
00870         }
00871         ppEnum->Release();
00872         return hr;
00873 }
00874 
00875 // ================================================================
00876 
00877 HRESULT MPDirectShow::SaveGraphEditFile(WCHAR* wszFileName)
00878 {
00879     const WCHAR wszStreamName[] = L"ActiveMovieGraph";
00880     HRESULT hr;
00881 //      CString oldErr = m_ErrMsg;
00882 //      m_ErrMsg = "Error connecting filters";
00883 
00884     IStorage *pStorage = NULL;
00885     JIF(StgCreateDocfile(
00886         wszFileName,
00887         STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
00888         0, &pStorage));
00889 
00890     IStream *pStream;
00891     hr = pStorage->CreateStream(
00892         wszStreamName,
00893         STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
00894         0, 0, &pStream);
00895     if (FAILED(hr))
00896     {
00897         pStorage->Release();
00898         JIF(hr);
00899     }
00900 
00901     CComQIPtr< IPersistStream > pPersist; //IPersistStream *pPersist = NULL;
00902     pPersist = pGraph; //pGraph->QueryInterface(IID_IPersistStream, reinterpret_cast<void**>(&pPersist));
00903     hr = pPersist->Save(pStream, TRUE);
00904     pStream->Release();
00905     pPersist.Release(); //pPersist->Release();
00906     if (SUCCEEDED(hr))
00907     {
00908         hr = pStorage->Commit(STGC_DEFAULT);
00909     }
00910     pStorage->Release();
00911         JIF(hr);
00912 
00913 //      m_ErrMsg = oldErr;
00914     return hr;
00915 }
00916 
00917 // ================================================================
00918 
00919 int MPDirectShow::GetVideoDevices() {
00920         HRESULT hr;
00921         int totalDevicesFound;
00922 
00923         hr = FindAllDevices( CLSID_VideoInputDeviceCategory, &totalDevicesFound);
00924 
00925         return totalDevicesFound;
00926 }
00927 
00928 // ================================================================
00929 
00930 void MPDirectShow::SetVideoDevices(int pos) {
00931         HRESULT hr;
00932         CComPtr< IBaseFilter > pVideoCap;
00933 
00934         GetListedDevice( &pVideoCap, CLSID_VideoInputDeviceCategory, m_deviceNames[pos]);
00935         JIF(pGraph->AddFilter( pVideoCap, L"Video Camera" ));
00936 }
00937 
00938 // ================================================================
00939 
00940 /*
00941  * 
00942  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00943  * 
00944  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00945  *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
00946  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00947  * 
00948  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00949  * 
00950  */
00951 

Generated on Mon Nov 8 17:07:43 2004 for MPT by  doxygen 1.3.9.1