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