Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / base / text_ranges.cc
blob41bc7d0905dd36d6de2adfb20bb8a25f9488a44b
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/text_ranges.h"
7 #include "base/logging.h"
9 namespace media {
11 TextRanges::TextRanges() {
12 Reset();
15 TextRanges::~TextRanges() {
18 void TextRanges::Reset() {
19 curr_range_itr_ = range_map_.end();
22 bool TextRanges::AddCue(base::TimeDelta start_time) {
23 typedef RangeMap::iterator Itr;
25 if (curr_range_itr_ == range_map_.end()) {
26 // There is no active time range, so this is the first AddCue()
27 // attempt that follows a Reset().
29 if (range_map_.empty()) {
30 NewRange(start_time);
31 return true;
34 if (start_time < range_map_.begin()->first) {
35 NewRange(start_time);
36 return true;
39 const Itr itr = --Itr(range_map_.upper_bound(start_time));
40 DCHECK(start_time >= itr->first);
42 Range& range = itr->second;
44 if (start_time > range.last_time()) {
45 NewRange(start_time);
46 return true;
49 range.ResetCount(start_time);
50 curr_range_itr_ = itr;
51 return false;
54 DCHECK(start_time >= curr_range_itr_->first);
56 Range& curr_range = curr_range_itr_->second;
58 if (start_time <= curr_range.last_time())
59 return curr_range.AddCue(start_time);
61 const Itr next_range_itr = ++Itr(curr_range_itr_);
63 if (next_range_itr != range_map_.end()) {
64 DCHECK(next_range_itr->first > curr_range.last_time());
65 DCHECK(start_time <= next_range_itr->first);
67 if (start_time == next_range_itr->first) {
68 // We have walked off the current range, and onto the next one.
69 // There is now no ambiguity about where the current time range
70 // ends, and so we coalesce the current and next ranges.
72 Merge(curr_range, next_range_itr);
73 return false;
77 // Either |curr_range| is the last range in the map, or there is a
78 // next range beyond |curr_range|, but its start time is ahead of
79 // this cue's start time. In either case, this cue becomes the new
80 // last_time for |curr_range|. Eventually we will see a cue whose
81 // time matches the start time of the next range, in which case we
82 // coalesce the current and next ranges.
84 curr_range.SetLastTime(start_time);
85 return true;
88 size_t TextRanges::RangeCountForTesting() const {
89 return range_map_.size();
92 void TextRanges::NewRange(base::TimeDelta start_time) {
93 Range range;
94 range.SetLastTime(start_time);
96 std::pair<RangeMap::iterator, bool> result =
97 range_map_.insert(std::make_pair(start_time, range));
98 DCHECK(result.second);
100 curr_range_itr_ = result.first;
103 void TextRanges::Merge(
104 Range& curr_range,
105 const RangeMap::iterator& next_range_itr) {
106 curr_range = next_range_itr->second;
107 curr_range.ResetCount(next_range_itr->first);
108 range_map_.erase(next_range_itr);
111 void TextRanges::Range::ResetCount(base::TimeDelta start_time) {
112 count_ = (start_time < last_time_) ? 0 : 1;
115 void TextRanges::Range::SetLastTime(base::TimeDelta last_time) {
116 last_time_ = last_time;
117 count_ = 1;
118 max_count_ = 1;
121 bool TextRanges::Range::AddCue(base::TimeDelta start_time) {
122 if (start_time < last_time_) {
123 DCHECK_EQ(count_, 0);
124 return false;
127 DCHECK(start_time == last_time_);
129 ++count_;
130 if (count_ <= max_count_)
131 return false;
133 ++max_count_;
134 return true;
137 base::TimeDelta TextRanges::Range::last_time() const {
138 return last_time_;
141 } // namespace media