Directshow(SDK)学习笔记九 - 视频捕捉 联系客服

发布时间 : 星期六 文章Directshow(SDK)学习笔记九 - 视频捕捉更新完毕开始阅读f2cc4bf69e314332396893b8

IBaseFilter *pMux = 0;

IFileSinkFilter *pSink = 0;

hr = pBuild->SetOutputFileName(

&CLSID_MyCustomMuxFilter, //自己开发的Filter

L\

4如何将视频流保存进多个文件

当你将视频流保存进一个文件后,如果你想开始保存第二个文件,这时,你应该首先将graph停止,然后通过IFileSinkFilter::SetFileName改变 File Writer 的文件名称。注意,IFileSinkFilter指针你可以在SetOutputFileName时通过第四个参数返回的。 看看保存多个文件的代码吧

IBaseFilter *pMux;

IFileSinkFilter *pSink

hr = pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, L\

&pMux, &pSink);

if (SUCCEEDED(hr)) {

hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,

pCap, NULL, pMux);

if (SUCCEEDED(hr)) {

pControl->Run();

/* Wait awhile, then stop the graph. */

pControl->Stop();

// Change the file name and run the graph again.

pSink->SetFileName(L\

pControl->Run(); }

pMux->Release();

pSink->Release(); }

5组合视频的捕捉和预览

如果想组建一个既可以预览视频,又可以将视频保存成文件的graph,只需要两次调用ICaptureGraphBuilder2::RenderStream即可。代码如下:

// Render the preview stream to the video renderer.

hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);

// Render the capture stream to the mux.

hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap, NULL, pMux);

在上面的代码中,graph builder 其实隐藏了下面的细节。

1 如果capture Filter既有preview pin 也有captrue pin,那么RenderStream仅仅将两个pin和render filter接起来。如下图

图4

2如果caprture Filter只有一个capture pin,那么Capture Graph Builder就采用一个

Smart Tee Filter将视频流分流,graph图如下

图5

5如何控制Capture Graph(Controlling Capture Graph)

Filter图表管理器可以通过IMediaControl接口控制整个graph的运行,停止和暂停。但是当一个graph有捕捉和预览两个数据流的时候,如果我们想单独的控制其中的一个数据流话,我们可以通过ICaptureGraphBuilder2::ControlStream 。 下面讲一下如何来单独控制捕捉和预览数据流。 1 控制捕捉视频流

下面的代码,让捕捉数据流在graph开始运行1秒后开始,允运行4秒后结束。

// Control the video capture stream.

REFERENCE_TIME rtStart = 1000 0000, rtStop = 5000 0000;

const WORD wStartCookie = 1, wStopCookie = 2; // Arbitrary values.

hr = pBuild->ControlStream(

&PIN_CATEGORY_CAPTURE, // Pin category.

&MEDIATYPE_Video, // Media type.

pCap, // Capture filter.

&rtStart, &rtStop, // Start and stop times.

wStartCookie, wStopCookie // Values for the start and stop events. );

pControl->Run();

第一个参数表明需要控制的数据流,一般采用的是pin种类GUID, 第二个参数表明了媒体类型。

第三个参数指明了捕捉的filter。如果想要控制graph图中的所有捕捉filter,第二个和第三个参数都要设置成NULL。

第四和第五个参数表明了流开始和结束的时间,这是一个相对于graph开始的时间。 只有你调用IMediaControl::Run以后,这个函数才有作用。如果graph正在运行,这个设置

立即生效。

最后的两个参数用来设置当数据流停止,开始能够得到的事件通知。对于任何一个运用此方法的数据流,graph当流开始的时候,会发送EC_STREAM_CONTROL_STARTED通知,在流结束的时候,要发送EC_STREAM_CONTROL_STOPPED通知。wStartCookie和wStopCookie是作为第二个参数的。 看看事件通知处理过程吧

while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr)) {

switch (evCode) {

case EC_STREAM_CONTROL_STARTED:

// param2 == wStartCookie

break;

case EC_STREAM_CONTROL_STOPPED:

// param2 == wStopCookie

break; }

pEvent->FreeEventParams(evCode, param1, param2); }

ControlStream还定义了一些特定的值来表示开始和停止的时间。 MAXLONGLONG 从不开始,只有在graph停止的时候才停止 NULL, 立即开始和停止

例如,下面的代码立即停止捕捉流。