From dc24f856915208d5e2417cc822509d4c177b809f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 1 Sep 2010 21:39:04 +0000 Subject: [PATCH] Use rounding to avoid the situation, that FindKeyFrame() returns a frame, and using that very same frame again for FindKeyFrame() returns a different frame, because the rounding effects have converted the time to be smaller than the timestamp that was found for the first call to FindKeyFrame(). It still happens sometimes, but a lot less frequently. Ideas appreciated. :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38504 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ffmpeg/AVFormatReader.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index 586252a656..166a49a7e1 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -921,7 +921,7 @@ AVFormatReader::StreamCookie::FindKeyFrame(uint32 flags, int64* frame, double frameRate = FrameRate(); if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) - *time = (bigtime_t)(*frame * 1000000LL / frameRate + 0.5); + *time = (bigtime_t)(*frame * 1000000.0 / frameRate + 0.5); int64_t timeStamp = _ConvertToStreamTimeBase(*time); @@ -941,6 +941,11 @@ AVFormatReader::StreamCookie::FindKeyFrame(uint32 flags, int64* frame, const AVIndexEntry& entry = fStream->index_entries[index]; timeStamp = entry.timestamp; bigtime_t foundTime = _ConvertFromStreamTimeBase(timeStamp); + // It's really important that we can convert this back to the + // same time-stamp (i.e. FindKeyFrame() with the time we return + // should return the same time again)! + if (_ConvertToStreamTimeBase(foundTime) < timeStamp) + foundTime++; bigtime_t timeDiff = foundTime > *time ? foundTime - *time : *time - foundTime; @@ -958,7 +963,7 @@ AVFormatReader::StreamCookie::FindKeyFrame(uint32 flags, int64* frame, TRACE_FIND(" found time: %.2fs (%lld)\n", *time / 1000000.0, timeStamp); if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) { - *frame = *time * frameRate / 1000000LL + 0.5; + *frame = int64_t(*time * frameRate / 1000000.0 + 0.5); TRACE_FIND(" found frame: %lld\n", *frame); } @@ -1152,15 +1157,16 @@ AVFormatReader::StreamCookie::_NextPacket(bool reuse) int64_t AVFormatReader::StreamCookie::_ConvertToStreamTimeBase(bigtime_t time) const { - return time * fStream->time_base.den - / (1000000LL * fStream->time_base.num); + return int64_t((double)time * fStream->time_base.den + / (1000000.0 * fStream->time_base.num) + 0.5); } bigtime_t AVFormatReader::StreamCookie::_ConvertFromStreamTimeBase(int64_t time) const { - return 1000000LL * time * fStream->time_base.num / fStream->time_base.den; + return bigtime_t(1000000.0 * time * fStream->time_base.num + / fStream->time_base.den + 0.5); }