none
WINCE6.0下使用DSHOW编程,用摄像头录像的问题。 RRS feed

  • 问题

  • /*
    *函数介绍: 初始化DSHOW接口,并预览视频
    *入口参数: hVideoWnd : 显示视频的窗口句柄
    			strFileName :录像文件名
    *出口参数:(无)
    *返回值:TRUE:成功;FALSE:失败
    */
    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; //摄像头属性页
    
    	//--定义录像用到的编码、写文件等FILTER
    	CComPtr<IBaseFilter>      pVideoEncoder;
    	CComPtr<IBaseFilter>      pASFMultiplexer;
    	CComPtr<IFileSinkFilter>    pFileSinkFilter;
    	CComPtr<IDMOWrapperFilter>   pWrapperFilter;
    
    	//默认先释放DSHOW接口
    	FreeDShow();
    
    	//1,创建ICaptureGraphBuilder2接口,用于管理媒体捕捉对象
    	CHK(m_pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder));
    
    	//2,创建IGraphBuilder接口
    	CHK(m_pGraphBuilder.CoCreateInstance(CLSID_FilterGraph));
    
    	//3,
    	CHK(m_pCaptureGraphBuilder->SetFiltergraph(m_pGraphBuilder ));
    
    	//4,得到IMediaControl接口,用于控制流播放
    	CHK(m_pGraphBuilder.QueryInterface(&m_pMediaControl)); 
    
    
    	//5,得到IMediaSeeking接口,用于设置播放位置
    	CHK(m_pGraphBuilder.QueryInterface(&m_pMediaSeeking)); 
    
    	//6,得到m_pMediaEvent接口,用于获取媒体事件
    	CHK(m_pGraphBuilder.QueryInterface(&m_pMediaEvent)); 
    
    	//7,创建视频捕捉Filter
    	CHK(m_pVideoCaptureFilter.CoCreateInstance(CLSID_VideoCapture));
    
    	//8,得到视频捕捉属性页接口
    	CHK(m_pVideoCaptureFilter->QueryInterface(&m_pPropertyBag ));
    
    	//9,选择视频捕捉设备
    	//得到第1个视频捕捉设备名。
    	if (!GetFirstCameraDriver( wzDeviceName ))
    	{
    		goto Cleanup;
    	}
    	varCamName = wzDeviceName;
    	if(( varCamName.vt == VT_BSTR ) == NULL ) {
    		return FALSE;
    	}
    	//设置视频捕捉为第1个捕捉设备
    	PropBag.Write( L"VCapName", &varCamName );  
    	CHK(m_pPropertyBag->Load( &PropBag, NULL ));
    
    	//10,将视频捕捉FILTER添加到FILTER图中。
    	CHK(m_pGraphBuilder->AddFilter( m_pVideoCaptureFilter, L"Video capture source" ));
    
    	//11,创建IDMOWrapperFilter接口
    	CHK(pVideoEncoder.CoCreateInstance( CLSID_DMOWrapperFilter ));
    	CHK(pVideoEncoder.QueryInterface( &pWrapperFilter ));
    	//12,加载WMV9 DMO
    	CHK(pWrapperFilter->Init( CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER ));
    
    	// 13,将编码器FILTER加入到过滤器图中
    	CHK(m_pGraphBuilder->AddFilter( pVideoEncoder, L"WMV9 DMO Encoder" ));
    
    	//14,创建ASF多路(复用)器,并加入到过滤器图中
    	CHK(m_pCaptureGraphBuilder->SetOutputFileName( &MEDIASUBTYPE_Asf,strFileName, &pASFMultiplexer, &pFileSinkFilter ));
    
    
    	//15,渲染预览视频PIN
    	CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_PREVIEW,
    		&MEDIATYPE_Video, m_pVideoCaptureFilter,
    		NULL, NULL ));
    
    	//16,设置视频预览窗口
    	CHK(m_pGraphBuilder.QueryInterface(&m_pVideoWindow));
    
    	////设置视频播放的WINDOWS窗口
    	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);
    	
    	//17,渲染捕捉PIN, 用于录像
    	CHK(m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder, pASFMultiplexer ));
    
    	//18,创建Still Pin,用于抓图
    	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 ));
    
    	//19,设置捕捉流暂停
    	CHK(m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0,0 ));
    
    	//20,预览视频
    	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;
    	}
    
    }
    
    
    /*
    *函数介绍:开始录像
    *入口参数: (无)
    *出口参数:(无)
    *返回值:TRUE:成功;FALSE:失败
    */
    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 );
    	//hResult = m_pCaptureGraphBuilder->CopyCaptureFile(wachSrcFile, wachDstFile,TRUE,NULL);
    	TRACE(L"开始录制\n");
    	if( FAILED( hResult ))
    	{
    		return FALSE;
    	}
    	else
    	{
    		return TRUE;
    	}
    }
    
    /*
    *函数介绍:停止录像
    *入口参数: (无)
    *出口参数:(无)
    *返回值:TRUE:成功;FALSE:失败
    */
    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;
    	}
    }
    
    这个是WINCE编程实例中的代码,用来进行摄像头拍照,录像的。
    问题是在录像的时候,录像停止后会等待很长的时间来保存文件。
    这个程序值录了5秒钟的录像。
    
    2010年12月7日 10:04

答案

全部回复