转自:http://blog.csdn.net/northcan/article/details/7268745
WinCE系统下基于DirectShow的摄像头应用编程
在WinCE设备上使用摄像头时,一般都是向厂家索要驱动。对于摄像头设备,WinCE会有一个标准的流驱动框架,大多数厂商就会按照这个标准完成WinCE系统下的摄像头驱动程序。
一般情况下,视频采集设备被封装成Filter,并包含相应的Pin(比如Capture Pin、Preview Pin)。这样程序员就可以通过Pin连接的Filter Graph来完成摄像头的视频采集应用,这里以汪兵老师封装的CEricCamera为例,简单学习一下。
(a) 首先本例中使用到的DirectShow接口一共有9个,如下:
-
-
CComPtr<ICaptureGraphBuilder2> m_pCaptureGraphBuilder;
-
-
-
CComPtr<IGraphBuilder> m_pGraphBuilder;
-
-
-
CComPtr<IBaseFilter> m_pVideoCaptureFilter;
-
-
-
CComPtr<IPersistPropertyBag> m_pPropertyBag ;
-
-
-
CComPtr<IBaseFilter> m_pImageSinkFilter;
-
-
-
CComPtr<IMediaControl> m_pMediaControl ;
-
-
-
CComPtr<IVideoWindow> m_pVideoWindow ;
-
-
-
CComPtr<IMediaSeeking> m_pMediaSeeking;
-
-
-
CComPtr<IMediaEvent> m_pMediaEvent;
(b) 下面是利用这些DirectShow接口及其方法,完成摄像头视频采集的基本流程。
(1) 创建Capture Gpaph Builder组件,而该组件由ICaptureGraphBuilder2接口实现,所以首先创建ICaptureGraphBuilder2接口。
-
m_pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder);
(2) 创建IGraphBuilder接口。
-
m_pGraphBuilder.CoCreateInstance(CLSID_FilterGraph);
(3)将ICaptureGraphBuilder2接口与IGraphBuilder接口连接起来,即调用ICaptureGraphBuilder2接口的SetFilterGraph方法,并将IGraphBuilder接口对象指针传递给它。以便后面将Capture到的数据通过Filter Graph构造成视频数据。
-
m_pCaptureGraphBuilder->SetFiltergraph(m_pGraphBuilder );
(4) 获取IMediaControl接口,后面将通过该接口的Run,Pause,Stop方法控制视频流的播放。
-
m_pGraphBuilder.QueryInterface(&m_pMediaControl);
(5) 获取IMediaControl接口,用于对多媒体数据流的播放位置等属性进行控制。如GetCurrentPositions获得当前播放位置。
-
m_pGraphBuilder.QueryInterface(&m_pMediaSeeking);
(6) 获取m_pMediaEvent接口,用于获取Filter Graph产生的事件。
-
m_pGraphBuilder.QueryInterface(&m_pMediaEvent);
(7) 创建视频捕捉过滤器(Filter)。
-
m_pVideoCaptureFilter.CoCreateInstance(CLSID_VideoCapture)
(8) 通过(7)中创建的视频捕捉过滤器,获取视频捕捉属性页接口(IPersistPropertyBag)。
-
m_pVideoCaptureFilter->QueryInterface(&m_pPropertyBag);
(9) 得到视频捕捉设备名。
-
GetFirstCameraDriver(wzDeviceName );
-
varCamName = wzDeviceName;
(10) 初始化(8)中获取的视频捕捉属性页接口m_pPropertyBag,设置视频捕捉设备名。
-
PropBag.Write(TEXT("VCapName"), &varCamName);
-
m_pPropertyBag->Load(&PropBag, NULL);
(11) 将(7)中创建的视频捕捉过滤器接口m_pVideoCaptureFilter添加到Filter Graph(过滤器图)中。
-
m_pGraphBuilder->AddFilter( m_pVideoCaptureFilter, TEXT("Video capture source" ));
(12) 创建IDMOWrapperFilter接口。
-
CComPtr<IBaseFilter> pVideoEncoder;
-
pVideoEncoder.CoCreateInstance(CLSID_DMOWrapperFilter);
-
CComPtr<IDMOWrapperFilter> pWrapperFilter;
-
pVideoEncoder.QueryInterface(&pWrapperFilter);
(13) 利用(12)中创建的IDMOWrapperFilter接口pWrapperFilter,加载WMV9 DMO Encoder(WMV格式的编码器),因为我们将使用该编码器将摄像头采集到的视频数据编码为WMV格式的视频文件。
-
pWrapperFilter->Init(CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER);
(14) 将WMV9编码器添加到Filter Graph(过滤器图)中。
-
m_pGraphBuilder->AddFilter( pVideoEncoder, TEXT("WMV9 DMO Encoder"));
(15) 创建ASF多路(复用)器,并加入到过滤器图中。
-
m_pCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Asf,strFileName, &pASFMultiplexer, &pFileSinkFilter);
(16) 渲染预览视频Pin。
-
m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, NULL);
(17) 获取IVideoWindow接口,用于设置多媒体播放窗口的属性。如put_Owner指定视频播放窗口,put_WindowStyle设置视频窗口风格属性。
-
m_pGraphBuilder.QueryInterface(&m_pVideoWindow);
(18) 设置视频播放窗口及窗口风格。
-
m_pVideoWindow->put_Owner((OAHWND)hVideoWnd);
-
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
-
GetClientRect(hVideoWnd,&rectVideo);
-
m_pVideoWindow->SetWindowPosition(0,0,rectVideo.Width(),rectVideo.Height());
-
m_pVideoWindow->put_Visible(OATRUE);
(19) 渲染捕捉Pin用于录像。
-
m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter,pVideoEncoder, pASFMultiplexer);
(20) 创建Still Pin(静态Pin)用于抓图。下面的代码首先创建静态捕捉Pin过滤器接口m_pImageSinkFilter,然后将其添加到Filter Graph(过滤器图)中,最后渲染Still Pin(静态Pin)。
-
m_pImageSinkFilter.CoCreateInstance(CLSID_IMGSinkFilter);
-
m_pGraphBuilder->AddFilter(m_pImageSinkFilter, TEXT("Still image filter"));
-
m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_STILL, &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, m_pImageSinkFilter);
(21) 设置捕捉流暂停。
-
m_pCaptureGraphBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0, 0);
(22) 预览视频
(c) 下面是汪兵老师封装的CEricCamera类完整源代码,该类主要导出4个公共接口:PreviewCamera预览视频,StartRecord开始录像,StopRecord停止录像,SnapPicture抓拍。
(1) PropertyBag.h
-
#pragma once
-
-
struct VAR_LIST
-
{
-
VARIANT var;
-
VAR_LIST *pNext;
-
BSTR pBSTRName;
-
};
-
-
class CPropertyBag : public IPropertyBag
-
{
-
public:
-
HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog);
-
HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT *pVar);
-
ULONG STDMETHODCALLTYPE AddRef();
-
ULONG STDMETHODCALLTYPE Release();
-
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
-
CPropertyBag();
-
~CPropertyBag();
-
private:
-
ULONG _refCount;
-
VAR_LIST *pVar;
-
};
(2) PropertyBag.cpp
-
#include "StdAfx.h"
-
#include "PropertyBag.h"
-
#include <Ocidl.h>
-
#include <oleauto.h>
-
-
-
CPropertyBag::CPropertyBag() : _refCount(1), pVar(0)
-
{}
-
-
-
CPropertyBag::~CPropertyBag()
-
{
-
VAR_LIST *pTemp = pVar;
-
HRESULT hr = S_OK;
-
while(pTemp)
-
{
-
VAR_LIST *pDel = pTemp;
-
VariantClear(&pTemp->var);
-
SysFreeString(pTemp->pBSTRName);
-
pTemp = pTemp->pNext;
-
delete pDel;
-
}
-
}
-
-
-
HRESULT STDMETHODCALLTYPE CPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *_pVar, IErrorLog *pErrorLog)
-
{
-
VAR_LIST *pTemp = pVar;
-
HRESULT hr = S_OK;
-
while(pTemp)
-
{
-
if(0 == wcscmp(pszPropName, pTemp->pBSTRName))
-
{
-
hr = VariantCopy(_pVar, &pTemp->var);
-
break;
-
}
-
pTemp = pTemp->pNext;
-
}
-
-
return hr;
-
}
-
-
-
HRESULT STDMETHODCALLTYPE CPropertyBag::Write(LPCOLESTR pszPropName, VARIANT *_pVar)
-
{
-
HRESULT hr = S_OK;
-
VAR_LIST *pTemp = new VAR_LIST();
-
ASSERT(pTemp);
-
if(!pTemp)
-
{
-
return E_OUTOFMEMORY;
-
}
-
-
VariantInit(&pTemp->var);
-
pTemp->pBSTRName = SysAllocString(pszPropName);
-
pTemp->pNext = pVar;
-
pVar = pTemp;
-
return VariantCopy(&pTemp->var, _pVar);
-
}
-
-
ULONG STDMETHODCALLTYPE CPropertyBag::AddRef()
-
{
-
return InterlockedIncrement((LONG *)&_refCount);
-
}
-
-
ULONG STDMETHODCALLTYPE CPropertyBag::Release()
-
{
-
ASSERT(_refCount != 0xFFFFFFFF);
-
ULONG ret = InterlockedDecrement((LONG *)&_refCount);
-
if(!ret)
-
{
-
delete this;
-
}
-
-
return ret;
-
}
-
-
HRESULT STDMETHODCALLTYPE CPropertyBag::QueryInterface(REFIID riid, void** ppv)
-
{
-
if(!ppv)
-
{
-
return E_POINTER;
-
}
-
-
if(riid == IID_IPropertyBag)
-
{
-
*ppv = static_cast<IPropertyBag*>(this);
-
}
-
else
-
{
-
return *ppv = 0, E_NOINTERFACE;
-
}
-
-
return AddRef(), S_OK;
-
}
(3) EricCamera.h
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#pragma once
-
#include <streams.h>
-
#include <dmodshow.h>
-
#include <dmoreg.h>
-
#include <wmcodecids.h>
-
-
class CEricCamera
-
{
-
public:
-
CEricCamera(void);
-
~CEricCamera(void);
-
private:
-
-
-
-
CComPtr<ICaptureGraphBuilder2> m_pCaptureGraphBuilder;
-
-
-
CComPtr<IGraphBuilder> m_pGraphBuilder;
-
-
-
CComPtr<IBaseFilter> m_pVideoCaptureFilter;
-
-
-
CComPtr<IPersistPropertyBag> m_pPropertyBag ;
-
-
-
CComPtr<IBaseFilter> m_pImageSinkFilter;
-
-
-
CComPtr<IMediaControl> m_pMediaControl ;
-
-
-
CComPtr<IVideoWindow> m_pVideoWindow ;
-
-
-
CComPtr<IMediaSeeking> m_pMediaSeeking;
-
-
-
CComPtr<IMediaEvent> m_pMediaEvent;
-
-
public:
-
-
void FreeDShow();
-
-
-
BOOL GetFirstCameraDriver(WCHAR *pwzName);
-
-
-
BOOL PreviewCamera(HWND hVideoWnd , LPCTSTR strFileName );
-
-
-
BOOL StartRecord();
-
-
-
BOOL StopRecord();
-
-
-
BOOL SnapPicture(LPCTSTR strFileName );
-
-
};
(4) EricCamera.cpp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#include "StdAfx.h"
-
#include "EricCamera.h"
-
#include "PropertyBag.h"
-
-
#define CHK( x ) do{ if( FAILED( hResult = ( x ))) { goto Cleanup; }} while( FALSE );
-
#define ERR( x ) do{ hResult = x; goto Cleanup; } while( FALSE );
-
-
-
CEricCamera::CEricCamera(void)
-
{
-
-
CoInitialize(NULL);
-
}
-
-
-
CEricCamera::~CEricCamera(void)
-
{
-
-
FreeDShow();
-
-
CoUninitialize();
-
}
-
-
-
-
-
-
-
-
void CEricCamera::FreeDShow()
-
{
-
-
if (m_pMediaControl != NULL)
-
{
-
m_pMediaControl->Stop();
-
m_pMediaControl.Release();
-
m_pMediaControl = NULL;
-
}
-
-
if (m_pPropertyBag != NULL)
-
{
-
m_pPropertyBag.Release();
-
m_pPropertyBag = NULL;
-
}
-
-
if (m_pVideoWindow != NULL)
-
{
-
-
m_pVideoWindow->put_Visible(OAFALSE);
-
-
m_pVideoWindow->put_Owner(NULL);
-
m_pVideoWindow.Release();
-
m_pVideoWindow = NULL;
-
}
-
-
if (m_pMediaSeeking != NULL)
-
{
-
m_pMediaSeeking.Release();
-
m_pMediaSeeking = NULL;
-
}
-
-
if (m_pMediaEvent != NULL)
-
{
-
m_pMediaEvent.Release();
-
m_pMediaEvent = NULL;
-
}
-
-
if (m_pVideoCaptureFilter != NULL )
-
{
-
m_pVideoCaptureFilter.Release();
-
m_pVideoCaptureFilter = NULL;
-
}
-
-
if (m_pImageSinkFilter != NULL )
-
{
-
m_pImageSinkFilter.Release();
-
m_pImageSinkFilter = NULL;
-
}
-
-
if (m_pGraphBuilder != NULL)
-
{
-
m_pGraphBuilder.Release();
-
m_pGraphBuilder = NULL;
-
}
-
-
if (m_pCaptureGraphBuilder != NULL)
-
{
-
m_pCaptureGraphBuilder->SetFiltergraph(NULL);
-
m_pCaptureGraphBuilder.Release();
-
m_pCaptureGraphBuilder = NULL;
-
}
-
}
-
-
-
-
-
-
-
-
BOOL CEricCamera::GetFirstCameraDriver( WCHAR *pwzName )
-
{
-
HRESULT hr = S_OK;
-
HANDLE handle = NULL;
-
DEVMGR_DEVICE_INFORMATION di;
-
GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 };
-
if( pwzName == NULL )
-
{
-
return FALSE;
-
}
-
-
di.dwSize = sizeof(di);
-
-
-
handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di );
-
if(( handle == NULL ) || ( di.hDevice == NULL ))
-
{
-
FindClose( handle );
-
return FALSE;
-
}
-
-
-
StringCchCopy( pwzName, MAX_PATH, di.szLegacyName );
-
-
-
FindClose( handle );
-
-
return TRUE;
-
}
-
-
-
-
-
-
-
-
-
BOOL CEricCamera::PreviewCamera(HWND hVideoWnd , LPCTSTR strFileName )
-
{
-
HRESULT hResult = S_FALSE;
-
LONGLONG dwStart = 0, dwEnd = 0;
-
WORD wStartCookie = 1, wEndCookie = 2;
-
CRect rectVideo;
-
CComVariant varCamName;
-
WCHAR wzDeviceName[ MAX_PATH + 1 ];
-
CPropertyBag PropBag;
-
-
-
CComPtr<IBaseFilter> pVideoEncoder;
-
CComPtr<IBaseFilter> pASFMultiplexer;
-
CComPtr<IFileSinkFilter> pFileSinkFilter;
-
CComPtr<IDMOWrapperFilter> pWrapperFilter;
-
-
-
FreeDShow();
-
-
-
CHK(m_pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder));
-
-
-
CHK(m_pGraphBuilder.CoCreateInstance(CLSID_FilterGraph));
-
-
-
CHK(m_pCaptureGraphBuilder->SetFiltergraph(m_pGraphBuilder ));
-
-
-
CHK(m_pGraphBuilder.QueryInterface(&m_pMediaControl));
-
-
-
CHK(m_pGraphBuilder.QueryInterface(&m_pMediaSeeking));
-
-
-
CHK(m_pGraphBuilder.QueryInterface(&m_pMediaEvent));
-
-
-
CHK(m_pVideoCaptureFilter.CoCreateInstance(CLSID_VideoCapture));
-
-
-
CHK(m_pVideoCaptureFilter->QueryInterface(&m_pPropertyBag));
-
-
-
-
if (!GetFirstCameraDriver( wzDeviceName ))
-
{
-
goto Cleanup;
-
}
-
-
varCamName = wzDeviceName;
-
if(( varCamName.vt == VT_BSTR ) == NULL ) {
-
return FALSE;
-
}
-
-
-
PropBag.Write( L"VCapName", &varCamName);
-
CHK(m_pPropertyBag->Load( &PropBag, NULL));
-
-
-
CHK(m_pGraphBuilder->AddFilter( m_pVideoCaptureFilter, L"Video capture source" ));
-
-
-
CHK(pVideoEncoder.CoCreateInstance( CLSID_DMOWrapperFilter ));
-
CHK(pVideoEncoder.QueryInterface( &pWrapperFilter ));
-
-
-
CHK(pWrapperFilter->Init( CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER ));
-
-
-
CHK(m_pGraphBuilder->AddFilter( pVideoEncoder, L"WMV9 DMO Encoder" ));
-
-
-
CHK(m_pCaptureGraphBuilder->SetOutputFileName( &MEDIASUBTYPE_Asf,strFileName, &pASFMultiplexer, &pFileSinkFilter ));
-
-
-
CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, m_pVideoCaptureFilter,NULL, NULL));
-
-
-
CHK(m_pGraphBuilder.QueryInterface(&m_pVideoWindow));
-
-
-
m_pVideoWindow->put_Owner((OAHWND)hVideoWnd);
-
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
-
-
-
GetClientRect(hVideoWnd,&rectVideo);
-
m_pVideoWindow->SetWindowPosition(0,0,rectVideo.Width(),rectVideo.Height());
-
m_pVideoWindow->put_Visible(OATRUE);
-
-
-
CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder, pASFMultiplexer ));
-
-
-
CHK(m_pImageSinkFilter.CoCreateInstance(CLSID_IMGSinkFilter));
-
CHK(m_pGraphBuilder->AddFilter(m_pImageSinkFilter, L"Still image filter" ));
-
CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_STILL, &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, m_pImageSinkFilter ));
-
-
-
CHK(m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0,0 ));
-
-
-
CHK(m_pMediaControl->Run());
-
Sleep(1000);
-
-
Cleanup:
-
-
-
if (pVideoEncoder != NULL)
-
{
-
pVideoEncoder.Release();
-
pVideoEncoder = NULL;
-
}
-
-
if (pASFMultiplexer != NULL)
-
{
-
pASFMultiplexer.Release();
-
pASFMultiplexer = NULL;
-
}
-
-
if (pFileSinkFilter != NULL)
-
{
-
pFileSinkFilter.Release();
-
pFileSinkFilter = NULL;
-
}
-
-
if (pWrapperFilter != NULL)
-
{
-
pWrapperFilter.Release();
-
pWrapperFilter = NULL;
-
}
-
-
if( FAILED( hResult ))
-
{
-
return FALSE;
-
}
-
else
-
{
-
return TRUE;
-
}
-
}
-
-
-
-
-
-
-
-
BOOL CEricCamera::StartRecord()
-
{
-
LONGLONG dwStart = 0, dwEnd = 0;
-
WORD wStartCookie = 1, wEndCookie = 2;
-
HRESULT hResult = 0;
-
if( m_pCaptureGraphBuilder == NULL )
-
{
-
return FALSE;
-
}
-
-
-
dwStart = 0;
-
dwEnd = MAXLONGLONG;
-
hResult = m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie );
-
TRACE(L"开始录制\n");
-
if( FAILED( hResult ))
-
{
-
return FALSE;
-
}
-
else
-
{
-
return TRUE;
-
}
-
}
-
-
-
-
-
-
-
-
BOOL CEricCamera::StopRecord()
-
{
-
HRESULT hResult = S_OK;
-
LONGLONG dwStart = 0, dwEnd = 0;
-
WORD wStartCookie = 1, wEndCookie = 2;
-
LONG lEventCode = 0;
-
LONG lParam1 = 0;
-
LONG lParam2 = 0;
-
-
if( m_pCaptureGraphBuilder == NULL )
-
{
-
return FALSE;
-
}
-
-
-
dwStart = 0;
-
hResult = m_pMediaSeeking->GetCurrentPosition( &dwEnd );
-
hResult = m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie );
-
-
-
while (true)
-
{
-
m_pMediaEvent->GetEvent( &lEventCode, &lParam1, &lParam2, INFINITE );
-
m_pMediaEvent->FreeEventParams( lEventCode, lParam1, lParam2 );
-
if( lEventCode == EC_STREAM_CONTROL_STOPPED ) {
-
TRACE(L"录像停止\n");
-
break;
-
}
-
}
-
-
-
if( FAILED( hResult ))
-
{
-
return FALSE;
-
}
-
else
-
{
-
return TRUE;
-
}
-
}
-
-
-
-
-
-
-
-
BOOL CEricCamera::SnapPicture(LPCTSTR strFileName )
-
{
-
HRESULT hResult = S_FALSE;
-
CComPtr<IFileSinkFilter> pFileSink;
-
CComPtr<IUnknown> pUnkCaptureFilter;
-
CComPtr<IPin> pStillPin;
-
CComPtr<IAMVideoControl> pVideoControl;
-
-
if( m_pCaptureGraphBuilder == NULL )
-
{
-
goto Cleanup;
-
}
-
-
-
CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
-
-
-
CHK( pFileSink->SetFileName( strFileName, NULL ));
-
-
-
CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
-
CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0, &pStillPin ));
-
-
-
CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
-
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
-
-
Cleanup:
-
-
if (pFileSink != NULL)
-
{
-
pFileSink.Release();
-
pFileSink = NULL;
-
}
-
-
if (!pUnkCaptureFilter != NULL)
-
{
-
pUnkCaptureFilter.Release();
-
pUnkCaptureFilter = NULL;
-
}
-
-
if (pStillPin != NULL)
-
{
-
pStillPin.Release();
-
pStillPin = NULL;
-
}
-
-
if (pVideoControl != NULL)
-
{
-
pVideoControl.Release();
-
pVideoControl = NULL;
-
}
-
-
if( FAILED( hResult ))
-
{
-
return FALSE;
-
}
-
else
-
{
-
return TRUE;
-
}
|