質問

How can I render video stream from webcam to file if I use smart tee filter? So I add SmartTee filter and get something like that:

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

So that's connetion capture filter and smart tee:

// 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);

That's connection with grabber and rendering (just in case):

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));

And that's all I have in saving file part:

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();

It's no thrown exceptions. Just creating file with size 64Kb. What's wrong with my saving to file code?

Added. I check out CapWMV example and in there saving is like this:

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);

And again I get 64 Kb file and nothing else. Where's my mistake?

役に立ちましたか?

解決

The topology on the top is about right.

Your code however does not match it: you connect multiplexer input and then you Run. No code exists or shown to connect multiplexer output, which is mandatory.

Next thing is that your actual topology might differ from expected because of filters provided automatically with Intelligent Connect, you need to review this as well by either enumerating filters or publishing to ROT and viewing with external tool.

If you had a chance to look at real topology, you would perhaps grasp the problem immediately:

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

You are connecting first grabbed output pin to Sample Grabber and preview video renderer. However, index zero output pin is Capture:

The capture pin is output pin 0, and the preview pin is output pin 1.

So you are writing preview (timeless) media samples to a file, it is not going to work, so you need to connect tee output pins properly - so that tee's capture output is connected to mux/writer leg.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top