TEST(TimeRanges, IntersectWith_Self) { RefPtr<TimeRanges> ranges = TimeRanges::create(0, 2); ASSERT_RANGE("{ [0,2) }", ranges); ranges->intersectWith(ranges.get()); ASSERT_RANGE("{ [0,2) }", ranges); }
PassRefPtr<TimeRanges> MediaController::buffered() const { if (m_mediaElements.isEmpty()) return TimeRanges::create(); // The buffered attribute must return a new static normalized TimeRanges object that represents // the intersection of the ranges of the media resources of the slaved media elements that the // user agent has buffered, at the time the attribute is evaluated. RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered(); for (size_t index = 1; index < m_mediaElements.size(); ++index) bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get()); return bufferedRanges; }
TEST(TimeRanges, IntersectWith_Empty) { RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2); RefPtr<TimeRanges> rangesB = TimeRanges::create(); ASSERT_RANGE("{ [0,2) }", rangesA); ASSERT_RANGE("{ }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ }", rangesA); ASSERT_RANGE("{ }", rangesB); }
TEST(TimeRanges, IntersectWith_IdenticalRange) { RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2); RefPtr<TimeRanges> rangesB = rangesA->copy(); ASSERT_RANGE("{ [0,2) }", rangesA); ASSERT_RANGE("{ [0,2) }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ [0,2) }", rangesA); ASSERT_RANGE("{ [0,2) }", rangesB); }
PassRefPtr<TimeRanges> MediaController::buffered() const { if (m_mediaElements.isEmpty()) return TimeRanges::create(); // The buffered attribute must return a new static normalized TimeRanges object that represents // the intersection of the ranges of the media resources of the slaved media elements that the // user agent has buffered, at the time the attribute is evaluated. MediaElementSequence::const_iterator it = m_mediaElements.begin(); RefPtr<TimeRanges> bufferedRanges = (*it)->buffered(); for (++it; it != m_mediaElements.end(); ++it) bufferedRanges->intersectWith((*it)->buffered().get()); return bufferedRanges; }
PassRefPtr<TimeRanges> MediaSource::buffered() const { // Implements MediaSource algorithm for HTMLMediaElement.buffered. // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions Vector<RefPtr<TimeRanges> > ranges(m_activeSourceBuffers->length()); for (size_t i = 0; i < m_activeSourceBuffers->length(); ++i) ranges[i] = m_activeSourceBuffers->item(i)->buffered(ASSERT_NO_EXCEPTION); // 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges object and abort these steps. if (ranges.isEmpty()) return TimeRanges::create(); // 2. Let active ranges be the ranges returned by buffered for each SourceBuffer object in activeSourceBuffers. // 3. Let highest end time be the largest range end time in the active ranges. double highestEndTime = -1; for (size_t i = 0; i < ranges.size(); ++i) { unsigned length = ranges[i]->length(); if (length) highestEndTime = std::max(highestEndTime, ranges[i]->end(length - 1, ASSERT_NO_EXCEPTION)); } // Return an empty range if all ranges are empty. if (highestEndTime < 0) return TimeRanges::create(); // 4. Let intersection ranges equal a TimeRange object containing a single range from 0 to highest end time. RefPtr<TimeRanges> intersectionRanges = TimeRanges::create(0, highestEndTime); // 5. For each SourceBuffer object in activeSourceBuffers run the following steps: bool ended = readyState() == endedKeyword(); for (size_t i = 0; i < ranges.size(); ++i) { // 5.1 Let source ranges equal the ranges returned by the buffered attribute on the current SourceBuffer. TimeRanges* sourceRanges = ranges[i].get(); // 5.2 If readyState is "ended", then set the end time on the last range in source ranges to highest end time. if (ended && sourceRanges->length()) sourceRanges->add(sourceRanges->start(sourceRanges->length() - 1, ASSERT_NO_EXCEPTION), highestEndTime); // 5.3 Let new intersection ranges equal the the intersection between the intersection ranges and the source ranges. // 5.4 Replace the ranges in intersection ranges with the new intersection ranges. intersectionRanges->intersectWith(sourceRanges); } return intersectionRanges.release(); }
TEST(TimeRanges, IntersectWith_Gaps1) { RefPtr<TimeRanges> rangesA = TimeRanges::create(); RefPtr<TimeRanges> rangesB = TimeRanges::create(); rangesA->add(0, 2); rangesA->add(4, 6); rangesB->add(1, 5); ASSERT_RANGE("{ [0,2) [4,6) }", rangesA); ASSERT_RANGE("{ [1,5) }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ [1,2) [4,5) }", rangesA); ASSERT_RANGE("{ [1,5) }", rangesB); }
TEST(TimeRanges, IntersectWith_CompleteOverlap2) { RefPtr<TimeRanges> rangesA = TimeRanges::create(); RefPtr<TimeRanges> rangesB = TimeRanges::create(); rangesA->add(1, 3); rangesA->add(4, 5); rangesA->add(6, 9); rangesB->add(1, 9); ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); ASSERT_RANGE("{ [1,9) }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); ASSERT_RANGE("{ [1,9) }", rangesB); }
TEST(TimeRanges, IntersectWith_DisjointRanges2) { RefPtr<TimeRanges> rangesA = TimeRanges::create(); RefPtr<TimeRanges> rangesB = TimeRanges::create(); rangesA->add(0, 1); rangesA->add(4, 5); rangesB->add(1, 4); rangesB->add(5, 7); ASSERT_RANGE("{ [0,1) [4,5) }", rangesA); ASSERT_RANGE("{ [1,4) [5,7) }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ }", rangesA); ASSERT_RANGE("{ [1,4) [5,7) }", rangesB); }
TEST(TimeRanges, IntersectWith_Gaps3) { RefPtr<TimeRanges> rangesA = TimeRanges::create(); RefPtr<TimeRanges> rangesB = TimeRanges::create(); rangesA->add(0, 2); rangesA->add(4, 7); rangesA->add(8, 10); rangesB->add(1, 5); rangesB->add(6, 9); ASSERT_RANGE("{ [0,2) [4,7) [8,10) }", rangesA); ASSERT_RANGE("{ [1,5) [6,9) }", rangesB); rangesA->intersectWith(rangesB.get()); ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA); ASSERT_RANGE("{ [1,5) [6,9) }", rangesB); }
TEST(TimeRanges, IntersectWith_DisjointRanges1) { RefPtr<TimeRanges> rangesA = TimeRanges::create(); RefPtr<TimeRanges> rangesB = TimeRanges::create(); rangesA->add(0, 1); rangesA->add(4, 5); rangesB->add(2, 3); rangesB->add(6, 7); ASSERT_RANGE("{ [0,1) [4,5) }", rangesA); ASSERT_RANGE("{ [2,3) [6,7) }", rangesB); rangesA->intersectWith(*rangesB.get()); ASSERT_RANGE("{ }", rangesA); ASSERT_RANGE("{ [2,3) [6,7) }", rangesB); }