From b781e774ae4f5d579c8e9122ea9baafb1f54261a Mon Sep 17 00:00:00 2001 From: "scherkus@chromium.org" Date: Fri, 4 Feb 2011 20:27:51 +0000 Subject: Fix frame accurate seeking for the third time. Turns out we need to do an integer round to paper over floating point issues. Refer to discussion on https://bugs.webkit.org/show_bug.cgi?id=52697 for details. BUG=69499 TEST=layout test in linked bug Review URL: http://codereview.chromium.org/6250137 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73838 0039d316-1c4b-4281-b951-d872f2087c98 --- webkit/glue/webmediaplayer_impl.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'webkit/glue/webmediaplayer_impl.cc') diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index b9df79d..9d51910 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -59,6 +59,25 @@ const int kMaxOutstandingRepaints = 50; const float kMinRate = 0.0625f; const float kMaxRate = 16.0f; +// Platform independent method for converting and rounding floating point +// seconds to an int64 timestamp. +// +// Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details. +base::TimeDelta ConvertSecondsToTimestamp(float seconds) { + float microseconds = seconds * base::Time::kMicrosecondsPerSecond; + float integer = ceilf(microseconds); + float difference = integer - microseconds; + + // Round down if difference is large enough. + if ((microseconds > 0 && difference > 0.5f) || + (microseconds <= 0 && difference >= 0.5f)) { + integer -= 1.0f; + } + + // Now we can safely cast to int64 microseconds. + return base::TimeDelta::FromMicroseconds(static_cast(integer)); +} + } // namespace namespace webkit_glue { @@ -374,10 +393,7 @@ void WebMediaPlayerImpl::seek(float seconds) { return; } - // Try to preserve as much accuracy as possible. - float microseconds = seconds * base::Time::kMicrosecondsPerSecond; - base::TimeDelta seek_time = - base::TimeDelta::FromMicroseconds(static_cast(microseconds)); + base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); // Update our paused time. if (paused_) { -- cgit v1.1