15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/text_ranges.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextRanges::TextRanges() {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Reset();
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextRanges::~TextRanges() {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextRanges::Reset() {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  curr_range_itr_ = range_map_.end();
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TextRanges::AddCue(base::TimeDelta start_time) {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef RangeMap::iterator Itr;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (curr_range_itr_ == range_map_.end()) {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // There is no active time range, so this is the first AddCue()
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // attempt that follows a Reset().
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (range_map_.empty()) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NewRange(start_time);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (start_time < range_map_.begin()->first) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NewRange(start_time);
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Itr itr = --Itr(range_map_.upper_bound(start_time));
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(start_time >= itr->first);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Range& range = itr->second;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (start_time > range.last_time()) {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NewRange(start_time);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    range.ResetCount(start_time);
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    curr_range_itr_ = itr;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(start_time >= curr_range_itr_->first);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Range& curr_range = curr_range_itr_->second;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (start_time <= curr_range.last_time())
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return curr_range.AddCue(start_time);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Itr next_range_itr = ++Itr(curr_range_itr_);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (next_range_itr != range_map_.end()) {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(next_range_itr->first > curr_range.last_time());
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(start_time <= next_range_itr->first);
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (start_time == next_range_itr->first) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // We have walked off the current range, and onto the next one.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // There is now no ambiguity about where the current time range
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // ends, and so we coalesce the current and next ranges.
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Merge(curr_range, next_range_itr);
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Either |curr_range| is the last range in the map, or there is a
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // next range beyond |curr_range|, but its start time is ahead of
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this cue's start time.  In either case, this cue becomes the new
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // last_time for |curr_range|.  Eventually we will see a cue whose
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // time matches the start time of the next range, in which case we
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // coalesce the current and next ranges.
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  curr_range.SetLastTime(start_time);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)size_t TextRanges::RangeCountForTesting() const {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return range_map_.size();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextRanges::NewRange(base::TimeDelta start_time) {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Range range;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  range.SetLastTime(start_time);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::pair<RangeMap::iterator, bool> result =
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      range_map_.insert(std::make_pair(start_time, range));
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(result.second);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  curr_range_itr_ = result.first;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextRanges::Merge(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Range& curr_range,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const RangeMap::iterator& next_range_itr) {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  curr_range = next_range_itr->second;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  curr_range.ResetCount(next_range_itr->first);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  range_map_.erase(next_range_itr);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextRanges::Range::ResetCount(base::TimeDelta start_time) {
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  count_ = (start_time < last_time_) ? 0 : 1;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextRanges::Range::SetLastTime(base::TimeDelta last_time) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  last_time_ = last_time;
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  count_ = 1;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  max_count_ = 1;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TextRanges::Range::AddCue(base::TimeDelta start_time) {
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (start_time < last_time_) {
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(count_, 0);
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(start_time == last_time_);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ++count_;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (count_ <= max_count_)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ++max_count_;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta TextRanges::Range::last_time() const {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return last_time_;
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
142