Question

Ma tâche est:. Je crée un graphique, veuillez joindre une SampleGrabber à lui, et de saisir les images clés en utilisant l'interface IMediaSeeking après la construction du graphique

Ce qui suit est ce que je l'ai fait: Dans la méthode principale:

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

Dans le procédé de rappel 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;
    }

Ainsi, je l'ai mis en place les choses. Maintenant, quand je lance le programme, tout charge correctement. Mais le rappel est appelé une seule fois, puis le rendu arrête. Plus de rendu et pas plus callbacks. Je l'avais essayé de voir si elle suit le même sort l'autre méthode de rappel ISampleGrabber :: BufferCB (). Mais non! BufferCB () est appelée chaque fois qu'un cadre est saisi et la vidéo est rendue jusqu'à la fin.

Qu'est-ce que je fais mal? Toutes les suggestions à ce sujet? Merci:)

Était-ce utile?

La solution

ok..I ont finalement été en mesure de résoudre ce problème. Je décrirais ici dans le cas où il aide quelqu'un d'autre. Je ne désactivait pas fait l'objet IMediaSample dans la méthode de rappel. C'est un must pour le faire, étant un objet COM.

En ajoutant simplement la Marshal.ReleaseComObject () à ma méthode de rappel SampleCB (), il est maintenant appelé à chaque fois que l'SampleGrabber saisit un échantillon.

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

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

Je suis face à une autre question maintenant. Cependant, je l'ai fait un autre poste pour que il ne marche pas tout à fait se rapportent à cette question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top