source_buffer_stream.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "media/filters/source_buffer_stream.h" 6 7#include <algorithm> 8#include <map> 9 10#include "base/bind.h" 11#include "base/debug/trace_event.h" 12#include "base/logging.h" 13#include "media/base/audio_splicer.h" 14 15namespace media { 16 17typedef StreamParser::BufferQueue BufferQueue; 18 19// Buffers with the same timestamp are only allowed under certain conditions. 20// More precisely, it is allowed in all situations except when the previous 21// frame is not a key frame and the current is a key frame. 22// Examples of situations where DTS of two consecutive frames can be equal: 23// - Video: VP8 Alt-Ref frames. 24// - Video: IPBPBP...: DTS for I frame and for P frame can be equal. 25// - Text track cues that start at same time. 26// Returns true if |prev_is_keyframe| and |current_is_keyframe| indicate a 27// same timestamp situation that is allowed. False is returned otherwise. 28static bool AllowSameTimestamp( 29 bool prev_is_keyframe, bool current_is_keyframe, 30 SourceBufferStream::Type type) { 31 return prev_is_keyframe || !current_is_keyframe; 32} 33 34// Returns the config ID of |buffer| if |buffer| has no splice buffers or 35// |index| is out of range. Otherwise returns the config ID for the fade out 36// preroll buffer at position |index|. 37static int GetConfigId(StreamParserBuffer* buffer, size_t index) { 38 return index < buffer->get_splice_buffers().size() 39 ? buffer->get_splice_buffers()[index]->GetConfigId() 40 : buffer->GetConfigId(); 41} 42 43// Helper class representing a range of buffered data. All buffers in a 44// SourceBufferRange are ordered sequentially in presentation order with no 45// gaps. 46class SourceBufferRange { 47 public: 48 // Returns the maximum distance in time between any buffer seen in this 49 // stream. Used to estimate the duration of a buffer if its duration is not 50 // known. 51 typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB; 52 53 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be 54 // empty and the front of |new_buffers| must be a keyframe. 55 // |media_segment_start_time| refers to the starting timestamp for the media 56 // segment to which these buffers belong. 57 SourceBufferRange(SourceBufferStream::Type type, 58 const BufferQueue& new_buffers, 59 base::TimeDelta media_segment_start_time, 60 const InterbufferDistanceCB& interbuffer_distance_cb); 61 62 // Appends |buffers| to the end of the range and updates |keyframe_map_| as 63 // it encounters new keyframes. Assumes |buffers| belongs at the end of the 64 // range. 65 void AppendBuffersToEnd(const BufferQueue& buffers); 66 bool CanAppendBuffersToEnd(const BufferQueue& buffers) const; 67 68 // Appends the buffers from |range| into this range. 69 // The first buffer in |range| must come directly after the last buffer 70 // in this range. 71 // If |transfer_current_position| is true, |range|'s |next_buffer_index_| 72 // is transfered to this SourceBufferRange. 73 void AppendRangeToEnd(const SourceBufferRange& range, 74 bool transfer_current_position); 75 bool CanAppendRangeToEnd(const SourceBufferRange& range) const; 76 77 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. 78 // Assumes |timestamp| is valid and in this range. 79 void Seek(base::TimeDelta timestamp); 80 81 // Updates |next_buffer_index_| to point to next keyframe after or equal to 82 // |timestamp|. 83 void SeekAheadTo(base::TimeDelta timestamp); 84 85 // Updates |next_buffer_index_| to point to next keyframe strictly after 86 // |timestamp|. 87 void SeekAheadPast(base::TimeDelta timestamp); 88 89 // Seeks to the beginning of the range. 90 void SeekToStart(); 91 92 // Finds the next keyframe from |buffers_| after |timestamp| (or at 93 // |timestamp| if |is_exclusive| is false) and creates and returns a new 94 // SourceBufferRange with the buffers from that keyframe onward. 95 // The buffers in the new SourceBufferRange are moved out of this range. If 96 // there is no keyframe after |timestamp|, SplitRange() returns null and this 97 // range is unmodified. 98 SourceBufferRange* SplitRange(base::TimeDelta timestamp, bool is_exclusive); 99 100 // Deletes the buffers from this range starting at |timestamp|, exclusive if 101 // |is_exclusive| is true, inclusive otherwise. 102 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was 103 // deleted, and deletes the |keyframe_map_| entries for the buffers that 104 // were removed. 105 // |deleted_buffers| contains the buffers that were deleted from this range, 106 // starting at the buffer that had been at |next_buffer_index_|. 107 // Returns true if everything in the range was deleted. Otherwise 108 // returns false. 109 bool TruncateAt(base::TimeDelta timestamp, 110 BufferQueue* deleted_buffers, bool is_exclusive); 111 // Deletes all buffers in range. 112 void DeleteAll(BufferQueue* deleted_buffers); 113 114 // Deletes a GOP from the front or back of the range and moves these 115 // buffers into |deleted_buffers|. Returns the number of bytes deleted from 116 // the range (i.e. the size in bytes of |deleted_buffers|). 117 int DeleteGOPFromFront(BufferQueue* deleted_buffers); 118 int DeleteGOPFromBack(BufferQueue* deleted_buffers); 119 120 // Gets the range of GOP to secure at least |bytes_to_free| from 121 // [|start_timestamp|, |end_timestamp|). 122 // Returns the size of the buffers to secure if the buffers of 123 // [|start_timestamp|, |end_removal_timestamp|) is removed. 124 // Will not update |end_removal_timestamp| if the returned size is 0. 125 int GetRemovalGOP( 126 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, 127 int bytes_to_free, base::TimeDelta* end_removal_timestamp); 128 129 // Indicates whether the GOP at the beginning or end of the range contains the 130 // next buffer position. 131 bool FirstGOPContainsNextBufferPosition() const; 132 bool LastGOPContainsNextBufferPosition() const; 133 134 // Updates |out_buffer| with the next buffer in presentation order. Seek() 135 // must be called before calls to GetNextBuffer(), and buffers are returned 136 // in order from the last call to Seek(). Returns true if |out_buffer| is 137 // filled with a valid buffer, false if there is not enough data to fulfill 138 // the request. 139 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); 140 bool HasNextBuffer() const; 141 142 // Returns the config ID for the buffer that will be returned by 143 // GetNextBuffer(). 144 int GetNextConfigId() const; 145 146 // Returns true if the range knows the position of the next buffer it should 147 // return, i.e. it has been Seek()ed. This does not necessarily mean that it 148 // has the next buffer yet. 149 bool HasNextBufferPosition() const; 150 151 // Resets this range to an "unseeked" state. 152 void ResetNextBufferPosition(); 153 154 // Returns the timestamp of the next buffer that will be returned from 155 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. 156 base::TimeDelta GetNextTimestamp() const; 157 158 // Returns the start timestamp of the range. 159 base::TimeDelta GetStartTimestamp() const; 160 161 // Returns the timestamp of the last buffer in the range. 162 base::TimeDelta GetEndTimestamp() const; 163 164 // Returns the timestamp for the end of the buffered region in this range. 165 // This is an approximation if the duration for the last buffer in the range 166 // is unset. 167 base::TimeDelta GetBufferedEndTimestamp() const; 168 169 // Gets the timestamp for the keyframe that is after |timestamp|. If 170 // there isn't a keyframe in the range after |timestamp| then kNoTimestamp() 171 // is returned. 172 base::TimeDelta NextKeyframeTimestamp(base::TimeDelta timestamp); 173 174 // Gets the timestamp for the closest keyframe that is <= |timestamp|. If 175 // there isn't a keyframe before |timestamp| or |timestamp| is outside 176 // this range, then kNoTimestamp() is returned. 177 base::TimeDelta KeyframeBeforeTimestamp(base::TimeDelta timestamp); 178 179 // Returns whether a buffer with a starting timestamp of |timestamp| would 180 // belong in this range. This includes a buffer that would be appended to 181 // the end of the range. 182 bool BelongsToRange(base::TimeDelta timestamp) const; 183 184 // Returns true if the range has enough data to seek to the specified 185 // |timestamp|, false otherwise. 186 bool CanSeekTo(base::TimeDelta timestamp) const; 187 188 // Returns true if this range's buffered timespan completely overlaps the 189 // buffered timespan of |range|. 190 bool CompletelyOverlaps(const SourceBufferRange& range) const; 191 192 // Returns true if the end of this range contains buffers that overlaps with 193 // the beginning of |range|. 194 bool EndOverlaps(const SourceBufferRange& range) const; 195 196 // Returns true if |timestamp| is the timestamp of the next buffer in 197 // sequence after |buffers_.back()|, false otherwise. 198 bool IsNextInSequence(base::TimeDelta timestamp, bool is_keyframe) const; 199 200 // Adds all buffers which overlap [start, end) to the end of |buffers|. If 201 // no buffers exist in the range returns false, true otherwise. 202 bool GetBuffersInRange(base::TimeDelta start, base::TimeDelta end, 203 BufferQueue* buffers); 204 205 int size_in_bytes() const { return size_in_bytes_; } 206 207 private: 208 typedef std::map<base::TimeDelta, int> KeyframeMap; 209 210 // Seeks the range to the next keyframe after |timestamp|. If 211 // |skip_given_timestamp| is true, the seek will go to a keyframe with a 212 // timestamp strictly greater than |timestamp|. 213 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); 214 215 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|. 216 // If |skip_given_timestamp| is true, this returns the first buffer with 217 // timestamp greater than |timestamp|. 218 BufferQueue::iterator GetBufferItrAt( 219 base::TimeDelta timestamp, bool skip_given_timestamp); 220 221 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after 222 // |timestamp|. If |skip_given_timestamp| is true, this returns the first 223 // keyframe with a timestamp strictly greater than |timestamp|. 224 KeyframeMap::iterator GetFirstKeyframeAt( 225 base::TimeDelta timestamp, bool skip_given_timestamp); 226 227 // Returns an iterator in |keyframe_map_| pointing to the first keyframe 228 // before or at |timestamp|. 229 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); 230 231 // Helper method to delete buffers in |buffers_| starting at 232 // |starting_point|, an iterator in |buffers_|. 233 // Returns true if everything in the range was removed. Returns 234 // false if the range still contains buffers. 235 bool TruncateAt(const BufferQueue::iterator& starting_point, 236 BufferQueue* deleted_buffers); 237 238 // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and 239 // updates the |size_in_bytes_| accordingly. Does not update |keyframe_map_|. 240 void FreeBufferRange(const BufferQueue::iterator& starting_point, 241 const BufferQueue::iterator& ending_point); 242 243 // Returns the distance in time estimating how far from the beginning or end 244 // of this range a buffer can be to considered in the range. 245 base::TimeDelta GetFudgeRoom() const; 246 247 // Returns the approximate duration of a buffer in this range. 248 base::TimeDelta GetApproximateDuration() const; 249 250 // Type of this stream. 251 const SourceBufferStream::Type type_; 252 253 // An ordered list of buffers in this range. 254 BufferQueue buffers_; 255 256 // Maps keyframe timestamps to its index position in |buffers_|. 257 KeyframeMap keyframe_map_; 258 259 // Index base of all positions in |keyframe_map_|. In other words, the 260 // real position of entry |k| of |keyframe_map_| in the range is: 261 // keyframe_map_[k] - keyframe_map_index_base_ 262 int keyframe_map_index_base_; 263 264 // Index into |buffers_| for the next buffer to be returned by 265 // GetNextBuffer(), set to -1 before Seek(). 266 int next_buffer_index_; 267 268 // If the first buffer in this range is the beginning of a media segment, 269 // |media_segment_start_time_| is the time when the media segment begins. 270 // |media_segment_start_time_| may be <= the timestamp of the first buffer in 271 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range 272 // does not start at the beginning of a media segment, which can only happen 273 // garbage collection or after an end overlap that results in a split range 274 // (we don't have a way of knowing the media segment timestamp for the new 275 // range). 276 base::TimeDelta media_segment_start_time_; 277 278 // Called to get the largest interbuffer distance seen so far in the stream. 279 InterbufferDistanceCB interbuffer_distance_cb_; 280 281 // Stores the amount of memory taken up by the data in |buffers_|. 282 int size_in_bytes_; 283 284 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); 285}; 286 287} // namespace media 288 289// Helper method that returns true if |ranges| is sorted in increasing order, 290// false otherwise. 291static bool IsRangeListSorted( 292 const std::list<media::SourceBufferRange*>& ranges) { 293 base::TimeDelta prev = media::kNoTimestamp(); 294 for (std::list<media::SourceBufferRange*>::const_iterator itr = 295 ranges.begin(); itr != ranges.end(); ++itr) { 296 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp()) 297 return false; 298 prev = (*itr)->GetEndTimestamp(); 299 } 300 return true; 301} 302 303// Comparison operators for std::upper_bound() and std::lower_bound(). 304static bool CompareTimeDeltaToStreamParserBuffer( 305 const base::TimeDelta& decode_timestamp, 306 const scoped_refptr<media::StreamParserBuffer>& buffer) { 307 return decode_timestamp < buffer->GetDecodeTimestamp(); 308} 309static bool CompareStreamParserBufferToTimeDelta( 310 const scoped_refptr<media::StreamParserBuffer>& buffer, 311 const base::TimeDelta& decode_timestamp) { 312 return buffer->GetDecodeTimestamp() < decode_timestamp; 313} 314 315// Returns an estimate of how far from the beginning or end of a range a buffer 316// can be to still be considered in the range, given the |approximate_duration| 317// of a buffer in the stream. 318static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { 319 // Because we do not know exactly when is the next timestamp, any buffer 320 // that starts within 2x the approximate duration of a buffer is considered 321 // within this range. 322 return 2 * approximate_duration; 323} 324 325// An arbitrarily-chosen number to estimate the duration of a buffer if none 326// is set and there's not enough information to get a better estimate. 327static int kDefaultBufferDurationInMs = 125; 328 329// The amount of time the beginning of the buffered data can differ from the 330// start time in order to still be considered the start of stream. 331static base::TimeDelta kSeekToStartFudgeRoom() { 332 return base::TimeDelta::FromMilliseconds(1000); 333} 334// The maximum amount of data in bytes the stream will keep in memory. 335// 12MB: approximately 5 minutes of 320Kbps content. 336// 150MB: approximately 5 minutes of 4Mbps content. 337static int kDefaultAudioMemoryLimit = 12 * 1024 * 1024; 338static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024; 339 340namespace media { 341 342SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 343 const LogCB& log_cb, 344 bool splice_frames_enabled) 345 : log_cb_(log_cb), 346 current_config_index_(0), 347 append_config_index_(0), 348 seek_pending_(false), 349 end_of_stream_(false), 350 seek_buffer_timestamp_(kNoTimestamp()), 351 selected_range_(NULL), 352 media_segment_start_time_(kNoTimestamp()), 353 range_for_next_append_(ranges_.end()), 354 new_media_segment_(false), 355 last_appended_buffer_timestamp_(kNoTimestamp()), 356 last_appended_buffer_is_keyframe_(false), 357 last_output_buffer_timestamp_(kNoTimestamp()), 358 max_interbuffer_distance_(kNoTimestamp()), 359 memory_limit_(kDefaultAudioMemoryLimit), 360 config_change_pending_(false), 361 splice_buffers_index_(0), 362 splice_frames_enabled_(splice_frames_enabled) { 363 DCHECK(audio_config.IsValidConfig()); 364 audio_configs_.push_back(audio_config); 365} 366 367SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 368 const LogCB& log_cb, 369 bool splice_frames_enabled) 370 : log_cb_(log_cb), 371 current_config_index_(0), 372 append_config_index_(0), 373 seek_pending_(false), 374 end_of_stream_(false), 375 seek_buffer_timestamp_(kNoTimestamp()), 376 selected_range_(NULL), 377 media_segment_start_time_(kNoTimestamp()), 378 range_for_next_append_(ranges_.end()), 379 new_media_segment_(false), 380 last_appended_buffer_timestamp_(kNoTimestamp()), 381 last_appended_buffer_is_keyframe_(false), 382 last_output_buffer_timestamp_(kNoTimestamp()), 383 max_interbuffer_distance_(kNoTimestamp()), 384 memory_limit_(kDefaultVideoMemoryLimit), 385 config_change_pending_(false), 386 splice_buffers_index_(0), 387 splice_frames_enabled_(splice_frames_enabled) { 388 DCHECK(video_config.IsValidConfig()); 389 video_configs_.push_back(video_config); 390} 391 392SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 393 const LogCB& log_cb, 394 bool splice_frames_enabled) 395 : log_cb_(log_cb), 396 current_config_index_(0), 397 append_config_index_(0), 398 text_track_config_(text_config), 399 seek_pending_(false), 400 end_of_stream_(false), 401 seek_buffer_timestamp_(kNoTimestamp()), 402 selected_range_(NULL), 403 media_segment_start_time_(kNoTimestamp()), 404 range_for_next_append_(ranges_.end()), 405 new_media_segment_(false), 406 last_appended_buffer_timestamp_(kNoTimestamp()), 407 last_appended_buffer_is_keyframe_(false), 408 last_output_buffer_timestamp_(kNoTimestamp()), 409 max_interbuffer_distance_(kNoTimestamp()), 410 memory_limit_(kDefaultAudioMemoryLimit), 411 config_change_pending_(false), 412 splice_buffers_index_(0), 413 splice_frames_enabled_(splice_frames_enabled) {} 414 415SourceBufferStream::~SourceBufferStream() { 416 while (!ranges_.empty()) { 417 delete ranges_.front(); 418 ranges_.pop_front(); 419 } 420} 421 422void SourceBufferStream::OnNewMediaSegment( 423 base::TimeDelta media_segment_start_time) { 424 DCHECK(!end_of_stream_); 425 media_segment_start_time_ = media_segment_start_time; 426 new_media_segment_ = true; 427 428 RangeList::iterator last_range = range_for_next_append_; 429 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); 430 431 // Only reset |last_appended_buffer_timestamp_| if this new media segment is 432 // not adjacent to the previous media segment appended to the stream. 433 if (range_for_next_append_ == ranges_.end() || 434 !AreAdjacentInSequence(last_appended_buffer_timestamp_, 435 media_segment_start_time)) { 436 last_appended_buffer_timestamp_ = kNoTimestamp(); 437 last_appended_buffer_is_keyframe_ = false; 438 } else if (last_range != ranges_.end()) { 439 DCHECK(last_range == range_for_next_append_); 440 } 441} 442 443bool SourceBufferStream::Append(const BufferQueue& buffers) { 444 TRACE_EVENT2("media", "SourceBufferStream::Append", 445 "stream type", GetStreamTypeName(), 446 "buffers to append", buffers.size()); 447 448 DCHECK(!buffers.empty()); 449 DCHECK(media_segment_start_time_ != kNoTimestamp()); 450 DCHECK(!end_of_stream_); 451 452 // New media segments must begin with a keyframe. 453 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { 454 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe."; 455 return false; 456 } 457 458 // Buffers within a media segment should be monotonically increasing. 459 if (!IsMonotonicallyIncreasing(buffers)) 460 return false; 461 462 if (media_segment_start_time_ < base::TimeDelta() || 463 buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { 464 MEDIA_LOG(log_cb_) 465 << "Cannot append a media segment with negative timestamps."; 466 return false; 467 } 468 469 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), 470 buffers.front()->IsKeyframe())) { 471 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time " 472 << buffers.front()->GetDecodeTimestamp().InSecondsF(); 473 474 return false; 475 } 476 477 UpdateMaxInterbufferDistance(buffers); 478 SetConfigIds(buffers); 479 480 // Save a snapshot of stream state before range modifications are made. 481 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); 482 BufferQueue deleted_buffers; 483 484 PrepareRangesForNextAppend(buffers, &deleted_buffers); 485 486 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 487 // create a new range with |buffers|. 488 if (range_for_next_append_ != ranges_.end()) { 489 (*range_for_next_append_)->AppendBuffersToEnd(buffers); 490 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 491 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); 492 } else { 493 base::TimeDelta new_range_start_time = media_segment_start_time_; 494 const BufferQueue* buffers_for_new_range = &buffers; 495 BufferQueue trimmed_buffers; 496 497 // If the new range is not being created because of a new media 498 // segment, then we must make sure that we start with a keyframe. 499 // This can happen if the GOP in the previous append gets destroyed 500 // by a Remove() call. 501 if (!new_media_segment_ && !buffers.front()->IsKeyframe()) { 502 BufferQueue::const_iterator itr = buffers.begin(); 503 504 // Scan past all the non-keyframes. 505 while (itr != buffers.end() && !(*itr)->IsKeyframe()) { 506 ++itr; 507 } 508 509 // If we didn't find a keyframe, then update the last appended 510 // buffer state and return. 511 if (itr == buffers.end()) { 512 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 513 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); 514 return true; 515 } 516 517 // Copy the first keyframe and everything after it into |trimmed_buffers|. 518 trimmed_buffers.assign(itr, buffers.end()); 519 520 new_range_start_time = trimmed_buffers.front()->GetDecodeTimestamp(); 521 buffers_for_new_range = &trimmed_buffers; 522 } 523 524 range_for_next_append_ = 525 AddToRanges(new SourceBufferRange( 526 GetType(), *buffers_for_new_range, new_range_start_time, 527 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, 528 base::Unretained(this)))); 529 last_appended_buffer_timestamp_ = 530 buffers_for_new_range->back()->GetDecodeTimestamp(); 531 last_appended_buffer_is_keyframe_ = 532 buffers_for_new_range->back()->IsKeyframe(); 533 } 534 535 new_media_segment_ = false; 536 537 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 538 539 // Seek to try to fulfill a previous call to Seek(). 540 if (seek_pending_) { 541 DCHECK(!selected_range_); 542 DCHECK(deleted_buffers.empty()); 543 Seek(seek_buffer_timestamp_); 544 } 545 546 if (!deleted_buffers.empty()) { 547 base::TimeDelta start_of_deleted = 548 deleted_buffers.front()->GetDecodeTimestamp(); 549 550 DCHECK(track_buffer_.empty() || 551 track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted) 552 << "decode timestamp " 553 << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec" 554 << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec"; 555 556 track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(), 557 deleted_buffers.end()); 558 } 559 560 // Prune any extra buffers in |track_buffer_| if new keyframes 561 // are appended to the range covered by |track_buffer_|. 562 if (!track_buffer_.empty()) { 563 base::TimeDelta keyframe_timestamp = 564 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); 565 if (keyframe_timestamp != kNoTimestamp()) 566 PruneTrackBuffer(keyframe_timestamp); 567 } 568 569 SetSelectedRangeIfNeeded(next_buffer_timestamp); 570 571 GarbageCollectIfNeeded(); 572 573 DCHECK(IsRangeListSorted(ranges_)); 574 DCHECK(OnlySelectedRangeIsSeeked()); 575 return true; 576} 577 578void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, 579 base::TimeDelta duration) { 580 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() 581 << ", " << end.InSecondsF() 582 << ", " << duration.InSecondsF() << ")"; 583 DCHECK(start >= base::TimeDelta()) << start.InSecondsF(); 584 DCHECK(start < end) << "start " << start.InSecondsF() 585 << " end " << end.InSecondsF(); 586 DCHECK(duration != kNoTimestamp()); 587 588 base::TimeDelta remove_end_timestamp = duration; 589 base::TimeDelta keyframe_timestamp = FindKeyframeAfterTimestamp(end); 590 if (keyframe_timestamp != kNoTimestamp()) { 591 remove_end_timestamp = keyframe_timestamp; 592 } else if (end < remove_end_timestamp) { 593 remove_end_timestamp = end; 594 } 595 596 BufferQueue deleted_buffers; 597 RemoveInternal(start, remove_end_timestamp, false, &deleted_buffers); 598 599 if (!deleted_buffers.empty()) 600 SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp()); 601} 602 603void SourceBufferStream::RemoveInternal( 604 base::TimeDelta start, base::TimeDelta end, bool is_exclusive, 605 BufferQueue* deleted_buffers) { 606 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() 607 << ", " << end.InSecondsF() 608 << ", " << is_exclusive << ")"; 609 610 DCHECK(start >= base::TimeDelta()); 611 DCHECK(start < end) << "start " << start.InSecondsF() 612 << " end " << end.InSecondsF(); 613 DCHECK(deleted_buffers); 614 615 RangeList::iterator itr = ranges_.begin(); 616 617 while (itr != ranges_.end()) { 618 SourceBufferRange* range = *itr; 619 if (range->GetStartTimestamp() >= end) 620 break; 621 622 // Split off any remaining end piece and add it to |ranges_|. 623 SourceBufferRange* new_range = range->SplitRange(end, is_exclusive); 624 if (new_range) { 625 itr = ranges_.insert(++itr, new_range); 626 --itr; 627 628 // Update the selected range if the next buffer position was transferred 629 // to |new_range|. 630 if (new_range->HasNextBufferPosition()) 631 SetSelectedRange(new_range); 632 } 633 634 // Truncate the current range so that it only contains data before 635 // the removal range. 636 BufferQueue saved_buffers; 637 bool delete_range = range->TruncateAt(start, &saved_buffers, is_exclusive); 638 639 // Check to see if the current playback position was removed and 640 // update the selected range appropriately. 641 if (!saved_buffers.empty()) { 642 DCHECK(!range->HasNextBufferPosition()); 643 DCHECK(deleted_buffers->empty()); 644 645 *deleted_buffers = saved_buffers; 646 } 647 648 if (range == selected_range_ && !range->HasNextBufferPosition()) 649 SetSelectedRange(NULL); 650 651 // If the current range now is completely covered by the removal 652 // range then delete it and move on. 653 if (delete_range) { 654 DeleteAndRemoveRange(&itr); 655 continue; 656 } 657 658 // Clear |range_for_next_append_| if we determine that the removal 659 // operation makes it impossible for the next append to be added 660 // to the current range. 661 if (range_for_next_append_ != ranges_.end() && 662 *range_for_next_append_ == range && 663 last_appended_buffer_timestamp_ != kNoTimestamp()) { 664 base::TimeDelta potential_next_append_timestamp = 665 last_appended_buffer_timestamp_ + 666 base::TimeDelta::FromInternalValue(1); 667 668 if (!range->BelongsToRange(potential_next_append_timestamp)) { 669 DVLOG(1) << "Resetting range_for_next_append_ since the next append" 670 << " can't add to the current range."; 671 range_for_next_append_ = 672 FindExistingRangeFor(potential_next_append_timestamp); 673 } 674 } 675 676 // Move on to the next range. 677 ++itr; 678 } 679 680 DCHECK(IsRangeListSorted(ranges_)); 681 DCHECK(OnlySelectedRangeIsSeeked()); 682 DVLOG(1) << __FUNCTION__ << " : done"; 683} 684 685void SourceBufferStream::ResetSeekState() { 686 SetSelectedRange(NULL); 687 track_buffer_.clear(); 688 config_change_pending_ = false; 689 last_output_buffer_timestamp_ = kNoTimestamp(); 690 splice_buffers_index_ = 0; 691 splice_buffer_ = NULL; 692} 693 694bool SourceBufferStream::ShouldSeekToStartOfBuffered( 695 base::TimeDelta seek_timestamp) const { 696 if (ranges_.empty()) 697 return false; 698 base::TimeDelta beginning_of_buffered = 699 ranges_.front()->GetStartTimestamp(); 700 return (seek_timestamp <= beginning_of_buffered && 701 beginning_of_buffered < kSeekToStartFudgeRoom()); 702} 703 704bool SourceBufferStream::IsMonotonicallyIncreasing( 705 const BufferQueue& buffers) const { 706 DCHECK(!buffers.empty()); 707 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; 708 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 709 for (BufferQueue::const_iterator itr = buffers.begin(); 710 itr != buffers.end(); ++itr) { 711 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); 712 bool current_is_keyframe = (*itr)->IsKeyframe(); 713 DCHECK(current_timestamp != kNoTimestamp()); 714 715 if (prev_timestamp != kNoTimestamp()) { 716 if (current_timestamp < prev_timestamp) { 717 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; 718 return false; 719 } 720 721 if (current_timestamp == prev_timestamp && 722 !AllowSameTimestamp(prev_is_keyframe, current_is_keyframe, 723 GetType())) { 724 MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the" 725 << " same timestamp detected at " 726 << current_timestamp.InSecondsF(); 727 return false; 728 } 729 } 730 731 prev_timestamp = current_timestamp; 732 prev_is_keyframe = current_is_keyframe; 733 } 734 return true; 735} 736 737bool SourceBufferStream::IsNextTimestampValid( 738 base::TimeDelta next_timestamp, bool next_is_keyframe) const { 739 return (last_appended_buffer_timestamp_ != next_timestamp) || 740 new_media_segment_ || 741 AllowSameTimestamp(last_appended_buffer_is_keyframe_, next_is_keyframe, 742 GetType()); 743} 744 745 746bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { 747 for (RangeList::const_iterator itr = ranges_.begin(); 748 itr != ranges_.end(); ++itr) { 749 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) 750 return false; 751 } 752 return !selected_range_ || selected_range_->HasNextBufferPosition(); 753} 754 755void SourceBufferStream::UpdateMaxInterbufferDistance( 756 const BufferQueue& buffers) { 757 DCHECK(!buffers.empty()); 758 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; 759 for (BufferQueue::const_iterator itr = buffers.begin(); 760 itr != buffers.end(); ++itr) { 761 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); 762 DCHECK(current_timestamp != kNoTimestamp()); 763 764 if (prev_timestamp != kNoTimestamp()) { 765 base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp; 766 if (max_interbuffer_distance_ == kNoTimestamp()) { 767 max_interbuffer_distance_ = interbuffer_distance; 768 } else { 769 max_interbuffer_distance_ = 770 std::max(max_interbuffer_distance_, interbuffer_distance); 771 } 772 } 773 prev_timestamp = current_timestamp; 774 } 775} 776 777void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { 778 for (BufferQueue::const_iterator itr = buffers.begin(); 779 itr != buffers.end(); ++itr) { 780 (*itr)->SetConfigId(append_config_index_); 781 } 782} 783 784void SourceBufferStream::GarbageCollectIfNeeded() { 785 // Compute size of |ranges_|. 786 int ranges_size = 0; 787 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) 788 ranges_size += (*itr)->size_in_bytes(); 789 790 // Return if we're under or at the memory limit. 791 if (ranges_size <= memory_limit_) 792 return; 793 794 int bytes_to_free = ranges_size - memory_limit_; 795 796 // Begin deleting after the last appended buffer. 797 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); 798 799 // Begin deleting from the front. 800 if (bytes_to_free - bytes_freed > 0) 801 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); 802 803 // Begin deleting from the back. 804 if (bytes_to_free - bytes_freed > 0) 805 FreeBuffers(bytes_to_free - bytes_freed, true); 806} 807 808int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) { 809 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); 810 if (last_appended_buffer_timestamp_ == kNoTimestamp() || 811 next_buffer_timestamp == kNoTimestamp() || 812 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { 813 return 0; 814 } 815 816 base::TimeDelta remove_range_start = last_appended_buffer_timestamp_; 817 if (last_appended_buffer_is_keyframe_) 818 remove_range_start += GetMaxInterbufferDistance(); 819 820 base::TimeDelta remove_range_start_keyframe = FindKeyframeAfterTimestamp( 821 remove_range_start); 822 if (remove_range_start_keyframe != kNoTimestamp()) 823 remove_range_start = remove_range_start_keyframe; 824 if (remove_range_start >= next_buffer_timestamp) 825 return 0; 826 827 base::TimeDelta remove_range_end; 828 int bytes_freed = GetRemovalRange( 829 remove_range_start, next_buffer_timestamp, total_bytes_to_free, 830 &remove_range_end); 831 if (bytes_freed > 0) 832 Remove(remove_range_start, remove_range_end, next_buffer_timestamp); 833 return bytes_freed; 834} 835 836int SourceBufferStream::GetRemovalRange( 837 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, 838 int total_bytes_to_free, base::TimeDelta* removal_end_timestamp) { 839 DCHECK(start_timestamp >= base::TimeDelta()) << start_timestamp.InSecondsF(); 840 DCHECK(start_timestamp < end_timestamp) 841 << "start " << start_timestamp.InSecondsF() 842 << ", end " << end_timestamp.InSecondsF(); 843 844 int bytes_to_free = total_bytes_to_free; 845 int bytes_freed = 0; 846 847 for (RangeList::iterator itr = ranges_.begin(); 848 itr != ranges_.end() && bytes_to_free > 0; ++itr) { 849 SourceBufferRange* range = *itr; 850 if (range->GetStartTimestamp() >= end_timestamp) 851 break; 852 if (range->GetEndTimestamp() < start_timestamp) 853 continue; 854 855 int bytes_removed = range->GetRemovalGOP( 856 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); 857 bytes_to_free -= bytes_removed; 858 bytes_freed += bytes_removed; 859 } 860 return bytes_freed; 861} 862 863int SourceBufferStream::FreeBuffers(int total_bytes_to_free, 864 bool reverse_direction) { 865 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", 866 "total bytes to free", total_bytes_to_free, 867 "reverse direction", reverse_direction); 868 869 DCHECK_GT(total_bytes_to_free, 0); 870 int bytes_to_free = total_bytes_to_free; 871 int bytes_freed = 0; 872 873 // This range will save the last GOP appended to |range_for_next_append_| 874 // if the buffers surrounding it get deleted during garbage collection. 875 SourceBufferRange* new_range_for_append = NULL; 876 877 while (!ranges_.empty() && bytes_to_free > 0) { 878 SourceBufferRange* current_range = NULL; 879 BufferQueue buffers; 880 int bytes_deleted = 0; 881 882 if (reverse_direction) { 883 current_range = ranges_.back(); 884 if (current_range->LastGOPContainsNextBufferPosition()) { 885 DCHECK_EQ(current_range, selected_range_); 886 break; 887 } 888 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); 889 } else { 890 current_range = ranges_.front(); 891 if (current_range->FirstGOPContainsNextBufferPosition()) { 892 DCHECK_EQ(current_range, selected_range_); 893 break; 894 } 895 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); 896 } 897 898 // Check to see if we've just deleted the GOP that was last appended. 899 base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp(); 900 if (end_timestamp == last_appended_buffer_timestamp_) { 901 DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp()); 902 DCHECK(!new_range_for_append); 903 // Create a new range containing these buffers. 904 new_range_for_append = new SourceBufferRange( 905 GetType(), buffers, kNoTimestamp(), 906 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, 907 base::Unretained(this))); 908 range_for_next_append_ = ranges_.end(); 909 } else { 910 bytes_to_free -= bytes_deleted; 911 bytes_freed += bytes_deleted; 912 } 913 914 if (current_range->size_in_bytes() == 0) { 915 DCHECK_NE(current_range, selected_range_); 916 DCHECK(range_for_next_append_ == ranges_.end() || 917 *range_for_next_append_ != current_range); 918 delete current_range; 919 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); 920 } 921 } 922 923 // Insert |new_range_for_append| into |ranges_|, if applicable. 924 if (new_range_for_append) { 925 range_for_next_append_ = AddToRanges(new_range_for_append); 926 DCHECK(range_for_next_append_ != ranges_.end()); 927 928 // Check to see if we need to merge |new_range_for_append| with the range 929 // before or after it. |new_range_for_append| is created whenever the last 930 // GOP appended is encountered, regardless of whether any buffers after it 931 // are ultimately deleted. Merging is necessary if there were no buffers 932 // (or very few buffers) deleted after creating |new_range_for_append|. 933 if (range_for_next_append_ != ranges_.begin()) { 934 RangeList::iterator range_before_next = range_for_next_append_; 935 --range_before_next; 936 MergeWithAdjacentRangeIfNecessary(range_before_next); 937 } 938 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 939 } 940 return bytes_freed; 941} 942 943void SourceBufferStream::PrepareRangesForNextAppend( 944 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 945 DCHECK(deleted_buffers); 946 947 bool temporarily_select_range = false; 948 if (!track_buffer_.empty()) { 949 base::TimeDelta tb_timestamp = track_buffer_.back()->GetDecodeTimestamp(); 950 base::TimeDelta seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp); 951 if (seek_timestamp != kNoTimestamp() && 952 seek_timestamp < new_buffers.front()->GetDecodeTimestamp() && 953 range_for_next_append_ != ranges_.end() && 954 (*range_for_next_append_)->BelongsToRange(seek_timestamp)) { 955 DCHECK(tb_timestamp < seek_timestamp); 956 DCHECK(!selected_range_); 957 DCHECK(!(*range_for_next_append_)->HasNextBufferPosition()); 958 959 // If there are GOPs between the end of the track buffer and the 960 // beginning of the new buffers, then temporarily seek the range 961 // so that the buffers between these two times will be deposited in 962 // |deleted_buffers| as if they were part of the current playback 963 // position. 964 // TODO(acolwell): Figure out a more elegant way to do this. 965 SeekAndSetSelectedRange(*range_for_next_append_, seek_timestamp); 966 temporarily_select_range = true; 967 } 968 } 969 970 // Handle splices between the existing buffers and the new buffers. If a 971 // splice is generated the timestamp and duration of the first buffer in 972 // |new_buffers| will be modified. 973 if (splice_frames_enabled_) 974 GenerateSpliceFrame(new_buffers); 975 976 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; 977 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 978 base::TimeDelta next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 979 bool next_is_keyframe = new_buffers.front()->IsKeyframe(); 980 981 if (prev_timestamp != kNoTimestamp() && prev_timestamp != next_timestamp) { 982 // Clean up the old buffers between the last appended buffer and the 983 // beginning of |new_buffers|. 984 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 985 } 986 987 // Make the delete range exclusive if we are dealing with an allowed same 988 // timestamp situation. This prevents the first buffer in the current append 989 // from deleting the last buffer in the previous append if both buffers 990 // have the same timestamp. 991 bool is_exclusive = (prev_timestamp == next_timestamp) && 992 AllowSameTimestamp(prev_is_keyframe, next_is_keyframe, GetType()); 993 994 // Delete the buffers that |new_buffers| overlaps. 995 base::TimeDelta start = new_buffers.front()->GetDecodeTimestamp(); 996 base::TimeDelta end = new_buffers.back()->GetDecodeTimestamp(); 997 base::TimeDelta duration = new_buffers.back()->duration(); 998 999 if (duration != kNoTimestamp() && duration > base::TimeDelta()) { 1000 end += duration; 1001 } else { 1002 // TODO(acolwell): Ensure all buffers actually have proper 1003 // duration info so that this hack isn't needed. 1004 // http://crbug.com/312836 1005 end += base::TimeDelta::FromInternalValue(1); 1006 } 1007 1008 RemoveInternal(start, end, is_exclusive, deleted_buffers); 1009 1010 // Restore the range seek state if necessary. 1011 if (temporarily_select_range) 1012 SetSelectedRange(NULL); 1013} 1014 1015bool SourceBufferStream::AreAdjacentInSequence( 1016 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const { 1017 return first_timestamp < second_timestamp && 1018 second_timestamp <= 1019 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1020} 1021 1022void SourceBufferStream::PruneTrackBuffer(const base::TimeDelta timestamp) { 1023 // If we don't have the next timestamp, we don't have anything to delete. 1024 if (timestamp == kNoTimestamp()) 1025 return; 1026 1027 while (!track_buffer_.empty() && 1028 track_buffer_.back()->GetDecodeTimestamp() >= timestamp) { 1029 track_buffer_.pop_back(); 1030 } 1031} 1032 1033void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( 1034 const RangeList::iterator& range_with_new_buffers_itr) { 1035 DCHECK(range_with_new_buffers_itr != ranges_.end()); 1036 1037 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 1038 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 1039 ++next_range_itr; 1040 1041 if (next_range_itr == ranges_.end() || 1042 !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) { 1043 return; 1044 } 1045 1046 bool transfer_current_position = selected_range_ == *next_range_itr; 1047 range_with_new_buffers->AppendRangeToEnd(**next_range_itr, 1048 transfer_current_position); 1049 // Update |selected_range_| pointer if |range| has become selected after 1050 // merges. 1051 if (transfer_current_position) 1052 SetSelectedRange(range_with_new_buffers); 1053 1054 if (next_range_itr == range_for_next_append_) 1055 range_for_next_append_ = range_with_new_buffers_itr; 1056 1057 DeleteAndRemoveRange(&next_range_itr); 1058} 1059 1060void SourceBufferStream::Seek(base::TimeDelta timestamp) { 1061 DCHECK(timestamp >= base::TimeDelta()); 1062 ResetSeekState(); 1063 1064 if (ShouldSeekToStartOfBuffered(timestamp)) { 1065 ranges_.front()->SeekToStart(); 1066 SetSelectedRange(ranges_.front()); 1067 seek_pending_ = false; 1068 return; 1069 } 1070 1071 seek_buffer_timestamp_ = timestamp; 1072 seek_pending_ = true; 1073 1074 RangeList::iterator itr = ranges_.end(); 1075 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1076 if ((*itr)->CanSeekTo(timestamp)) 1077 break; 1078 } 1079 1080 if (itr == ranges_.end()) 1081 return; 1082 1083 SeekAndSetSelectedRange(*itr, timestamp); 1084 seek_pending_ = false; 1085} 1086 1087bool SourceBufferStream::IsSeekPending() const { 1088 return !(end_of_stream_ && IsEndSelected()) && seek_pending_; 1089} 1090 1091void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { 1092 RangeList::iterator itr = ranges_.end(); 1093 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1094 if ((*itr)->GetEndTimestamp() > duration) 1095 break; 1096 } 1097 if (itr == ranges_.end()) 1098 return; 1099 1100 // Need to partially truncate this range. 1101 if ((*itr)->GetStartTimestamp() < duration) { 1102 bool delete_range = (*itr)->TruncateAt(duration, NULL, false); 1103 if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition()) 1104 SetSelectedRange(NULL); 1105 1106 if (delete_range) { 1107 DeleteAndRemoveRange(&itr); 1108 } else { 1109 ++itr; 1110 } 1111 } 1112 1113 // Delete all ranges that begin after |duration|. 1114 while (itr != ranges_.end()) { 1115 // If we're about to delete the selected range, also reset the seek state. 1116 DCHECK((*itr)->GetStartTimestamp() >= duration); 1117 if (*itr == selected_range_) 1118 ResetSeekState(); 1119 DeleteAndRemoveRange(&itr); 1120 } 1121} 1122 1123SourceBufferStream::Status SourceBufferStream::GetNextBuffer( 1124 scoped_refptr<StreamParserBuffer>* out_buffer) { 1125 if (!splice_buffer_) { 1126 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); 1127 1128 // Just return if GetNextBufferInternal() failed or there's no fade out 1129 // preroll, there's nothing else to do. 1130 if (status != SourceBufferStream::kSuccess || 1131 (*out_buffer)->get_splice_buffers().empty()) { 1132 return status; 1133 } 1134 1135 // Fall through into splice buffer processing. 1136 splice_buffers_index_ = 0; 1137 splice_buffer_.swap(*out_buffer); 1138 } 1139 1140 DCHECK(splice_buffer_); 1141 const BufferQueue& splice_buffers = splice_buffer_->get_splice_buffers(); 1142 const size_t last_splice_buffer_index = splice_buffers.size() - 1; 1143 1144 // Are there any splice buffers left to hand out? The last buffer should be 1145 // handed out separately since it represents the first post-splice buffer. 1146 if (splice_buffers_index_ < last_splice_buffer_index) { 1147 // Account for config changes which occur between fade out buffers. 1148 if (current_config_index_ != 1149 splice_buffers[splice_buffers_index_]->GetConfigId()) { 1150 config_change_pending_ = true; 1151 DVLOG(1) << "Config change (splice buffer config ID does not match)."; 1152 return SourceBufferStream::kConfigChange; 1153 } 1154 1155 // Every pre splice buffer must have the same splice_timestamp(). 1156 DCHECK(splice_buffer_->splice_timestamp() == 1157 splice_buffers[splice_buffers_index_]->splice_timestamp()); 1158 1159 *out_buffer = splice_buffers[splice_buffers_index_++]; 1160 return SourceBufferStream::kSuccess; 1161 } 1162 1163 // Did we hand out the last pre-splice buffer on the previous call? 1164 if (splice_buffers_index_ == last_splice_buffer_index) { 1165 splice_buffers_index_++; 1166 config_change_pending_ = true; 1167 DVLOG(1) << "Config change (forced for fade in of splice frame)."; 1168 return SourceBufferStream::kConfigChange; 1169 } 1170 1171 // All pre-splice buffers have been handed out and a config change completed, 1172 // so hand out the final buffer for fade in. Because a config change is 1173 // always issued prior to handing out this buffer, any changes in config id 1174 // have been inherently handled. 1175 DCHECK_GE(splice_buffers_index_, splice_buffers.size()); 1176 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp()); 1177 *out_buffer = splice_buffers.back(); 1178 splice_buffer_ = NULL; 1179 splice_buffers_index_ = 0; 1180 return SourceBufferStream::kSuccess; 1181} 1182 1183SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( 1184 scoped_refptr<StreamParserBuffer>* out_buffer) { 1185 CHECK(!config_change_pending_); 1186 1187 if (!track_buffer_.empty()) { 1188 DCHECK(!selected_range_); 1189 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); 1190 1191 // If the next buffer is an audio splice frame, the next effective config id 1192 // comes from the first splice buffer. 1193 if (GetConfigId(next_buffer, 0) != current_config_index_) { 1194 config_change_pending_ = true; 1195 DVLOG(1) << "Config change (track buffer config ID does not match)."; 1196 return kConfigChange; 1197 } 1198 1199 *out_buffer = next_buffer; 1200 track_buffer_.pop_front(); 1201 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1202 1203 // If the track buffer becomes empty, then try to set the selected range 1204 // based on the timestamp of this buffer being returned. 1205 if (track_buffer_.empty()) 1206 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); 1207 1208 return kSuccess; 1209 } 1210 1211 if (!selected_range_ || !selected_range_->HasNextBuffer()) { 1212 if (end_of_stream_ && IsEndSelected()) 1213 return kEndOfStream; 1214 return kNeedBuffer; 1215 } 1216 1217 if (selected_range_->GetNextConfigId() != current_config_index_) { 1218 config_change_pending_ = true; 1219 DVLOG(1) << "Config change (selected range config ID does not match)."; 1220 return kConfigChange; 1221 } 1222 1223 CHECK(selected_range_->GetNextBuffer(out_buffer)); 1224 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1225 return kSuccess; 1226} 1227 1228base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { 1229 if (!track_buffer_.empty()) 1230 return track_buffer_.front()->GetDecodeTimestamp(); 1231 1232 if (!selected_range_) 1233 return kNoTimestamp(); 1234 1235 DCHECK(selected_range_->HasNextBufferPosition()); 1236 return selected_range_->GetNextTimestamp(); 1237} 1238 1239base::TimeDelta SourceBufferStream::GetEndBufferTimestamp() { 1240 if (!selected_range_) 1241 return kNoTimestamp(); 1242 return selected_range_->GetEndTimestamp(); 1243} 1244 1245SourceBufferStream::RangeList::iterator 1246SourceBufferStream::FindExistingRangeFor(base::TimeDelta start_timestamp) { 1247 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1248 if ((*itr)->BelongsToRange(start_timestamp)) 1249 return itr; 1250 } 1251 return ranges_.end(); 1252} 1253 1254SourceBufferStream::RangeList::iterator 1255SourceBufferStream::AddToRanges(SourceBufferRange* new_range) { 1256 base::TimeDelta start_timestamp = new_range->GetStartTimestamp(); 1257 RangeList::iterator itr = ranges_.end(); 1258 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1259 if ((*itr)->GetStartTimestamp() > start_timestamp) 1260 break; 1261 } 1262 return ranges_.insert(itr, new_range); 1263} 1264 1265SourceBufferStream::RangeList::iterator 1266SourceBufferStream::GetSelectedRangeItr() { 1267 DCHECK(selected_range_); 1268 RangeList::iterator itr = ranges_.end(); 1269 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1270 if (*itr == selected_range_) 1271 break; 1272 } 1273 DCHECK(itr != ranges_.end()); 1274 return itr; 1275} 1276 1277void SourceBufferStream::SeekAndSetSelectedRange( 1278 SourceBufferRange* range, base::TimeDelta seek_timestamp) { 1279 if (range) 1280 range->Seek(seek_timestamp); 1281 SetSelectedRange(range); 1282} 1283 1284void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { 1285 DVLOG(1) << __FUNCTION__ << " : " << selected_range_ << " -> " << range; 1286 if (selected_range_) 1287 selected_range_->ResetNextBufferPosition(); 1288 DCHECK(!range || range->HasNextBufferPosition()); 1289 selected_range_ = range; 1290} 1291 1292Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { 1293 Ranges<base::TimeDelta> ranges; 1294 for (RangeList::const_iterator itr = ranges_.begin(); 1295 itr != ranges_.end(); ++itr) { 1296 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp()); 1297 } 1298 return ranges; 1299} 1300 1301base::TimeDelta SourceBufferStream::GetBufferedDuration() const { 1302 if (ranges_.empty()) 1303 return base::TimeDelta(); 1304 1305 return ranges_.back()->GetBufferedEndTimestamp(); 1306} 1307 1308void SourceBufferStream::MarkEndOfStream() { 1309 DCHECK(!end_of_stream_); 1310 end_of_stream_ = true; 1311} 1312 1313void SourceBufferStream::UnmarkEndOfStream() { 1314 DCHECK(end_of_stream_); 1315 end_of_stream_ = false; 1316} 1317 1318bool SourceBufferStream::IsEndSelected() const { 1319 if (ranges_.empty()) 1320 return true; 1321 1322 if (seek_pending_) 1323 return seek_buffer_timestamp_ >= ranges_.back()->GetBufferedEndTimestamp(); 1324 1325 return selected_range_ == ranges_.back(); 1326} 1327 1328const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { 1329 if (config_change_pending_) 1330 CompleteConfigChange(); 1331 return audio_configs_[current_config_index_]; 1332} 1333 1334const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { 1335 if (config_change_pending_) 1336 CompleteConfigChange(); 1337 return video_configs_[current_config_index_]; 1338} 1339 1340const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() { 1341 return text_track_config_; 1342} 1343 1344base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { 1345 if (max_interbuffer_distance_ == kNoTimestamp()) 1346 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); 1347 return max_interbuffer_distance_; 1348} 1349 1350bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 1351 DCHECK(!audio_configs_.empty()); 1352 DCHECK(video_configs_.empty()); 1353 DVLOG(3) << "UpdateAudioConfig."; 1354 1355 if (audio_configs_[0].codec() != config.codec()) { 1356 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; 1357 return false; 1358 } 1359 1360 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { 1361 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; 1362 return false; 1363 } 1364 1365 // Check to see if the new config matches an existing one. 1366 for (size_t i = 0; i < audio_configs_.size(); ++i) { 1367 if (config.Matches(audio_configs_[i])) { 1368 append_config_index_ = i; 1369 return true; 1370 } 1371 } 1372 1373 // No matches found so let's add this one to the list. 1374 append_config_index_ = audio_configs_.size(); 1375 DVLOG(2) << "New audio config - index: " << append_config_index_; 1376 audio_configs_.resize(audio_configs_.size() + 1); 1377 audio_configs_[append_config_index_] = config; 1378 return true; 1379} 1380 1381bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { 1382 DCHECK(!video_configs_.empty()); 1383 DCHECK(audio_configs_.empty()); 1384 DVLOG(3) << "UpdateVideoConfig."; 1385 1386 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { 1387 MEDIA_LOG(log_cb_) << "Video Encryption changes not allowed."; 1388 return false; 1389 } 1390 1391 if (video_configs_[0].codec() != config.codec()) { 1392 MEDIA_LOG(log_cb_) << "Video codec changes not allowed."; 1393 return false; 1394 } 1395 1396 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { 1397 MEDIA_LOG(log_cb_) << "Video encryption changes not allowed."; 1398 return false; 1399 } 1400 1401 // Check to see if the new config matches an existing one. 1402 for (size_t i = 0; i < video_configs_.size(); ++i) { 1403 if (config.Matches(video_configs_[i])) { 1404 append_config_index_ = i; 1405 return true; 1406 } 1407 } 1408 1409 // No matches found so let's add this one to the list. 1410 append_config_index_ = video_configs_.size(); 1411 DVLOG(2) << "New video config - index: " << append_config_index_; 1412 video_configs_.resize(video_configs_.size() + 1); 1413 video_configs_[append_config_index_] = config; 1414 return true; 1415} 1416 1417void SourceBufferStream::CompleteConfigChange() { 1418 config_change_pending_ = false; 1419 1420 if (splice_buffer_) { 1421 current_config_index_ = 1422 GetConfigId(splice_buffer_, splice_buffers_index_); 1423 return; 1424 } 1425 1426 if (!track_buffer_.empty()) { 1427 current_config_index_ = GetConfigId(track_buffer_.front(), 0); 1428 return; 1429 } 1430 1431 if (selected_range_ && selected_range_->HasNextBuffer()) 1432 current_config_index_ = selected_range_->GetNextConfigId(); 1433} 1434 1435void SourceBufferStream::SetSelectedRangeIfNeeded( 1436 const base::TimeDelta timestamp) { 1437 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; 1438 1439 if (selected_range_) { 1440 DCHECK(track_buffer_.empty()); 1441 return; 1442 } 1443 1444 if (!track_buffer_.empty()) { 1445 DCHECK(!selected_range_); 1446 return; 1447 } 1448 1449 base::TimeDelta start_timestamp = timestamp; 1450 1451 // If the next buffer timestamp is not known then use a timestamp just after 1452 // the timestamp on the last buffer returned by GetNextBuffer(). 1453 if (start_timestamp == kNoTimestamp()) { 1454 if (last_output_buffer_timestamp_ == kNoTimestamp()) 1455 return; 1456 1457 start_timestamp = last_output_buffer_timestamp_ + 1458 base::TimeDelta::FromInternalValue(1); 1459 } 1460 1461 base::TimeDelta seek_timestamp = 1462 FindNewSelectedRangeSeekTimestamp(start_timestamp); 1463 1464 // If we don't have buffered data to seek to, then return. 1465 if (seek_timestamp == kNoTimestamp()) 1466 return; 1467 1468 DCHECK(track_buffer_.empty()); 1469 SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp), 1470 seek_timestamp); 1471} 1472 1473base::TimeDelta SourceBufferStream::FindNewSelectedRangeSeekTimestamp( 1474 const base::TimeDelta start_timestamp) { 1475 DCHECK(start_timestamp != kNoTimestamp()); 1476 DCHECK(start_timestamp >= base::TimeDelta()); 1477 1478 RangeList::iterator itr = ranges_.begin(); 1479 1480 for (; itr != ranges_.end(); ++itr) { 1481 if ((*itr)->GetEndTimestamp() >= start_timestamp) { 1482 break; 1483 } 1484 } 1485 1486 if (itr == ranges_.end()) 1487 return kNoTimestamp(); 1488 1489 // First check for a keyframe timestamp >= |start_timestamp| 1490 // in the current range. 1491 base::TimeDelta keyframe_timestamp = 1492 (*itr)->NextKeyframeTimestamp(start_timestamp); 1493 1494 if (keyframe_timestamp != kNoTimestamp()) 1495 return keyframe_timestamp; 1496 1497 // If a keyframe was not found then look for a keyframe that is 1498 // "close enough" in the current or next range. 1499 base::TimeDelta end_timestamp = 1500 start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1501 DCHECK(start_timestamp < end_timestamp); 1502 1503 // Make sure the current range doesn't start beyond |end_timestamp|. 1504 if ((*itr)->GetStartTimestamp() >= end_timestamp) 1505 return kNoTimestamp(); 1506 1507 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp); 1508 1509 // Check to see if the keyframe is within the acceptable range 1510 // (|start_timestamp|, |end_timestamp|]. 1511 if (keyframe_timestamp != kNoTimestamp() && 1512 start_timestamp < keyframe_timestamp && 1513 keyframe_timestamp <= end_timestamp) { 1514 return keyframe_timestamp; 1515 } 1516 1517 // If |end_timestamp| is within this range, then no other checks are 1518 // necessary. 1519 if (end_timestamp <= (*itr)->GetEndTimestamp()) 1520 return kNoTimestamp(); 1521 1522 // Move on to the next range. 1523 ++itr; 1524 1525 // Return early if the next range does not contain |end_timestamp|. 1526 if (itr == ranges_.end() || (*itr)->GetStartTimestamp() >= end_timestamp) 1527 return kNoTimestamp(); 1528 1529 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp); 1530 1531 // Check to see if the keyframe is within the acceptable range 1532 // (|start_timestamp|, |end_timestamp|]. 1533 if (keyframe_timestamp != kNoTimestamp() && 1534 start_timestamp < keyframe_timestamp && 1535 keyframe_timestamp <= end_timestamp) { 1536 return keyframe_timestamp; 1537 } 1538 1539 return kNoTimestamp(); 1540} 1541 1542base::TimeDelta SourceBufferStream::FindKeyframeAfterTimestamp( 1543 const base::TimeDelta timestamp) { 1544 DCHECK(timestamp != kNoTimestamp()); 1545 1546 RangeList::iterator itr = FindExistingRangeFor(timestamp); 1547 1548 if (itr == ranges_.end()) 1549 return kNoTimestamp(); 1550 1551 // First check for a keyframe timestamp >= |timestamp| 1552 // in the current range. 1553 return (*itr)->NextKeyframeTimestamp(timestamp); 1554} 1555 1556std::string SourceBufferStream::GetStreamTypeName() const { 1557 switch (GetType()) { 1558 case kAudio: 1559 return "AUDIO"; 1560 case kVideo: 1561 return "VIDEO"; 1562 case kText: 1563 return "TEXT"; 1564 } 1565 NOTREACHED(); 1566 return ""; 1567} 1568 1569SourceBufferStream::Type SourceBufferStream::GetType() const { 1570 if (!audio_configs_.empty()) 1571 return kAudio; 1572 if (!video_configs_.empty()) 1573 return kVideo; 1574 DCHECK_NE(text_track_config_.kind(), kTextNone); 1575 return kText; 1576} 1577 1578void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) { 1579 DVLOG(1) << __FUNCTION__; 1580 1581 DCHECK(*itr != ranges_.end()); 1582 if (**itr == selected_range_) { 1583 DVLOG(1) << __FUNCTION__ << " deleting selected range."; 1584 SetSelectedRange(NULL); 1585 } 1586 1587 if (*itr == range_for_next_append_) { 1588 DVLOG(1) << __FUNCTION__ << " deleting range_for_next_append_."; 1589 range_for_next_append_ = ranges_.end(); 1590 } 1591 1592 delete **itr; 1593 *itr = ranges_.erase(*itr); 1594} 1595 1596void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { 1597 DCHECK(!new_buffers.empty()); 1598 1599 // Splice frames are only supported for audio. 1600 if (GetType() != kAudio) 1601 return; 1602 1603 // Find the overlapped range (if any). 1604 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp(); 1605 RangeList::iterator range_itr = FindExistingRangeFor(splice_timestamp); 1606 if (range_itr == ranges_.end()) 1607 return; 1608 1609 const base::TimeDelta max_splice_end_timestamp = 1610 splice_timestamp + base::TimeDelta::FromMilliseconds( 1611 AudioSplicer::kCrossfadeDurationInMilliseconds); 1612 1613 // Find all buffers involved before the splice point. 1614 BufferQueue pre_splice_buffers; 1615 if (!(*range_itr)->GetBuffersInRange( 1616 splice_timestamp, max_splice_end_timestamp, &pre_splice_buffers)) { 1617 return; 1618 } 1619 1620 // If there are gaps in the timeline, it's possible that we only find buffers 1621 // after the splice point but within the splice range. For simplicity, we do 1622 // not generate splice frames in this case. 1623 // 1624 // We also do not want to generate splices if the first new buffer replaces an 1625 // existing buffer exactly. 1626 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) 1627 return; 1628 1629 // Sanitize |pre_splice_buffers| so that there are no recursive splices. 1630 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { 1631 const BufferQueue& original_splice_buffers = 1632 pre_splice_buffers[i]->get_splice_buffers(); 1633 if (original_splice_buffers.empty()) 1634 continue; 1635 1636 // Remove the original splice and move our index back to compensate. NOTE: 1637 // |i| will underflow if the splice is the first buffer, this is okay. It 1638 // will be corrected below or on the next loop iteration. 1639 pre_splice_buffers.erase(pre_splice_buffers.begin() + i--); 1640 1641 // Cull all buffers which start after the end of the new splice point or 1642 // after original overlapping buffer; this may introduce gaps, but no more 1643 // than Remove() does currently. 1644 const scoped_refptr<StreamParserBuffer>& overlapping_buffer = 1645 original_splice_buffers.back(); 1646 for (BufferQueue::const_iterator it = original_splice_buffers.begin(); 1647 it != original_splice_buffers.end(); 1648 ++it) { 1649 const scoped_refptr<StreamParserBuffer>& buffer = *it; 1650 if (buffer->timestamp() <= max_splice_end_timestamp && 1651 (buffer->timestamp() < overlapping_buffer->timestamp() || 1652 buffer == overlapping_buffer)) { 1653 // Add the buffer and adjust the index forward to compensate. 1654 pre_splice_buffers.insert(pre_splice_buffers.begin() + ++i, buffer); 1655 } 1656 } 1657 } 1658 1659 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); 1660} 1661 1662SourceBufferRange::SourceBufferRange( 1663 SourceBufferStream::Type type, const BufferQueue& new_buffers, 1664 base::TimeDelta media_segment_start_time, 1665 const InterbufferDistanceCB& interbuffer_distance_cb) 1666 : type_(type), 1667 keyframe_map_index_base_(0), 1668 next_buffer_index_(-1), 1669 media_segment_start_time_(media_segment_start_time), 1670 interbuffer_distance_cb_(interbuffer_distance_cb), 1671 size_in_bytes_(0) { 1672 DCHECK(!new_buffers.empty()); 1673 DCHECK(new_buffers.front()->IsKeyframe()); 1674 DCHECK(!interbuffer_distance_cb.is_null()); 1675 AppendBuffersToEnd(new_buffers); 1676} 1677 1678void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { 1679 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); 1680 for (BufferQueue::const_iterator itr = new_buffers.begin(); 1681 itr != new_buffers.end(); ++itr) { 1682 DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp()); 1683 buffers_.push_back(*itr); 1684 size_in_bytes_ += (*itr)->data_size(); 1685 1686 if ((*itr)->IsKeyframe()) { 1687 keyframe_map_.insert( 1688 std::make_pair((*itr)->GetDecodeTimestamp(), 1689 buffers_.size() - 1 + keyframe_map_index_base_)); 1690 } 1691 } 1692} 1693 1694void SourceBufferRange::Seek(base::TimeDelta timestamp) { 1695 DCHECK(CanSeekTo(timestamp)); 1696 DCHECK(!keyframe_map_.empty()); 1697 1698 KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp); 1699 next_buffer_index_ = result->second - keyframe_map_index_base_; 1700 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 1701} 1702 1703void SourceBufferRange::SeekAheadTo(base::TimeDelta timestamp) { 1704 SeekAhead(timestamp, false); 1705} 1706 1707void SourceBufferRange::SeekAheadPast(base::TimeDelta timestamp) { 1708 SeekAhead(timestamp, true); 1709} 1710 1711void SourceBufferRange::SeekAhead(base::TimeDelta timestamp, 1712 bool skip_given_timestamp) { 1713 DCHECK(!keyframe_map_.empty()); 1714 1715 KeyframeMap::iterator result = 1716 GetFirstKeyframeAt(timestamp, skip_given_timestamp); 1717 1718 // If there isn't a keyframe after |timestamp|, then seek to end and return 1719 // kNoTimestamp to signal such. 1720 if (result == keyframe_map_.end()) { 1721 next_buffer_index_ = -1; 1722 return; 1723 } 1724 next_buffer_index_ = result->second - keyframe_map_index_base_; 1725 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 1726} 1727 1728void SourceBufferRange::SeekToStart() { 1729 DCHECK(!buffers_.empty()); 1730 next_buffer_index_ = 0; 1731} 1732 1733SourceBufferRange* SourceBufferRange::SplitRange( 1734 base::TimeDelta timestamp, bool is_exclusive) { 1735 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not 1736 // include keyframes at |timestamp|. 1737 KeyframeMap::iterator new_beginning_keyframe = 1738 GetFirstKeyframeAt(timestamp, is_exclusive); 1739 1740 // If there is no keyframe after |timestamp|, we can't split the range. 1741 if (new_beginning_keyframe == keyframe_map_.end()) 1742 return NULL; 1743 1744 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 1745 // into |removed_buffers|. 1746 int keyframe_index = 1747 new_beginning_keyframe->second - keyframe_map_index_base_; 1748 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 1749 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 1750 BufferQueue removed_buffers(starting_point, buffers_.end()); 1751 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); 1752 FreeBufferRange(starting_point, buffers_.end()); 1753 1754 // Create a new range with |removed_buffers|. 1755 SourceBufferRange* split_range = 1756 new SourceBufferRange( 1757 type_, removed_buffers, kNoTimestamp(), interbuffer_distance_cb_); 1758 1759 // If the next buffer position is now in |split_range|, update the state of 1760 // this range and |split_range| accordingly. 1761 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 1762 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; 1763 ResetNextBufferPosition(); 1764 } 1765 1766 return split_range; 1767} 1768 1769BufferQueue::iterator SourceBufferRange::GetBufferItrAt( 1770 base::TimeDelta timestamp, 1771 bool skip_given_timestamp) { 1772 return skip_given_timestamp 1773 ? std::upper_bound(buffers_.begin(), 1774 buffers_.end(), 1775 timestamp, 1776 CompareTimeDeltaToStreamParserBuffer) 1777 : std::lower_bound(buffers_.begin(), 1778 buffers_.end(), 1779 timestamp, 1780 CompareStreamParserBufferToTimeDelta); 1781} 1782 1783SourceBufferRange::KeyframeMap::iterator 1784SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, 1785 bool skip_given_timestamp) { 1786 return skip_given_timestamp ? 1787 keyframe_map_.upper_bound(timestamp) : 1788 keyframe_map_.lower_bound(timestamp); 1789} 1790 1791SourceBufferRange::KeyframeMap::iterator 1792SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { 1793 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 1794 // lower_bound() returns the first element >= |timestamp|, so we want the 1795 // previous element if it did not return the element exactly equal to 1796 // |timestamp|. 1797 if (result != keyframe_map_.begin() && 1798 (result == keyframe_map_.end() || result->first != timestamp)) { 1799 --result; 1800 } 1801 return result; 1802} 1803 1804void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 1805 TruncateAt(buffers_.begin(), removed_buffers); 1806} 1807 1808bool SourceBufferRange::TruncateAt( 1809 base::TimeDelta timestamp, BufferQueue* removed_buffers, 1810 bool is_exclusive) { 1811 // Find the place in |buffers_| where we will begin deleting data. 1812 BufferQueue::iterator starting_point = 1813 GetBufferItrAt(timestamp, is_exclusive); 1814 return TruncateAt(starting_point, removed_buffers); 1815} 1816 1817int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) { 1818 DCHECK(!FirstGOPContainsNextBufferPosition()); 1819 DCHECK(deleted_buffers); 1820 1821 int buffers_deleted = 0; 1822 int total_bytes_deleted = 0; 1823 1824 KeyframeMap::iterator front = keyframe_map_.begin(); 1825 DCHECK(front != keyframe_map_.end()); 1826 1827 // Delete the keyframe at the start of |keyframe_map_|. 1828 keyframe_map_.erase(front); 1829 1830 // Now we need to delete all the buffers that depend on the keyframe we've 1831 // just deleted. 1832 int end_index = keyframe_map_.size() > 0 ? 1833 keyframe_map_.begin()->second - keyframe_map_index_base_ : 1834 buffers_.size(); 1835 1836 // Delete buffers from the beginning of the buffered range up until (but not 1837 // including) the next keyframe. 1838 for (int i = 0; i < end_index; i++) { 1839 int bytes_deleted = buffers_.front()->data_size(); 1840 size_in_bytes_ -= bytes_deleted; 1841 total_bytes_deleted += bytes_deleted; 1842 deleted_buffers->push_back(buffers_.front()); 1843 buffers_.pop_front(); 1844 ++buffers_deleted; 1845 } 1846 1847 // Update |keyframe_map_index_base_| to account for the deleted buffers. 1848 keyframe_map_index_base_ += buffers_deleted; 1849 1850 if (next_buffer_index_ > -1) { 1851 next_buffer_index_ -= buffers_deleted; 1852 DCHECK_GE(next_buffer_index_, 0); 1853 } 1854 1855 // Invalidate media segment start time if we've deleted the first buffer of 1856 // the range. 1857 if (buffers_deleted > 0) 1858 media_segment_start_time_ = kNoTimestamp(); 1859 1860 return total_bytes_deleted; 1861} 1862 1863int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { 1864 DCHECK(!LastGOPContainsNextBufferPosition()); 1865 DCHECK(deleted_buffers); 1866 1867 // Remove the last GOP's keyframe from the |keyframe_map_|. 1868 KeyframeMap::iterator back = keyframe_map_.end(); 1869 DCHECK_GT(keyframe_map_.size(), 0u); 1870 --back; 1871 1872 // The index of the first buffer in the last GOP is equal to the new size of 1873 // |buffers_| after that GOP is deleted. 1874 size_t goal_size = back->second - keyframe_map_index_base_; 1875 keyframe_map_.erase(back); 1876 1877 int total_bytes_deleted = 0; 1878 while (buffers_.size() != goal_size) { 1879 int bytes_deleted = buffers_.back()->data_size(); 1880 size_in_bytes_ -= bytes_deleted; 1881 total_bytes_deleted += bytes_deleted; 1882 // We're removing buffers from the back, so push each removed buffer to the 1883 // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing 1884 // order. 1885 deleted_buffers->push_front(buffers_.back()); 1886 buffers_.pop_back(); 1887 } 1888 1889 return total_bytes_deleted; 1890} 1891 1892int SourceBufferRange::GetRemovalGOP( 1893 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, 1894 int total_bytes_to_free, base::TimeDelta* removal_end_timestamp) { 1895 int bytes_to_free = total_bytes_to_free; 1896 int bytes_removed = 0; 1897 1898 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); 1899 if (gop_itr == keyframe_map_.end()) 1900 return 0; 1901 int keyframe_index = gop_itr->second - keyframe_map_index_base_; 1902 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; 1903 KeyframeMap::iterator gop_end = keyframe_map_.end(); 1904 if (end_timestamp < GetBufferedEndTimestamp()) 1905 gop_end = GetFirstKeyframeBefore(end_timestamp); 1906 1907 // Check if the removal range is within a GOP and skip the loop if so. 1908 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] 1909 KeyframeMap::iterator gop_itr_prev = gop_itr; 1910 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) 1911 gop_end = gop_itr; 1912 1913 while (gop_itr != gop_end && bytes_to_free > 0) { 1914 ++gop_itr; 1915 1916 int gop_size = 0; 1917 int next_gop_index = gop_itr == keyframe_map_.end() ? 1918 buffers_.size() : gop_itr->second - keyframe_map_index_base_; 1919 BufferQueue::iterator next_gop_start = buffers_.begin() + next_gop_index; 1920 for (; buffer_itr != next_gop_start; ++buffer_itr) 1921 gop_size += (*buffer_itr)->data_size(); 1922 1923 bytes_removed += gop_size; 1924 bytes_to_free -= gop_size; 1925 } 1926 if (bytes_removed > 0) { 1927 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? 1928 GetBufferedEndTimestamp() : gop_itr->first; 1929 } 1930 return bytes_removed; 1931} 1932 1933bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { 1934 if (!HasNextBufferPosition()) 1935 return false; 1936 1937 // If there is only one GOP, it must contain the next buffer position. 1938 if (keyframe_map_.size() == 1u) 1939 return true; 1940 1941 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); 1942 ++second_gop; 1943 return next_buffer_index_ < second_gop->second - keyframe_map_index_base_; 1944} 1945 1946bool SourceBufferRange::LastGOPContainsNextBufferPosition() const { 1947 if (!HasNextBufferPosition()) 1948 return false; 1949 1950 // If there is only one GOP, it must contain the next buffer position. 1951 if (keyframe_map_.size() == 1u) 1952 return true; 1953 1954 KeyframeMap::const_iterator last_gop = keyframe_map_.end(); 1955 --last_gop; 1956 return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_; 1957} 1958 1959void SourceBufferRange::FreeBufferRange( 1960 const BufferQueue::iterator& starting_point, 1961 const BufferQueue::iterator& ending_point) { 1962 for (BufferQueue::iterator itr = starting_point; 1963 itr != ending_point; ++itr) { 1964 size_in_bytes_ -= (*itr)->data_size(); 1965 DCHECK_GE(size_in_bytes_, 0); 1966 } 1967 buffers_.erase(starting_point, ending_point); 1968} 1969 1970bool SourceBufferRange::TruncateAt( 1971 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { 1972 DCHECK(!removed_buffers || removed_buffers->empty()); 1973 1974 // Return if we're not deleting anything. 1975 if (starting_point == buffers_.end()) 1976 return false; 1977 1978 // Reset the next buffer index if we will be deleting the buffer that's next 1979 // in sequence. 1980 if (HasNextBufferPosition()) { 1981 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); 1982 if (next_buffer_timestamp == kNoTimestamp() || 1983 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { 1984 if (HasNextBuffer() && removed_buffers) { 1985 int starting_offset = starting_point - buffers_.begin(); 1986 int next_buffer_offset = next_buffer_index_ - starting_offset; 1987 DCHECK_GE(next_buffer_offset, 0); 1988 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); 1989 removed_buffers->swap(saved); 1990 } 1991 ResetNextBufferPosition(); 1992 } 1993 } 1994 1995 // Remove keyframes from |starting_point| onward. 1996 KeyframeMap::iterator starting_point_keyframe = 1997 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); 1998 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); 1999 2000 // Remove everything from |starting_point| onward. 2001 FreeBufferRange(starting_point, buffers_.end()); 2002 return buffers_.empty(); 2003} 2004 2005bool SourceBufferRange::GetNextBuffer( 2006 scoped_refptr<StreamParserBuffer>* out_buffer) { 2007 if (!HasNextBuffer()) 2008 return false; 2009 2010 *out_buffer = buffers_[next_buffer_index_]; 2011 next_buffer_index_++; 2012 return true; 2013} 2014 2015bool SourceBufferRange::HasNextBuffer() const { 2016 return next_buffer_index_ >= 0 && 2017 next_buffer_index_ < static_cast<int>(buffers_.size()); 2018} 2019 2020int SourceBufferRange::GetNextConfigId() const { 2021 DCHECK(HasNextBuffer()); 2022 // If the next buffer is an audio splice frame, the next effective config id 2023 // comes from the first fade out preroll buffer. 2024 return GetConfigId(buffers_[next_buffer_index_], 0); 2025} 2026 2027base::TimeDelta SourceBufferRange::GetNextTimestamp() const { 2028 DCHECK(!buffers_.empty()); 2029 DCHECK(HasNextBufferPosition()); 2030 2031 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 2032 return kNoTimestamp(); 2033 } 2034 2035 return buffers_[next_buffer_index_]->GetDecodeTimestamp(); 2036} 2037 2038bool SourceBufferRange::HasNextBufferPosition() const { 2039 return next_buffer_index_ >= 0; 2040} 2041 2042void SourceBufferRange::ResetNextBufferPosition() { 2043 next_buffer_index_ = -1; 2044} 2045 2046void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range, 2047 bool transfer_current_position) { 2048 DCHECK(CanAppendRangeToEnd(range)); 2049 DCHECK(!buffers_.empty()); 2050 2051 if (transfer_current_position && range.next_buffer_index_ >= 0) 2052 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); 2053 2054 AppendBuffersToEnd(range.buffers_); 2055} 2056 2057bool SourceBufferRange::CanAppendRangeToEnd( 2058 const SourceBufferRange& range) const { 2059 return CanAppendBuffersToEnd(range.buffers_); 2060} 2061 2062bool SourceBufferRange::CanAppendBuffersToEnd( 2063 const BufferQueue& buffers) const { 2064 DCHECK(!buffers_.empty()); 2065 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), 2066 buffers.front()->IsKeyframe()); 2067} 2068 2069bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { 2070 DCHECK(!buffers_.empty()); 2071 2072 return (IsNextInSequence(timestamp, false) || 2073 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 2074} 2075 2076bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { 2077 base::TimeDelta start_timestamp = 2078 std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom()); 2079 return !keyframe_map_.empty() && start_timestamp <= timestamp && 2080 timestamp < GetBufferedEndTimestamp(); 2081} 2082 2083bool SourceBufferRange::CompletelyOverlaps( 2084 const SourceBufferRange& range) const { 2085 return GetStartTimestamp() <= range.GetStartTimestamp() && 2086 GetEndTimestamp() >= range.GetEndTimestamp(); 2087} 2088 2089bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { 2090 return range.GetStartTimestamp() <= GetEndTimestamp() && 2091 GetEndTimestamp() < range.GetEndTimestamp(); 2092} 2093 2094base::TimeDelta SourceBufferRange::GetStartTimestamp() const { 2095 DCHECK(!buffers_.empty()); 2096 base::TimeDelta start_timestamp = media_segment_start_time_; 2097 if (start_timestamp == kNoTimestamp()) 2098 start_timestamp = buffers_.front()->GetDecodeTimestamp(); 2099 return start_timestamp; 2100} 2101 2102base::TimeDelta SourceBufferRange::GetEndTimestamp() const { 2103 DCHECK(!buffers_.empty()); 2104 return buffers_.back()->GetDecodeTimestamp(); 2105} 2106 2107base::TimeDelta SourceBufferRange::GetBufferedEndTimestamp() const { 2108 DCHECK(!buffers_.empty()); 2109 base::TimeDelta duration = buffers_.back()->duration(); 2110 if (duration == kNoTimestamp() || duration == base::TimeDelta()) 2111 duration = GetApproximateDuration(); 2112 return GetEndTimestamp() + duration; 2113} 2114 2115base::TimeDelta SourceBufferRange::NextKeyframeTimestamp( 2116 base::TimeDelta timestamp) { 2117 DCHECK(!keyframe_map_.empty()); 2118 2119 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 2120 return kNoTimestamp(); 2121 2122 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); 2123 if (itr == keyframe_map_.end()) 2124 return kNoTimestamp(); 2125 return itr->first; 2126} 2127 2128base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp( 2129 base::TimeDelta timestamp) { 2130 DCHECK(!keyframe_map_.empty()); 2131 2132 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 2133 return kNoTimestamp(); 2134 2135 return GetFirstKeyframeBefore(timestamp)->first; 2136} 2137 2138bool SourceBufferRange::IsNextInSequence( 2139 base::TimeDelta timestamp, bool is_keyframe) const { 2140 base::TimeDelta end = buffers_.back()->GetDecodeTimestamp(); 2141 if (end < timestamp && 2142 (type_ == SourceBufferStream::kText || 2143 timestamp <= end + GetFudgeRoom())) { 2144 return true; 2145 } 2146 2147 return timestamp == end && AllowSameTimestamp( 2148 buffers_.back()->IsKeyframe(), is_keyframe, type_); 2149} 2150 2151base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 2152 return ComputeFudgeRoom(GetApproximateDuration()); 2153} 2154 2155base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 2156 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 2157 DCHECK(max_interbuffer_distance != kNoTimestamp()); 2158 return max_interbuffer_distance; 2159} 2160 2161bool SourceBufferRange::GetBuffersInRange(base::TimeDelta start, 2162 base::TimeDelta end, 2163 BufferQueue* buffers) { 2164 // Find the nearest buffer with a decode timestamp <= start. 2165 const base::TimeDelta first_timestamp = KeyframeBeforeTimestamp(start); 2166 if (first_timestamp == kNoTimestamp()) 2167 return false; 2168 2169 // Find all buffers involved in the range. 2170 const size_t previous_size = buffers->size(); 2171 for (BufferQueue::iterator it = GetBufferItrAt(first_timestamp, false); 2172 it != buffers_.end(); 2173 ++it) { 2174 const scoped_refptr<StreamParserBuffer>& buffer = *it; 2175 // Buffers without duration are not supported, so bail if we encounter any. 2176 if (buffer->duration() == kNoTimestamp() || 2177 buffer->duration() <= base::TimeDelta()) { 2178 return false; 2179 } 2180 if (buffer->end_of_stream() || buffer->timestamp() >= end) 2181 break; 2182 if (buffer->timestamp() + buffer->duration() <= start) 2183 continue; 2184 buffers->push_back(buffer); 2185 } 2186 return previous_size < buffers->size(); 2187} 2188 2189} // namespace media 2190