[Libav-user] Why is av_seek_frame() inaccurate in some cases ?

Lucas Soltic soltic.lucas at gmail.com
Sat Apr 14 18:40:09 CEST 2012


I'm working on a movie playback library but I'm getting issues with seeking. I'm using av_seek_frame() and FFmpeg 0.10.
The problem is that the audio stream is correctly sought but not the video stream, except for H.264 video stream (not working for DivX, MPEG4v2 or Theora video streams).

Here is what I get:

When seeking I print these debug messages:
REQUESTED SEEK to 276.794s
video seek pos = 276793952
video seek target = 6643
video seek as seconds = 276.794
audio seek pos = 276793952
audio seek target = 11533
audio seek as seconds = 276.794

Where 'video seek target' and 'audio seek target' are the values given to av_seek_frame() for both streams.
But right after this, after calling av_decode_* for the first time, here is what I get for the packet that has just been decoded:
audio pts = 276792ms
video pts = 271583ms

As you can see, the gathered audio PTS is fine : 276.792s. Whereas the video one isn't : 271.583s. I do not know why this is happening, especially as it's working fine with H.264 streams. Note that the time gap isn't fixed, I sometimes get a 2 or 8 seconds difference for example.

So that you can understand how I got these results, here is what I did:

When seeking:
flush the queued video AVPackets
AVRational timeBase = m_avFormatCtx->streams[videoStreamID]->time_base;
int flags = (targetPosition is before currentPosition) ? AVSEEK_FLAG_BACKWARD : 0;
int64_t seek_pos = (int64_t)(targetPosition.asSeconds() * AV_TIME_BASE); // ::asSeconds() returns a float value
int64_t seek_target = av_rescale_q(seek_pos, AV_TIME_BASE_Q, timeBase);
av_seek_frame(m_avFormatCtx, videoStreamID, seek_target, flags)

When decoding:
check if there are available video packets (but since we flushed everything there are none)
read the movie file until we get video packets
avcodec_decode_video2(m_codecCtx, m_rawFrame, &didDecodeFrame, videoPacket);
int64_t seek_target = av_rescale_q(videoPacket->pts, videoTimeBase, AV_TIME_BASE_Q) / 1000;
std::cout << "video pts = " << seek_target << "ms" << std::endl;

So I don't think I did anything fancy, but I still can't find out why the video seeking is inaccurate. I would be really grateful if someone had ideas about this issue.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120414/704c29aa/attachment.html>

More information about the Libav-user mailing list