ffmpeg av_seek_frame with AVSEEK_FLAG_ANY causes grey screen

3down votefavorite

2

Problem: omxplayer's source code calls the ffmpeg av_seek_frame() method using the AVSEEK_FLAG_BACKWARD flag. Although not 100% sure, I believe this seeks to the closest i-frame. Instead, I want to seek to exact locations, so I modified the source code such that the av_seek_frame() method now uses the AVSEEK_FLAG_ANY flag. Now, when the movie loads, I get a grey screen, generally for 1 second, during which I can hear the audio. I have tried this on multiple computers (I am actually synchronizing them, therefore, at the same time too) so it is not a n isolated incident. My guess is that seeking to non i-frames is computationally more expensive, resulting in the initial grey screen.

Question: How, using ffmpeg, can I instruct the audio to wait until the video is ready before proceeding.

6down voteaccepted

Actually, AVSEEK_FLAG_BACKWARD indicates that you want to find closest keyframe having a smaller timestamp than the one you are seeking.

By using AVSEEK_FLAG_ANY, you get the frame that corresponds exactly to the timestamp you asked for. But this frame might not be a keyframe, which means that it cannot be fully decoded. That explains your "grey screen", that appears until the next keyframe is reached.

The solution would therefore be to seek backward using AVSEEK_FLAG_BACKWARD and, from this keyframe, read the next frames (e.g. using av_read_frame()) until you get to the one corresponding to your timestamp. At this point, your frame would be fully decoded, and would not appear as a "grey screen" anymore.

NOTE: It appears that, for some reason, av_seek_frame() using AVSEEK_FLAG_BACKWARD returns the next keyframe when the frame that I am seeking is the one directly before this keyframe. Otherwise it returns the previous keyframe (which is what I want). My solution is to change the timestamp I give to av_seek_frame() to ensure that it will return the keyframe before the frame I am seeking.

 

翻译:

实际上,AVSEEK_FLAG_BACKWARD表明您希望找到时间戳小于您正在寻找的时间戳的最接近的关键帧。

通过使用AvSexkFravaGyn,您可以得到与您所要求的时间戳完全一致的帧。但是这个帧可能不是一个关键帧,这意味着它不能被完全解码。这解释了你的“灰色屏幕”,直到下一个关键帧达到为止。

因此,解决方案是使用AVSEEK_FLAG_BACKWARD向后查找,并从此关键帧读取下一帧(例如,使用av_read_frame()),直到找到与时间戳相对应的帧。在这一点上,你的帧将被完全解码,并且不再显示为“灰色屏幕”。

注意:由于某些原因,当我正在寻找的帧是直接在这个关键帧之前的帧时,使用AVSEEK_FLAG_BACKWARD的av_._frame()返回下一个关键帧。否则,它返回先前的关键帧(这就是我想要的)。我的解决方案是改变我给av_._frame()的时间戳,以确保它将在我寻找的帧之前返回关键帧。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值