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

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

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