积极答复者
WINCE6.0下使用DSHOW编程,用摄像头录像的问题。

问题
-
/* *函数介绍: 初始化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秒钟的录像。
答案
-
您好,
建议您在StopRecord()函数里面设置断点,然后看看,是那一部分消耗的时间比较多。
Best regards,
Jesse
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- 已标记为答案 gyrenModerator 2011年3月30日 13:04
全部回复
-
您好,
建议您在StopRecord()函数里面设置断点,然后看看,是那一部分消耗的时间比较多。
Best regards,
Jesse
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- 已标记为答案 gyrenModerator 2011年3月30日 13:04