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