b5e8f4704ccfc49b5f8f1652116f2593d393b6d0
[platform/framework/web/chromium-efl.git] / media / filters / source_buffer_range.cc
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/filters/source_buffer_range.h"
6
7 #include <algorithm>
8 #include <sstream>
9 #include <string>
10 #include <vector>
11
12 #include "base/logging.h"
13 #include "media/base/stream_parser_buffer.h"
14 #include "media/base/timestamp_constants.h"
15
16 namespace media {
17
18 SourceBufferRange::SourceBufferRange(
19     GapPolicy gap_policy,
20     const BufferQueue& new_buffers,
21     base::TimeDelta range_start_pts,
22     InterbufferDistanceCB interbuffer_distance_cb)
23     : gap_policy_(gap_policy),
24       next_buffer_index_(-1),
25       interbuffer_distance_cb_(std::move(interbuffer_distance_cb)),
26       size_in_bytes_(0),
27       range_start_pts_(range_start_pts),
28       keyframe_map_index_base_(0) {
29   DVLOG(3) << __func__;
30   DCHECK(interbuffer_distance_cb_);
31   CHECK(!new_buffers.empty());
32   DCHECK(new_buffers.front()->is_key_frame());
33   AppendBuffersToEnd(new_buffers, range_start_pts_);
34 }
35
36 SourceBufferRange::~SourceBufferRange() = default;
37
38 void SourceBufferRange::DeleteAll(BufferQueue* deleted_buffers) {
39   DVLOG(1) << __func__;
40   DVLOG(4) << ToStringForDebugging();
41
42   TruncateAt(0u, deleted_buffers);
43 }
44
45 void SourceBufferRange::SeekToStart() {
46   CHECK(!buffers_.empty());
47   next_buffer_index_ = 0;
48 }
49
50 bool SourceBufferRange::GetNextBuffer(
51     scoped_refptr<StreamParserBuffer>* out_buffer) {
52   if (!HasNextBuffer())
53     return false;
54
55   *out_buffer = buffers_[next_buffer_index_];
56   next_buffer_index_++;
57   return true;
58 }
59
60 bool SourceBufferRange::HasNextBuffer() const {
61   return next_buffer_index_ >= 0 &&
62       next_buffer_index_ < static_cast<int>(buffers_.size());
63 }
64
65 int SourceBufferRange::GetNextConfigId() const {
66   CHECK(HasNextBuffer()) << next_buffer_index_;
67   // If the next buffer is an audio splice frame, the next effective config id
68   // comes from the first fade out preroll buffer.
69   return buffers_[next_buffer_index_]->GetConfigId();
70 }
71
72 bool SourceBufferRange::HasNextBufferPosition() const {
73   return next_buffer_index_ >= 0;
74 }
75
76 void SourceBufferRange::ResetNextBufferPosition() {
77   next_buffer_index_ = -1;
78 }
79
80 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
81                                          bool transfer_current_position) {
82   DVLOG(1) << __func__;
83   DVLOG(4) << ToStringForDebugging();
84
85   DCHECK(CanAppendRangeToEnd(range));
86   DCHECK(!buffers_.empty());
87
88   if (transfer_current_position && range.next_buffer_index_ >= 0)
89     next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
90
91   AppendBuffersToEnd(range.buffers_,
92                      NextRangeStartTimeForAppendRangeToEnd(range));
93 }
94
95 bool SourceBufferRange::CanAppendRangeToEnd(
96     const SourceBufferRange& range) const {
97   DVLOG(1) << __func__;
98   DVLOG(4) << ToStringForDebugging();
99
100   return CanAppendBuffersToEnd(range.buffers_,
101                                NextRangeStartTimeForAppendRangeToEnd(range));
102 }
103
104 void SourceBufferRange::AppendBuffersToEnd(
105     const BufferQueue& new_buffers,
106     base::TimeDelta new_buffers_group_start_pts) {
107   DVLOG(1) << __func__;
108   DVLOG(4) << ToStringForDebugging();
109
110   CHECK(buffers_.empty() ||
111         CanAppendBuffersToEnd(new_buffers, new_buffers_group_start_pts));
112
113   DCHECK(new_buffers_group_start_pts == kNoTimestamp ||
114          new_buffers.front()->is_key_frame())
115       << range_start_pts_ << ", " << new_buffers.front()->is_key_frame();
116
117   AdjustEstimatedDurationForNewAppend(new_buffers);
118
119   for (BufferQueue::const_iterator itr = new_buffers.begin();
120        itr != new_buffers.end(); ++itr) {
121     DCHECK((*itr)->timestamp() != kNoTimestamp);
122     DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp);
123
124     buffers_.push_back(*itr);
125     UpdateEndTime(*itr);
126     size_in_bytes_ += (*itr)->data_size();
127
128     if ((*itr)->is_key_frame()) {
129       keyframe_map_.insert(std::make_pair(
130           (*itr)->timestamp(), buffers_.size() - 1 + keyframe_map_index_base_));
131     }
132   }
133
134   DVLOG(4) << __func__ << " Result: " << ToStringForDebugging();
135 }
136
137 bool SourceBufferRange::AllowableAppendAfterEstimatedDuration(
138     const BufferQueue& buffers,
139     base::TimeDelta new_buffers_group_start_pts) const {
140   if (buffers_.empty() || !buffers_.back()->is_duration_estimated() ||
141       buffers.empty() || !buffers.front()->is_key_frame()) {
142     return false;
143   }
144
145   if (new_buffers_group_start_pts == kNoTimestamp) {
146     return GetBufferedEndTimestamp() == buffers.front()->timestamp();
147   }
148
149   return GetBufferedEndTimestamp() == new_buffers_group_start_pts;
150 }
151
152 bool SourceBufferRange::CanAppendBuffersToEnd(
153     const BufferQueue& buffers,
154     base::TimeDelta new_buffers_group_start_pts) const {
155   DVLOG(1) << __func__;
156   DVLOG(4) << ToStringForDebugging();
157
158   DCHECK(!buffers_.empty());
159   if (new_buffers_group_start_pts == kNoTimestamp) {
160     return buffers.front()->is_key_frame()
161                ? (IsNextInPresentationSequence(buffers.front()->timestamp()) ||
162                   AllowableAppendAfterEstimatedDuration(
163                       buffers, new_buffers_group_start_pts))
164                : IsNextInDecodeSequence(buffers.front()->GetDecodeTimestamp());
165   }
166   CHECK(buffers.front()->is_key_frame());
167   DCHECK(new_buffers_group_start_pts >= GetEndTimestamp());
168   DCHECK(buffers.front()->timestamp() >= new_buffers_group_start_pts);
169   return IsNextInPresentationSequence(new_buffers_group_start_pts) ||
170          AllowableAppendAfterEstimatedDuration(buffers,
171                                                new_buffers_group_start_pts);
172 }
173
174 void SourceBufferRange::Seek(base::TimeDelta timestamp) {
175   DVLOG(1) << __func__;
176   DVLOG(4) << ToStringForDebugging();
177
178   DCHECK(CanSeekTo(timestamp));
179   DCHECK(!keyframe_map_.empty());
180
181   auto result = GetFirstKeyframeAtOrBefore(timestamp);
182   next_buffer_index_ = result->second - keyframe_map_index_base_;
183   CHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()))
184       << next_buffer_index_ << ", size = " << buffers_.size();
185 }
186 #if BUILDFLAG(IS_TIZEN_TV)
187 void SourceBufferRange::ModifyFirstFrameForMpeghCodec() {
188   DVLOG(1) << __func__;
189   DVLOG(4) << ToStringForDebugging();
190   // MPEGH codec starting sequence
191   std::vector<uint8_t> start_sequence = {0x01, 0x00, 0x00, 0x00, 0x18,
192                                          0x00, 0x00, 0x00, 0x00};
193
194   if (buffers_.size() <= next_buffer_index_)
195     return;
196
197   auto old_data_ = buffers_[next_buffer_index_]->data();
198   auto old_data_size = buffers_[next_buffer_index_]->data_size();
199
200   // This is used to check whether we do not try to add starting sequence to
201   // frame that already had it added while demuxing ie. first uploaded frame
202   bool is_starting_sequence_already_present = true;
203   for (unsigned int i = 0; i < start_sequence.size() && i < old_data_size;
204        i++) {
205     if (start_sequence[i] != old_data_[i]) {
206       is_starting_sequence_already_present = false;
207       break;
208     }
209   }
210
211   if (is_starting_sequence_already_present &&
212       old_data_size > start_sequence.size())
213     return;
214
215   // New container for old data with added starting sequence
216   std::vector<uint8_t> new_data =
217       std::vector<uint8_t>(old_data_size + start_sequence.size());
218
219   // Starting sequence inserted in front of new data
220   // new_data.insert(new_data.begin(),start_sequence.begin(),start_sequence.end());
221   for (unsigned int i = 0; i < start_sequence.size(); i++) {
222     new_data[i] = start_sequence[i];
223   }
224
225   // Loop copying old data to new container
226   for (unsigned int i = 0; i < old_data_size; i++) {
227     new_data[i + start_sequence.size()] = old_data_[i];
228   }
229
230   // Creating new buffer based on changed data
231   auto new_buffer = StreamParserBuffer::CopyFrom(
232       &(new_data.front()), new_data.size(),
233 #if !defined(EWK_BRINGUP)  // FIXME: m120 bringup (Removed in Open Source)
234       buffers_[next_buffer_index_]->side_data(),
235       buffers_[next_buffer_index_]->side_data_size(),
236 #endif
237       buffers_[next_buffer_index_]->is_key_frame(),
238       buffers_[next_buffer_index_]->type(),
239       buffers_[next_buffer_index_]->track_id());
240
241   // Setting other necessary data not copied by previous function
242   new_buffer->SetConfigId(buffers_[next_buffer_index_]->GetConfigId());
243   new_buffer->SetDecodeTimestamp(
244       buffers_[next_buffer_index_]->GetDecodeTimestamp());
245   new_buffer->set_is_duration_estimated(
246       buffers_[next_buffer_index_]->is_duration_estimated());
247   new_buffer->set_duration(buffers_[next_buffer_index_]->duration());
248   new_buffer->set_timestamp(buffers_[next_buffer_index_]->timestamp());
249
250   // Swapping old buffer to new buffer. Old buffer is discarded.
251   buffers_[next_buffer_index_].swap(new_buffer);
252 }
253 #endif
254
255 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const {
256   DVLOG(1) << __func__;
257   DVLOG(4) << ToStringForDebugging();
258
259   base::TimeDelta start_timestamp =
260       std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom());
261   return !keyframe_map_.empty() && start_timestamp <= timestamp &&
262          timestamp < GetBufferedEndTimestamp();
263 }
264
265 int SourceBufferRange::GetConfigIdAtTime(base::TimeDelta timestamp) const {
266   DVLOG(1) << __func__;
267   DVLOG(4) << ToStringForDebugging();
268
269   DCHECK(CanSeekTo(timestamp));
270   DCHECK(!keyframe_map_.empty());
271
272   auto result = GetFirstKeyframeAtOrBefore(timestamp);
273   CHECK(result != keyframe_map_.end());
274   size_t buffer_index = result->second - keyframe_map_index_base_;
275   CHECK_LT(buffer_index, buffers_.size())
276       << buffer_index << ", size = " << buffers_.size();
277
278   return buffers_[buffer_index]->GetConfigId();
279 }
280
281 bool SourceBufferRange::SameConfigThruRange(base::TimeDelta start,
282                                             base::TimeDelta end) const {
283   DVLOG(1) << __func__;
284   DVLOG(4) << ToStringForDebugging();
285
286   DCHECK(CanSeekTo(start));
287   DCHECK(CanSeekTo(end));
288   DCHECK(start <= end);
289   DCHECK(!keyframe_map_.empty());
290
291   if (start == end)
292     return true;
293
294   auto result = GetFirstKeyframeAtOrBefore(start);
295   CHECK(result != keyframe_map_.end());
296   size_t buffer_index = result->second - keyframe_map_index_base_;
297   CHECK_LT(buffer_index, buffers_.size())
298       << buffer_index << ", size = " << buffers_.size();
299
300   int start_config = buffers_[buffer_index]->GetConfigId();
301   buffer_index++;
302   while (buffer_index < buffers_.size() &&
303          buffers_[buffer_index]->timestamp() <= end) {
304     if (buffers_[buffer_index]->GetConfigId() != start_config)
305       return false;
306     buffer_index++;
307   }
308
309   return true;
310 }
311
312 std::unique_ptr<SourceBufferRange> SourceBufferRange::SplitRange(
313     base::TimeDelta timestamp) {
314   DVLOG(1) << __func__;
315   DVLOG(4) << ToStringForDebugging();
316
317   CHECK(!buffers_.empty());
318
319   // Find the first keyframe at or after |timestamp|.
320   auto new_beginning_keyframe = GetFirstKeyframeAt(timestamp, false);
321
322   // If there is no keyframe at or after |timestamp|, we can't split the range.
323   if (new_beginning_keyframe == keyframe_map_.end())
324     return nullptr;
325
326   // Remove the data beginning at |keyframe_index| from |buffers_| and save it
327   // into |removed_buffers|.
328   int keyframe_index =
329       new_beginning_keyframe->second - keyframe_map_index_base_;
330   CHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
331   BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
332   BufferQueue removed_buffers(starting_point, buffers_.end());
333
334   base::TimeDelta new_range_start_pts =
335       std::max(timestamp, GetStartTimestamp());
336   DCHECK(new_range_start_pts <= removed_buffers.front()->timestamp());
337
338   keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
339   FreeBufferRange(starting_point, buffers_.end());
340   UpdateEndTimeUsingLastGOP();
341
342   // Create a new range with |removed_buffers|.
343   std::unique_ptr<SourceBufferRange> split_range =
344       std::make_unique<SourceBufferRange>(gap_policy_, removed_buffers,
345                                           new_range_start_pts,
346                                           interbuffer_distance_cb_);
347
348   // If the next buffer position is now in |split_range|, update the state of
349   // this range and |split_range| accordingly.
350   if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
351     split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
352
353     int split_range_next_buffer_index = split_range->next_buffer_index_;
354     CHECK_GE(split_range_next_buffer_index, 0);
355     // Note that a SourceBufferRange's |next_buffer_index_| can be the index
356     // of a buffer one beyond what is currently in |buffers_|.
357     CHECK_LE(split_range_next_buffer_index,
358              static_cast<int>(split_range->buffers_.size()));
359
360     ResetNextBufferPosition();
361   }
362
363   return split_range;
364 }
365
366 bool SourceBufferRange::TruncateAt(base::TimeDelta timestamp,
367                                    BufferQueue* deleted_buffers,
368                                    bool is_exclusive) {
369   DVLOG(1) << __func__;
370   DVLOG(4) << ToStringForDebugging();
371
372   // Find the place in |buffers_| where we will begin deleting data, then
373   // truncate from there.
374   return TruncateAt(GetBufferIndexAt(timestamp, is_exclusive), deleted_buffers);
375 }
376
377 size_t SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
378   DVLOG(1) << __func__;
379   DVLOG(4) << ToStringForDebugging();
380
381   DCHECK(!buffers_.empty());
382   DCHECK(!FirstGOPContainsNextBufferPosition());
383   DCHECK(deleted_buffers);
384
385   int buffers_deleted = 0;
386   size_t total_bytes_deleted = 0;
387
388   KeyframeMap::const_iterator front = keyframe_map_.begin();
389   DCHECK(front != keyframe_map_.end());
390
391   // Delete the keyframe at the start of |keyframe_map_|.
392   keyframe_map_.erase(front);
393
394   // Now we need to delete all the buffers that depend on the keyframe we've
395   // just deleted.
396   int end_index = keyframe_map_.size() > 0
397                       ? keyframe_map_.begin()->second - keyframe_map_index_base_
398                       : buffers_.size();
399
400   // Delete buffers from the beginning of the buffered range up until (but not
401   // including) the next keyframe.
402   for (int i = 0; i < end_index; i++) {
403     size_t bytes_deleted = buffers_.front()->data_size();
404     DCHECK_GE(size_in_bytes_, bytes_deleted);
405     size_in_bytes_ -= bytes_deleted;
406     total_bytes_deleted += bytes_deleted;
407     deleted_buffers->push_back(buffers_.front());
408     buffers_.pop_front();
409     ++buffers_deleted;
410   }
411
412   // Update |keyframe_map_index_base_| to account for the deleted buffers.
413   keyframe_map_index_base_ += buffers_deleted;
414
415   if (next_buffer_index_ > -1) {
416     next_buffer_index_ -= buffers_deleted;
417     CHECK_GE(next_buffer_index_, 0)
418         << next_buffer_index_ << ", deleted " << buffers_deleted;
419   }
420
421   // Invalidate range start time if we've deleted the first buffer of the range.
422   if (buffers_deleted > 0) {
423     range_start_pts_ = kNoTimestamp;
424     // Reset the range end time tracking if there are no more buffers in the
425     // range.
426     if (buffers_.empty())
427       highest_frame_ = nullptr;
428   }
429
430   return total_bytes_deleted;
431 }
432
433 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
434   DVLOG(1) << __func__;
435   DVLOG(4) << ToStringForDebugging();
436
437   DCHECK(!buffers_.empty());
438   DCHECK(!LastGOPContainsNextBufferPosition());
439   DCHECK(deleted_buffers);
440
441   // Remove the last GOP's keyframe from the |keyframe_map_|.
442   KeyframeMap::const_iterator back = keyframe_map_.end();
443   DCHECK_GT(keyframe_map_.size(), 0u);
444   --back;
445
446   // The index of the first buffer in the last GOP is equal to the new size of
447   // |buffers_| after that GOP is deleted.
448   size_t goal_size = back->second - keyframe_map_index_base_;
449   keyframe_map_.erase(back);
450
451   size_t total_bytes_deleted = 0;
452   while (buffers_.size() != goal_size) {
453     size_t bytes_deleted = buffers_.back()->data_size();
454     DCHECK_GE(size_in_bytes_, bytes_deleted);
455     size_in_bytes_ -= bytes_deleted;
456     total_bytes_deleted += bytes_deleted;
457     // We're removing buffers from the back, so push each removed buffer to the
458     // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing
459     // order.
460     deleted_buffers->push_front(buffers_.back());
461     buffers_.pop_back();
462   }
463
464   UpdateEndTimeUsingLastGOP();
465
466   return total_bytes_deleted;
467 }
468
469 size_t SourceBufferRange::GetRemovalGOP(
470     base::TimeDelta start_timestamp,
471     base::TimeDelta end_timestamp,
472     size_t total_bytes_to_free,
473     base::TimeDelta* removal_end_timestamp) const {
474   DVLOG(1) << __func__;
475   DVLOG(4) << ToStringForDebugging();
476
477   size_t bytes_removed = 0;
478
479   auto gop_itr = GetFirstKeyframeAt(start_timestamp, false);
480   if (gop_itr == keyframe_map_.end())
481     return 0;
482   int keyframe_index = gop_itr->second - keyframe_map_index_base_;
483   BufferQueue::const_iterator buffer_itr = buffers_.begin() + keyframe_index;
484   auto gop_end = keyframe_map_.end();
485   if (end_timestamp < GetBufferedEndTimestamp())
486     gop_end = GetFirstKeyframeAtOrBefore(end_timestamp);
487
488   // Check if the removal range is within a GOP and skip the loop if so.
489   // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe]
490   auto gop_itr_prev = gop_itr;
491   if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end)
492     gop_end = gop_itr;
493
494   while (gop_itr != gop_end && bytes_removed < total_bytes_to_free) {
495     ++gop_itr;
496
497     size_t gop_size = 0;
498     int next_gop_index = gop_itr == keyframe_map_.end()
499                              ? buffers_.size()
500                              : gop_itr->second - keyframe_map_index_base_;
501     BufferQueue::const_iterator next_gop_start =
502         buffers_.begin() + next_gop_index;
503     for (; buffer_itr != next_gop_start; ++buffer_itr) {
504       gop_size += (*buffer_itr)->data_size();
505     }
506
507     bytes_removed += gop_size;
508   }
509   if (bytes_removed > 0) {
510     *removal_end_timestamp = gop_itr == keyframe_map_.end()
511                                  ? GetBufferedEndTimestamp()
512                                  : gop_itr->first;
513   }
514   return bytes_removed;
515 }
516
517 bool SourceBufferRange::FirstGOPEarlierThanMediaTime(
518     base::TimeDelta media_time) const {
519   DVLOG(1) << __func__;
520   DVLOG(4) << ToStringForDebugging();
521
522   if (keyframe_map_.size() == 1u)
523     return (GetBufferedEndTimestamp() <= media_time);
524
525   auto second_gop = keyframe_map_.begin();
526   ++second_gop;
527   return second_gop->first <= media_time;
528 }
529
530 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const {
531   DVLOG(1) << __func__;
532   DVLOG(4) << ToStringForDebugging();
533
534   if (!HasNextBufferPosition())
535     return false;
536
537   // If there is only one GOP, it must contain the next buffer position.
538   if (keyframe_map_.size() == 1u)
539     return true;
540
541   auto second_gop = keyframe_map_.begin();
542   ++second_gop;
543   return next_buffer_index_ < second_gop->second - keyframe_map_index_base_;
544 }
545
546 bool SourceBufferRange::LastGOPContainsNextBufferPosition() const {
547   DVLOG(1) << __func__;
548   DVLOG(4) << ToStringForDebugging();
549
550   if (!HasNextBufferPosition())
551     return false;
552
553   // If there is only one GOP, it must contain the next buffer position.
554   if (keyframe_map_.size() == 1u)
555     return true;
556
557   auto last_gop = keyframe_map_.end();
558   --last_gop;
559   return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_;
560 }
561
562 base::TimeDelta SourceBufferRange::GetNextTimestamp() const {
563   DVLOG(1) << __func__;
564   DVLOG(4) << ToStringForDebugging();
565
566   CHECK(!buffers_.empty()) << next_buffer_index_;
567   CHECK(HasNextBufferPosition())
568       << next_buffer_index_ << ", size=" << buffers_.size();
569
570   if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
571     return kNoTimestamp;
572   }
573
574   return buffers_[next_buffer_index_]->timestamp();
575 }
576
577 base::TimeDelta SourceBufferRange::GetStartTimestamp() const {
578   DVLOG(1) << __func__;
579   DVLOG(4) << ToStringForDebugging();
580
581   DCHECK(!buffers_.empty());
582   base::TimeDelta start_timestamp = range_start_pts_;
583   if (start_timestamp == kNoTimestamp)
584     start_timestamp = buffers_.front()->timestamp();
585   return start_timestamp;
586 }
587
588 base::TimeDelta SourceBufferRange::GetEndTimestamp() const {
589   DVLOG(1) << __func__;
590   DVLOG(4) << ToStringForDebugging();
591
592   DCHECK(!buffers_.empty());
593   return highest_frame_->timestamp();
594 }
595
596 base::TimeDelta SourceBufferRange::GetBufferedEndTimestamp() const {
597   DVLOG(1) << __func__;
598   DVLOG(4) << ToStringForDebugging();
599
600   DCHECK(!buffers_.empty());
601   base::TimeDelta duration = highest_frame_->duration();
602
603   // FrameProcessor should protect against unknown buffer durations.
604   DCHECK_NE(duration, kNoTimestamp);
605
606   // Because media::Ranges<base::TimeDelta>::Add() ignores 0 duration ranges,
607   // report 1 microsecond for the last buffer's duration if it is a 0 duration
608   // buffer.
609   if (duration.is_zero())
610     duration = base::Microseconds(1);
611
612   return GetEndTimestamp() + duration;
613 }
614
615 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const {
616   DVLOG(1) << __func__;
617   DVLOG(4) << ToStringForDebugging();
618
619   DCHECK(!buffers_.empty());
620
621   return (IsNextInPresentationSequence(timestamp) ||
622           (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
623 }
624
625 base::TimeDelta SourceBufferRange::FindHighestBufferedTimestampAtOrBefore(
626     base::TimeDelta timestamp) const {
627   DVLOG(1) << __func__;
628   DVLOG(4) << ToStringForDebugging();
629
630   DCHECK(!buffers_.empty());
631   DCHECK(BelongsToRange(timestamp));
632
633   if (keyframe_map_.begin()->first > timestamp) {
634     // If the first keyframe in the range starts after |timestamp|, then
635     // return the range start time (which could be earlier due to coded frame
636     // group signalling.)
637     base::TimeDelta range_start = GetStartTimestamp();
638     DCHECK(timestamp >= range_start) << "BelongsToRange() semantics failed.";
639     return range_start;
640   }
641
642   if (keyframe_map_.begin()->first == timestamp) {
643     return timestamp;
644   }
645
646   auto key_iter = GetFirstKeyframeAtOrBefore(timestamp);
647   DCHECK(key_iter != keyframe_map_.end())
648       << "BelongsToRange() semantics failed.";
649   DCHECK(key_iter->first <= timestamp);
650
651   // Scan forward in |buffers_| to find the highest frame with timestamp <=
652   // |timestamp|. Stop once a frame with timestamp > |timestamp| is encountered.
653   size_t key_index = key_iter->second - keyframe_map_index_base_;
654   SourceBufferRange::BufferQueue::const_iterator search_iter =
655       buffers_.begin() + key_index;
656   CHECK(search_iter != buffers_.end());
657   base::TimeDelta cur_frame_time = (*search_iter)->timestamp();
658   base::TimeDelta result = cur_frame_time;
659   while (true) {
660     result = std::max(result, cur_frame_time);
661     search_iter++;
662     if (search_iter == buffers_.end())
663       return result;
664     cur_frame_time = (*search_iter)->timestamp();
665     if (cur_frame_time > timestamp)
666       return result;
667   }
668
669   NOTREACHED_NORETURN();
670 }
671
672 base::TimeDelta SourceBufferRange::NextKeyframeTimestamp(
673     base::TimeDelta timestamp) const {
674   DVLOG(1) << __func__;
675   DVLOG(4) << ToStringForDebugging();
676
677   DCHECK(!keyframe_map_.empty());
678
679   if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
680     return kNoTimestamp;
681
682   auto itr = GetFirstKeyframeAt(timestamp, false);
683   if (itr == keyframe_map_.end())
684     return kNoTimestamp;
685
686   // If the timestamp is inside the gap between the start of the coded frame
687   // group and the first buffer, then just pretend there is a keyframe at the
688   // specified timestamp.
689   if (itr == keyframe_map_.begin() && timestamp > range_start_pts_ &&
690       timestamp < itr->first) {
691     return timestamp;
692   }
693
694   return itr->first;
695 }
696
697 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp(
698     base::TimeDelta timestamp) const {
699   DVLOG(1) << __func__;
700   DVLOG(4) << ToStringForDebugging();
701
702   DCHECK(!keyframe_map_.empty());
703
704   if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
705     return kNoTimestamp;
706
707   return GetFirstKeyframeAtOrBefore(timestamp)->first;
708 }
709
710 bool SourceBufferRange::GetBuffersInRange(base::TimeDelta start,
711                                           base::TimeDelta end,
712                                           BufferQueue* buffers) const {
713   DVLOG(1) << __func__;
714   DVLOG(4) << ToStringForDebugging();
715
716   // Find the nearest buffer with a timestamp <= start.
717   const base::TimeDelta first_timestamp = KeyframeBeforeTimestamp(start);
718   if (first_timestamp == kNoTimestamp)
719     return false;
720
721   // Find all buffers involved in the range.
722   const size_t previous_size = buffers->size();
723   for (BufferQueue::const_iterator it = GetBufferItrAt(first_timestamp, false);
724        it != buffers_.end(); ++it) {
725     scoped_refptr<StreamParserBuffer> buffer = *it;
726     // Buffers without duration are not supported, so bail if we encounter any.
727     if (buffer->duration() == kNoTimestamp ||
728         buffer->duration() <= base::TimeDelta()) {
729       return false;
730     }
731     if (buffer->timestamp() >= end)
732       break;
733
734     if (buffer->timestamp() + buffer->duration() <= start)
735       continue;
736
737     buffers->emplace_back(std::move(buffer));
738   }
739   return previous_size < buffers->size();
740 }
741
742 void SourceBufferRange::AdjustEstimatedDurationForNewAppend(
743     const BufferQueue& new_buffers) {
744   if (buffers_.empty() || new_buffers.empty()) {
745     return;
746   }
747
748   // Do not adjust estimate for Audio buffers to avoid competing with
749   // SourceBufferStream::TrimSpliceOverlap()
750   if (buffers_.front()->type() == StreamParserBuffer::Type::AUDIO) {
751     return;
752   }
753
754   // If the last of the previously appended buffers contains estimated duration,
755   // we now refine that estimate by taking the PTS delta from the first new
756   // buffer being appended.
757   const auto& last_appended_buffer = buffers_.back();
758   if (last_appended_buffer->is_duration_estimated()) {
759     base::TimeDelta timestamp_delta =
760         new_buffers.front()->timestamp() - last_appended_buffer->timestamp();
761     DCHECK_GE(timestamp_delta, base::TimeDelta());
762     if (last_appended_buffer->duration() != timestamp_delta) {
763       DVLOG(1) << "Replacing estimated duration ("
764                << last_appended_buffer->duration()
765                << ") from previous range-end with derived duration ("
766                << timestamp_delta << ").";
767       last_appended_buffer->set_duration(timestamp_delta);
768     }
769   }
770 }
771
772 void SourceBufferRange::FreeBufferRange(
773     const BufferQueue::const_iterator& starting_point,
774     const BufferQueue::const_iterator& ending_point) {
775   for (BufferQueue::const_iterator itr = starting_point; itr != ending_point;
776        ++itr) {
777     size_t itr_data_size = static_cast<size_t>((*itr)->data_size());
778     DCHECK_GE(size_in_bytes_, itr_data_size);
779     size_in_bytes_ -= itr_data_size;
780   }
781   buffers_.erase(starting_point, ending_point);
782 }
783
784 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
785   // Because we do not know exactly when is the next timestamp, any buffer
786   // that starts within 2x the approximate duration of a buffer is considered
787   // within this range.
788   return 2 * GetApproximateDuration();
789 }
790
791 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
792   base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
793   DCHECK(max_interbuffer_distance != kNoTimestamp);
794   return max_interbuffer_distance;
795 }
796
797 void SourceBufferRange::UpdateEndTime(
798     scoped_refptr<StreamParserBuffer> new_buffer) {
799   base::TimeDelta timestamp = new_buffer->timestamp();
800   base::TimeDelta duration = new_buffer->duration();
801   DVLOG(1) << __func__ << " timestamp=" << timestamp
802            << ", duration=" << duration;
803   DCHECK_NE(timestamp, kNoTimestamp);
804   DCHECK_GE(timestamp, base::TimeDelta());
805   DCHECK_GE(duration, base::TimeDelta());
806
807   if (!highest_frame_) {
808     DVLOG(1) << "Updating range end time from <empty> to "
809              << timestamp.InMicroseconds() << "us, "
810              << (timestamp + duration).InMicroseconds() << "us";
811     highest_frame_ = std::move(new_buffer);
812     return;
813   }
814
815   if (highest_frame_->timestamp() < timestamp ||
816       (highest_frame_->timestamp() == timestamp &&
817        highest_frame_->duration() <= duration)) {
818     DVLOG(1) << "Updating range end time from "
819              << highest_frame_->timestamp().InMicroseconds() << "us, "
820              << (highest_frame_->timestamp() + highest_frame_->duration())
821                     .InMicroseconds()
822              << "us to " << timestamp.InMicroseconds() << "us, "
823              << (timestamp + duration).InMicroseconds();
824     highest_frame_ = std::move(new_buffer);
825   }
826 }
827
828 bool SourceBufferRange::IsNextInPresentationSequence(
829     base::TimeDelta timestamp) const {
830   DCHECK_NE(timestamp, kNoTimestamp);
831   CHECK(!buffers_.empty());
832   base::TimeDelta highest_timestamp = highest_frame_->timestamp();
833   DCHECK_NE(highest_timestamp, kNoTimestamp);
834   return (highest_timestamp == timestamp ||
835           (highest_timestamp < timestamp &&
836            (gap_policy_ == ALLOW_GAPS ||
837             timestamp <= highest_timestamp + GetFudgeRoom())));
838 }
839
840 bool SourceBufferRange::IsNextInDecodeSequence(
841     DecodeTimestamp decode_timestamp) const {
842   CHECK(!buffers_.empty());
843   DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp();
844   return (
845       end == decode_timestamp ||
846       (end < decode_timestamp && (gap_policy_ == ALLOW_GAPS ||
847                                   decode_timestamp <= end + GetFudgeRoom())));
848 }
849
850 base::TimeDelta SourceBufferRange::NextRangeStartTimeForAppendRangeToEnd(
851     const SourceBufferRange& range) const {
852   DCHECK(!buffers_.empty());
853   DCHECK(!range.buffers_.empty());
854
855   base::TimeDelta next_range_first_buffer_time =
856       range.buffers_.front()->timestamp();
857   base::TimeDelta this_range_end_time = GetEndTimestamp();
858   if (next_range_first_buffer_time < this_range_end_time)
859     return kNoTimestamp;
860
861   base::TimeDelta next_range_start_time = range.GetStartTimestamp();
862   DCHECK(next_range_start_time <= next_range_first_buffer_time);
863
864   if (next_range_start_time >= this_range_end_time)
865     return next_range_start_time;
866
867   return this_range_end_time;
868 }
869
870 size_t SourceBufferRange::GetBufferIndexAt(base::TimeDelta timestamp,
871                                            bool skip_given_timestamp) const {
872   DVLOG(1) << __func__;
873   DVLOG(4) << ToStringForDebugging();
874
875   // Find the GOP containing |timestamp| (or trivial buffers_.size() if none
876   // contain |timestamp|).
877   auto gop_iter = GetFirstKeyframeAtOrBefore(timestamp);
878   if (gop_iter == keyframe_map_.end())
879     return buffers_.size();
880
881   // Then scan forward in this GOP in decode sequence for the first frame with
882   // PTS >= |timestamp| (or strictly > if |skip_given_timestamp| is true). If
883   // this GOP doesn't contain such a frame, returns the index of the keyframe of
884   // the next GOP (which could be the index of end() of |buffers_| if this was
885   // the last GOP in |buffers_|). We do linear scan of the GOP here because we
886   // don't know the DTS for the searched-for frame, and the PTS sequence within
887   // a GOP may not match the DTS-sorted sequence of frames within the GOP.
888   DCHECK_GT(buffers_.size(), 0u);
889   size_t search_index = gop_iter->second - keyframe_map_index_base_;
890   SourceBufferRange::BufferQueue::const_iterator search_iter =
891       buffers_.begin() + search_index;
892   gop_iter++;
893
894   SourceBufferRange::BufferQueue::const_iterator next_gop_start =
895       gop_iter == keyframe_map_.end()
896           ? buffers_.end()
897           : buffers_.begin() + (gop_iter->second - keyframe_map_index_base_);
898
899   while (search_iter != next_gop_start) {
900     if (((*search_iter)->timestamp() > timestamp) ||
901         (!skip_given_timestamp && (*search_iter)->timestamp() == timestamp)) {
902       break;
903     }
904     search_index++;
905     search_iter++;
906   }
907
908   return search_index;
909 }
910
911 SourceBufferRange::BufferQueue::const_iterator
912 SourceBufferRange::GetBufferItrAt(base::TimeDelta timestamp,
913                                   bool skip_given_timestamp) const {
914   DVLOG(1) << __func__;
915   DVLOG(4) << ToStringForDebugging();
916
917   return buffers_.begin() + GetBufferIndexAt(timestamp, skip_given_timestamp);
918 }
919
920 SourceBufferRange::KeyframeMap::const_iterator
921 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp,
922                                       bool skip_given_timestamp) const {
923   DVLOG(1) << __func__;
924   DVLOG(4) << ToStringForDebugging();
925
926   return skip_given_timestamp ? keyframe_map_.upper_bound(timestamp)
927                               : keyframe_map_.lower_bound(timestamp);
928 }
929
930 SourceBufferRange::KeyframeMap::const_iterator
931 SourceBufferRange::GetFirstKeyframeAtOrBefore(base::TimeDelta timestamp) const {
932   DVLOG(1) << __func__;
933   DVLOG(4) << ToStringForDebugging();
934
935   auto result = keyframe_map_.lower_bound(timestamp);
936   // lower_bound() returns the first element >= |timestamp|, so we want the
937   // previous element if it did not return the element exactly equal to
938   // |timestamp|.
939   if (result != keyframe_map_.begin() &&
940       (result == keyframe_map_.end() || result->first != timestamp)) {
941     --result;
942   }
943   return result;
944 }
945
946 bool SourceBufferRange::TruncateAt(const size_t starting_point,
947                                    BufferQueue* deleted_buffers) {
948   DVLOG(1) << __func__;
949   DVLOG(4) << ToStringForDebugging();
950
951   CHECK_LE(starting_point, buffers_.size());
952   DCHECK(!deleted_buffers || deleted_buffers->empty());
953
954   // Return if we're not deleting anything.
955   if (starting_point == buffers_.size())
956     return buffers_.empty();
957
958   // Reset the next buffer index if we will be deleting the buffer that's next
959   // in sequence.
960   if (HasNextBufferPosition()) {
961     if (static_cast<size_t>(next_buffer_index_) >= starting_point) {
962       if (HasNextBuffer() && deleted_buffers) {
963         BufferQueue saved(buffers_.begin() + next_buffer_index_,
964                           buffers_.end());
965         deleted_buffers->swap(saved);
966       }
967       ResetNextBufferPosition();
968     }
969   }
970
971   const BufferQueue::const_iterator starting_point_iter =
972       buffers_.begin() + starting_point;
973
974   // Remove keyframes from |starting_point| onward.
975   KeyframeMap::const_iterator starting_point_keyframe =
976       keyframe_map_.lower_bound((*starting_point_iter)->timestamp());
977   keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end());
978
979   // Remove everything from |starting_point| onward.
980   FreeBufferRange(starting_point_iter, buffers_.end());
981
982   UpdateEndTimeUsingLastGOP();
983   return buffers_.empty();
984 }
985
986 void SourceBufferRange::UpdateEndTimeUsingLastGOP() {
987   DVLOG(1) << __func__;
988   DVLOG(4) << ToStringForDebugging();
989
990   if (buffers_.empty()) {
991     DVLOG(1) << __func__ << " Empty range, resetting range end";
992     highest_frame_ = nullptr;
993     return;
994   }
995
996   highest_frame_ = nullptr;
997
998   KeyframeMap::const_iterator last_gop = keyframe_map_.end();
999   CHECK_GT(keyframe_map_.size(), 0u);
1000   --last_gop;
1001
1002   // Iterate through the frames of the last GOP in this range, finding the
1003   // frame with the highest PTS.
1004   for (BufferQueue::const_iterator buffer_itr =
1005            buffers_.begin() + (last_gop->second - keyframe_map_index_base_);
1006        buffer_itr != buffers_.end(); ++buffer_itr) {
1007     UpdateEndTime(*buffer_itr);
1008   }
1009
1010   DVLOG(1) << __func__ << " Updated range end time to "
1011            << highest_frame_->timestamp() << ", "
1012            << highest_frame_->timestamp() + highest_frame_->duration();
1013 }
1014
1015 std::string SourceBufferRange::ToStringForDebugging() const {
1016   std::stringstream result;
1017
1018 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
1019   result << "keyframe_map_index_base_=" << keyframe_map_index_base_
1020          << ", buffers.size()=" << buffers_.size()
1021          << ", keyframe_map_.size()=" << keyframe_map_.size()
1022          << ", keyframe_map_:\n";
1023   for (const auto& [time_delta, idx] : keyframe_map_) {
1024     result << "\t pts " << time_delta.InMicroseconds()
1025            << ", unadjusted idx = " << idx << "\n";
1026   }
1027 #endif  // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
1028
1029   return result.str();
1030 }
1031
1032 }  // namespace media