如何从网络摄像头捕获视频时加快IMediaControl :: Run()的速度?

时间:2015-03-27 13:52:34

标签: c++ webcam directshow video-capture

代码功能按预期使用(使用预览和样本抓取器,抓取并压缩实时视频)。我试图解决的问题是在一台相对高端的机器上,启动视频流的实际Run()命令可能需要4-5秒才能执行,导致我的应用程序出现难看的延迟...似乎必须有一些我可以做的事情加快这一点。以下是代码(减去错误检查,故障路径等):

CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&pGraphBuilder );
CoCreateInstance( CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&pCaptureGraphBuilder2 );
pGraphBuilder->QueryInterface( IID_IMediaControl, (LPVOID *) &pMediaControl );

// initialize the capture graph builder
pCaptureGraphBuilder2->SetFiltergraph( pGraphBuilder );  

// get a video window interface for the preview
pGraphBuilder->QueryInterface( IID_IVideoWindow, (LPVOID *) &pVideoWindow );

// get and set the notification parent
pGraphBuilder->QueryInterface( IID_IMediaEventEx, (LPVOID *) &pMediaEventsEx );
pMediaEventsEx->SetNotifyWindow( (OAHWND)msgWindow, WM_GRAPHNOTIFY, 0 );

// pick the camera by the index selected
findCaptureDevice( &pSrcFilter, deviceIndex );

// add Capture filter to our graph
pGraphBuilder->AddFilter( pSrcFilter, L"Video Capture" );

// add in our sample grabber
sampleGrabber.Add( pGraphBuilder );
sampleGrabber.SetMediaType( doOneShot, deviceFormat );
sampleGrabber.SetCallback( this );

// render the preview pin on the video capture filter
pCaptureGraphBuilder2->RenderStream( &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pSrcFilter, sampleGrabber.GetFilter(), NULL );
sampleGrabber.GetMediaType(); // for the dimensions
pSrcFilter->Release();

// set video preview window
setupVideoWindow( previewStatic.m_hWnd );

// 4+ seconds delay here, then everything works fine....
pMediaControl->Run();

任何指示赞赏!

1 个答案:

答案 0 :(得分:1)

耗时Run通常是由硬件延迟(源过滤器背景某处)引起的。过滤器图形管理器和其他过滤器在几分之一秒内完成时间转换。您当然可以提前做Pause并且Run可能更快完成(延迟的一部分将转移到停止/暂停转换),但是如果硬件需要这么多时间来起飞,则最有可能需要提前开始捕获并跳过下游过滤器链中的数据。然后,当你需要开始捕获时,你将只是停止忽略流并开始捕获将立即。

您可能还想查看更简单的图形相机来源 - > Null Renderer并测量其运行时间,以确认它是添加延迟的源过滤器。如果源过滤器快速启动,则需要通过逐步向图表添加过滤器来将延迟隔离到特定过滤器。