delphidirectshowdspack

How to capture frames using Delphi/DSPack without displaying it on TVideoWindow?


DSpack has example code to play a DirectShow compatible video device and to capture the video frames simultaneously. A TVideoWindow is attached to the FilterGraph to display the video (Firgure-1). If you remove the TVideoWindow, then the Operating System (Windows) will automatically bring up ActiveMovie and display the video on a separate window (Figure-2).

Is there a way to use DSPack to capture video frames without using any of the GUI components and without displaying the video?

DSPack forum has some mention about NullRenderer filter but there is no documentation or examples on how to use it. Looks like we can achieve that if we manually replace the Video Renderer with Null Render directly in the GraphEdit (Figure-3).

How can we achive the result shown in Figure-3 by doing all manipulations within the code? DSPack does not explain how to create a Null Renderer.

Figure-1: The graph of the default example code

Figure-1

Figure-2: Shows what happens if I remove the TVideoWindow

Figure-2

Figure-3: Shows what happens if I replace Video Renderer with a 
         Null Renderer and manually connect them in the GraphEdit. 

Figure-3

This is what I ended up doing (so far)

Call the following ReassignSampleGrabberOutput just before filterGraph.Play;

procedure TForm1.ReassignSampleGrabberOutput;
var
  nullRenderer : IBaseFilter;
  nullRendererPins: IEnumPins;
  nullRendererPin : IPin;
  graph:   IGraphBuilder;
begin

  nullRenderer := CreateComObject(CLSID_NullRenderer) as IBaseFilter;
  FilterGraph1.QueryInterface(IID_IGraphBuilder, graph);
  graph.AddFilter(nullRenderer, 'Null Renderer');

  nullRenderer.EnumPins(nullRendererPins);

  nullRendererPins.Reset;

  if nullRendererPins.Next(1, nullRendererPin, nil) = S_OK then
  begin
    //SampleGrabber1.OutPutPin.Disconnect;
    //SampleGrabber1.OutPutPin.Connect(nullRendererPin, nil);

    graph.Disconnect(SampleGrabber1.OutPutPin);
    graph.FindFilterByName('Video Renderer', filter);
    graph.RemoveFilter(filter);
    graph.Connect(SampleGrabber1.OutPutPin, nullRendererPin);

  end;
end;

Solution

  • Null Renderer Filter is a standard filter/class. In code you just need to instantiate it (CoCreateInstance), add it to the graph, and connect its input pin to the unconnected output pin of the Sample Grabber.

    In Delphi/DSPack it should be like this:

    Renderer := CreateComObject(CLSID_NullRenderer) as IBaseFilter;