¿Cómo capturar fotogramas usando Delphi/DSPack sin mostrarlos en TVideoWindow?
-
12-12-2019 - |
Pregunta
DSpack tiene un código de ejemplo para reproducir un dispositivo de video compatible con DirectShow y capturar los cuadros de video simultáneamente.Se adjunta una TVideoWindow al FilterGraph para mostrar el video (Figura-1).Si elimina TVideoWindow, el sistema operativo (Windows) abrirá automáticamente ActiveMovie y mostrará el video en una ventana separada (Figura 2).
¿Existe alguna forma de utilizar DSPack para capturar fotogramas de vídeo sin utilizar ninguno de los componentes de la GUI y sin mostrar el vídeo?
El foro DSPack menciona algo sobre el filtro NullRenderer, pero no hay documentación ni ejemplos sobre cómo usarlo.Parece que podemos lograrlo si reemplazamos manualmente Video Renderer con Null Render directamente en GraphEdit (Figura-3).
¿Cómo podemos lograr el resultado que se muestra en la Figura 3 realizando todas las manipulaciones dentro del código?DSPack no explica cómo crear un procesador nulo.
Figure-1: The graph of the default example code
Figure-2: Shows what happens if I remove the TVideoWindow
Figure-3: Shows what happens if I replace Video Renderer with a
Null Renderer and manually connect them in the GraphEdit.
Esto es lo que terminé haciendo (hasta ahora)
llama a lo siguiente ReassignSampleGrabberOutput
justo antes 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;
Solución
Null Renderer Filter
es un filtro/clase estándar.En el código solo necesitas crear una instancia (CoCreateInstance
), agréguelo al gráfico y conecte su pin de entrada al pin de salida desconectado del Sample Grabber.
En Delphi/DSPack debería ser así:
Renderer := CreateComObject(CLSID_NullRenderer) as IBaseFilter;