directshow方法关键帧java,使用DirectShowNet寻找关键帧

My task is : I create a graph, attach a SampleGrabber to it, and grab the keyframes using the IMediaSeeking interface after building the graph.

The following is what I have done :

In the Main method :

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

In the SampleCB() callback method :

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;

}

Thus, I have set up the things. Now, when i run the program, everything loads correctly. But the callback is called only once, and then the rendering stops. No more rendering and no more callbacks.

I had tried the another callback method ISampleGrabber::BufferCB() to see if it follows the same fate. But no! BufferCB() is called everytime a frame is grabbed and the video is rendered till the end.

What am I doing wrong? Any suggestions on this?

Thank you :)

解决方案

ok..I have finally been able to solve that problem. I would describe it here in case it helps anyone else.

I was not actually releasing the IMediaSample object in the callback method. That is a must to do, it being a COM object.

On simply adding the Marshal.ReleaseComObject() to my SampleCB() callback method, it is now called everytime the SampleGrabber grabs a sample.

public int SampleCB ( double sampleTime, IMediaSample mediaSample )

{

Console.WriteLine ( "SampleCB Callback" );

Console.WriteLine ( mediaSample.IsSyncPoint ( ) + " " );

/* other code */

Marshal.ReleaseComObject ( mediaSample );

return 0;

}

I am facing another issue now. However, I have made another post for that as it doesnt totally relate to this question.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值