summaryrefslogtreecommitdiffstats
path: root/chromium/media/base/text_ranges.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/base/text_ranges.cc')
-rw-r--r--chromium/media/base/text_ranges.cc141
1 files changed, 141 insertions, 0 deletions
diff --git a/chromium/media/base/text_ranges.cc b/chromium/media/base/text_ranges.cc
new file mode 100644
index 00000000000..41bc7d0905d
--- /dev/null
+++ b/chromium/media/base/text_ranges.cc
@@ -0,0 +1,141 @@
+// Copyright 2014 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.
+
+#include "media/base/text_ranges.h"
+
+#include "base/logging.h"
+
+namespace media {
+
+TextRanges::TextRanges() {
+ Reset();
+}
+
+TextRanges::~TextRanges() {
+}
+
+void TextRanges::Reset() {
+ curr_range_itr_ = range_map_.end();
+}
+
+bool TextRanges::AddCue(base::TimeDelta start_time) {
+ typedef RangeMap::iterator Itr;
+
+ if (curr_range_itr_ == range_map_.end()) {
+ // There is no active time range, so this is the first AddCue()
+ // attempt that follows a Reset().
+
+ if (range_map_.empty()) {
+ NewRange(start_time);
+ return true;
+ }
+
+ if (start_time < range_map_.begin()->first) {
+ NewRange(start_time);
+ return true;
+ }
+
+ const Itr itr = --Itr(range_map_.upper_bound(start_time));
+ DCHECK(start_time >= itr->first);
+
+ Range& range = itr->second;
+
+ if (start_time > range.last_time()) {
+ NewRange(start_time);
+ return true;
+ }
+
+ range.ResetCount(start_time);
+ curr_range_itr_ = itr;
+ return false;
+ }
+
+ DCHECK(start_time >= curr_range_itr_->first);
+
+ Range& curr_range = curr_range_itr_->second;
+
+ if (start_time <= curr_range.last_time())
+ return curr_range.AddCue(start_time);
+
+ const Itr next_range_itr = ++Itr(curr_range_itr_);
+
+ if (next_range_itr != range_map_.end()) {
+ DCHECK(next_range_itr->first > curr_range.last_time());
+ DCHECK(start_time <= next_range_itr->first);
+
+ if (start_time == next_range_itr->first) {
+ // We have walked off the current range, and onto the next one.
+ // There is now no ambiguity about where the current time range
+ // ends, and so we coalesce the current and next ranges.
+
+ Merge(curr_range, next_range_itr);
+ return false;
+ }
+ }
+
+ // Either |curr_range| is the last range in the map, or there is a
+ // next range beyond |curr_range|, but its start time is ahead of
+ // this cue's start time. In either case, this cue becomes the new
+ // last_time for |curr_range|. Eventually we will see a cue whose
+ // time matches the start time of the next range, in which case we
+ // coalesce the current and next ranges.
+
+ curr_range.SetLastTime(start_time);
+ return true;
+}
+
+size_t TextRanges::RangeCountForTesting() const {
+ return range_map_.size();
+}
+
+void TextRanges::NewRange(base::TimeDelta start_time) {
+ Range range;
+ range.SetLastTime(start_time);
+
+ std::pair<RangeMap::iterator, bool> result =
+ range_map_.insert(std::make_pair(start_time, range));
+ DCHECK(result.second);
+
+ curr_range_itr_ = result.first;
+}
+
+void TextRanges::Merge(
+ Range& curr_range,
+ const RangeMap::iterator& next_range_itr) {
+ curr_range = next_range_itr->second;
+ curr_range.ResetCount(next_range_itr->first);
+ range_map_.erase(next_range_itr);
+}
+
+void TextRanges::Range::ResetCount(base::TimeDelta start_time) {
+ count_ = (start_time < last_time_) ? 0 : 1;
+}
+
+void TextRanges::Range::SetLastTime(base::TimeDelta last_time) {
+ last_time_ = last_time;
+ count_ = 1;
+ max_count_ = 1;
+}
+
+bool TextRanges::Range::AddCue(base::TimeDelta start_time) {
+ if (start_time < last_time_) {
+ DCHECK_EQ(count_, 0);
+ return false;
+ }
+
+ DCHECK(start_time == last_time_);
+
+ ++count_;
+ if (count_ <= max_count_)
+ return false;
+
+ ++max_count_;
+ return true;
+}
+
+base::TimeDelta TextRanges::Range::last_time() const {
+ return last_time_;
+}
+
+} // namespace media