首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DirectShowNet搜索关键帧

使用DirectShowNet搜索关键帧
EN

Stack Overflow用户
提问于 2011-01-19 16:34:28
回答 1查看 2.6K关注 0票数 1

我的任务是:创建一个图形,将SampleGrabber附加到该图形上,并在构建图形后使用IMediaSeeking接口获取关键帧。

以下是我所做的工作:在Main方法中:

代码语言:javascript
复制
   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 );

在SampleCB()回调方法中:

代码语言:javascript
复制
    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;
    }

因此,我已经设置好了这些东西。现在,当我运行程序时,一切都正确加载。但是回调只调用一次,然后渲染就会停止。不再渲染,也不再回调。我尝试了另一个回调方法ISampleGrabber::BufferCB(),看看它是否遵循同样的命运。但是不是的!每次抓取帧时都会调用BufferCB(),并将视频渲染到最后。

我做错了什么?对此有什么建议吗?谢谢您:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-01-24 19:11:21

好的.我终于能够解决这个问题了。我会在这里描述它,以防它对其他人有帮助。我实际上并没有在回调方法中释放IMediaSample对象。这是必须要做的,因为它是一个COM对象。

只需将Marshal.ReleaseComObject()添加到我的SampleCB()回调方法中,现在每次SampleGrabber抓取样本时都会调用它。

代码语言:javascript
复制
public int SampleCB ( double sampleTime, IMediaSample mediaSample )
{
    Console.WriteLine ( "SampleCB Callback" );
    Console.WriteLine ( mediaSample.IsSyncPoint ( ) + " " );

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

我现在面对的是另一个问题。然而,我已经为此写了另一篇文章,因为它并不完全与这个问题相关。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4733186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档