Fix TimeRanges::nearest() to actually calculate nearest time.

The existing implementation instead couldn't decide if it wanted to
calculate the nearest time or how close a given time was to a range.

The new implementation follows the HTML spec for TimeRanges where
nearest() returns a time within the range closest to the desired
time. Equidistant matches are resolved by distance from the current
time.

BUG=412562
TEST=new unittest.

Review URL: https://codereview.chromium.org/559993004

git-svn-id: svn://svn.chromium.org/blink/trunk@181859 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 7b23e23f
......@@ -1992,7 +1992,7 @@ void HTMLMediaElement::seek(double time)
m_seeking = false;
return;
}
time = seekableRanges->nearest(time);
time = seekableRanges->nearest(time, now);
if (m_playing) {
if (m_lastSeekTime < now)
......
......@@ -182,21 +182,33 @@ bool TimeRanges::contain(double time) const
return false;
}
double TimeRanges::nearest(double time) const
double TimeRanges::nearest(double newPlaybackPosition, double currentPlaybackPosition) const
{
double closest = 0;
unsigned count = length();
double bestMatch = 0;
double bestDelta = std::numeric_limits<double>::infinity();
for (unsigned ndx = 0; ndx < count; ndx++) {
double startTime = start(ndx, IGNORE_EXCEPTION);
double endTime = end(ndx, IGNORE_EXCEPTION);
if (time >= startTime && time <= endTime)
return time;
if (fabs(startTime - time) < closest)
closest = fabs(startTime - time);
else if (fabs(endTime - time) < closest)
closest = fabs(endTime - time);
if (newPlaybackPosition >= startTime && newPlaybackPosition <= endTime)
return newPlaybackPosition;
double delta, match;
if (newPlaybackPosition < startTime) {
delta = startTime - newPlaybackPosition;
match = startTime;
} else {
delta = newPlaybackPosition - endTime;
match = endTime;
}
if (delta < bestDelta || (delta == bestDelta
&& std::abs(currentPlaybackPosition - match) < std::abs(currentPlaybackPosition - bestMatch))) {
bestDelta = delta;
bestMatch = match;
}
}
return closest;
return bestMatch;
}
void TimeRanges::trace(Visitor* visitor)
......
......@@ -109,7 +109,7 @@ public:
bool contain(double time) const;
double nearest(double time) const;
double nearest(double newPlaybackPosition, double currentPlaybackPosition) const;
void trace(Visitor*);
......
......@@ -298,3 +298,23 @@ TEST(TimeRanges, IntersectWith_Gaps3)
ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA);
ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
}
TEST(TimeRanges, Nearest)
{
RefPtrWillBeRawPtr<TimeRanges> ranges = TimeRanges::create();
ranges->add(0, 2);
ranges->add(5, 7);
ASSERT_EQ(0, ranges->nearest(0, 0));
ASSERT_EQ(1, ranges->nearest(1, 0));
ASSERT_EQ(2, ranges->nearest(2, 0));
ASSERT_EQ(2, ranges->nearest(3, 0));
ASSERT_EQ(5, ranges->nearest(4, 0));
ASSERT_EQ(5, ranges->nearest(5, 0));
ASSERT_EQ(7, ranges->nearest(8, 0));
ranges->add(9, 11);
ASSERT_EQ(7, ranges->nearest(8, 6));
ASSERT_EQ(7, ranges->nearest(8, 8));
ASSERT_EQ(9, ranges->nearest(8, 10));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment