[Libav-user] Seeking problem with avformat_seek_file

Dan Haddix dan6992 at hotmail.com
Tue Sep 13 20:35:51 CEST 2011

I've run into a few issues with seeking in my usage of FFmpeg and, after several incarnations, I've found that this code works well...

        int defaultStreamIndex = av_find_default_stream_index(m_pFormatContext);
        int seekStreamIndex = (m_videoStreamIndex != -1)? m_videoStreamIndex : defaultStreamIndex;
        __int64 seekTime = av_rescale_q(seekTimeDS, ds_time_base, m_pFormatContext->streams[seekStreamIndex]->time_base);
        __int64 seekStreamDuration = m_pFormatContext->streams[seekStreamIndex]->duration;

        int flags = AVSEEK_FLAG_BACKWARD;
        if (seekTime > 0 && seekTime < seekStreamDuration)
            flags |= AVSEEK_FLAG_ANY; // H.264 I frames don't always register as "key frames" in FFmpeg

        int ret = av_seek_frame(m_pFormatContext, seekStreamIndex, seekTime, flags);
        if (ret < 0)
            ret = av_seek_frame(m_pFormatContext, seekStreamIndex, seekTime, AVSEEK_FLAG_ANY);

My program uses DirectShow timecodes internally which is why I rescale the incoming timecode. (i.e. seekTimeDS) m_videoStreamIndex is the index of the video stream I store during the initial open. However I also allow audio only files in my program, so that check uses the video stream if it exists or the FFmpeg default stream if it doesn't.  You may not need either of those depending on how your code works. The main things are... You need to be careful not to use the AVSEEK_FLAG_ANY past the end of the file because that screws up some of the demuxers and causes future seeks to mess up. And the extra check at the very end is necessary because on some files the AVSEEK_FLAG_BACKWARDS does not work when seeking to 0, so you have to catch it and try again with AVSEEK_FLAG_ANY to make sure you actually end up at the start.

This code works well on all the files I've tested, but we only use FFmpeg for MP4, MKV and FLV so you may still have trouble with other formats.


From: moiein2000 at gmail.com
Date: Tue, 13 Sep 2011 12:49:14 -0400
To: libav-user at ffmpeg.org
Subject: Re: [Libav-user] Seeking problem with avformat_seek_file

On Tue, Sep 13, 2011 at 12:42 PM, Benjamin Gretsch <libav at dndrunde.de> wrote:

Good afternoon,

After days of searching and trying, I still have a problem:

When I use avformat_seek_file() to go back to the very beginning of a file

and then av_read_frame(), I still don't get the first frames again.

The goal is to extract multiple chunks of audio from a stream.

My approach is to read the stream, discard what I don't need. While doing

that I create a list of "points of interest" where I need to go back later.

My intermediate approach is to always go back to the beginning and start

discarding again.

What I am doing exactly is:

//read frames, discard what's not needed:

while(...) av_read_frame(...)

//go back to the beginning (that's the part that doesn't work):

avcodec_flush_buffers(avcc); //flush the codec's buffers


        avf, streamIndex,

        bytepos, bytepos, bytepos,


); //bytepos is packet.pos of the first packet I have read

   //and will later be a position from the index that I will build
 Have you tried moving the flush after the seek (not sure if that will make a difference). Here's how I use it, without any problem: avformat_seek_file(m_pFormatCtx, m_nVideoStream, INT64_MIN, nTime, INT64_MAX, 0), where nTime would be zero. This is how it'd done (min/max) in in one of the ffmpeg.c or ffplay.c files.

If you have an example file I can try it and see if I also have that issue. Which type of file are you using btw?


Libav-user mailing list
Libav-user at ffmpeg.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20110913/e3f34ee6/attachment.html>

More information about the Libav-user mailing list