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()的时间戳,以确保它将在我寻找的帧之前返回关键帧。