From 41457111ecc1f436210d66d4b89c74fae9c152ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 29 Sep 2010 15:20:12 +0000 Subject: [PATCH] * Try harder to seek somewhere and fall back to seeking to the beginning of the stream by bytes, if all else fails. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38853 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ffmpeg/AVFormatReader.cpp | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index 3a87a3160b..edf947283c 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -32,7 +32,7 @@ extern "C" { # define TRACE printf # define TRACE_IO(a...) # define TRACE_SEEK(a...) printf(a) -# define TRACE_FIND(a...) printf(a) +# define TRACE_FIND(a...) # define TRACE_PACKET(a...) #else # define TRACE(a...) @@ -554,7 +554,9 @@ StreamBase::Seek(uint32 flags, int64* frame, bigtime_t* time) int64_t streamTimeStamp = _ConvertToStreamTimeBase(*time); int index = av_index_search_timestamp(fStream, streamTimeStamp, searchFlags); - if (index >= 0) { + if (index < 0) { + TRACE(" av_index_search_timestamp() failed\n"); + } else { if (index > 0) { const AVIndexEntry& entry = fStream->index_entries[index]; streamTimeStamp = entry.timestamp; @@ -582,7 +584,7 @@ StreamBase::Seek(uint32 flags, int64* frame, bigtime_t* time) // since when seeking back there will be later index entries, // but we still want to ignore the found entry. fStreamBuildsIndexWhileReading = true; - TRACE_FIND(" Not trusting generic index entry. " + TRACE_SEEK(" Not trusting generic index entry. " "(Current count: %d)\n", fStream->nb_index_entries); } else { // If we found a reasonably time, write it into *time. @@ -595,9 +597,23 @@ StreamBase::Seek(uint32 flags, int64* frame, bigtime_t* time) if (avformat_seek_file(fContext, -1, INT64_MIN, timeStamp, INT64_MAX, searchFlags) < 0) { - TRACE(" avformat_seek_file()%s failed.\n", fSeekByBytes - ? " (by bytes)" : ""); - return B_ERROR; + TRACE(" avformat_seek_file() failed.\n"); + // Try to fall back to av_seek_frame() + timeStamp = _ConvertToStreamTimeBase(timeStamp); + if (av_seek_frame(fContext, fStream->index, timeStamp, + searchFlags) < 0) { + TRACE(" avformat_seek_frame() failed as well.\n"); + // Fall back to seeking to the beginning by bytes + timeStamp = 0; + if (av_seek_frame(fContext, fStream->index, timeStamp, + AVSEEK_FLAG_BYTE) < 0) { + TRACE(" avformat_seek_frame() by bytes failed as " + "well.\n"); + // Do not propagate error in any case. We fail if we can't + // read another packet. + } else + *time = 0; + } } // Our last packet is toast in any case. Read the next one so