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 #include "media/filters/source_buffer_platform.h" 15 #include "media/filters/source_buffer_range.h" 16 17 namespace media { 18 19 // Helper method that returns true if |ranges| is sorted in increasing order, 20 // false otherwise. 21 static bool IsRangeListSorted( 22 const std::list<media::SourceBufferRange*>& ranges) { 23 DecodeTimestamp prev = kNoDecodeTimestamp(); 24 for (std::list<SourceBufferRange*>::const_iterator itr = 25 ranges.begin(); itr != ranges.end(); ++itr) { 26 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) 27 return false; 28 prev = (*itr)->GetEndTimestamp(); 29 } 30 return true; 31 } 32 33 // Returns an estimate of how far from the beginning or end of a range a buffer 34 // can be to still be considered in the range, given the |approximate_duration| 35 // of a buffer in the stream. 36 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use 37 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) 38 // instead of an overall maximum interbuffer delta for range discontinuity 39 // detection, and adjust similarly for splice frame discontinuity detection. 40 // See http://crbug.com/351489 and http://crbug.com/351166. 41 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { 42 // Because we do not know exactly when is the next timestamp, any buffer 43 // that starts within 2x the approximate duration of a buffer is considered 44 // within this range. 45 return 2 * approximate_duration; 46 } 47 48 // An arbitrarily-chosen number to estimate the duration of a buffer if none 49 // is set and there's not enough information to get a better estimate. 50 static int kDefaultBufferDurationInMs = 125; 51 52 // The amount of time the beginning of the buffered data can differ from the 53 // start time in order to still be considered the start of stream. 54 static base::TimeDelta kSeekToStartFudgeRoom() { 55 return base::TimeDelta::FromMilliseconds(1000); 56 } 57 58 static SourceBufferRange::GapPolicy TypeToGapPolicy( 59 SourceBufferStream::Type type) { 60 switch (type) { 61 case SourceBufferStream::kAudio: 62 case SourceBufferStream::kVideo: 63 return SourceBufferRange::NO_GAPS_ALLOWED; 64 case SourceBufferStream::kText: 65 return SourceBufferRange::ALLOW_GAPS; 66 } 67 68 NOTREACHED(); 69 return SourceBufferRange::NO_GAPS_ALLOWED; 70 } 71 72 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 73 const LogCB& log_cb, 74 bool splice_frames_enabled) 75 : log_cb_(log_cb), 76 current_config_index_(0), 77 append_config_index_(0), 78 seek_pending_(false), 79 end_of_stream_(false), 80 seek_buffer_timestamp_(kNoTimestamp()), 81 selected_range_(NULL), 82 media_segment_start_time_(kNoDecodeTimestamp()), 83 range_for_next_append_(ranges_.end()), 84 new_media_segment_(false), 85 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 86 last_appended_buffer_is_keyframe_(false), 87 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 88 max_interbuffer_distance_(kNoTimestamp()), 89 memory_limit_(kSourceBufferAudioMemoryLimit), 90 config_change_pending_(false), 91 splice_buffers_index_(0), 92 pending_buffers_complete_(false), 93 splice_frames_enabled_(splice_frames_enabled) { 94 DCHECK(audio_config.IsValidConfig()); 95 audio_configs_.push_back(audio_config); 96 } 97 98 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 99 const LogCB& log_cb, 100 bool splice_frames_enabled) 101 : log_cb_(log_cb), 102 current_config_index_(0), 103 append_config_index_(0), 104 seek_pending_(false), 105 end_of_stream_(false), 106 seek_buffer_timestamp_(kNoTimestamp()), 107 selected_range_(NULL), 108 media_segment_start_time_(kNoDecodeTimestamp()), 109 range_for_next_append_(ranges_.end()), 110 new_media_segment_(false), 111 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 112 last_appended_buffer_is_keyframe_(false), 113 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 114 max_interbuffer_distance_(kNoTimestamp()), 115 memory_limit_(kSourceBufferVideoMemoryLimit), 116 config_change_pending_(false), 117 splice_buffers_index_(0), 118 pending_buffers_complete_(false), 119 splice_frames_enabled_(splice_frames_enabled) { 120 DCHECK(video_config.IsValidConfig()); 121 video_configs_.push_back(video_config); 122 } 123 124 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 125 const LogCB& log_cb, 126 bool splice_frames_enabled) 127 : log_cb_(log_cb), 128 current_config_index_(0), 129 append_config_index_(0), 130 text_track_config_(text_config), 131 seek_pending_(false), 132 end_of_stream_(false), 133 seek_buffer_timestamp_(kNoTimestamp()), 134 selected_range_(NULL), 135 media_segment_start_time_(kNoDecodeTimestamp()), 136 range_for_next_append_(ranges_.end()), 137 new_media_segment_(false), 138 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 139 last_appended_buffer_is_keyframe_(false), 140 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 141 max_interbuffer_distance_(kNoTimestamp()), 142 memory_limit_(kSourceBufferAudioMemoryLimit), 143 config_change_pending_(false), 144 splice_buffers_index_(0), 145 pending_buffers_complete_(false), 146 splice_frames_enabled_(splice_frames_enabled) {} 147 148 SourceBufferStream::~SourceBufferStream() { 149 while (!ranges_.empty()) { 150 delete ranges_.front(); 151 ranges_.pop_front(); 152 } 153 } 154 155 void SourceBufferStream::OnNewMediaSegment( 156 DecodeTimestamp media_segment_start_time) { 157 DVLOG(1) << __FUNCTION__ << "(" << media_segment_start_time.InSecondsF() 158 << ")"; 159 DCHECK(!end_of_stream_); 160 media_segment_start_time_ = media_segment_start_time; 161 new_media_segment_ = true; 162 163 RangeList::iterator last_range = range_for_next_append_; 164 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); 165 166 // Only reset |last_appended_buffer_timestamp_| if this new media segment is 167 // not adjacent to the previous media segment appended to the stream. 168 if (range_for_next_append_ == ranges_.end() || 169 !AreAdjacentInSequence(last_appended_buffer_timestamp_, 170 media_segment_start_time)) { 171 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 172 last_appended_buffer_is_keyframe_ = false; 173 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range"; 174 } else if (last_range != ranges_.end()) { 175 DCHECK(last_range == range_for_next_append_); 176 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " 177 << "unless intervening remove makes discontinuity"; 178 } 179 } 180 181 bool SourceBufferStream::Append(const BufferQueue& buffers) { 182 TRACE_EVENT2("media", "SourceBufferStream::Append", 183 "stream type", GetStreamTypeName(), 184 "buffers to append", buffers.size()); 185 186 DCHECK(!buffers.empty()); 187 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); 188 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); 189 DCHECK(!end_of_stream_); 190 191 // New media segments must begin with a keyframe. 192 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { 193 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe."; 194 return false; 195 } 196 197 // Buffers within a media segment should be monotonically increasing. 198 if (!IsMonotonicallyIncreasing(buffers)) 199 return false; 200 201 if (media_segment_start_time_ < DecodeTimestamp() || 202 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { 203 MEDIA_LOG(log_cb_) 204 << "Cannot append a media segment with negative timestamps."; 205 return false; 206 } 207 208 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), 209 buffers.front()->IsKeyframe())) { 210 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time " 211 << buffers.front()->GetDecodeTimestamp().InSecondsF(); 212 213 return false; 214 } 215 216 UpdateMaxInterbufferDistance(buffers); 217 SetConfigIds(buffers); 218 219 // Save a snapshot of stream state before range modifications are made. 220 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 221 BufferQueue deleted_buffers; 222 223 PrepareRangesForNextAppend(buffers, &deleted_buffers); 224 225 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 226 // create a new range with |buffers|. 227 if (range_for_next_append_ != ranges_.end()) { 228 (*range_for_next_append_)->AppendBuffersToEnd(buffers); 229 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 230 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); 231 } else { 232 DecodeTimestamp new_range_start_time = std::min( 233 media_segment_start_time_, buffers.front()->GetDecodeTimestamp()); 234 const BufferQueue* buffers_for_new_range = &buffers; 235 BufferQueue trimmed_buffers; 236 237 // If the new range is not being created because of a new media 238 // segment, then we must make sure that we start with a keyframe. 239 // This can happen if the GOP in the previous append gets destroyed 240 // by a Remove() call. 241 if (!new_media_segment_) { 242 BufferQueue::const_iterator itr = buffers.begin(); 243 244 // Scan past all the non-keyframes. 245 while (itr != buffers.end() && !(*itr)->IsKeyframe()) { 246 ++itr; 247 } 248 249 // If we didn't find a keyframe, then update the last appended 250 // buffer state and return. 251 if (itr == buffers.end()) { 252 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 253 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); 254 return true; 255 } else if (itr != buffers.begin()) { 256 // Copy the first keyframe and everything after it into 257 // |trimmed_buffers|. 258 trimmed_buffers.assign(itr, buffers.end()); 259 buffers_for_new_range = &trimmed_buffers; 260 } 261 262 new_range_start_time = 263 buffers_for_new_range->front()->GetDecodeTimestamp(); 264 } 265 266 range_for_next_append_ = 267 AddToRanges(new SourceBufferRange( 268 TypeToGapPolicy(GetType()), 269 *buffers_for_new_range, new_range_start_time, 270 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, 271 base::Unretained(this)))); 272 last_appended_buffer_timestamp_ = 273 buffers_for_new_range->back()->GetDecodeTimestamp(); 274 last_appended_buffer_is_keyframe_ = 275 buffers_for_new_range->back()->IsKeyframe(); 276 } 277 278 new_media_segment_ = false; 279 280 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 281 282 // Seek to try to fulfill a previous call to Seek(). 283 if (seek_pending_) { 284 DCHECK(!selected_range_); 285 DCHECK(deleted_buffers.empty()); 286 Seek(seek_buffer_timestamp_); 287 } 288 289 if (!deleted_buffers.empty()) { 290 DecodeTimestamp start_of_deleted = 291 deleted_buffers.front()->GetDecodeTimestamp(); 292 293 DCHECK(track_buffer_.empty() || 294 track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted) 295 << "decode timestamp " 296 << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec" 297 << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec"; 298 299 track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(), 300 deleted_buffers.end()); 301 } 302 303 // Prune any extra buffers in |track_buffer_| if new keyframes 304 // are appended to the range covered by |track_buffer_|. 305 if (!track_buffer_.empty()) { 306 DecodeTimestamp keyframe_timestamp = 307 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); 308 if (keyframe_timestamp != kNoDecodeTimestamp()) 309 PruneTrackBuffer(keyframe_timestamp); 310 } 311 312 SetSelectedRangeIfNeeded(next_buffer_timestamp); 313 314 GarbageCollectIfNeeded(); 315 316 DCHECK(IsRangeListSorted(ranges_)); 317 DCHECK(OnlySelectedRangeIsSeeked()); 318 return true; 319 } 320 321 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, 322 base::TimeDelta duration) { 323 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() 324 << ", " << end.InSecondsF() 325 << ", " << duration.InSecondsF() << ")"; 326 DCHECK(start >= base::TimeDelta()) << start.InSecondsF(); 327 DCHECK(start < end) << "start " << start.InSecondsF() 328 << " end " << end.InSecondsF(); 329 DCHECK(duration != kNoTimestamp()); 330 331 DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start); 332 DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end); 333 DecodeTimestamp remove_end_timestamp = 334 DecodeTimestamp::FromPresentationTime(duration); 335 DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts); 336 if (keyframe_timestamp != kNoDecodeTimestamp()) { 337 remove_end_timestamp = keyframe_timestamp; 338 } else if (end_dts < remove_end_timestamp) { 339 remove_end_timestamp = end_dts; 340 } 341 342 BufferQueue deleted_buffers; 343 RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers); 344 345 if (!deleted_buffers.empty()) 346 SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp()); 347 } 348 349 void SourceBufferStream::RemoveInternal( 350 DecodeTimestamp start, DecodeTimestamp end, bool is_exclusive, 351 BufferQueue* deleted_buffers) { 352 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() 353 << ", " << end.InSecondsF() 354 << ", " << is_exclusive << ")"; 355 356 DCHECK(start >= DecodeTimestamp()); 357 DCHECK(start < end) << "start " << start.InSecondsF() 358 << " end " << end.InSecondsF(); 359 DCHECK(deleted_buffers); 360 361 RangeList::iterator itr = ranges_.begin(); 362 363 while (itr != ranges_.end()) { 364 SourceBufferRange* range = *itr; 365 if (range->GetStartTimestamp() >= end) 366 break; 367 368 // Split off any remaining end piece and add it to |ranges_|. 369 SourceBufferRange* new_range = range->SplitRange(end, is_exclusive); 370 if (new_range) { 371 itr = ranges_.insert(++itr, new_range); 372 --itr; 373 374 // Update the selected range if the next buffer position was transferred 375 // to |new_range|. 376 if (new_range->HasNextBufferPosition()) 377 SetSelectedRange(new_range); 378 } 379 380 // Truncate the current range so that it only contains data before 381 // the removal range. 382 BufferQueue saved_buffers; 383 bool delete_range = range->TruncateAt(start, &saved_buffers, is_exclusive); 384 385 // Check to see if the current playback position was removed and 386 // update the selected range appropriately. 387 if (!saved_buffers.empty()) { 388 DCHECK(!range->HasNextBufferPosition()); 389 DCHECK(deleted_buffers->empty()); 390 391 *deleted_buffers = saved_buffers; 392 } 393 394 if (range == selected_range_ && !range->HasNextBufferPosition()) 395 SetSelectedRange(NULL); 396 397 // If the current range now is completely covered by the removal 398 // range then delete it and move on. 399 if (delete_range) { 400 DeleteAndRemoveRange(&itr); 401 continue; 402 } 403 404 // Clear |range_for_next_append_| if we determine that the removal 405 // operation makes it impossible for the next append to be added 406 // to the current range. 407 if (range_for_next_append_ != ranges_.end() && 408 *range_for_next_append_ == range && 409 last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) { 410 DecodeTimestamp potential_next_append_timestamp = 411 last_appended_buffer_timestamp_ + 412 base::TimeDelta::FromInternalValue(1); 413 414 if (!range->BelongsToRange(potential_next_append_timestamp)) { 415 DVLOG(1) << "Resetting range_for_next_append_ since the next append" 416 << " can't add to the current range."; 417 range_for_next_append_ = 418 FindExistingRangeFor(potential_next_append_timestamp); 419 } 420 } 421 422 // Move on to the next range. 423 ++itr; 424 } 425 426 DCHECK(IsRangeListSorted(ranges_)); 427 DCHECK(OnlySelectedRangeIsSeeked()); 428 DVLOG(1) << __FUNCTION__ << " : done"; 429 } 430 431 void SourceBufferStream::ResetSeekState() { 432 SetSelectedRange(NULL); 433 track_buffer_.clear(); 434 config_change_pending_ = false; 435 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); 436 splice_buffers_index_ = 0; 437 pending_buffer_ = NULL; 438 pending_buffers_complete_ = false; 439 } 440 441 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 442 base::TimeDelta seek_timestamp) const { 443 if (ranges_.empty()) 444 return false; 445 base::TimeDelta beginning_of_buffered = 446 ranges_.front()->GetStartTimestamp().ToPresentationTime(); 447 return (seek_timestamp <= beginning_of_buffered && 448 beginning_of_buffered < kSeekToStartFudgeRoom()); 449 } 450 451 bool SourceBufferStream::IsMonotonicallyIncreasing( 452 const BufferQueue& buffers) const { 453 DCHECK(!buffers.empty()); 454 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 455 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 456 for (BufferQueue::const_iterator itr = buffers.begin(); 457 itr != buffers.end(); ++itr) { 458 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); 459 bool current_is_keyframe = (*itr)->IsKeyframe(); 460 DCHECK(current_timestamp != kNoDecodeTimestamp()); 461 DCHECK((*itr)->duration() >= base::TimeDelta()) 462 << "Packet with invalid duration." 463 << " pts " << (*itr)->timestamp().InSecondsF() 464 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() 465 << " dur " << (*itr)->duration().InSecondsF(); 466 467 if (prev_timestamp != kNoDecodeTimestamp()) { 468 if (current_timestamp < prev_timestamp) { 469 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; 470 return false; 471 } 472 473 if (current_timestamp == prev_timestamp && 474 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, 475 current_is_keyframe)) { 476 MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the" 477 << " same timestamp detected at " 478 << current_timestamp.InSecondsF(); 479 return false; 480 } 481 } 482 483 prev_timestamp = current_timestamp; 484 prev_is_keyframe = current_is_keyframe; 485 } 486 return true; 487 } 488 489 bool SourceBufferStream::IsNextTimestampValid( 490 DecodeTimestamp next_timestamp, bool next_is_keyframe) const { 491 return (last_appended_buffer_timestamp_ != next_timestamp) || 492 new_media_segment_ || 493 SourceBufferRange::AllowSameTimestamp(last_appended_buffer_is_keyframe_, 494 next_is_keyframe); 495 } 496 497 498 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { 499 for (RangeList::const_iterator itr = ranges_.begin(); 500 itr != ranges_.end(); ++itr) { 501 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) 502 return false; 503 } 504 return !selected_range_ || selected_range_->HasNextBufferPosition(); 505 } 506 507 void SourceBufferStream::UpdateMaxInterbufferDistance( 508 const BufferQueue& buffers) { 509 DCHECK(!buffers.empty()); 510 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 511 for (BufferQueue::const_iterator itr = buffers.begin(); 512 itr != buffers.end(); ++itr) { 513 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); 514 DCHECK(current_timestamp != kNoDecodeTimestamp()); 515 516 base::TimeDelta interbuffer_distance = (*itr)->duration(); 517 DCHECK(interbuffer_distance >= base::TimeDelta()); 518 519 if (prev_timestamp != kNoDecodeTimestamp()) { 520 interbuffer_distance = 521 std::max(current_timestamp - prev_timestamp, interbuffer_distance); 522 } 523 524 if (interbuffer_distance > base::TimeDelta()) { 525 if (max_interbuffer_distance_ == kNoTimestamp()) { 526 max_interbuffer_distance_ = interbuffer_distance; 527 } else { 528 max_interbuffer_distance_ = 529 std::max(max_interbuffer_distance_, interbuffer_distance); 530 } 531 } 532 prev_timestamp = current_timestamp; 533 } 534 } 535 536 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { 537 for (BufferQueue::const_iterator itr = buffers.begin(); 538 itr != buffers.end(); ++itr) { 539 (*itr)->SetConfigId(append_config_index_); 540 } 541 } 542 543 void SourceBufferStream::GarbageCollectIfNeeded() { 544 // Compute size of |ranges_|. 545 int ranges_size = 0; 546 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) 547 ranges_size += (*itr)->size_in_bytes(); 548 549 // Return if we're under or at the memory limit. 550 if (ranges_size <= memory_limit_) 551 return; 552 553 int bytes_to_free = ranges_size - memory_limit_; 554 555 // Begin deleting after the last appended buffer. 556 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); 557 558 // Begin deleting from the front. 559 if (bytes_to_free - bytes_freed > 0) 560 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); 561 562 // Begin deleting from the back. 563 if (bytes_to_free - bytes_freed > 0) 564 FreeBuffers(bytes_to_free - bytes_freed, true); 565 } 566 567 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) { 568 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 569 if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() || 570 next_buffer_timestamp == kNoDecodeTimestamp() || 571 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { 572 return 0; 573 } 574 575 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; 576 if (last_appended_buffer_is_keyframe_) 577 remove_range_start += GetMaxInterbufferDistance(); 578 579 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( 580 remove_range_start); 581 if (remove_range_start_keyframe != kNoDecodeTimestamp()) 582 remove_range_start = remove_range_start_keyframe; 583 if (remove_range_start >= next_buffer_timestamp) 584 return 0; 585 586 DecodeTimestamp remove_range_end; 587 int bytes_freed = GetRemovalRange( 588 remove_range_start, next_buffer_timestamp, total_bytes_to_free, 589 &remove_range_end); 590 if (bytes_freed > 0) { 591 Remove(remove_range_start.ToPresentationTime(), 592 remove_range_end.ToPresentationTime(), 593 next_buffer_timestamp.ToPresentationTime()); 594 } 595 596 return bytes_freed; 597 } 598 599 int SourceBufferStream::GetRemovalRange( 600 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, 601 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { 602 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF(); 603 DCHECK(start_timestamp < end_timestamp) 604 << "start " << start_timestamp.InSecondsF() 605 << ", end " << end_timestamp.InSecondsF(); 606 607 int bytes_to_free = total_bytes_to_free; 608 int bytes_freed = 0; 609 610 for (RangeList::iterator itr = ranges_.begin(); 611 itr != ranges_.end() && bytes_to_free > 0; ++itr) { 612 SourceBufferRange* range = *itr; 613 if (range->GetStartTimestamp() >= end_timestamp) 614 break; 615 if (range->GetEndTimestamp() < start_timestamp) 616 continue; 617 618 int bytes_removed = range->GetRemovalGOP( 619 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); 620 bytes_to_free -= bytes_removed; 621 bytes_freed += bytes_removed; 622 } 623 return bytes_freed; 624 } 625 626 int SourceBufferStream::FreeBuffers(int total_bytes_to_free, 627 bool reverse_direction) { 628 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", 629 "total bytes to free", total_bytes_to_free, 630 "reverse direction", reverse_direction); 631 632 DCHECK_GT(total_bytes_to_free, 0); 633 int bytes_to_free = total_bytes_to_free; 634 int bytes_freed = 0; 635 636 // This range will save the last GOP appended to |range_for_next_append_| 637 // if the buffers surrounding it get deleted during garbage collection. 638 SourceBufferRange* new_range_for_append = NULL; 639 640 while (!ranges_.empty() && bytes_to_free > 0) { 641 SourceBufferRange* current_range = NULL; 642 BufferQueue buffers; 643 int bytes_deleted = 0; 644 645 if (reverse_direction) { 646 current_range = ranges_.back(); 647 if (current_range->LastGOPContainsNextBufferPosition()) { 648 DCHECK_EQ(current_range, selected_range_); 649 break; 650 } 651 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); 652 } else { 653 current_range = ranges_.front(); 654 if (current_range->FirstGOPContainsNextBufferPosition()) { 655 DCHECK_EQ(current_range, selected_range_); 656 break; 657 } 658 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); 659 } 660 661 // Check to see if we've just deleted the GOP that was last appended. 662 DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp(); 663 if (end_timestamp == last_appended_buffer_timestamp_) { 664 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp()); 665 DCHECK(!new_range_for_append); 666 // Create a new range containing these buffers. 667 new_range_for_append = new SourceBufferRange( 668 TypeToGapPolicy(GetType()), 669 buffers, kNoDecodeTimestamp(), 670 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, 671 base::Unretained(this))); 672 range_for_next_append_ = ranges_.end(); 673 } else { 674 bytes_to_free -= bytes_deleted; 675 bytes_freed += bytes_deleted; 676 } 677 678 if (current_range->size_in_bytes() == 0) { 679 DCHECK_NE(current_range, selected_range_); 680 DCHECK(range_for_next_append_ == ranges_.end() || 681 *range_for_next_append_ != current_range); 682 delete current_range; 683 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); 684 } 685 } 686 687 // Insert |new_range_for_append| into |ranges_|, if applicable. 688 if (new_range_for_append) { 689 range_for_next_append_ = AddToRanges(new_range_for_append); 690 DCHECK(range_for_next_append_ != ranges_.end()); 691 692 // Check to see if we need to merge |new_range_for_append| with the range 693 // before or after it. |new_range_for_append| is created whenever the last 694 // GOP appended is encountered, regardless of whether any buffers after it 695 // are ultimately deleted. Merging is necessary if there were no buffers 696 // (or very few buffers) deleted after creating |new_range_for_append|. 697 if (range_for_next_append_ != ranges_.begin()) { 698 RangeList::iterator range_before_next = range_for_next_append_; 699 --range_before_next; 700 MergeWithAdjacentRangeIfNecessary(range_before_next); 701 } 702 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 703 } 704 return bytes_freed; 705 } 706 707 void SourceBufferStream::PrepareRangesForNextAppend( 708 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 709 DCHECK(deleted_buffers); 710 711 bool temporarily_select_range = false; 712 if (!track_buffer_.empty()) { 713 DecodeTimestamp tb_timestamp = track_buffer_.back()->GetDecodeTimestamp(); 714 DecodeTimestamp seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp); 715 if (seek_timestamp != kNoDecodeTimestamp() && 716 seek_timestamp < new_buffers.front()->GetDecodeTimestamp() && 717 range_for_next_append_ != ranges_.end() && 718 (*range_for_next_append_)->BelongsToRange(seek_timestamp)) { 719 DCHECK(tb_timestamp < seek_timestamp); 720 DCHECK(!selected_range_); 721 DCHECK(!(*range_for_next_append_)->HasNextBufferPosition()); 722 723 // If there are GOPs between the end of the track buffer and the 724 // beginning of the new buffers, then temporarily seek the range 725 // so that the buffers between these two times will be deposited in 726 // |deleted_buffers| as if they were part of the current playback 727 // position. 728 // TODO(acolwell): Figure out a more elegant way to do this. 729 SeekAndSetSelectedRange(*range_for_next_append_, seek_timestamp); 730 temporarily_select_range = true; 731 } 732 } 733 734 // Handle splices between the existing buffers and the new buffers. If a 735 // splice is generated the timestamp and duration of the first buffer in 736 // |new_buffers| will be modified. 737 if (splice_frames_enabled_) 738 GenerateSpliceFrame(new_buffers); 739 740 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 741 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 742 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 743 bool next_is_keyframe = new_buffers.front()->IsKeyframe(); 744 745 if (prev_timestamp != kNoDecodeTimestamp() && 746 prev_timestamp != next_timestamp) { 747 // Clean up the old buffers between the last appended buffer and the 748 // beginning of |new_buffers|. 749 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 750 } 751 752 // Make the delete range exclusive if we are dealing with an allowed same 753 // timestamp situation. This prevents the first buffer in the current append 754 // from deleting the last buffer in the previous append if both buffers 755 // have the same timestamp. 756 // 757 // The delete range should never be exclusive if a splice frame was generated 758 // because we don't generate splice frames for same timestamp situations. 759 DCHECK(new_buffers.front()->splice_timestamp() != 760 new_buffers.front()->timestamp()); 761 const bool is_exclusive = 762 new_buffers.front()->splice_buffers().empty() && 763 prev_timestamp == next_timestamp && 764 SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, next_is_keyframe); 765 766 // Delete the buffers that |new_buffers| overlaps. 767 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); 768 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 769 base::TimeDelta duration = new_buffers.back()->duration(); 770 771 if (duration != kNoTimestamp() && duration > base::TimeDelta()) { 772 end += duration; 773 } else { 774 // TODO(acolwell): Ensure all buffers actually have proper 775 // duration info so that this hack isn't needed. 776 // http://crbug.com/312836 777 end += base::TimeDelta::FromInternalValue(1); 778 } 779 780 RemoveInternal(start, end, is_exclusive, deleted_buffers); 781 782 // Restore the range seek state if necessary. 783 if (temporarily_select_range) 784 SetSelectedRange(NULL); 785 } 786 787 bool SourceBufferStream::AreAdjacentInSequence( 788 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { 789 return first_timestamp < second_timestamp && 790 second_timestamp <= 791 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 792 } 793 794 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { 795 // If we don't have the next timestamp, we don't have anything to delete. 796 if (timestamp == kNoDecodeTimestamp()) 797 return; 798 799 while (!track_buffer_.empty() && 800 track_buffer_.back()->GetDecodeTimestamp() >= timestamp) { 801 track_buffer_.pop_back(); 802 } 803 } 804 805 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( 806 const RangeList::iterator& range_with_new_buffers_itr) { 807 DCHECK(range_with_new_buffers_itr != ranges_.end()); 808 809 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 810 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 811 ++next_range_itr; 812 813 if (next_range_itr == ranges_.end() || 814 !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) { 815 return; 816 } 817 818 bool transfer_current_position = selected_range_ == *next_range_itr; 819 range_with_new_buffers->AppendRangeToEnd(**next_range_itr, 820 transfer_current_position); 821 // Update |selected_range_| pointer if |range| has become selected after 822 // merges. 823 if (transfer_current_position) 824 SetSelectedRange(range_with_new_buffers); 825 826 if (next_range_itr == range_for_next_append_) 827 range_for_next_append_ = range_with_new_buffers_itr; 828 829 DeleteAndRemoveRange(&next_range_itr); 830 } 831 832 void SourceBufferStream::Seek(base::TimeDelta timestamp) { 833 DCHECK(timestamp >= base::TimeDelta()); 834 ResetSeekState(); 835 836 if (ShouldSeekToStartOfBuffered(timestamp)) { 837 ranges_.front()->SeekToStart(); 838 SetSelectedRange(ranges_.front()); 839 seek_pending_ = false; 840 return; 841 } 842 843 seek_buffer_timestamp_ = timestamp; 844 seek_pending_ = true; 845 846 DecodeTimestamp seek_dts = DecodeTimestamp::FromPresentationTime(timestamp); 847 848 RangeList::iterator itr = ranges_.end(); 849 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 850 if ((*itr)->CanSeekTo(seek_dts)) 851 break; 852 } 853 854 if (itr == ranges_.end()) 855 return; 856 857 SeekAndSetSelectedRange(*itr, seek_dts); 858 seek_pending_ = false; 859 } 860 861 bool SourceBufferStream::IsSeekPending() const { 862 return !(end_of_stream_ && IsEndSelected()) && seek_pending_; 863 } 864 865 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { 866 DecodeTimestamp duration_dts = 867 DecodeTimestamp::FromPresentationTime(duration); 868 869 RangeList::iterator itr = ranges_.end(); 870 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 871 if ((*itr)->GetEndTimestamp() > duration_dts) 872 break; 873 } 874 if (itr == ranges_.end()) 875 return; 876 877 // Need to partially truncate this range. 878 if ((*itr)->GetStartTimestamp() < duration_dts) { 879 bool delete_range = (*itr)->TruncateAt(duration_dts, NULL, false); 880 if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition()) 881 SetSelectedRange(NULL); 882 883 if (delete_range) { 884 DeleteAndRemoveRange(&itr); 885 } else { 886 ++itr; 887 } 888 } 889 890 // Delete all ranges that begin after |duration_dts|. 891 while (itr != ranges_.end()) { 892 // If we're about to delete the selected range, also reset the seek state. 893 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); 894 if (*itr == selected_range_) 895 ResetSeekState(); 896 DeleteAndRemoveRange(&itr); 897 } 898 } 899 900 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( 901 scoped_refptr<StreamParserBuffer>* out_buffer) { 902 if (!pending_buffer_.get()) { 903 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); 904 if (status != SourceBufferStream::kSuccess || !SetPendingBuffer(out_buffer)) 905 return status; 906 } 907 908 if (!pending_buffer_->splice_buffers().empty()) 909 return HandleNextBufferWithSplice(out_buffer); 910 911 DCHECK(pending_buffer_->preroll_buffer().get()); 912 return HandleNextBufferWithPreroll(out_buffer); 913 } 914 915 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( 916 scoped_refptr<StreamParserBuffer>* out_buffer) { 917 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); 918 const size_t last_splice_buffer_index = splice_buffers.size() - 1; 919 920 // Are there any splice buffers left to hand out? The last buffer should be 921 // handed out separately since it represents the first post-splice buffer. 922 if (splice_buffers_index_ < last_splice_buffer_index) { 923 // Account for config changes which occur between fade out buffers. 924 if (current_config_index_ != 925 splice_buffers[splice_buffers_index_]->GetConfigId()) { 926 config_change_pending_ = true; 927 DVLOG(1) << "Config change (splice buffer config ID does not match)."; 928 return SourceBufferStream::kConfigChange; 929 } 930 931 // Every pre splice buffer must have the same splice_timestamp(). 932 DCHECK(pending_buffer_->splice_timestamp() == 933 splice_buffers[splice_buffers_index_]->splice_timestamp()); 934 935 // No pre splice buffers should have preroll. 936 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get()); 937 938 *out_buffer = splice_buffers[splice_buffers_index_++]; 939 return SourceBufferStream::kSuccess; 940 } 941 942 // Did we hand out the last pre-splice buffer on the previous call? 943 if (!pending_buffers_complete_) { 944 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); 945 pending_buffers_complete_ = true; 946 config_change_pending_ = true; 947 DVLOG(1) << "Config change (forced for fade in of splice frame)."; 948 return SourceBufferStream::kConfigChange; 949 } 950 951 // All pre-splice buffers have been handed out and a config change completed, 952 // so hand out the final buffer for fade in. Because a config change is 953 // always issued prior to handing out this buffer, any changes in config id 954 // have been inherently handled. 955 DCHECK(pending_buffers_complete_); 956 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1); 957 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp()); 958 *out_buffer = splice_buffers.back(); 959 pending_buffer_ = NULL; 960 961 // If the last splice buffer has preroll, hand off to the preroll handler. 962 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer) 963 : SourceBufferStream::kSuccess; 964 } 965 966 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll( 967 scoped_refptr<StreamParserBuffer>* out_buffer) { 968 // Any config change should have already been handled. 969 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId()); 970 971 // Check if the preroll buffer has already been handed out. 972 if (!pending_buffers_complete_) { 973 pending_buffers_complete_ = true; 974 *out_buffer = pending_buffer_->preroll_buffer(); 975 return SourceBufferStream::kSuccess; 976 } 977 978 // Preroll complete, hand out the final buffer. 979 *out_buffer = pending_buffer_; 980 pending_buffer_ = NULL; 981 return SourceBufferStream::kSuccess; 982 } 983 984 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( 985 scoped_refptr<StreamParserBuffer>* out_buffer) { 986 CHECK(!config_change_pending_); 987 988 if (!track_buffer_.empty()) { 989 DCHECK(!selected_range_); 990 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); 991 992 // If the next buffer is an audio splice frame, the next effective config id 993 // comes from the first splice buffer. 994 if (next_buffer->GetSpliceBufferConfigId(0) != current_config_index_) { 995 config_change_pending_ = true; 996 DVLOG(1) << "Config change (track buffer config ID does not match)."; 997 return kConfigChange; 998 } 999 1000 *out_buffer = next_buffer; 1001 track_buffer_.pop_front(); 1002 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1003 1004 // If the track buffer becomes empty, then try to set the selected range 1005 // based on the timestamp of this buffer being returned. 1006 if (track_buffer_.empty()) 1007 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); 1008 1009 return kSuccess; 1010 } 1011 1012 if (!selected_range_ || !selected_range_->HasNextBuffer()) { 1013 if (end_of_stream_ && IsEndSelected()) 1014 return kEndOfStream; 1015 return kNeedBuffer; 1016 } 1017 1018 if (selected_range_->GetNextConfigId() != current_config_index_) { 1019 config_change_pending_ = true; 1020 DVLOG(1) << "Config change (selected range config ID does not match)."; 1021 return kConfigChange; 1022 } 1023 1024 CHECK(selected_range_->GetNextBuffer(out_buffer)); 1025 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1026 return kSuccess; 1027 } 1028 1029 DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() { 1030 if (!track_buffer_.empty()) 1031 return track_buffer_.front()->GetDecodeTimestamp(); 1032 1033 if (!selected_range_) 1034 return kNoDecodeTimestamp(); 1035 1036 DCHECK(selected_range_->HasNextBufferPosition()); 1037 return selected_range_->GetNextTimestamp(); 1038 } 1039 1040 SourceBufferStream::RangeList::iterator 1041 SourceBufferStream::FindExistingRangeFor(DecodeTimestamp start_timestamp) { 1042 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1043 if ((*itr)->BelongsToRange(start_timestamp)) 1044 return itr; 1045 } 1046 return ranges_.end(); 1047 } 1048 1049 SourceBufferStream::RangeList::iterator 1050 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) { 1051 DecodeTimestamp start_timestamp = new_range->GetStartTimestamp(); 1052 RangeList::iterator itr = ranges_.end(); 1053 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1054 if ((*itr)->GetStartTimestamp() > start_timestamp) 1055 break; 1056 } 1057 return ranges_.insert(itr, new_range); 1058 } 1059 1060 SourceBufferStream::RangeList::iterator 1061 SourceBufferStream::GetSelectedRangeItr() { 1062 DCHECK(selected_range_); 1063 RangeList::iterator itr = ranges_.end(); 1064 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 1065 if (*itr == selected_range_) 1066 break; 1067 } 1068 DCHECK(itr != ranges_.end()); 1069 return itr; 1070 } 1071 1072 void SourceBufferStream::SeekAndSetSelectedRange( 1073 SourceBufferRange* range, DecodeTimestamp seek_timestamp) { 1074 if (range) 1075 range->Seek(seek_timestamp); 1076 SetSelectedRange(range); 1077 } 1078 1079 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { 1080 DVLOG(1) << __FUNCTION__ << " : " << selected_range_ << " -> " << range; 1081 if (selected_range_) 1082 selected_range_->ResetNextBufferPosition(); 1083 DCHECK(!range || range->HasNextBufferPosition()); 1084 selected_range_ = range; 1085 } 1086 1087 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { 1088 Ranges<base::TimeDelta> ranges; 1089 for (RangeList::const_iterator itr = ranges_.begin(); 1090 itr != ranges_.end(); ++itr) { 1091 ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(), 1092 (*itr)->GetBufferedEndTimestamp().ToPresentationTime()); 1093 } 1094 return ranges; 1095 } 1096 1097 base::TimeDelta SourceBufferStream::GetBufferedDuration() const { 1098 if (ranges_.empty()) 1099 return base::TimeDelta(); 1100 1101 return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime(); 1102 } 1103 1104 void SourceBufferStream::MarkEndOfStream() { 1105 DCHECK(!end_of_stream_); 1106 end_of_stream_ = true; 1107 } 1108 1109 void SourceBufferStream::UnmarkEndOfStream() { 1110 DCHECK(end_of_stream_); 1111 end_of_stream_ = false; 1112 } 1113 1114 bool SourceBufferStream::IsEndSelected() const { 1115 if (ranges_.empty()) 1116 return true; 1117 1118 if (seek_pending_) { 1119 base::TimeDelta last_range_end_time = 1120 ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime(); 1121 return seek_buffer_timestamp_ >= last_range_end_time; 1122 } 1123 1124 return selected_range_ == ranges_.back(); 1125 } 1126 1127 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { 1128 if (config_change_pending_) 1129 CompleteConfigChange(); 1130 return audio_configs_[current_config_index_]; 1131 } 1132 1133 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { 1134 if (config_change_pending_) 1135 CompleteConfigChange(); 1136 return video_configs_[current_config_index_]; 1137 } 1138 1139 const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() { 1140 return text_track_config_; 1141 } 1142 1143 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { 1144 if (max_interbuffer_distance_ == kNoTimestamp()) 1145 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); 1146 return max_interbuffer_distance_; 1147 } 1148 1149 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 1150 DCHECK(!audio_configs_.empty()); 1151 DCHECK(video_configs_.empty()); 1152 DVLOG(3) << "UpdateAudioConfig."; 1153 1154 if (audio_configs_[0].codec() != config.codec()) { 1155 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; 1156 return false; 1157 } 1158 1159 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { 1160 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; 1161 return false; 1162 } 1163 1164 // Check to see if the new config matches an existing one. 1165 for (size_t i = 0; i < audio_configs_.size(); ++i) { 1166 if (config.Matches(audio_configs_[i])) { 1167 append_config_index_ = i; 1168 return true; 1169 } 1170 } 1171 1172 // No matches found so let's add this one to the list. 1173 append_config_index_ = audio_configs_.size(); 1174 DVLOG(2) << "New audio config - index: " << append_config_index_; 1175 audio_configs_.resize(audio_configs_.size() + 1); 1176 audio_configs_[append_config_index_] = config; 1177 return true; 1178 } 1179 1180 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { 1181 DCHECK(!video_configs_.empty()); 1182 DCHECK(audio_configs_.empty()); 1183 DVLOG(3) << "UpdateVideoConfig."; 1184 1185 if (video_configs_[0].codec() != config.codec()) { 1186 MEDIA_LOG(log_cb_) << "Video codec changes not allowed."; 1187 return false; 1188 } 1189 1190 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { 1191 MEDIA_LOG(log_cb_) << "Video encryption changes not allowed."; 1192 return false; 1193 } 1194 1195 // Check to see if the new config matches an existing one. 1196 for (size_t i = 0; i < video_configs_.size(); ++i) { 1197 if (config.Matches(video_configs_[i])) { 1198 append_config_index_ = i; 1199 return true; 1200 } 1201 } 1202 1203 // No matches found so let's add this one to the list. 1204 append_config_index_ = video_configs_.size(); 1205 DVLOG(2) << "New video config - index: " << append_config_index_; 1206 video_configs_.resize(video_configs_.size() + 1); 1207 video_configs_[append_config_index_] = config; 1208 return true; 1209 } 1210 1211 void SourceBufferStream::CompleteConfigChange() { 1212 config_change_pending_ = false; 1213 1214 if (pending_buffer_.get()) { 1215 current_config_index_ = 1216 pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_); 1217 return; 1218 } 1219 1220 if (!track_buffer_.empty()) { 1221 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); 1222 return; 1223 } 1224 1225 if (selected_range_ && selected_range_->HasNextBuffer()) 1226 current_config_index_ = selected_range_->GetNextConfigId(); 1227 } 1228 1229 void SourceBufferStream::SetSelectedRangeIfNeeded( 1230 const DecodeTimestamp timestamp) { 1231 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; 1232 1233 if (selected_range_) { 1234 DCHECK(track_buffer_.empty()); 1235 return; 1236 } 1237 1238 if (!track_buffer_.empty()) { 1239 DCHECK(!selected_range_); 1240 return; 1241 } 1242 1243 DecodeTimestamp start_timestamp = timestamp; 1244 1245 // If the next buffer timestamp is not known then use a timestamp just after 1246 // the timestamp on the last buffer returned by GetNextBuffer(). 1247 if (start_timestamp == kNoDecodeTimestamp()) { 1248 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) 1249 return; 1250 1251 start_timestamp = last_output_buffer_timestamp_ + 1252 base::TimeDelta::FromInternalValue(1); 1253 } 1254 1255 DecodeTimestamp seek_timestamp = 1256 FindNewSelectedRangeSeekTimestamp(start_timestamp); 1257 1258 // If we don't have buffered data to seek to, then return. 1259 if (seek_timestamp == kNoDecodeTimestamp()) 1260 return; 1261 1262 DCHECK(track_buffer_.empty()); 1263 SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp), 1264 seek_timestamp); 1265 } 1266 1267 DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp( 1268 const DecodeTimestamp start_timestamp) { 1269 DCHECK(start_timestamp != kNoDecodeTimestamp()); 1270 DCHECK(start_timestamp >= DecodeTimestamp()); 1271 1272 RangeList::iterator itr = ranges_.begin(); 1273 1274 for (; itr != ranges_.end(); ++itr) { 1275 if ((*itr)->GetEndTimestamp() >= start_timestamp) { 1276 break; 1277 } 1278 } 1279 1280 if (itr == ranges_.end()) 1281 return kNoDecodeTimestamp(); 1282 1283 // First check for a keyframe timestamp >= |start_timestamp| 1284 // in the current range. 1285 DecodeTimestamp keyframe_timestamp = 1286 (*itr)->NextKeyframeTimestamp(start_timestamp); 1287 1288 if (keyframe_timestamp != kNoDecodeTimestamp()) 1289 return keyframe_timestamp; 1290 1291 // If a keyframe was not found then look for a keyframe that is 1292 // "close enough" in the current or next range. 1293 DecodeTimestamp end_timestamp = 1294 start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1295 DCHECK(start_timestamp < end_timestamp); 1296 1297 // Make sure the current range doesn't start beyond |end_timestamp|. 1298 if ((*itr)->GetStartTimestamp() >= end_timestamp) 1299 return kNoDecodeTimestamp(); 1300 1301 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp); 1302 1303 // Check to see if the keyframe is within the acceptable range 1304 // (|start_timestamp|, |end_timestamp|]. 1305 if (keyframe_timestamp != kNoDecodeTimestamp() && 1306 start_timestamp < keyframe_timestamp && 1307 keyframe_timestamp <= end_timestamp) { 1308 return keyframe_timestamp; 1309 } 1310 1311 // If |end_timestamp| is within this range, then no other checks are 1312 // necessary. 1313 if (end_timestamp <= (*itr)->GetEndTimestamp()) 1314 return kNoDecodeTimestamp(); 1315 1316 // Move on to the next range. 1317 ++itr; 1318 1319 // Return early if the next range does not contain |end_timestamp|. 1320 if (itr == ranges_.end() || (*itr)->GetStartTimestamp() >= end_timestamp) 1321 return kNoDecodeTimestamp(); 1322 1323 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp); 1324 1325 // Check to see if the keyframe is within the acceptable range 1326 // (|start_timestamp|, |end_timestamp|]. 1327 if (keyframe_timestamp != kNoDecodeTimestamp() && 1328 start_timestamp < keyframe_timestamp && 1329 keyframe_timestamp <= end_timestamp) { 1330 return keyframe_timestamp; 1331 } 1332 1333 return kNoDecodeTimestamp(); 1334 } 1335 1336 DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp( 1337 const DecodeTimestamp timestamp) { 1338 DCHECK(timestamp != kNoDecodeTimestamp()); 1339 1340 RangeList::iterator itr = FindExistingRangeFor(timestamp); 1341 1342 if (itr == ranges_.end()) 1343 return kNoDecodeTimestamp(); 1344 1345 // First check for a keyframe timestamp >= |timestamp| 1346 // in the current range. 1347 return (*itr)->NextKeyframeTimestamp(timestamp); 1348 } 1349 1350 std::string SourceBufferStream::GetStreamTypeName() const { 1351 switch (GetType()) { 1352 case kAudio: 1353 return "AUDIO"; 1354 case kVideo: 1355 return "VIDEO"; 1356 case kText: 1357 return "TEXT"; 1358 } 1359 NOTREACHED(); 1360 return ""; 1361 } 1362 1363 SourceBufferStream::Type SourceBufferStream::GetType() const { 1364 if (!audio_configs_.empty()) 1365 return kAudio; 1366 if (!video_configs_.empty()) 1367 return kVideo; 1368 DCHECK_NE(text_track_config_.kind(), kTextNone); 1369 return kText; 1370 } 1371 1372 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) { 1373 DVLOG(1) << __FUNCTION__; 1374 1375 DCHECK(*itr != ranges_.end()); 1376 if (**itr == selected_range_) { 1377 DVLOG(1) << __FUNCTION__ << " deleting selected range."; 1378 SetSelectedRange(NULL); 1379 } 1380 1381 if (*itr == range_for_next_append_) { 1382 DVLOG(1) << __FUNCTION__ << " deleting range_for_next_append_."; 1383 range_for_next_append_ = ranges_.end(); 1384 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 1385 last_appended_buffer_is_keyframe_ = false; 1386 } 1387 1388 delete **itr; 1389 *itr = ranges_.erase(*itr); 1390 } 1391 1392 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { 1393 DCHECK(!new_buffers.empty()); 1394 1395 // Splice frames are only supported for audio. 1396 if (GetType() != kAudio) 1397 return; 1398 1399 // Find the overlapped range (if any). 1400 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp(); 1401 const DecodeTimestamp splice_dts = 1402 DecodeTimestamp::FromPresentationTime(splice_timestamp); 1403 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts); 1404 if (range_itr == ranges_.end()) 1405 return; 1406 1407 const DecodeTimestamp max_splice_end_dts = 1408 splice_dts + base::TimeDelta::FromMilliseconds( 1409 AudioSplicer::kCrossfadeDurationInMilliseconds); 1410 1411 // Find all buffers involved before the splice point. 1412 BufferQueue pre_splice_buffers; 1413 if (!(*range_itr)->GetBuffersInRange( 1414 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { 1415 return; 1416 } 1417 1418 // If there are gaps in the timeline, it's possible that we only find buffers 1419 // after the splice point but within the splice range. For simplicity, we do 1420 // not generate splice frames in this case. 1421 // 1422 // We also do not want to generate splices if the first new buffer replaces an 1423 // existing buffer exactly. 1424 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) 1425 return; 1426 1427 // If any |pre_splice_buffers| are already splices or preroll, do not generate 1428 // a splice. 1429 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { 1430 const BufferQueue& original_splice_buffers = 1431 pre_splice_buffers[i]->splice_buffers(); 1432 if (!original_splice_buffers.empty()) { 1433 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " 1434 "pre-existing splice."; 1435 return; 1436 } 1437 1438 if (pre_splice_buffers[i]->preroll_buffer().get()) { 1439 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; 1440 return; 1441 } 1442 } 1443 1444 // Don't generate splice frames which represent less than two frames, since we 1445 // need at least that much to generate a crossfade. Per the spec, make this 1446 // check using the sample rate of the overlapping buffers. 1447 const base::TimeDelta splice_duration = 1448 pre_splice_buffers.back()->timestamp() + 1449 pre_splice_buffers.back()->duration() - splice_timestamp; 1450 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD( 1451 2.0 / audio_configs_[append_config_index_].samples_per_second()); 1452 if (splice_duration < minimum_splice_duration) { 1453 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " 1454 << splice_duration.InMicroseconds() << " us, but need " 1455 << minimum_splice_duration.InMicroseconds() << " us."; 1456 return; 1457 } 1458 1459 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); 1460 } 1461 1462 bool SourceBufferStream::SetPendingBuffer( 1463 scoped_refptr<StreamParserBuffer>* out_buffer) { 1464 DCHECK(out_buffer->get()); 1465 DCHECK(!pending_buffer_.get()); 1466 1467 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); 1468 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); 1469 1470 if (!have_splice_buffers && !have_preroll_buffer) 1471 return false; 1472 1473 DCHECK_NE(have_splice_buffers, have_preroll_buffer); 1474 splice_buffers_index_ = 0; 1475 pending_buffer_.swap(*out_buffer); 1476 pending_buffers_complete_ = false; 1477 return true; 1478 } 1479 1480 } // namespace media 1481