text_ranges.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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.
  4. #include "media/base/text_ranges.h"
  5. #include "base/check_op.h"
  6. namespace media {
  7. TextRanges::TextRanges() {
  8. Reset();
  9. }
  10. TextRanges::~TextRanges() = default;
  11. void TextRanges::Reset() {
  12. curr_range_itr_ = range_map_.end();
  13. }
  14. bool TextRanges::AddCue(base::TimeDelta start_time) {
  15. typedef RangeMap::iterator Itr;
  16. if (curr_range_itr_ == range_map_.end()) {
  17. // There is no active time range, so this is the first AddCue()
  18. // attempt that follows a Reset().
  19. if (range_map_.empty()) {
  20. NewRange(start_time);
  21. return true;
  22. }
  23. if (start_time < range_map_.begin()->first) {
  24. NewRange(start_time);
  25. return true;
  26. }
  27. const Itr itr = --Itr(range_map_.upper_bound(start_time));
  28. DCHECK(start_time >= itr->first);
  29. Range& range = itr->second;
  30. if (start_time > range.last_time()) {
  31. NewRange(start_time);
  32. return true;
  33. }
  34. range.ResetCount(start_time);
  35. curr_range_itr_ = itr;
  36. return false;
  37. }
  38. DCHECK(start_time >= curr_range_itr_->first);
  39. Range& curr_range = curr_range_itr_->second;
  40. if (start_time <= curr_range.last_time())
  41. return curr_range.AddCue(start_time);
  42. const Itr next_range_itr = ++Itr(curr_range_itr_);
  43. if (next_range_itr != range_map_.end()) {
  44. DCHECK(next_range_itr->first > curr_range.last_time());
  45. DCHECK(start_time <= next_range_itr->first);
  46. if (start_time == next_range_itr->first) {
  47. // We have walked off the current range, and onto the next one.
  48. // There is now no ambiguity about where the current time range
  49. // ends, and so we coalesce the current and next ranges.
  50. Merge(curr_range, next_range_itr);
  51. return false;
  52. }
  53. }
  54. // Either |curr_range| is the last range in the map, or there is a
  55. // next range beyond |curr_range|, but its start time is ahead of
  56. // this cue's start time. In either case, this cue becomes the new
  57. // last_time for |curr_range|. Eventually we will see a cue whose
  58. // time matches the start time of the next range, in which case we
  59. // coalesce the current and next ranges.
  60. curr_range.SetLastTime(start_time);
  61. return true;
  62. }
  63. size_t TextRanges::RangeCountForTesting() const {
  64. return range_map_.size();
  65. }
  66. void TextRanges::NewRange(base::TimeDelta start_time) {
  67. Range range;
  68. range.SetLastTime(start_time);
  69. std::pair<RangeMap::iterator, bool> result =
  70. range_map_.insert(std::make_pair(start_time, range));
  71. DCHECK(result.second);
  72. curr_range_itr_ = result.first;
  73. }
  74. void TextRanges::Merge(
  75. Range& curr_range,
  76. const RangeMap::iterator& next_range_itr) {
  77. curr_range = next_range_itr->second;
  78. curr_range.ResetCount(next_range_itr->first);
  79. range_map_.erase(next_range_itr);
  80. }
  81. void TextRanges::Range::ResetCount(base::TimeDelta start_time) {
  82. count_ = (start_time < last_time_) ? 0 : 1;
  83. }
  84. void TextRanges::Range::SetLastTime(base::TimeDelta last_time) {
  85. last_time_ = last_time;
  86. count_ = 1;
  87. max_count_ = 1;
  88. }
  89. bool TextRanges::Range::AddCue(base::TimeDelta start_time) {
  90. if (start_time < last_time_) {
  91. DCHECK_EQ(count_, 0);
  92. return false;
  93. }
  94. DCHECK(start_time == last_time_);
  95. ++count_;
  96. if (count_ <= max_count_)
  97. return false;
  98. ++max_count_;
  99. return true;
  100. }
  101. base::TimeDelta TextRanges::Range::last_time() const {
  102. return last_time_;
  103. }
  104. } // namespace media