Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / source_buffer_stream.cc
1 // Copyright 2012 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_stream.h"
6
7 #include <algorithm>
8 #include <map>
9 #include <memory>
10 #include <sstream>
11 #include <string>
12
13 #include "base/functional/bind.h"
14 #include "base/logging.h"
15 #include "base/trace_event/trace_event.h"
16 #include "media/base/demuxer_memory_limit.h"
17 #include "media/base/media_switches.h"
18 #include "media/base/stream_parser_buffer.h"
19 #include "media/base/timestamp_constants.h"
20
21 namespace media {
22
23 namespace {
24
25 // The minimum interbuffer decode timestamp delta (or buffer duration) for use
26 // in fudge room for range membership, adjacency and coalescing.
27 const int kMinimumInterbufferDistanceInMs = 1;
28
29 // Limit the number of MEDIA_LOG() logs for track buffer time gaps.
30 const int kMaxTrackBufferGapWarningLogs = 20;
31
32 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
33 const int kMaxGarbageCollectAlgorithmWarningLogs = 20;
34
35 // Limit the number of MEDIA_LOG() logs for splice overlap trimming.
36 const int kMaxAudioSpliceLogs = 20;
37
38 // Helper method that returns true if |ranges| is sorted in increasing order,
39 // false otherwise.
40 bool IsRangeListSorted(const SourceBufferStream::RangeList& ranges) {
41   base::TimeDelta prev = kNoTimestamp;
42   for (const auto& range_ptr : ranges) {
43     if (prev != kNoTimestamp && prev >= range_ptr->GetStartTimestamp())
44       return false;
45     prev = range_ptr->GetBufferedEndTimestamp();
46   }
47   return true;
48 }
49
50 // Returns an estimate of how far from the beginning or end of a range a buffer
51 // can be to still be considered in the range, given the |approximate_duration|
52 // of a buffer in the stream.
53 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use
54 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp)
55 // instead of an overall maximum interbuffer delta for range discontinuity
56 // detection.
57 // See http://crbug.com/351489 and http://crbug.com/351166.
58 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
59   // Because we do not know exactly when is the next timestamp, any buffer
60   // that starts within 2x the approximate duration of a buffer is considered
61   // within this range.
62   return 2 * approximate_duration;
63 }
64
65 // The amount of time the beginning of the buffered data can differ from the
66 // start time in order to still be considered the start of stream.
67 base::TimeDelta kSeekToStartFudgeRoom() {
68   return base::Milliseconds(1000);
69 }
70
71 // Helper method for logging.
72 std::string StatusToString(const SourceBufferStreamStatus& status) {
73   switch (status) {
74     case SourceBufferStreamStatus::kSuccess:
75       return "kSuccess";
76     case SourceBufferStreamStatus::kNeedBuffer:
77       return "kNeedBuffer";
78     case SourceBufferStreamStatus::kConfigChange:
79       return "kConfigChange";
80     case SourceBufferStreamStatus::kEndOfStream:
81       return "kEndOfStream";
82   }
83   NOTREACHED_NORETURN();
84 }
85
86 // Helper method for logging, converts a range into a readable string.
87 std::string RangeToString(const SourceBufferRange& range) {
88   if (range.size_in_bytes() == 0) {
89     return "[]";
90   }
91   std::stringstream ss;
92   ss << "[" << range.GetStartTimestamp().InMicroseconds() << "us;"
93      << range.GetEndTimestamp().InMicroseconds() << "us("
94      << range.GetBufferedEndTimestamp().InMicroseconds() << "us)]";
95   return ss.str();
96 }
97
98 // Helper method for logging, converts a set of ranges into a readable string.
99 std::string RangesToString(const SourceBufferStream::RangeList& ranges) {
100   if (ranges.empty())
101     return "<EMPTY>";
102
103   std::stringstream ss;
104   for (const auto& range_ptr : ranges) {
105     if (range_ptr != ranges.front())
106       ss << " ";
107     ss << RangeToString(*range_ptr);
108   }
109   return ss.str();
110 }
111
112 std::string BufferQueueBuffersToLogString(
113     const SourceBufferStream::BufferQueue& buffers) {
114   std::stringstream result;
115
116   result << "Buffers:\n";
117   for (const auto& buf : buffers) {
118     result << "\tdts=" << buf->GetDecodeTimestamp().InMicroseconds() << " "
119            << buf->AsHumanReadableString()
120            << ", is_duration_estimated=" << buf->is_duration_estimated()
121            << "\n";
122   }
123
124   return result.str();
125 }
126
127 std::string BufferQueueMetadataToLogString(
128     const SourceBufferStream::BufferQueue& buffers) {
129   std::stringstream result;
130   base::TimeDelta pts_interval_start;
131   base::TimeDelta pts_interval_end;
132   SourceBufferStream::GetTimestampInterval(buffers, &pts_interval_start,
133                                            &pts_interval_end);
134
135   result << "dts=[" << buffers.front()->GetDecodeTimestamp().InMicroseconds()
136          << "us;" << buffers.back()->GetDecodeTimestamp().InMicroseconds()
137          << "us(last frame dur=" << buffers.back()->duration().InMicroseconds()
138          << "us)], pts interval=[" << pts_interval_start.InMicroseconds()
139          << "us," << pts_interval_end.InMicroseconds() << "us)";
140   return result.str();
141 }
142
143 }  // namespace
144
145 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
146                                        MediaLog* media_log)
147     : media_log_(media_log),
148       seek_buffer_timestamp_(kNoTimestamp),
149       coded_frame_group_start_pts_(kNoTimestamp),
150       range_for_next_append_(ranges_.end()),
151       highest_output_buffer_timestamp_(kNoTimestamp),
152       max_interbuffer_distance_(
153           base::Milliseconds(kMinimumInterbufferDistanceInMs)),
154       memory_limit_(GetDemuxerStreamAudioMemoryLimit(&audio_config)) {
155   DCHECK(audio_config.IsValidConfig());
156   audio_configs_.push_back(audio_config);
157   DVLOG(2) << __func__ << ": audio_buffer_size= " << memory_limit_;
158 }
159
160 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
161                                        MediaLog* media_log)
162     : media_log_(media_log),
163       seek_buffer_timestamp_(kNoTimestamp),
164       coded_frame_group_start_pts_(kNoTimestamp),
165       range_for_next_append_(ranges_.end()),
166       highest_output_buffer_timestamp_(kNoTimestamp),
167       max_interbuffer_distance_(
168           base::Milliseconds(kMinimumInterbufferDistanceInMs)),
169       memory_limit_(
170           GetDemuxerStreamVideoMemoryLimit(Demuxer::DemuxerTypes::kChunkDemuxer,
171                                            &video_config)) {
172   DCHECK(video_config.IsValidConfig());
173   video_configs_.push_back(video_config);
174   DVLOG(2) << __func__ << ": video_buffer_size= " << memory_limit_;
175 }
176
177 SourceBufferStream::~SourceBufferStream() = default;
178
179 void SourceBufferStream::OnStartOfCodedFrameGroup(
180     base::TimeDelta coded_frame_group_start_pts) {
181   DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (pts "
182            << coded_frame_group_start_pts.InMicroseconds() << "us)";
183   DCHECK(!end_of_stream_);
184   coded_frame_group_start_pts_ = coded_frame_group_start_pts;
185   new_coded_frame_group_ = true;
186
187   auto last_range = range_for_next_append_;
188   range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_pts_);
189
190   // Only reset |last_appended_buffer_timestamp_| if this new coded frame group
191   // is not adjacent to the previous coded frame group appended to the stream.
192   if (range_for_next_append_ == ranges_.end() ||
193       !IsNextGopAdjacentToEndOfCurrentAppendSequence(
194           coded_frame_group_start_pts_)) {
195     ResetLastAppendedState();
196     DVLOG(3) << __func__ << " next appended buffers will "
197              << (range_for_next_append_ == ranges_.end()
198                      ? "be in a new range"
199                      : "overlap an existing range");
200
201     if (range_for_next_append_ != ranges_.end()) {
202       // If this new coded frame group overlaps an existing range, preserve
203       // continuity from that range to the new group by moving the start time
204       // earlier (but not at or beyond the most recent buffered frame's time
205       // before |coded_frame_group_start_pts_| in the range, and not beyond the
206       // range's start time. This update helps prevent discontinuity from being
207       // introduced by the ::RemoveInternal processing during the next ::Append
208       // call.
209       base::TimeDelta adjusted_start_time =
210           (*range_for_next_append_)
211               ->FindHighestBufferedTimestampAtOrBefore(
212                   coded_frame_group_start_pts_);
213       if (adjusted_start_time < coded_frame_group_start_pts_) {
214         // Exclude removal of that earlier frame during later Append
215         // processing by adjusting the removal range slightly forward.
216         coded_frame_group_start_pts_ =
217             adjusted_start_time + base::Microseconds(1);
218       }
219     }
220   } else if (last_range != ranges_.end()) {
221     DCHECK(last_range == range_for_next_append_);
222     DVLOG(3) << __func__ << " next appended buffers will continue range unless "
223              << "intervening remove makes discontinuity";
224   }
225 }
226
227 void SourceBufferStream::Append(const BufferQueue& buffers) {
228   TRACE_EVENT2("media", "SourceBufferStream::Append",
229                "stream type", GetStreamTypeName(),
230                "buffers to append", buffers.size());
231
232   DCHECK(!buffers.empty());
233   DCHECK(coded_frame_group_start_pts_ != kNoTimestamp);
234   DCHECK(!end_of_stream_);
235
236   DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": buffers "
237            << BufferQueueMetadataToLogString(buffers);
238   DVLOG(4) << BufferQueueBuffersToLogString(buffers);
239
240   DCHECK(!buffers.front()->is_key_frame() ||
241          coded_frame_group_start_pts_ <= buffers.front()->timestamp());
242   DVLOG_IF(2, coded_frame_group_start_pts_ > buffers.front()->timestamp())
243       << __func__
244       << " Suspected SAP-Type-2 occurrence: coded_frame_group_start_pts_="
245       << coded_frame_group_start_pts_.InMicroseconds()
246       << "us, first new buffer has timestamp="
247       << buffers.front()->timestamp().InMicroseconds() << "us";
248
249   // New coded frame groups emitted by the coded frame processor must begin with
250   // a keyframe. Avoid propagating with escalating impact if this assumption is
251   // broken.
252   CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame());
253
254   // Buffers within each GOP in a coded frame group must be monotonically
255   // increasing in DTS order.
256   DCHECK(IsDtsMonotonicallyIncreasing(buffers));
257
258   // Both of these checks enforce what should be guaranteed by how
259   // FrameProcessor signals OnStartOfCodedFrameGroup and the buffers it tells us
260   // to Append.
261   DCHECK(coded_frame_group_start_pts_ >= base::TimeDelta());
262   DCHECK(buffers.front()->timestamp() >= base::TimeDelta());
263
264   if (UpdateMaxInterbufferDtsDistance(buffers)) {
265     // Coalesce |ranges_| using the new fudge room. This helps keep |ranges_|
266     // sorted in complex scenarios.  See https://crbug.com/793247.
267     MergeAllAdjacentRanges();
268   }
269
270   SetConfigIds(buffers);
271
272   // Save a snapshot of stream state before range modifications are made.
273   base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
274   BufferQueue deleted_buffers;
275
276   PrepareRangesForNextAppend(buffers, &deleted_buffers);
277
278   // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
279   // create a new range with |buffers|.
280   if (range_for_next_append_ != ranges_.end()) {
281     if (new_coded_frame_group_) {
282       // If the first append to this stream in a new coded frame group continues
283       // a previous range, use the new group's start time instead of the first
284       // new buffer's timestamp as the proof of adjacency to the existing range.
285       // A large gap (larger than our normal buffer adjacency test) can occur in
286       // a muxed set of streams (which share a common coded frame group start
287       // time) with a significantly jagged start across the streams.
288       (*range_for_next_append_)
289           ->AppendBuffersToEnd(buffers, coded_frame_group_start_pts_);
290     } else {
291       // Otherwise, use the first new buffer as proof of adjacency.
292       (*range_for_next_append_)->AppendBuffersToEnd(buffers, kNoTimestamp);
293     }
294
295     last_appended_buffer_timestamp_ = buffers.back()->timestamp();
296     last_appended_buffer_duration_ = buffers.back()->duration();
297     last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
298     last_appended_buffer_decode_timestamp_ =
299         buffers.back()->GetDecodeTimestamp();
300     highest_timestamp_in_append_sequence_ =
301         (*range_for_next_append_)->GetEndTimestamp();
302     highest_buffered_end_time_in_append_sequence_ =
303         (*range_for_next_append_)->GetBufferedEndTimestamp();
304   } else {
305     base::TimeDelta new_range_start_time =
306         std::min(coded_frame_group_start_pts_, buffers.front()->timestamp());
307
308     const BufferQueue* buffers_for_new_range = &buffers;
309     BufferQueue trimmed_buffers;
310
311     // If the new range is not being created because of a new coded frame group,
312     // then we must make sure that we start with a key frame.  This can happen
313     // if the GOP in the previous append gets destroyed by a Remove() call.
314     if (!new_coded_frame_group_) {
315       BufferQueue::const_iterator itr = buffers.begin();
316
317       // Scan past all the non-key-frames.
318       while (itr != buffers.end() && !(*itr)->is_key_frame()) {
319         ++itr;
320       }
321
322       // If we didn't find a key frame, then update the last appended
323       // buffer state and return.
324       if (itr == buffers.end()) {
325         last_appended_buffer_timestamp_ = buffers.back()->timestamp();
326         last_appended_buffer_duration_ = buffers.back()->duration();
327         last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
328         last_appended_buffer_decode_timestamp_ =
329             buffers.back()->GetDecodeTimestamp();
330         // Since we didn't buffer anything, don't update
331         // |highest_timestamp_in_append_sequence_|.
332         DVLOG(1) << __func__ << " " << GetStreamTypeName()
333                  << ": new buffers in the middle of coded frame group depend on"
334                     " keyframe that has been removed, and contain no keyframes."
335                     " Skipping further processing.";
336         DVLOG(1) << __func__ << " " << GetStreamTypeName()
337                  << ": done. ranges_=" << RangesToString(ranges_);
338         return;
339       } else if (itr != buffers.begin()) {
340         // Copy the first key frame and everything after it into
341         // |trimmed_buffers|.
342         trimmed_buffers.assign(itr, buffers.end());
343         buffers_for_new_range = &trimmed_buffers;
344       }
345
346       new_range_start_time = buffers_for_new_range->front()->timestamp();
347     }
348
349     range_for_next_append_ = AddToRanges(std::make_unique<SourceBufferRange>(
350         SourceBufferRange::NO_GAPS_ALLOWED, *buffers_for_new_range,
351         new_range_start_time,
352         base::BindRepeating(&SourceBufferStream::GetMaxInterbufferDistance,
353                             base::Unretained(this))));
354
355     last_appended_buffer_timestamp_ =
356         buffers_for_new_range->back()->timestamp();
357     last_appended_buffer_duration_ = buffers_for_new_range->back()->duration();
358     last_appended_buffer_is_keyframe_ =
359         buffers_for_new_range->back()->is_key_frame();
360     last_appended_buffer_decode_timestamp_ =
361         buffers_for_new_range->back()->GetDecodeTimestamp();
362     highest_timestamp_in_append_sequence_ =
363         (*range_for_next_append_)->GetEndTimestamp();
364     highest_buffered_end_time_in_append_sequence_ =
365         (*range_for_next_append_)->GetBufferedEndTimestamp();
366   }
367
368   new_coded_frame_group_ = false;
369
370   MergeWithNextRangeIfNecessary(range_for_next_append_);
371
372   // Some SAP-Type-2 append sequences require that we coalesce
373   // |range_for_next_append_| with the range that is *before* it.
374   if (range_for_next_append_ != ranges_.begin()) {
375     auto prior_range = range_for_next_append_;
376     prior_range--;
377     MergeWithNextRangeIfNecessary(prior_range);
378   }
379
380   // Seek to try to fulfill a previous call to Seek().
381   if (seek_pending_) {
382     DCHECK(!selected_range_);
383     DCHECK(deleted_buffers.empty());
384     Seek(seek_buffer_timestamp_);
385   }
386
387   if (!deleted_buffers.empty()) {
388     track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(),
389                          deleted_buffers.end());
390     DVLOG(3) << __func__ << " " << GetStreamTypeName() << " Added "
391              << deleted_buffers.size()
392              << " buffers to track buffer. TB size is now "
393              << track_buffer_.size();
394   } else {
395     DVLOG(3) << __func__ << " " << GetStreamTypeName()
396              << " No deleted buffers for track buffer";
397   }
398
399   // Prune any extra buffers in |track_buffer_| if new keyframes
400   // are appended to the range covered by |track_buffer_|.
401   if (!track_buffer_.empty()) {
402     base::TimeDelta keyframe_timestamp =
403         FindKeyframeAfterTimestamp(track_buffer_.front()->timestamp());
404     if (keyframe_timestamp != kNoTimestamp)
405       PruneTrackBuffer(keyframe_timestamp);
406   }
407
408   SetSelectedRangeIfNeeded(next_buffer_timestamp);
409
410   DVLOG(1) << __func__ << " " << GetStreamTypeName()
411            << ": done. ranges_=" << RangesToString(ranges_);
412   DCHECK(IsRangeListSorted(ranges_));
413   DCHECK(OnlySelectedRangeIsSeeked());
414 }
415
416 void SourceBufferStream::Remove(base::TimeDelta start,
417                                 base::TimeDelta end,
418                                 base::TimeDelta duration) {
419   DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
420            << start.InMicroseconds() << "us, " << end.InMicroseconds() << "us, "
421            << duration.InMicroseconds() << "us)";
422   DCHECK(start >= base::TimeDelta()) << start.InMicroseconds() << "us";
423   DCHECK(start < end) << "start " << start.InMicroseconds() << "us, end "
424                       << end.InMicroseconds() << "us";
425   DCHECK(duration != kNoTimestamp);
426
427   base::TimeDelta remove_end_timestamp = duration;
428   base::TimeDelta keyframe_timestamp = FindKeyframeAfterTimestamp(end);
429   if (keyframe_timestamp != kNoTimestamp) {
430     remove_end_timestamp = keyframe_timestamp;
431   } else if (end < remove_end_timestamp) {
432     remove_end_timestamp = end;
433   }
434
435   BufferQueue deleted_buffers;
436   RemoveInternal(start, remove_end_timestamp, false, &deleted_buffers);
437
438   if (!deleted_buffers.empty()) {
439     // Buffers for the current position have been removed.
440     SetSelectedRangeIfNeeded(deleted_buffers.front()->timestamp());
441     if (highest_output_buffer_timestamp_ == kNoTimestamp) {
442       // We just removed buffers for the current playback position for this
443       // stream, yet we also had output no buffer since the last Seek.
444       // Re-seek to prevent stall.
445       DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": re-seeking to "
446                << seek_buffer_timestamp_
447                << " to prevent stall if this time becomes buffered again";
448       Seek(seek_buffer_timestamp_);
449     }
450   }
451
452   DCHECK(OnlySelectedRangeIsSeeked());
453   DCHECK(IsRangeListSorted(ranges_));
454 }
455
456 base::TimeDelta SourceBufferStream::PotentialNextAppendTimestamp() const {
457   // The next potential append will either be in a GOP adjacent to
458   // |highest_timestamp_in_append_sequence_| (if known), or if unknown and we
459   // are still at the beginning of a new coded frame group, then will be into
460   // the range (if any) to which |coded_frame_group_start_pts_| belongs.
461   if (highest_timestamp_in_append_sequence_ != kNoTimestamp)
462     return highest_timestamp_in_append_sequence_;
463
464   if (new_coded_frame_group_)
465     return coded_frame_group_start_pts_;
466
467   // If we still don't know a potential next append timestamp, then we have
468   // removed the range to which it previously belonged and have not completed a
469   // subsequent append or received a subsequent OnStartOfCodedFrameGroup()
470   // signal.
471   return kNoTimestamp;
472 }
473
474 void SourceBufferStream::UpdateLastAppendStateForRemove(
475     base::TimeDelta remove_start,
476     base::TimeDelta remove_end,
477     bool exclude_start) {
478   // TODO(chcunningham): change exclude_start to include_start in this class and
479   // SourceBufferRange. Negatives are hard to reason about.
480   bool include_start = !exclude_start;
481
482   // No need to check previous append's GOP if starting a new CFG. New CFG is
483   // already required to begin with a key frame.
484   if (new_coded_frame_group_)
485     return;
486
487   if (range_for_next_append_ != ranges_.end()) {
488     if (last_appended_buffer_timestamp_ != kNoTimestamp) {
489       // Note start and end of last appended GOP.
490       base::TimeDelta gop_end = highest_timestamp_in_append_sequence_;
491       base::TimeDelta gop_start =
492           (*range_for_next_append_)->KeyframeBeforeTimestamp(gop_end);
493
494       // If last append is about to be disrupted, reset associated state so we
495       // know to create a new range for future appends and require an initial
496       // key frame.
497       if (((include_start && remove_start == gop_end) ||
498            remove_start < gop_end) &&
499           remove_end > gop_start) {
500         DVLOG(2) << __func__ << " " << GetStreamTypeName()
501                  << " Resetting next append state for remove ("
502                  << remove_start.InMicroseconds() << "us, "
503                  << remove_end.InMicroseconds() << "us, " << exclude_start
504                  << ")";
505         range_for_next_append_ = ranges_.end();
506         ResetLastAppendedState();
507       }
508     } else {
509       NOTREACHED() << __func__ << " " << GetStreamTypeName()
510                    << " range_for_next_append_ set, but not tracking last"
511                    << " append nor new coded frame group.";
512     }
513   }
514 }
515
516 void SourceBufferStream::RemoveInternal(base::TimeDelta start,
517                                         base::TimeDelta end,
518                                         bool exclude_start,
519                                         BufferQueue* deleted_buffers) {
520   DVLOG(2) << __func__ << " " << GetStreamTypeName() << " ("
521            << start.InMicroseconds() << "us, " << end.InMicroseconds() << "us, "
522            << exclude_start << ")";
523   DVLOG(3) << __func__ << " " << GetStreamTypeName()
524            << ": before remove ranges_=" << RangesToString(ranges_);
525
526   DCHECK(start >= base::TimeDelta());
527   DCHECK(start < end) << "start " << start.InMicroseconds() << "us, end "
528                       << end.InMicroseconds() << "us";
529   DCHECK(deleted_buffers);
530
531   // Doing this up-front simplifies decisions about |range_for_next_append_|
532   // below.
533   UpdateLastAppendStateForRemove(start, end, exclude_start);
534
535   auto itr = ranges_.begin();
536   while (itr != ranges_.end()) {
537     SourceBufferRange* range = itr->get();
538     if (range->GetStartTimestamp() >= end)
539       break;
540
541     // Split off any remaining GOPs starting at or after |end| and add it to
542     // |ranges_|.
543     std::unique_ptr<SourceBufferRange> new_range = range->SplitRange(end);
544     if (new_range) {
545       itr = ranges_.insert(++itr, std::move(new_range));
546
547       // Update |range_for_next_append_| if it was previously |range| and should
548       // be the new range (that |itr| is at) now.
549       if (range_for_next_append_ != ranges_.end() &&
550           range_for_next_append_->get() == range) {
551         base::TimeDelta potential_next_append_timestamp =
552             PotentialNextAppendTimestamp();
553         if (potential_next_append_timestamp != kNoTimestamp &&
554             (*itr)->BelongsToRange(potential_next_append_timestamp)) {
555           range_for_next_append_ = itr;
556         }
557       }
558
559       // Update the selected range if the next buffer position was transferred
560       // to the newly inserted range (that |itr| is at now).
561       if ((*itr)->HasNextBufferPosition())
562         SetSelectedRange(itr->get());
563
564       --itr;
565     }
566
567     // Truncate the current range so that it only contains data before
568     // the removal range.
569     BufferQueue saved_buffers;
570     bool delete_range = range->TruncateAt(start, &saved_buffers, exclude_start);
571
572     // Check to see if the current playback position was removed and update the
573     // selected range appropriately.
574     if (!saved_buffers.empty()) {
575       DCHECK(!range->HasNextBufferPosition());
576       DCHECK(deleted_buffers->empty());
577
578       *deleted_buffers = saved_buffers;
579     }
580
581     if (range == selected_range_ && !range->HasNextBufferPosition())
582       SetSelectedRange(NULL);
583
584     // If the current range now is completely covered by the removal
585     // range then delete it and move on.
586     if (delete_range) {
587       DeleteAndRemoveRange(&itr);
588       continue;
589     }
590
591     // Clear |range_for_next_append_| if we determine that the removal
592     // operation makes it impossible for the next append to be added
593     // to the current range.
594     if (range_for_next_append_ != ranges_.end() &&
595         range_for_next_append_->get() == range) {
596       base::TimeDelta potential_next_append_timestamp =
597           PotentialNextAppendTimestamp();
598
599       if (!range->BelongsToRange(potential_next_append_timestamp)) {
600         DVLOG(1) << "Resetting range_for_next_append_ since the next append"
601                  <<  " can't add to the current range.";
602         range_for_next_append_ =
603             FindExistingRangeFor(potential_next_append_timestamp);
604       }
605     }
606
607     // Move on to the next range.
608     ++itr;
609   }
610
611   DVLOG(3) << __func__ << " " << GetStreamTypeName()
612            << ": after remove ranges_=" << RangesToString(ranges_);
613
614   DCHECK(OnlySelectedRangeIsSeeked());
615 }
616
617 void SourceBufferStream::ResetSeekState() {
618   SetSelectedRange(NULL);
619   track_buffer_.clear();
620   config_change_pending_ = false;
621   highest_output_buffer_timestamp_ = kNoTimestamp;
622   just_exhausted_track_buffer_ = false;
623   pending_buffer_.reset();
624   pending_buffers_complete_ = false;
625 }
626
627 void SourceBufferStream::ResetLastAppendedState() {
628   last_appended_buffer_timestamp_ = kNoTimestamp;
629   last_appended_buffer_duration_ = kNoTimestamp;
630   last_appended_buffer_is_keyframe_ = false;
631   last_appended_buffer_decode_timestamp_ = kNoDecodeTimestamp;
632   highest_timestamp_in_append_sequence_ = kNoTimestamp;
633   highest_buffered_end_time_in_append_sequence_ = kNoTimestamp;
634 }
635
636 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
637     base::TimeDelta seek_timestamp) const {
638   if (ranges_.empty())
639     return false;
640   base::TimeDelta beginning_of_buffered = ranges_.front()->GetStartTimestamp();
641   return (seek_timestamp <= beginning_of_buffered &&
642           beginning_of_buffered < kSeekToStartFudgeRoom());
643 }
644
645 bool SourceBufferStream::IsDtsMonotonicallyIncreasing(
646     const BufferQueue& buffers) {
647   DCHECK(!buffers.empty());
648   DecodeTimestamp prev_dts = last_appended_buffer_decode_timestamp_;
649   for (BufferQueue::const_iterator itr = buffers.begin();
650        itr != buffers.end(); ++itr) {
651     DecodeTimestamp current_dts = (*itr)->GetDecodeTimestamp();
652     bool current_is_keyframe = (*itr)->is_key_frame();
653     DCHECK(current_dts != kNoDecodeTimestamp);
654     DCHECK((*itr)->duration() >= base::TimeDelta())
655         << "Packet with invalid duration."
656         << " pts " << (*itr)->timestamp().InMicroseconds() << "us dts "
657         << (*itr)->GetDecodeTimestamp().InMicroseconds() << "us dur "
658         << (*itr)->duration().InMicroseconds() << "us";
659
660     // Only verify DTS monotonicity within the current GOP (since the last
661     // keyframe). FrameProcessor should have enforced that all audio frames are
662     // keyframes already, or are nonkeyframes with monotonically increasing PTS
663     // since the last keyframe for those types of audio for which nonkeyframes
664     // may be involved, e.g. xHE-AAC. Video nonkeyframes are not restricted to
665     // being in-order by PTS, but both audio and video nonkeyframes must be in
666     // decode sequence since the last keyframe.
667     if (current_is_keyframe) {
668       // Reset prev_dts tracking since a new GOP is starting.
669       prev_dts = kNoDecodeTimestamp;
670     }
671
672     if (prev_dts != kNoDecodeTimestamp) {
673       if (current_dts < prev_dts) {
674         MEDIA_LOG(ERROR, media_log_)
675             << "Buffers did not monotonically increase.";
676         return false;
677       }
678     }
679
680     prev_dts = current_dts;
681   }
682   return true;
683 }
684
685 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
686   for (auto itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
687     if ((*itr)->HasNextBufferPosition() && itr->get() != selected_range_)
688       return false;
689   }
690   return !selected_range_ || selected_range_->HasNextBufferPosition();
691 }
692
693 bool SourceBufferStream::UpdateMaxInterbufferDtsDistance(
694     const BufferQueue& buffers) {
695   DCHECK(!buffers.empty());
696   base::TimeDelta old_distance = max_interbuffer_distance_;
697   DecodeTimestamp prev_dts = last_appended_buffer_decode_timestamp_;
698   for (BufferQueue::const_iterator itr = buffers.begin();
699        itr != buffers.end(); ++itr) {
700     DecodeTimestamp current_dts = (*itr)->GetDecodeTimestamp();
701     DCHECK(current_dts != kNoDecodeTimestamp);
702
703     base::TimeDelta interbuffer_distance = (*itr)->duration();
704     DCHECK(interbuffer_distance >= base::TimeDelta());
705
706     if (prev_dts != kNoDecodeTimestamp) {
707       interbuffer_distance =
708           std::max(current_dts - prev_dts, interbuffer_distance);
709     }
710
711     DCHECK(max_interbuffer_distance_ >=
712            base::Milliseconds(kMinimumInterbufferDistanceInMs));
713     max_interbuffer_distance_ =
714         std::max(max_interbuffer_distance_, interbuffer_distance);
715     prev_dts = current_dts;
716   }
717   bool changed_max = max_interbuffer_distance_ != old_distance;
718   DVLOG_IF(2, changed_max) << __func__ << " " << GetStreamTypeName()
719                            << " Changed max interbuffer DTS distance from "
720                            << old_distance.InMicroseconds() << "us to "
721                            << max_interbuffer_distance_.InMicroseconds()
722                            << "us";
723   return changed_max;
724 }
725
726 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
727   for (BufferQueue::const_iterator itr = buffers.begin();
728        itr != buffers.end(); ++itr) {
729     (*itr)->SetConfigId(append_config_index_);
730   }
731 }
732
733 void SourceBufferStream::OnMemoryPressure(
734     base::TimeDelta media_time,
735     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
736     bool force_instant_gc) {
737   DVLOG(4) << __func__ << " level=" << memory_pressure_level;
738   // TODO(sebmarchand): Check if MEMORY_PRESSURE_LEVEL_MODERATE should also be
739   // ignored.
740   if (memory_pressure_level ==
741       base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
742     return;
743   }
744
745   memory_pressure_level_ = memory_pressure_level;
746
747   if (force_instant_gc)
748     GarbageCollectIfNeeded(media_time, 0);
749 }
750
751 bool SourceBufferStream::GarbageCollectIfNeeded(base::TimeDelta media_time,
752                                                 size_t newDataSize) {
753   DCHECK(media_time != kNoTimestamp);
754   // Garbage collection should only happen before/during appending new data,
755   // which should not happen in end-of-stream state. Unless we also allow GC to
756   // happen on memory pressure notifications, which might happen even in EOS
757   // state.
758   if (!base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC))
759     DCHECK(!end_of_stream_);
760   // Compute size of |ranges_|.
761   size_t ranges_size = GetBufferedSize();
762
763   // Sanity and overflow checks
764   if ((newDataSize > memory_limit_) ||
765       (ranges_size + newDataSize < ranges_size)) {
766     LIMITED_MEDIA_LOG(DEBUG, media_log_, num_garbage_collect_algorithm_logs_,
767                       kMaxGarbageCollectAlgorithmWarningLogs)
768         << GetStreamTypeName() << " stream: "
769         << "new append of newDataSize=" << newDataSize
770         << " bytes exceeds memory_limit_=" << memory_limit_
771         << ", currently buffered ranges_size=" << ranges_size;
772     return false;
773   }
774
775   size_t effective_memory_limit = memory_limit_;
776   if (base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC)) {
777     switch (memory_pressure_level_) {
778       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
779         effective_memory_limit = memory_limit_ / 2;
780         break;
781       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
782         effective_memory_limit = 0;
783         break;
784       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
785         break;
786     }
787   }
788
789   // Return if we're under or at the memory limit.
790   if (ranges_size + newDataSize <= effective_memory_limit)
791     return true;
792
793   size_t bytes_over_hard_memory_limit = 0;
794   if (ranges_size + newDataSize > memory_limit_)
795     bytes_over_hard_memory_limit = ranges_size + newDataSize - memory_limit_;
796
797   size_t bytes_to_free = ranges_size + newDataSize - effective_memory_limit;
798
799   DVLOG(2) << __func__ << " " << GetStreamTypeName()
800            << ": Before GC media_time=" << media_time.InMicroseconds()
801            << "us ranges_=" << RangesToString(ranges_)
802            << " seek_pending_=" << seek_pending_
803            << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize
804            << " memory_limit_=" << memory_limit_
805            << " effective_memory_limit=" << effective_memory_limit
806            << " last_appended_buffer_timestamp_="
807            << last_appended_buffer_timestamp_.InMicroseconds()
808            << "us highest_timestamp_in_append_sequence_="
809            << highest_timestamp_in_append_sequence_.InMicroseconds()
810            << "us highest_buffered_end_time_in_append_sequence_="
811            << highest_buffered_end_time_in_append_sequence_.InMicroseconds()
812            << "us";
813
814   if (selected_range_ && !seek_pending_ &&
815       media_time > selected_range_->GetBufferedEndTimestamp()) {
816     // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime)
817     // should always be in the buffered ranges, but media::Pipeline uses audio
818     // stream as the main time source, when audio is present.
819     // In cases when audio and video streams have different buffered ranges, the
820     // |media_time| value might be slightly outside of the video stream buffered
821     // range. In those cases we need to clamp |media_time| value to the current
822     // stream buffered ranges, to ensure the MSE garbage collection algorithm
823     // works correctly (see crbug.com/563292 for details).
824     base::TimeDelta selected_buffered_end =
825         selected_range_->GetBufferedEndTimestamp();
826
827     DVLOG(2) << __func__ << " media_time " << media_time.InMicroseconds()
828              << "us is outside of selected_range_=["
829              << selected_range_->GetStartTimestamp().InMicroseconds() << "us;"
830              << selected_buffered_end.InMicroseconds()
831              << "us] clamping media_time to be "
832              << selected_buffered_end.InMicroseconds() << "us";
833     media_time = selected_buffered_end;
834   }
835
836   size_t bytes_freed = 0;
837
838   // If last appended buffer position was earlier than the current playback time
839   // then try deleting data between last append and current media_time.
840   if (last_appended_buffer_timestamp_ != kNoTimestamp &&
841       last_appended_buffer_duration_ != kNoTimestamp &&
842       highest_buffered_end_time_in_append_sequence_ != kNoTimestamp &&
843       media_time > highest_buffered_end_time_in_append_sequence_) {
844     size_t between = FreeBuffersAfterLastAppended(bytes_to_free, media_time);
845     DVLOG(3) << __func__ << " FreeBuffersAfterLastAppended "
846              << " released " << between << " bytes"
847              << " ranges_=" << RangesToString(ranges_);
848     bytes_freed += between;
849
850     // Some players start appending data at the new seek target position before
851     // actually initiating the seek operation (i.e. they try to improve seek
852     // performance by prebuffering some data at the seek target position and
853     // initiating seek once enough data is pre-buffered. In those cases we'll
854     // see that data is being appended at some new position, but there is no
855     // pending seek reported yet. In this situation we need to try preserving
856     // the most recently appended data, i.e. data belonging to the same buffered
857     // range as the most recent append.
858     if (range_for_next_append_ != ranges_.end()) {
859       DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time);
860       media_time = (*range_for_next_append_)->GetStartTimestamp();
861       DVLOG(3) << __func__ << " media_time adjusted to "
862                << media_time.InMicroseconds() << "us";
863     }
864   }
865
866   // If there is an unsatisfied pending seek, we can safely remove all data that
867   // is earlier than seek target, then remove from the back until we reach the
868   // most recently appended GOP and then remove from the front if we still don't
869   // have enough space for the upcoming append.
870   if (bytes_freed < bytes_to_free && seek_pending_) {
871     DCHECK(!ranges_.empty());
872     // All data earlier than the seek target |media_time| can be removed safely
873     size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
874     DVLOG(3) << __func__ << " Removed " << front
875              << " bytes from the front. ranges_=" << RangesToString(ranges_);
876     bytes_freed += front;
877
878     // If removing data earlier than |media_time| didn't free up enough space,
879     // then try deleting from the back until we reach most recently appended GOP
880     if (bytes_freed < bytes_to_free) {
881       size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
882       DVLOG(3) << __func__ << " Removed " << back
883                << " bytes from the back. ranges_=" << RangesToString(ranges_);
884       bytes_freed += back;
885     }
886
887     // If even that wasn't enough, then try greedily deleting from the front,
888     // that should allow us to remove as much data as necessary to succeed.
889     if (bytes_freed < bytes_to_free) {
890       size_t front2 = FreeBuffers(bytes_to_free - bytes_freed,
891                                   ranges_.back()->GetEndTimestamp(), false);
892       DVLOG(3) << __func__ << " Removed " << front2
893                << " bytes from the front. ranges_=" << RangesToString(ranges_);
894       bytes_freed += front2;
895     }
896     DCHECK(bytes_freed >= bytes_to_free);
897   }
898
899   // Try removing data from the front of the SourceBuffer up to |media_time|
900   // position.
901   if (bytes_freed < bytes_to_free) {
902     size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
903     DVLOG(3) << __func__ << " Removed " << front
904              << " bytes from the front. ranges_=" << RangesToString(ranges_);
905     bytes_freed += front;
906   }
907
908   // Try removing data from the back of the SourceBuffer, until we reach the
909   // most recent append position.
910   if (bytes_freed < bytes_to_free) {
911     size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
912     DVLOG(3) << __func__ << " Removed " << back
913              << " bytes from the back. ranges_=" << RangesToString(ranges_);
914     bytes_freed += back;
915   }
916
917   DVLOG(2) << __func__ << " " << GetStreamTypeName()
918            << ": After GC bytes_to_free=" << bytes_to_free
919            << " bytes_freed=" << bytes_freed
920            << " bytes_over_hard_memory_limit=" << bytes_over_hard_memory_limit
921            << " ranges_=" << RangesToString(ranges_);
922
923   return bytes_freed >= bytes_over_hard_memory_limit;
924 }
925
926 size_t SourceBufferStream::FreeBuffersAfterLastAppended(
927     size_t total_bytes_to_free,
928     base::TimeDelta media_time) {
929   DVLOG(4) << __func__ << " highest_buffered_end_time_in_append_sequence_="
930            << highest_buffered_end_time_in_append_sequence_.InMicroseconds()
931            << "us media_time=" << media_time.InMicroseconds() << "us";
932
933   base::TimeDelta remove_range_start =
934       highest_buffered_end_time_in_append_sequence_;
935   if (last_appended_buffer_is_keyframe_)
936     remove_range_start += GetMaxInterbufferDistance();
937
938   base::TimeDelta remove_range_start_keyframe =
939       FindKeyframeAfterTimestamp(remove_range_start);
940   if (remove_range_start_keyframe != kNoTimestamp)
941     remove_range_start = remove_range_start_keyframe;
942   if (remove_range_start >= media_time)
943     return 0;
944
945   base::TimeDelta remove_range_end;
946   size_t bytes_freed = GetRemovalRange(remove_range_start,
947                                        media_time,
948                                        total_bytes_to_free,
949                                        &remove_range_end);
950   if (bytes_freed > 0) {
951     DVLOG(4) << __func__ << " removing [" << remove_range_start.InMicroseconds()
952              << "us;" << remove_range_end.InMicroseconds() << "us]";
953     Remove(remove_range_start, remove_range_end, media_time);
954   }
955
956   return bytes_freed;
957 }
958
959 size_t SourceBufferStream::GetRemovalRange(
960     base::TimeDelta start_timestamp,
961     base::TimeDelta end_timestamp,
962     size_t total_bytes_to_free,
963     base::TimeDelta* removal_end_timestamp) {
964   DCHECK(start_timestamp >= base::TimeDelta())
965       << start_timestamp.InMicroseconds() << "us";
966   DCHECK(start_timestamp < end_timestamp)
967       << "start " << start_timestamp.InMicroseconds() << "us, end "
968       << end_timestamp.InMicroseconds() << "us";
969
970   size_t bytes_freed = 0;
971
972   for (auto itr = ranges_.begin();
973        itr != ranges_.end() && bytes_freed < total_bytes_to_free; ++itr) {
974     SourceBufferRange* range = itr->get();
975     if (range->GetStartTimestamp() >= end_timestamp)
976       break;
977     if (range->GetEndTimestamp() < start_timestamp)
978       continue;
979
980     size_t bytes_to_free = total_bytes_to_free - bytes_freed;
981     size_t bytes_removed = range->GetRemovalGOP(
982         start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp);
983     bytes_freed += bytes_removed;
984   }
985   return bytes_freed;
986 }
987
988 size_t SourceBufferStream::FreeBuffers(size_t total_bytes_to_free,
989                                        base::TimeDelta media_time,
990                                        bool reverse_direction) {
991   TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers",
992                "total bytes to free", total_bytes_to_free,
993                "reverse direction", reverse_direction);
994
995   DCHECK_GT(total_bytes_to_free, 0u);
996   size_t bytes_freed = 0;
997
998   // This range will save the last GOP appended to |range_for_next_append_|
999   // if the buffers surrounding it get deleted during garbage collection.
1000   std::unique_ptr<SourceBufferRange> new_range_for_append;
1001
1002   while (!ranges_.empty() && bytes_freed < total_bytes_to_free) {
1003     SourceBufferRange* current_range = NULL;
1004     BufferQueue buffers;
1005     size_t bytes_deleted = 0;
1006
1007     if (reverse_direction) {
1008       current_range = ranges_.back().get();
1009       DVLOG(5) << "current_range=" << RangeToString(*current_range);
1010       if (current_range->LastGOPContainsNextBufferPosition()) {
1011         DCHECK_EQ(current_range, selected_range_);
1012         DVLOG(5) << "current_range contains next read position, stopping GC";
1013         break;
1014       }
1015       DVLOG(5) << "Deleting GOP from back: " << RangeToString(*current_range);
1016       bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
1017     } else {
1018       current_range = ranges_.front().get();
1019       DVLOG(5) << "current_range=" << RangeToString(*current_range);
1020
1021       // FirstGOPEarlierThanMediaTime() is useful here especially if
1022       // |seek_pending_| (such that no range contains next buffer
1023       // position).
1024       // FirstGOPContainsNextBufferPosition() is useful here especially if
1025       // |!seek_pending_| to protect against DeleteGOPFromFront() if
1026       // FirstGOPEarlierThanMediaTime() was insufficient alone.
1027       if (!current_range->FirstGOPEarlierThanMediaTime(media_time) ||
1028           current_range->FirstGOPContainsNextBufferPosition()) {
1029         // We have removed all data up to the GOP that contains current playback
1030         // position, we can't delete any further.
1031         DVLOG(5) << "current_range contains playback position, stopping GC";
1032         break;
1033       }
1034       DVLOG(4) << "Deleting GOP from front: " << RangeToString(*current_range)
1035                << ", media_time: " << media_time.InMicroseconds()
1036                << ", current_range->HasNextBufferPosition(): "
1037                << current_range->HasNextBufferPosition();
1038       bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
1039     }
1040
1041     // Check to see if we've just deleted the GOP that was last appended.
1042     base::TimeDelta end_timestamp = buffers.back()->timestamp();
1043     if (end_timestamp == last_appended_buffer_timestamp_) {
1044       DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp);
1045       DCHECK(!new_range_for_append);
1046
1047       // Create a new range containing these buffers.
1048       new_range_for_append = std::make_unique<SourceBufferRange>(
1049           SourceBufferRange::NO_GAPS_ALLOWED, buffers, kNoTimestamp,
1050           base::BindRepeating(&SourceBufferStream::GetMaxInterbufferDistance,
1051                               base::Unretained(this)));
1052
1053       range_for_next_append_ = ranges_.end();
1054     } else {
1055       bytes_freed += bytes_deleted;
1056     }
1057
1058     if (current_range->size_in_bytes() == 0) {
1059       DCHECK_NE(current_range, selected_range_);
1060       DCHECK(range_for_next_append_ == ranges_.end() ||
1061              range_for_next_append_->get() != current_range);
1062
1063       // Delete |current_range| by popping it out of |ranges_|.
1064       reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
1065     }
1066
1067     if (reverse_direction && new_range_for_append) {
1068       // We don't want to delete any further, or we'll be creating gaps
1069       break;
1070     }
1071   }
1072
1073   // Insert |new_range_for_append| into |ranges_|, if applicable.
1074   if (new_range_for_append) {
1075     range_for_next_append_ = AddToRanges(std::move(new_range_for_append));
1076     DCHECK(range_for_next_append_ != ranges_.end());
1077
1078     // Check to see if we need to merge the just added range that was in
1079     // |new_range_for_append| with the range before or after it. That added
1080     // range is created whenever the last GOP appended is encountered,
1081     // regardless of whether any buffers after it are ultimately deleted.
1082     // Merging is necessary if there were no buffers (or very few buffers)
1083     // deleted after creating that added range.
1084     if (range_for_next_append_ != ranges_.begin()) {
1085       auto range_before_next = range_for_next_append_;
1086       --range_before_next;
1087       MergeWithNextRangeIfNecessary(range_before_next);
1088     }
1089     MergeWithNextRangeIfNecessary(range_for_next_append_);
1090   }
1091   return bytes_freed;
1092 }
1093
1094 void SourceBufferStream::TrimSpliceOverlap(const BufferQueue& new_buffers) {
1095   DCHECK(!new_buffers.empty());
1096   DCHECK_EQ(SourceBufferStreamType::kAudio, GetType());
1097
1098   const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
1099
1100   // Since some audio formats may have nonkeyframes (in PTS order since last
1101   // keyframe), if the front of the new buffers is one of those, it cannot be
1102   // used to begin a decode following an overlap. Here, we bail in this case,
1103   // since such a splice could not be coherently decoded.
1104   if (!new_buffers.front()->is_key_frame()) {
1105     DVLOG(3) << __func__
1106              << " No splice trimming. Front of |new_buffers| is not a "
1107                 "keyframe, at time "
1108              << splice_timestamp.InMicroseconds();
1109     return;
1110   }
1111
1112   // Find the overlapped range (if any).
1113   auto range_itr = FindExistingRangeFor(splice_timestamp);
1114   if (range_itr == ranges_.end()) {
1115     DVLOG(3) << __func__ << " No splice trimming. No range overlap at time "
1116              << splice_timestamp.InMicroseconds();
1117     return;
1118   }
1119
1120   // Search for overlapped buffer needs exclusive end value. Choosing smallest
1121   // possible value.
1122   const base::TimeDelta end_pts = splice_timestamp + base::Microseconds(1);
1123
1124   // Find if new buffer's start would overlap an existing buffer. Note that
1125   // overlapped audio buffers might be nonkeyframes, but if so, FrameProcessor
1126   // ensures they are in PTS order since the previous keyframe.
1127   BufferQueue overlapped_buffers;
1128   if (!(*range_itr)
1129            ->GetBuffersInRange(splice_timestamp, end_pts,
1130                                &overlapped_buffers)) {
1131     // Bail if no overlapped buffers found.
1132     DVLOG(3) << __func__ << " No splice trimming. No buffer overlap at time "
1133              << splice_timestamp.InMicroseconds();
1134     return;
1135   }
1136
1137   // At most one buffer should exist containing the time of the newly appended
1138   // buffer's start. It may happen that bad content appends buffers with
1139   // durations that cause nonsensical overlap. Trimming should not be performed
1140   // in these cases, as the content is already in a bad state.
1141   if (overlapped_buffers.size() != 1U) {
1142     DVLOG(3) << __func__
1143              << " No splice trimming. Found more than one overlapped buffer"
1144                 " (bad content) at time "
1145              << splice_timestamp.InMicroseconds();
1146
1147     MEDIA_LOG(WARNING, media_log_)
1148         << "Media is badly muxed. Detected " << overlapped_buffers.size()
1149         << " overlapping audio buffers at time "
1150         << splice_timestamp.InMicroseconds();
1151     return;
1152   }
1153   StreamParserBuffer* overlapped_buffer = overlapped_buffers.front().get();
1154
1155   if (overlapped_buffer->timestamp() == splice_timestamp) {
1156     // Ignore buffers with the same start time. They will be completely removed
1157     // in PrepareRangesForNextAppend().
1158     DVLOG(3) << __func__ << " No splice trimming at time "
1159              << splice_timestamp.InMicroseconds()
1160              << ". Overlapped buffer will be completely removed.";
1161     return;
1162   }
1163
1164   // Trimming a buffer with estimated duration is too risky. Estimates are rough
1165   // and what appears to be overlap may really just be a bad estimate. Imprecise
1166   // trimming may lead to loss of AV sync.
1167   if (overlapped_buffer->is_duration_estimated()) {
1168     DVLOG(3) << __func__ << " Skipping audio splice trimming at PTS="
1169              << splice_timestamp.InMicroseconds() << ". Overlapped buffer has "
1170              << "estimated duration.";
1171     return;
1172   }
1173
1174   // Determine the duration of overlap.
1175   base::TimeDelta overlapped_end_time =
1176       overlapped_buffer->timestamp() + overlapped_buffer->duration();
1177   base::TimeDelta overlap_duration = overlapped_end_time - splice_timestamp;
1178
1179   // At this point overlap should be non-empty (ruled out same-timestamp above).
1180   DCHECK_GT(overlap_duration, base::TimeDelta());
1181
1182   // Don't trim for overlaps of less than one millisecond (which is frequently
1183   // the extent of timestamp resolution for poorly encoded media).
1184   if (overlap_duration < base::Milliseconds(1)) {
1185     std::stringstream log_string;
1186     log_string << "Skipping audio splice trimming at PTS="
1187                << splice_timestamp.InMicroseconds() << "us. Found only "
1188                << overlap_duration.InMicroseconds()
1189                << "us of overlap, need at least 1000us. Multiple occurrences "
1190                << "may result in loss of A/V sync.";
1191     LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs)
1192         << log_string.str();
1193     DVLOG(1) << __func__ << log_string.str();
1194     return;
1195   }
1196
1197   // Trim overlap from the existing buffer.
1198   DecoderBuffer::DiscardPadding discard_padding =
1199       overlapped_buffer->discard_padding();
1200   discard_padding.second += overlap_duration;
1201   overlapped_buffer->set_discard_padding(discard_padding);
1202   overlapped_buffer->set_duration(overlapped_buffer->duration() -
1203                                   overlap_duration);
1204
1205   // Note that the range's end time tracking shouldn't need explicit updating
1206   // here due to the overlapped buffer's truncation because the range tracks
1207   // that end time using a pointer to the buffer (which should be
1208   // |overlapped_buffer| if the overlap occurred at the end of the range).
1209   // Every audio frame is either a keyframe, or if a nonkeyframe is in PTS order
1210   // since the last keyframe, so there is no out-of-order PTS vs DTS sequencing
1211   // to overcome. If the overlap occurs in the middle of the range, the caller
1212   // invokes methods on the range which internally update the end time(s) of the
1213   // resulting range(s) involved in the append.
1214
1215   std::stringstream log_string;
1216   log_string << "Audio buffer splice at PTS="
1217              << splice_timestamp.InMicroseconds()
1218              << "us. Trimmed tail of overlapped buffer (PTS="
1219              << overlapped_buffer->timestamp().InMicroseconds() << "us) by "
1220              << overlap_duration.InMicroseconds() << "us.";
1221   LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs)
1222       << log_string.str();
1223   DVLOG(1) << __func__ << log_string.str();
1224 }
1225
1226 void SourceBufferStream::PrepareRangesForNextAppend(
1227     const BufferQueue& new_buffers,
1228     BufferQueue* deleted_buffers) {
1229   DCHECK(deleted_buffers);
1230
1231   if (GetType() == SourceBufferStreamType::kAudio)
1232     TrimSpliceOverlap(new_buffers);
1233
1234   base::TimeDelta buffers_start_timestamp = kNoTimestamp;
1235   base::TimeDelta buffers_end_timestamp = kNoTimestamp;
1236   GetTimestampInterval(new_buffers, &buffers_start_timestamp,
1237                        &buffers_end_timestamp);
1238   DCHECK(buffers_start_timestamp != kNoTimestamp);
1239   DCHECK(buffers_end_timestamp != kNoTimestamp);
1240
1241   // 1. Clean up the old buffers between the last appended buffers and the
1242   //    beginning of |new_buffers|.
1243   if (highest_timestamp_in_append_sequence_ != kNoTimestamp &&
1244       highest_timestamp_in_append_sequence_ < buffers_start_timestamp) {
1245     RemoveInternal(highest_timestamp_in_append_sequence_,
1246                    buffers_start_timestamp, true, deleted_buffers);
1247   }
1248
1249   // 2. Delete the buffers that |new_buffers| overlaps.
1250   // There may be buffers in |new_buffers| with timestamp before
1251   // |highest_timestamp_in_append_sequence_| that shouldn't trigger removal of
1252   // stuff before |highest_timestamp_in_append_sequence_|.
1253   if (highest_timestamp_in_append_sequence_ != kNoTimestamp &&
1254       buffers_start_timestamp < highest_timestamp_in_append_sequence_) {
1255     DCHECK(highest_timestamp_in_append_sequence_ <=
1256            highest_buffered_end_time_in_append_sequence_);
1257     buffers_start_timestamp = highest_buffered_end_time_in_append_sequence_;
1258   }
1259
1260   if (new_coded_frame_group_) {
1261     // Extend the deletion range earlier to the coded frame group start time if
1262     // this is the first append in a new coded frame group.
1263     DCHECK(coded_frame_group_start_pts_ != kNoTimestamp);
1264     buffers_start_timestamp =
1265         std::min(coded_frame_group_start_pts_, buffers_start_timestamp);
1266   }
1267
1268   // Return early if no further overlap removal is needed. First check if
1269   // |buffers_start_timestamp| is in the middle of the range; we could be
1270   // overlap-appending the middle of a previous coded frame sequence's range
1271   // with non-keyframes prior to |highest_timestamp_in_append_sequence_|, so we
1272   // need to split that range appropriately here and then return early. If we
1273   // don't return early here, overlap removal (including any necessary range
1274   // splitting) will occur.
1275   if (buffers_start_timestamp >= buffers_end_timestamp) {
1276     DCHECK(highest_timestamp_in_append_sequence_ != kNoTimestamp);
1277     DCHECK(range_for_next_append_ != ranges_.end());
1278     DCHECK((*range_for_next_append_)->BelongsToRange(buffers_start_timestamp));
1279
1280     // Split the range at |buffers_start_timestamp|, if necessary, then return
1281     // early.
1282     std::unique_ptr<SourceBufferRange> new_range =
1283         (*range_for_next_append_)->SplitRange(buffers_start_timestamp);
1284     if (!new_range)
1285       return;
1286
1287     range_for_next_append_ =
1288         ranges_.insert(++range_for_next_append_, std::move(new_range));
1289
1290     // Update the selected range if the next buffer position was transferred
1291     // to the newly inserted range.
1292     if ((*range_for_next_append_)->HasNextBufferPosition())
1293       SetSelectedRange(range_for_next_append_->get());
1294
1295     --range_for_next_append_;
1296     return;
1297   }
1298
1299   // Exclude the start from removal to avoid deleting the highest appended
1300   // buffer in cases where the first buffer in |new_buffers| has same timestamp
1301   // as the highest appended buffer (even in out-of-order DTS vs PTS sequence).
1302   // Only do this when :
1303   //   A. Type is video. This may occur in cases of VP9 alt-ref frames or frames
1304   //      with incorrect timestamps. Removing a frame may break decode
1305   //      dependencies and there are no downsides to just keeping it (other than
1306   //      some throw-away decoder work).
1307   //   B. Type is audio and overlapped duration is 0. We've encountered Vorbis
1308   //      streams containing zero-duration buffers (i.e. no real overlap). For
1309   //      non-zero duration removing overlapped frames is important to preserve
1310   //      A/V sync (see AudioClock).
1311   const bool exclude_start =
1312       highest_timestamp_in_append_sequence_ ==
1313           new_buffers.front()->timestamp() &&
1314       (GetType() == SourceBufferStreamType::kVideo ||
1315        last_appended_buffer_duration_ == base::TimeDelta());
1316
1317   // Finally do the deletion of overlap.
1318   RemoveInternal(buffers_start_timestamp, buffers_end_timestamp, exclude_start,
1319                  deleted_buffers);
1320 }
1321
1322 // static
1323 void SourceBufferStream::GetTimestampInterval(const BufferQueue& buffers,
1324                                               base::TimeDelta* start,
1325                                               base::TimeDelta* end) {
1326   base::TimeDelta start_pts = buffers.front()->timestamp();
1327   base::TimeDelta end_pts = start_pts;
1328
1329   for (const auto& buffer : buffers) {
1330     base::TimeDelta timestamp = buffer->timestamp();
1331     start_pts = std::min(timestamp, start_pts);
1332     base::TimeDelta duration = buffer->duration();
1333
1334     // FrameProcessor should protect against unknown buffer durations.
1335     DCHECK_NE(duration, kNoTimestamp);
1336
1337     if (duration.is_positive() && !buffer->is_duration_estimated()) {
1338       timestamp += duration;
1339     } else {
1340       // TODO(chcunningham): Emit warning when 0ms durations are not expected.
1341       // http://crbug.com/312836
1342       timestamp += base::Microseconds(1);
1343     }
1344     end_pts = std::max(timestamp, end_pts);
1345   }
1346   *start = start_pts;
1347   *end = end_pts;
1348 }
1349
1350 bool SourceBufferStream::IsNextGopAdjacentToEndOfCurrentAppendSequence(
1351     base::TimeDelta next_gop_timestamp) const {
1352   base::TimeDelta upper_bound = highest_timestamp_in_append_sequence_ +
1353                                 ComputeFudgeRoom(GetMaxInterbufferDistance());
1354   DVLOG(4) << __func__ << " " << GetStreamTypeName()
1355            << " next_gop_timestamp=" << next_gop_timestamp.InMicroseconds()
1356            << "us, highest_timestamp_in_append_sequence_="
1357            << highest_timestamp_in_append_sequence_.InMicroseconds()
1358            << "us, upper_bound=" << upper_bound.InMicroseconds() << "us";
1359   return highest_timestamp_in_append_sequence_ < next_gop_timestamp &&
1360          next_gop_timestamp <= upper_bound;
1361 }
1362
1363 void SourceBufferStream::PruneTrackBuffer(const base::TimeDelta timestamp) {
1364   DCHECK(timestamp != kNoTimestamp);
1365
1366   // Scan forward until we find a buffer with timestamp at or beyond the limit.
1367   // Then remove all those at and beyond that point.
1368   size_t goal_size = 0;  // The number of buffers we will keep in the result.
1369   for (const auto& buf : track_buffer_) {
1370     if (buf->timestamp() >= timestamp)
1371       break;
1372     goal_size++;
1373   }
1374
1375   while (track_buffer_.size() > goal_size) {
1376     track_buffer_.pop_back();
1377   }
1378
1379   DVLOG(3) << __func__ << " " << GetStreamTypeName()
1380            << " Removed all buffers in track buffer sequence starting with the "
1381               "first at timestamp >= "
1382            << timestamp.InMicroseconds()
1383            << "us. New track buffer size:" << track_buffer_.size();
1384 }
1385
1386 void SourceBufferStream::MergeWithNextRangeIfNecessary(
1387     const RangeList::iterator& range_with_new_buffers_itr) {
1388   DCHECK(range_with_new_buffers_itr != ranges_.end());
1389
1390   SourceBufferRange* range_with_new_buffers = range_with_new_buffers_itr->get();
1391   RangeList::iterator next_range_itr = range_with_new_buffers_itr;
1392   ++next_range_itr;
1393
1394   if (next_range_itr == ranges_.end() ||
1395       !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
1396     return;
1397   }
1398
1399   bool transfer_current_position = selected_range_ == next_range_itr->get();
1400   DVLOG(3) << __func__ << " " << GetStreamTypeName() << " merging "
1401            << RangeToString(*range_with_new_buffers) << " into "
1402            << RangeToString(**next_range_itr);
1403   range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
1404                                            transfer_current_position);
1405   // Update |selected_range_| pointer if |range| has become selected after
1406   // merges.
1407   if (transfer_current_position)
1408     SetSelectedRange(range_with_new_buffers);
1409
1410   if (next_range_itr == range_for_next_append_)
1411     range_for_next_append_ = range_with_new_buffers_itr;
1412
1413   DeleteAndRemoveRange(&next_range_itr);
1414 }
1415
1416 void SourceBufferStream::MergeAllAdjacentRanges() {
1417   DVLOG(1) << __func__ << " " << GetStreamTypeName()
1418            << ": Before: ranges_=" << RangesToString(ranges_);
1419
1420   auto range_itr = ranges_.begin();
1421
1422   while (range_itr != ranges_.end()) {
1423     const size_t old_ranges_size = ranges_.size();
1424     MergeWithNextRangeIfNecessary(range_itr);
1425
1426     // Only proceed to the next range if the current range didn't merge with it.
1427     if (old_ranges_size == ranges_.size())
1428       range_itr++;
1429   }
1430
1431   DVLOG(1) << __func__ << " " << GetStreamTypeName()
1432            << ": After: ranges_=" << RangesToString(ranges_);
1433 }
1434
1435 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
1436   DCHECK(timestamp >= base::TimeDelta());
1437   DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
1438            << timestamp.InMicroseconds() << "us)";
1439   ResetSeekState();
1440
1441   seek_buffer_timestamp_ = timestamp;
1442   seek_pending_ = true;
1443
1444   if (ShouldSeekToStartOfBuffered(timestamp)) {
1445     ranges_.front()->SeekToStart();
1446     SetSelectedRange(ranges_.front().get());
1447     seek_pending_ = false;
1448     return;
1449   }
1450
1451   auto itr = ranges_.end();
1452   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1453     if ((*itr)->CanSeekTo(timestamp))
1454       break;
1455   }
1456
1457   if (itr == ranges_.end())
1458     return;
1459
1460   if (!audio_configs_.empty()) {
1461     // Adjust |timestamp| for an Opus stream backward up to the config's seek
1462     // preroll, but not further than the range start time, and not at all if
1463     // there is a config change in the middle of that preroll interval. If
1464     // |timestamp| is already before the range start time, as can happen due to
1465     // fudge room, do not adjust it.
1466     const auto& config = audio_configs_[(*itr)->GetConfigIdAtTime(timestamp)];
1467     if (config.codec() == AudioCodec::kOpus &&
1468         timestamp > (*itr)->GetStartTimestamp()) {
1469       base::TimeDelta preroll_timestamp = std::max(
1470           timestamp - config.seek_preroll(), (*itr)->GetStartTimestamp());
1471       if ((*itr)->CanSeekTo(preroll_timestamp) &&
1472           (*itr)->SameConfigThruRange(preroll_timestamp, timestamp)) {
1473         timestamp = preroll_timestamp;
1474       }
1475     }
1476   }
1477
1478   SeekAndSetSelectedRange(itr->get(), timestamp);
1479 #if BUILDFLAG(IS_TIZEN_TV)
1480   // After seeking on audio stream coded with mpeg-h codec, there is a need to
1481   // one more time inject starting sequence to first frame.
1482   if (!audio_configs_.empty()) {
1483     const auto& config = audio_configs_[(*itr)->GetConfigIdAtTime(timestamp)];
1484     if (config.codec() == AudioCodec::kMpegHAudio) {
1485       (*itr)->ModifyFirstFrameForMpeghCodec();
1486     }
1487   }
1488 #endif
1489   seek_pending_ = false;
1490 }
1491
1492 bool SourceBufferStream::IsSeekPending() const {
1493   return seek_pending_ && !IsEndOfStreamReached();
1494 }
1495
1496 // TODO(wolenetz): Disallow duration changes that truncate buffered media. See
1497 // https://crbug.com/623729.
1498 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
1499   DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
1500            << duration.InMicroseconds() << "us)";
1501   DCHECK(!end_of_stream_);
1502
1503   if (ranges_.empty())
1504     return;
1505
1506   base::TimeDelta start = duration;
1507   base::TimeDelta end = ranges_.back()->GetBufferedEndTimestamp();
1508
1509   // Trim the end if it exceeds the new duration.
1510   if (start < end) {
1511     BufferQueue deleted_buffers;
1512     RemoveInternal(start, end, false, &deleted_buffers);
1513
1514     if (!deleted_buffers.empty()) {
1515       // Truncation removed current position. Clear selected range.
1516       SetSelectedRange(NULL);
1517     }
1518   }
1519 }
1520
1521 SourceBufferStreamStatus SourceBufferStream::GetNextBuffer(
1522     scoped_refptr<StreamParserBuffer>* out_buffer) {
1523   DVLOG(2) << __func__ << " " << GetStreamTypeName();
1524   if (!pending_buffer_.get()) {
1525     const SourceBufferStreamStatus status = GetNextBufferInternal(out_buffer);
1526     if (status != SourceBufferStreamStatus::kSuccess ||
1527         !SetPendingBuffer(out_buffer)) {
1528       DVLOG(2) << __func__ << " " << GetStreamTypeName()
1529                << ": no pending buffer, returning status "
1530                << StatusToString(status);
1531       return status;
1532     }
1533   }
1534
1535   DCHECK(pending_buffer_->preroll_buffer().get());
1536
1537   const SourceBufferStreamStatus status =
1538       HandleNextBufferWithPreroll(out_buffer);
1539   DVLOG(2) << __func__ << " " << GetStreamTypeName()
1540            << ": handled next buffer with preroll, returning status "
1541            << StatusToString(status);
1542   return status;
1543 }
1544
1545 SourceBufferStreamStatus SourceBufferStream::HandleNextBufferWithPreroll(
1546     scoped_refptr<StreamParserBuffer>* out_buffer) {
1547   // Any config change should have already been handled.
1548   DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1549
1550   // Check if the preroll buffer has already been handed out.
1551   if (!pending_buffers_complete_) {
1552     pending_buffers_complete_ = true;
1553     *out_buffer = pending_buffer_->preroll_buffer();
1554     return SourceBufferStreamStatus::kSuccess;
1555   }
1556
1557   // Preroll complete, hand out the final buffer.
1558   *out_buffer = std::move(pending_buffer_);
1559   return SourceBufferStreamStatus::kSuccess;
1560 }
1561
1562 SourceBufferStreamStatus SourceBufferStream::GetNextBufferInternal(
1563     scoped_refptr<StreamParserBuffer>* out_buffer) {
1564   CHECK(!config_change_pending_);
1565
1566   if (!track_buffer_.empty()) {
1567     DCHECK(!selected_range_);
1568
1569     if (track_buffer_.front()->GetConfigId() != current_config_index_) {
1570       config_change_pending_ = true;
1571       DVLOG(1) << "Config change (track buffer config ID does not match).";
1572       return SourceBufferStreamStatus::kConfigChange;
1573     }
1574
1575     DVLOG(3) << __func__ << " Next buffer coming from track_buffer_";
1576     *out_buffer = std::move(track_buffer_.front());
1577     track_buffer_.pop_front();
1578     WarnIfTrackBufferExhaustionSkipsForward(*out_buffer);
1579     highest_output_buffer_timestamp_ =
1580         std::max(highest_output_buffer_timestamp_, (*out_buffer)->timestamp());
1581
1582     // If the track buffer becomes empty, then try to set the selected range
1583     // based on the timestamp of this buffer being returned.
1584     if (track_buffer_.empty()) {
1585       just_exhausted_track_buffer_ = true;
1586       SetSelectedRangeIfNeeded(highest_output_buffer_timestamp_);
1587     }
1588
1589     return SourceBufferStreamStatus::kSuccess;
1590   }
1591
1592   DCHECK(track_buffer_.empty());
1593   if (!selected_range_ || !selected_range_->HasNextBuffer()) {
1594     if (IsEndOfStreamReached()) {
1595       return SourceBufferStreamStatus::kEndOfStream;
1596     }
1597     DVLOG(3) << __func__ << " " << GetStreamTypeName()
1598              << ": returning kNeedBuffer "
1599              << (selected_range_ ? "(selected range has no next buffer)"
1600                                  : "(no selected range)");
1601     return SourceBufferStreamStatus::kNeedBuffer;
1602   }
1603
1604   if (selected_range_->GetNextConfigId() != current_config_index_) {
1605     config_change_pending_ = true;
1606     DVLOG(1) << "Config change (selected range config ID does not match).";
1607     return SourceBufferStreamStatus::kConfigChange;
1608   }
1609
1610   CHECK(selected_range_->GetNextBuffer(out_buffer));
1611   WarnIfTrackBufferExhaustionSkipsForward(*out_buffer);
1612   highest_output_buffer_timestamp_ =
1613       std::max(highest_output_buffer_timestamp_, (*out_buffer)->timestamp());
1614   return SourceBufferStreamStatus::kSuccess;
1615 }
1616
1617 void SourceBufferStream::WarnIfTrackBufferExhaustionSkipsForward(
1618     scoped_refptr<StreamParserBuffer> next_buffer) {
1619   if (!just_exhausted_track_buffer_)
1620     return;
1621
1622   just_exhausted_track_buffer_ = false;
1623   DCHECK(next_buffer->is_key_frame());
1624   base::TimeDelta next_output_buffer_timestamp = next_buffer->timestamp();
1625   base::TimeDelta delta =
1626       next_output_buffer_timestamp - highest_output_buffer_timestamp_;
1627   if (delta > GetMaxInterbufferDistance()) {
1628     LIMITED_MEDIA_LOG(DEBUG, media_log_, num_track_buffer_gap_warning_logs_,
1629                       kMaxTrackBufferGapWarningLogs)
1630         << "Media append that overlapped current playback position may cause "
1631            "time gap in playing "
1632         << GetStreamTypeName() << " stream because the next keyframe is "
1633         << delta.InMilliseconds()
1634         << "ms beyond last overlapped frame. Media may appear temporarily "
1635            "frozen.";
1636   }
1637 }
1638
1639 bool SourceBufferStream::IsNextBufferConfigChanged() {
1640   if (!track_buffer_.empty())
1641     return track_buffer_.front()->GetConfigId() != current_config_index_;
1642
1643   if (!selected_range_ || !selected_range_->HasNextBuffer())
1644     return false;
1645
1646   return selected_range_->GetNextConfigId() != current_config_index_;
1647 }
1648
1649 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() {
1650   if (!track_buffer_.empty())
1651     return track_buffer_.front()->timestamp();
1652
1653   if (!selected_range_)
1654     return kNoTimestamp;
1655
1656   DCHECK(selected_range_->HasNextBufferPosition());
1657   return selected_range_->GetNextTimestamp();
1658 }
1659
1660 SourceBufferStream::RangeList::iterator
1661 SourceBufferStream::FindExistingRangeFor(base::TimeDelta start_timestamp) {
1662   for (auto itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1663     if ((*itr)->BelongsToRange(start_timestamp))
1664       return itr;
1665   }
1666   return ranges_.end();
1667 }
1668
1669 SourceBufferStream::RangeList::iterator SourceBufferStream::AddToRanges(
1670     std::unique_ptr<SourceBufferRange> new_range) {
1671   base::TimeDelta start_timestamp = new_range->GetStartTimestamp();
1672   auto itr = ranges_.end();
1673   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1674     if ((*itr)->GetStartTimestamp() > start_timestamp)
1675       break;
1676   }
1677   return ranges_.insert(itr, std::move(new_range));
1678 }
1679
1680 void SourceBufferStream::SeekAndSetSelectedRange(
1681     SourceBufferRange* range,
1682     base::TimeDelta seek_timestamp) {
1683   if (range)
1684     range->Seek(seek_timestamp);
1685   SetSelectedRange(range);
1686 }
1687
1688 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
1689   DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": " << selected_range_
1690            << " " << (selected_range_ ? RangeToString(*selected_range_) : "")
1691            << " -> " << range << " " << (range ? RangeToString(*range) : "");
1692   if (selected_range_)
1693     selected_range_->ResetNextBufferPosition();
1694   DCHECK(!range || range->HasNextBufferPosition());
1695   selected_range_ = range;
1696 }
1697
1698 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
1699   Ranges<base::TimeDelta> ranges;
1700   for (auto itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1701     ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp());
1702   }
1703   return ranges;
1704 }
1705
1706 base::TimeDelta SourceBufferStream::GetLowestPresentationTimestamp() const {
1707   if (ranges_.empty()) {
1708     return base::TimeDelta();
1709   }
1710
1711   return ranges_.front()->GetStartTimestamp();
1712 }
1713
1714 base::TimeDelta SourceBufferStream::GetHighestPresentationTimestamp() const {
1715   if (ranges_.empty())
1716     return base::TimeDelta();
1717
1718   return ranges_.back()->GetEndTimestamp();
1719 }
1720
1721 base::TimeDelta SourceBufferStream::GetBufferedDuration() const {
1722   if (ranges_.empty())
1723     return base::TimeDelta();
1724
1725   return ranges_.back()->GetBufferedEndTimestamp();
1726 }
1727
1728 size_t SourceBufferStream::GetBufferedSize() const {
1729   size_t ranges_size = 0;
1730   for (const auto& range_ptr : ranges_)
1731     ranges_size += range_ptr->size_in_bytes();
1732   return ranges_size;
1733 }
1734
1735 void SourceBufferStream::MarkEndOfStream() {
1736   DCHECK(!end_of_stream_);
1737   end_of_stream_ = true;
1738 }
1739
1740 void SourceBufferStream::UnmarkEndOfStream() {
1741   DCHECK(end_of_stream_);
1742   end_of_stream_ = false;
1743 }
1744
1745 bool SourceBufferStream::IsEndOfStreamReached() const {
1746   if (!end_of_stream_ || !track_buffer_.empty())
1747     return false;
1748
1749   if (ranges_.empty())
1750     return true;
1751
1752   if (seek_pending_) {
1753     base::TimeDelta last_range_end_time =
1754         ranges_.back()->GetBufferedEndTimestamp();
1755     return seek_buffer_timestamp_ >= last_range_end_time;
1756   }
1757
1758   if (!selected_range_)
1759     return true;
1760
1761   return selected_range_ == ranges_.back().get();
1762 }
1763
1764 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
1765   if (config_change_pending_)
1766     CompleteConfigChange();
1767   // Trying to track down crash. http://crbug.com/715761
1768   CHECK(current_config_index_ >= 0 &&
1769         static_cast<size_t>(current_config_index_) < audio_configs_.size());
1770   return audio_configs_[current_config_index_];
1771 }
1772
1773 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
1774   if (config_change_pending_)
1775     CompleteConfigChange();
1776   // Trying to track down crash. http://crbug.com/715761
1777   CHECK(current_config_index_ >= 0 &&
1778         static_cast<size_t>(current_config_index_) < video_configs_.size());
1779   return video_configs_[current_config_index_];
1780 }
1781
1782 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
1783   return max_interbuffer_distance_;
1784 }
1785
1786 #if BUILDFLAG(IS_TIZEN_TV)
1787 void SourceBufferStream::updateFramerate(
1788     const StreamFramerate::Framerate& framerate) {
1789   CHECK(current_config_index_ >= 0 &&
1790         static_cast<size_t>(current_config_index_) < video_configs_.size());
1791
1792   video_configs_[current_config_index_].set_framerate_num(framerate.num);
1793   video_configs_[current_config_index_].set_framerate_den(framerate.den);
1794 }
1795 #endif
1796
1797 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config,
1798                                            bool allow_codec_change) {
1799   DCHECK(!audio_configs_.empty());
1800   DCHECK(video_configs_.empty());
1801   DVLOG(3) << "UpdateAudioConfig.";
1802
1803   if (!allow_codec_change &&
1804       audio_configs_[append_config_index_].codec() != config.codec()) {
1805     // TODO(wolenetz): When we relax addSourceBuffer() and changeType() codec
1806     // strictness, codec changes should be allowed even without changing the
1807     // bytestream.
1808     // TODO(wolenetz): Remove "experimental" from this error message when
1809     // changeType() ships without needing experimental blink flag.
1810     MEDIA_LOG(ERROR, media_log_) << "Audio codec changes not allowed unless "
1811                                     "using experimental changeType().";
1812     return false;
1813   }
1814
1815   // Check to see if the new config matches an existing one.
1816   for (size_t i = 0; i < audio_configs_.size(); ++i) {
1817     if (config.Matches(audio_configs_[i])) {
1818       append_config_index_ = i;
1819       return true;
1820     }
1821   }
1822
1823   // No matches found so let's add this one to the list.
1824   append_config_index_ = audio_configs_.size();
1825   DVLOG(2) << "New audio config - index: " << append_config_index_;
1826   audio_configs_.resize(audio_configs_.size() + 1);
1827   audio_configs_[append_config_index_] = config;
1828   return true;
1829 }
1830
1831 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config,
1832                                            bool allow_codec_change) {
1833   DCHECK(!video_configs_.empty());
1834   DCHECK(audio_configs_.empty());
1835   DVLOG(3) << "UpdateVideoConfig.";
1836
1837   if (!allow_codec_change &&
1838       video_configs_[append_config_index_].codec() != config.codec()) {
1839     // TODO(wolenetz): When we relax addSourceBuffer() and changeType() codec
1840     // strictness, codec changes should be allowed even without changing the
1841     // bytestream.
1842     // TODO(wolenetz): Remove "experimental" from this error message when
1843     // changeType() ships without needing experimental blink flag.
1844     MEDIA_LOG(ERROR, media_log_) << "Video codec changes not allowed unless "
1845                                     "using experimental changeType()";
1846     return false;
1847   }
1848
1849   // Check to see if the new config matches an existing one.
1850   for (size_t i = 0; i < video_configs_.size(); ++i) {
1851     if (config.Matches(video_configs_[i])) {
1852       append_config_index_ = i;
1853       return true;
1854     }
1855   }
1856
1857   // No matches found so let's add this one to the list.
1858   append_config_index_ = video_configs_.size();
1859   DVLOG(2) << "New video config - index: " << append_config_index_;
1860   video_configs_.resize(video_configs_.size() + 1);
1861   video_configs_[append_config_index_] = config;
1862 #if BUILDFLAG(IS_TIZEN_TV)
1863   size_t updated_memory_limit = UpdateDemuxerStreamVideoMemoryLimit(&config);
1864   memory_limit_ = std::max(memory_limit_, updated_memory_limit);
1865 #endif
1866   return true;
1867 }
1868
1869 void SourceBufferStream::CompleteConfigChange() {
1870   config_change_pending_ = false;
1871
1872   if (!track_buffer_.empty()) {
1873     current_config_index_ = track_buffer_.front()->GetConfigId();
1874     return;
1875   }
1876
1877   if (selected_range_ && selected_range_->HasNextBuffer())
1878     current_config_index_ = selected_range_->GetNextConfigId();
1879 }
1880
1881 void SourceBufferStream::SetSelectedRangeIfNeeded(
1882     const base::TimeDelta timestamp) {
1883   DVLOG(2) << __func__ << " " << GetStreamTypeName() << "("
1884            << timestamp.InMicroseconds() << "us)";
1885
1886   if (selected_range_) {
1887     DCHECK(track_buffer_.empty());
1888     return;
1889   }
1890
1891   if (!track_buffer_.empty()) {
1892     DCHECK(!selected_range_);
1893     return;
1894   }
1895
1896   base::TimeDelta start_timestamp = timestamp;
1897
1898   // If the next buffer timestamp is not known then use a timestamp just after
1899   // the timestamp on the last buffer returned by GetNextBuffer().
1900   if (start_timestamp == kNoTimestamp) {
1901     if (highest_output_buffer_timestamp_ == kNoTimestamp) {
1902       DVLOG(2) << __func__ << " " << GetStreamTypeName()
1903                << " no previous output timestamp";
1904       return;
1905     }
1906
1907     start_timestamp = highest_output_buffer_timestamp_ + base::Microseconds(1);
1908   }
1909
1910   base::TimeDelta seek_timestamp =
1911       FindNewSelectedRangeSeekTimestamp(start_timestamp);
1912
1913   // If we don't have buffered data to seek to, then return.
1914   if (seek_timestamp == kNoTimestamp) {
1915     DVLOG(2) << __func__ << " " << GetStreamTypeName()
1916              << " couldn't find new selected range seek timestamp";
1917     return;
1918   }
1919
1920   DCHECK(track_buffer_.empty());
1921   SeekAndSetSelectedRange(FindExistingRangeFor(seek_timestamp)->get(),
1922                           seek_timestamp);
1923 }
1924
1925 base::TimeDelta SourceBufferStream::FindNewSelectedRangeSeekTimestamp(
1926     const base::TimeDelta start_timestamp) {
1927   DCHECK(start_timestamp != kNoTimestamp);
1928   DCHECK(start_timestamp >= base::TimeDelta());
1929
1930   auto itr = ranges_.begin();
1931
1932   // When checking a range to see if it has or begins soon enough after
1933   // |start_timestamp|, use the fudge room to determine "soon enough".
1934   base::TimeDelta start_timestamp_plus_fudge =
1935       start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1936
1937   // Multiple ranges could be within the fudge room, because the fudge room is
1938   // dynamic based on max inter-buffer distance seen so far. Optimistically
1939   // check the earliest ones first.
1940   for (; itr != ranges_.end(); ++itr) {
1941     base::TimeDelta range_start = (*itr)->GetStartTimestamp();
1942     if (range_start >= start_timestamp_plus_fudge)
1943       break;
1944     if ((*itr)->GetEndTimestamp() < start_timestamp)
1945       continue;
1946     base::TimeDelta search_timestamp = start_timestamp;
1947     if (start_timestamp < range_start &&
1948         start_timestamp_plus_fudge >= range_start) {
1949       search_timestamp = range_start;
1950     }
1951     base::TimeDelta keyframe_timestamp =
1952         (*itr)->NextKeyframeTimestamp(search_timestamp);
1953     if (keyframe_timestamp != kNoTimestamp)
1954       return keyframe_timestamp;
1955   }
1956
1957   DVLOG(2) << __func__ << " " << GetStreamTypeName()
1958            << " no buffered data for pts=" << start_timestamp.InMicroseconds()
1959            << "us";
1960   return kNoTimestamp;
1961 }
1962
1963 base::TimeDelta SourceBufferStream::FindKeyframeAfterTimestamp(
1964     const base::TimeDelta timestamp) {
1965   DCHECK(timestamp != kNoTimestamp);
1966
1967   auto itr = FindExistingRangeFor(timestamp);
1968
1969   if (itr == ranges_.end())
1970     return kNoTimestamp;
1971
1972   // First check for a keyframe timestamp >= |timestamp|
1973   // in the current range.
1974   return (*itr)->NextKeyframeTimestamp(timestamp);
1975 }
1976
1977 std::string SourceBufferStream::GetStreamTypeName() const {
1978   switch (GetType()) {
1979     case SourceBufferStreamType::kAudio:
1980       return "AUDIO";
1981     case SourceBufferStreamType::kVideo:
1982       return "VIDEO";
1983   }
1984   NOTREACHED_NORETURN();
1985 }
1986
1987 SourceBufferStreamType SourceBufferStream::GetType() const {
1988   if (!audio_configs_.empty())
1989     return SourceBufferStreamType::kAudio;
1990   DCHECK(!video_configs_.empty());
1991   return SourceBufferStreamType::kVideo;
1992 }
1993
1994 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) {
1995   DVLOG(1) << __func__;
1996
1997   DCHECK(*itr != ranges_.end());
1998   if ((*itr)->get() == selected_range_) {
1999     DVLOG(1) << __func__ << " deleting selected range.";
2000     SetSelectedRange(NULL);
2001   }
2002
2003   if (*itr == range_for_next_append_) {
2004     DVLOG(1) << __func__ << " deleting range_for_next_append_.";
2005     range_for_next_append_ = ranges_.end();
2006     ResetLastAppendedState();
2007   }
2008
2009   *itr = ranges_.erase(*itr);
2010 }
2011
2012 bool SourceBufferStream::SetPendingBuffer(
2013     scoped_refptr<StreamParserBuffer>* out_buffer) {
2014   DCHECK(out_buffer->get());
2015   DCHECK(!pending_buffer_.get());
2016
2017   const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();
2018
2019   if (!have_preroll_buffer)
2020     return false;
2021
2022   pending_buffer_.swap(*out_buffer);
2023   pending_buffers_complete_ = false;
2024   return true;
2025 }
2026
2027 }  // namespace media