0

如果我使用智能三通过滤器,如何将网络摄像头的视频流渲染到文件?所以我添加了 SmartTee 过滤器并得到类似的东西:

Capture filter
        |
    SmartTee filter
    |           |
capture     preview
    |           |
Mux filter  GrabFilter
    |           |
FileWriter  VideoRenderer

这就是连接捕获过滤器和智能三通:

// Get capture filter
srcFilter = FindCaptureDevice();

// Add Capture filter to our graph.
graph.AddFilter(srcFilter, "Video Capture");

//Add smartTee filter to graph
smartTeeFilter = (IBaseFilter)new SmartTee();
graph.AddFilter(smartTeeFilter, "Smart Tee");

IPin outPin = GetPin(PinDirection.Output, srcFilter);
IPin inPin = GetPin(PinDirection.Input, smartTeeFilter);
graph.Connect(outPin, inPin);

这与抓取器和渲染有关(以防万一):

sampGrabber = new SampleGrabber() as ISampleGrabber;
baseGrabFilter = sampGrabber as IBaseFilter;
graph.AddFilter(baseGrabFilter, "Grabber");

IPin sourcePin, grabPin;
sourcePin = GetPin(PinDirection.Output, smartTeeFilter);
grabPin = GetPin(PinDirection.Input, baseGrabFilter);           
graph.Connect(sourcePin, grabPin);

graph.Render(GetPin(PinDirection.Output, baseGrabFilter));

这就是我保存文件部分的全部内容:

IBaseFilter mux;
IFileSinkFilter sink;

capture.SetOutputFileName(
    MediaSubType.Avi,      // Specifies AVI for the target file.
    path,                  // File name.
    out mux,               // Receives a pointer to the mux.
    out sink);             // (Optional) Receives a pointer to the file sink.

sink.SetFileName(path, null);

IPin outPin = DsFindPin.ByDirection(smartTeeFilter, PinDirection.Output, 1);
IPin inPin = GetPin(PinDirection.Input, mux);
graph.Connect(outPin, inPin);

control.Run();

它没有抛出异常。只需创建大小为 64Kb 的文件。我保存到文件代码有什么问题?

添加。我查看了 CapWMV 示例,其中保存是这样的:

IFileSinkFilter sink = null;
IBaseFilter fileWriterFilter = null;
capture = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();
capture.SetFiltergraph(graph);
int hr = capture.SetOutputFileName(MediaSubType.Avi, path, out fileWriterFilter, out sink);
DsError.ThrowExceptionForHR(hr);

hr = capture.RenderStream(null, null, smartTeeFilter, null, fileWriterFilter);
DsError.ThrowExceptionForHR(hr);

hr = control.Run();
DsError.ThrowExceptionForHR(hr);

我再次得到 64 Kb 文件,没有别的。我的错在哪里?

4

1 回答 1

1

顶部的拓扑是正确的。

但是,您的代码与它不匹配:您连接多路复用器输入,然后Run. 不存在或显示连接多路复用器输出的代码,这是强制性的。

接下来是您的实际拓扑可能与预期不同,因为 Intelligent Connect 自动提供了过滤器,您还需要通过枚举过滤器或发布到 ROT 并使用外部工具查看来查看这一点。

如果您有机会查看真实的拓扑,您可能会立即掌握问题:

IPin sourcePin, grabPin;
sourcePin = GetPin(PinDirection.Output, smartTeeFilter);
grabPin = GetPin(PinDirection.Input, baseGrabFilter);           
graph.Connect(sourcePin, grabPin);

您将第一个抓取的输出引脚连接到 Sample Grabber 和预览视频渲染器。但是,索引零输出引脚是 Capture

捕获引脚为输出引脚 0,预览引脚为输出引脚 1。

因此,您正在将预览(永恒)媒体样本写入文件,它不起作用,因此您需要正确连接 tee 输出引脚 - 以便 tee 的捕获输出连接到 mux/writer 腿。

于 2013-05-19T12:49:05.250 回答