[Libav-user] Seeking problem with avformat_seek_file
Benjamin Gretsch
libav at dndrunde.de
Tue Sep 13 20:55:28 CEST 2011
Thank you both for your input.
To call avcodec_flush_buffers() *after* the seek actually solved the problem.
I check for errors with av_seek_file() and do a close/open to be sure that I
have a good input.
I use ts, avi, mp2/3 and mkv for input, and later possibly wav (I haven't
tested that yet).
The problem with the ts files is that they are not accurately seekable and
that pts values are often messed up. That's why I need to rely on byte
positions for seeking.
Best regards
Benjamin
Am 13.09.2011 20:35, schrieb Dan Haddix:
> 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.
>
> Dan
>
>
>
> ----------------------------------------------------------------------------
> 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
> <mailto: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
> avformat_seek_file(
> avf, streamIndex,
> bytepos, bytepos, bytepos,
> AVSEEK_FLAG_BYTE
> ); //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?
>
> Matt
>
> _______________________________________________ Libav-user mailing list
> Libav-user at ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user
>
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
More information about the Libav-user
mailing list