Pregunta

Mi tarea es:. Puedo crear un gráfico, adjunto un SampleGrabber a ella, y agarro los fotogramas clave utilizando la interfaz IMediaSeeking después de construir el gráfico

Lo siguiente es lo que he hecho: En el método principal:

   Type comType = Type.GetTypeFromCLSID ( new Guid ( "e436ebb3-524f-11ce-9f53-0020af0ba770" ) );
   IGraphBuilder graphBuilder = (IGraphBuilder) Activator.CreateInstance ( comType );

   comType = Type.GetTypeFromCLSID ( new Guid ( "C1F400A0-3F08-11d3-9F0B-006008039E37" ) );
   ISampleGrabber sampleGrabber = (ISampleGrabber) Activator.CreateInstance ( comType );

   graphBuilder.AddFilter ( (IBaseFilter) sampleGrabber, "samplegrabber" );

   AMMediaType mediaType = new AMMediaType ( );
   mediaType.majorType = MediaType.Video;
   mediaType.subType = MediaSubType.RGB24;
   mediaType.formatType = FormatType.VideoInfo;
   sampleGrabber.SetMediaType ( mediaType );

   int hr = graphBuilder.RenderFile ( @"D:\test.wmv", null );

   IMediaEventEx mediaEvent = (IMediaEventEx) graphBuilder;
   IMediaControl mediaControl = (IMediaControl) graphBuilder;
   IVideoWindow videoWindow = (IVideoWindow) graphBuilder;
   IBasicAudio basicAudio = (IBasicAudio) graphBuilder;

   videoWindow.put_AutoShow ( OABool.False );
   basicAudio.put_Volume ( -10000 );

   sampleGrabber.SetOneShot ( false );
   sampleGrabber.SetBufferSamples ( true );

   //the same object has implemented the ISampleGrabberCB interface.
   //0 sets the callback to the ISampleGrabberCB::SampleCB() method.
   sampleGrabber.SetCallback (this, 0);

   mediaControl.Run ( );

   EventCode eventCode;
   mediaEvent.WaitForCompletion ( -1, out eventCode );


   Marshal.ReleaseComObject ( sampleGrabber );
   Marshal.ReleaseComObject ( graphBuilder );

En el método () de devolución de llamada SampleCB:

    public int SampleCB ( double sampleTime, IMediaSample mediaSample )
    {
        Console.WriteLine ( "SampleCB Callback" );
        Console.WriteLine ( mediaSample.IsSyncPoint ( ) + " " + mediaSample.GetActualDataLength() );
                    //check if its a keyframe using mediaSample.IsSyncPoint()
                    //and convert the buffer into image and save it.
        return 0;
    }

Por lo tanto, he creado las cosas. Ahora, cuando ejecuto el programa, todo carga correctamente. Sin embargo, la devolución de llamada se llama sólo una vez, y luego se detiene la prestación. No más de representación y no más devoluciones de llamada. Había probado el otro método de devolución de llamada ISampleGrabber :: BufferCB () para ver si se sigue el mismo destino. ¡Pero no! BufferCB () se llama cada vez que una trama se agarró y el video se procesa hasta el final.

¿Qué estoy haciendo mal? Cualquier sugerencia sobre esto? Gracias:)

¿Fue útil?

Solución

ok..I finalmente han sido capaces de resolver ese problema. Lo describiría aquí en caso de que ayuda a nadie más. En realidad no estaba liberando el objeto IMediaSample en el método de devolución de llamada. Esto es una necesidad para hacer, que es un objeto COM.

En la simple adición de la Marshal.ReleaseComObject () a mi SampleCB método de devolución de llamada (), que ahora se llama cada vez que el SampleGrabber toma una muestra.

public int SampleCB ( double sampleTime, IMediaSample mediaSample )
{
    Console.WriteLine ( "SampleCB Callback" );
    Console.WriteLine ( mediaSample.IsSyncPoint ( ) + " " );

        /* other code */
    Marshal.ReleaseComObject ( mediaSample );
    return 0;
}

Estoy frente a otro tema ahora. Sin embargo, he hecho otro post para que a medida totalmente doesnt se refieren a esta pregunta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top