| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/source_buffer_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 186 |
| 187 SourceBufferStream::~SourceBufferStream() { | 187 SourceBufferStream::~SourceBufferStream() { |
| 188 while (!ranges_.empty()) { | 188 while (!ranges_.empty()) { |
| 189 delete ranges_.front(); | 189 delete ranges_.front(); |
| 190 ranges_.pop_front(); | 190 ranges_.pop_front(); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 | 193 |
| 194 void SourceBufferStream::OnStartOfCodedFrameGroup( | 194 void SourceBufferStream::OnStartOfCodedFrameGroup( |
| 195 DecodeTimestamp coded_frame_group_start_time) { | 195 DecodeTimestamp coded_frame_group_start_time) { |
| 196 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << " (" | 196 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" |
| 197 << coded_frame_group_start_time.InSecondsF() << ")"; | 197 << coded_frame_group_start_time.InSecondsF() << ")"; |
| 198 DCHECK(!end_of_stream_); | 198 DCHECK(!end_of_stream_); |
| 199 coded_frame_group_start_time_ = coded_frame_group_start_time; | 199 coded_frame_group_start_time_ = coded_frame_group_start_time; |
| 200 new_coded_frame_group_ = true; | 200 new_coded_frame_group_ = true; |
| 201 | 201 |
| 202 RangeList::iterator last_range = range_for_next_append_; | 202 RangeList::iterator last_range = range_for_next_append_; |
| 203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time); | 203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time); |
| 204 | 204 |
| 205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group | 205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group |
| 206 // is not adjacent to the previous coded frame group appended to the stream. | 206 // is not adjacent to the previous coded frame group appended to the stream. |
| 207 if (range_for_next_append_ == ranges_.end() || | 207 if (range_for_next_append_ == ranges_.end() || |
| 208 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 208 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
| 209 coded_frame_group_start_time)) { | 209 coded_frame_group_start_time)) { |
| 210 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 210 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); |
| 211 last_appended_buffer_duration_ = kNoTimestamp; | 211 last_appended_buffer_duration_ = kNoTimestamp; |
| 212 last_appended_buffer_is_keyframe_ = false; | 212 last_appended_buffer_is_keyframe_ = false; |
| 213 DVLOG(3) << __FUNCTION__ << " next appended buffers will " | 213 DVLOG(3) << __func__ << " next appended buffers will " |
| 214 << (range_for_next_append_ == ranges_.end() | 214 << (range_for_next_append_ == ranges_.end() |
| 215 ? "be in a new range" | 215 ? "be in a new range" |
| 216 : "overlap an existing range"); | 216 : "overlap an existing range"); |
| 217 } else if (last_range != ranges_.end()) { | 217 } else if (last_range != ranges_.end()) { |
| 218 DCHECK(last_range == range_for_next_append_); | 218 DCHECK(last_range == range_for_next_append_); |
| 219 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " | 219 DVLOG(3) << __func__ << " next appended buffers will continue range unless " |
| 220 << "unless intervening remove makes discontinuity"; | 220 << "intervening remove makes discontinuity"; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 bool SourceBufferStream::Append(const BufferQueue& buffers) { | 224 bool SourceBufferStream::Append(const BufferQueue& buffers) { |
| 225 TRACE_EVENT2("media", "SourceBufferStream::Append", | 225 TRACE_EVENT2("media", "SourceBufferStream::Append", |
| 226 "stream type", GetStreamTypeName(), | 226 "stream type", GetStreamTypeName(), |
| 227 "buffers to append", buffers.size()); | 227 "buffers to append", buffers.size()); |
| 228 | 228 |
| 229 DCHECK(!buffers.empty()); | 229 DCHECK(!buffers.empty()); |
| 230 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); | 230 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); |
| 231 DCHECK(coded_frame_group_start_time_ <= | 231 DCHECK(coded_frame_group_start_time_ <= |
| 232 buffers.front()->GetDecodeTimestamp()); | 232 buffers.front()->GetDecodeTimestamp()); |
| 233 DCHECK(!end_of_stream_); | 233 DCHECK(!end_of_stream_); |
| 234 | 234 |
| 235 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 235 DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": buffers " |
| 236 << ": buffers " << BufferQueueToLogString(buffers); | 236 << BufferQueueToLogString(buffers); |
| 237 | 237 |
| 238 // New coded frame groups emitted by the coded frame processor must begin with | 238 // New coded frame groups emitted by the coded frame processor must begin with |
| 239 // a keyframe. TODO(wolenetz): Change this to [DCHECK + MEDIA_LOG(ERROR...) + | 239 // a keyframe. TODO(wolenetz): Change this to [DCHECK + MEDIA_LOG(ERROR...) + |
| 240 // return false] once the CHECK has baked in a stable release. See | 240 // return false] once the CHECK has baked in a stable release. See |
| 241 // https://crbug.com/580621. | 241 // https://crbug.com/580621. |
| 242 CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame()); | 242 CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame()); |
| 243 | 243 |
| 244 // Buffers within a coded frame group should be monotonically increasing. | 244 // Buffers within a coded frame group should be monotonically increasing. |
| 245 if (!IsMonotonicallyIncreasing(buffers)) { | 245 if (!IsMonotonicallyIncreasing(buffers)) { |
| 246 return false; | 246 return false; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 while (itr != buffers.end() && !(*itr)->is_key_frame()) { | 305 while (itr != buffers.end() && !(*itr)->is_key_frame()) { |
| 306 ++itr; | 306 ++itr; |
| 307 } | 307 } |
| 308 | 308 |
| 309 // If we didn't find a key frame, then update the last appended | 309 // If we didn't find a key frame, then update the last appended |
| 310 // buffer state and return. | 310 // buffer state and return. |
| 311 if (itr == buffers.end()) { | 311 if (itr == buffers.end()) { |
| 312 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 312 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
| 313 last_appended_buffer_duration_ = buffers.back()->duration(); | 313 last_appended_buffer_duration_ = buffers.back()->duration(); |
| 314 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); | 314 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); |
| 315 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 315 DVLOG(1) << __func__ << " " << GetStreamTypeName() |
| 316 << ": new buffers in the middle of coded frame group depend on" | 316 << ": new buffers in the middle of coded frame group depend on" |
| 317 "keyframe that has been removed, and contain no keyframes." | 317 "keyframe that has been removed, and contain no keyframes." |
| 318 "Skipping further processing."; | 318 "Skipping further processing."; |
| 319 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 319 DVLOG(1) << __func__ << " " << GetStreamTypeName() |
| 320 << ": done. ranges_=" << RangesToString(ranges_); | 320 << ": done. ranges_=" << RangesToString(ranges_); |
| 321 return true; | 321 return true; |
| 322 } else if (itr != buffers.begin()) { | 322 } else if (itr != buffers.begin()) { |
| 323 // Copy the first key frame and everything after it into | 323 // Copy the first key frame and everything after it into |
| 324 // |trimmed_buffers|. | 324 // |trimmed_buffers|. |
| 325 trimmed_buffers.assign(itr, buffers.end()); | 325 trimmed_buffers.assign(itr, buffers.end()); |
| 326 buffers_for_new_range = &trimmed_buffers; | 326 buffers_for_new_range = &trimmed_buffers; |
| 327 } | 327 } |
| 328 | 328 |
| 329 new_range_start_time = | 329 new_range_start_time = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 359 deleted_buffers.front()->GetDecodeTimestamp(); | 359 deleted_buffers.front()->GetDecodeTimestamp(); |
| 360 | 360 |
| 361 DCHECK(track_buffer_.empty() || | 361 DCHECK(track_buffer_.empty() || |
| 362 track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted) | 362 track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted) |
| 363 << "decode timestamp " | 363 << "decode timestamp " |
| 364 << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec" | 364 << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec" |
| 365 << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec"; | 365 << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec"; |
| 366 | 366 |
| 367 track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(), | 367 track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(), |
| 368 deleted_buffers.end()); | 368 deleted_buffers.end()); |
| 369 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() << " Added " | 369 DVLOG(3) << __func__ << " " << GetStreamTypeName() << " Added " |
| 370 << deleted_buffers.size() | 370 << deleted_buffers.size() |
| 371 << " buffers to track buffer. TB size is now " | 371 << " buffers to track buffer. TB size is now " |
| 372 << track_buffer_.size(); | 372 << track_buffer_.size(); |
| 373 } else { | 373 } else { |
| 374 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 374 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
| 375 << " No deleted buffers for track buffer"; | 375 << " No deleted buffers for track buffer"; |
| 376 } | 376 } |
| 377 | 377 |
| 378 // Prune any extra buffers in |track_buffer_| if new keyframes | 378 // Prune any extra buffers in |track_buffer_| if new keyframes |
| 379 // are appended to the range covered by |track_buffer_|. | 379 // are appended to the range covered by |track_buffer_|. |
| 380 if (!track_buffer_.empty()) { | 380 if (!track_buffer_.empty()) { |
| 381 DecodeTimestamp keyframe_timestamp = | 381 DecodeTimestamp keyframe_timestamp = |
| 382 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); | 382 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); |
| 383 if (keyframe_timestamp != kNoDecodeTimestamp()) | 383 if (keyframe_timestamp != kNoDecodeTimestamp()) |
| 384 PruneTrackBuffer(keyframe_timestamp); | 384 PruneTrackBuffer(keyframe_timestamp); |
| 385 } | 385 } |
| 386 | 386 |
| 387 SetSelectedRangeIfNeeded(next_buffer_timestamp); | 387 SetSelectedRangeIfNeeded(next_buffer_timestamp); |
| 388 | 388 |
| 389 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 389 DVLOG(1) << __func__ << " " << GetStreamTypeName() |
| 390 << ": done. ranges_=" << RangesToString(ranges_); | 390 << ": done. ranges_=" << RangesToString(ranges_); |
| 391 DCHECK(IsRangeListSorted(ranges_)); | 391 DCHECK(IsRangeListSorted(ranges_)); |
| 392 DCHECK(OnlySelectedRangeIsSeeked()); | 392 DCHECK(OnlySelectedRangeIsSeeked()); |
| 393 return true; | 393 return true; |
| 394 } | 394 } |
| 395 | 395 |
| 396 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, | 396 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, |
| 397 base::TimeDelta duration) { | 397 base::TimeDelta duration) { |
| 398 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 398 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" |
| 399 << " (" << start.InSecondsF() << ", " << end.InSecondsF() | 399 << start.InSecondsF() << ", " << end.InSecondsF() << ", " |
| 400 << ", " << duration.InSecondsF() << ")"; | 400 << duration.InSecondsF() << ")"; |
| 401 DCHECK(start >= base::TimeDelta()) << start.InSecondsF(); | 401 DCHECK(start >= base::TimeDelta()) << start.InSecondsF(); |
| 402 DCHECK(start < end) << "start " << start.InSecondsF() | 402 DCHECK(start < end) << "start " << start.InSecondsF() |
| 403 << " end " << end.InSecondsF(); | 403 << " end " << end.InSecondsF(); |
| 404 DCHECK(duration != kNoTimestamp); | 404 DCHECK(duration != kNoTimestamp); |
| 405 | 405 |
| 406 DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start); | 406 DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start); |
| 407 DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end); | 407 DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end); |
| 408 DecodeTimestamp remove_end_timestamp = | 408 DecodeTimestamp remove_end_timestamp = |
| 409 DecodeTimestamp::FromPresentationTime(duration); | 409 DecodeTimestamp::FromPresentationTime(duration); |
| 410 DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts); | 410 DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts); |
| 411 if (keyframe_timestamp != kNoDecodeTimestamp()) { | 411 if (keyframe_timestamp != kNoDecodeTimestamp()) { |
| 412 remove_end_timestamp = keyframe_timestamp; | 412 remove_end_timestamp = keyframe_timestamp; |
| 413 } else if (end_dts < remove_end_timestamp) { | 413 } else if (end_dts < remove_end_timestamp) { |
| 414 remove_end_timestamp = end_dts; | 414 remove_end_timestamp = end_dts; |
| 415 } | 415 } |
| 416 | 416 |
| 417 BufferQueue deleted_buffers; | 417 BufferQueue deleted_buffers; |
| 418 RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers); | 418 RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers); |
| 419 | 419 |
| 420 if (!deleted_buffers.empty()) { | 420 if (!deleted_buffers.empty()) { |
| 421 // Buffers for the current position have been removed. | 421 // Buffers for the current position have been removed. |
| 422 SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp()); | 422 SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp()); |
| 423 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) { | 423 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) { |
| 424 // We just removed buffers for the current playback position for this | 424 // We just removed buffers for the current playback position for this |
| 425 // stream, yet we also had output no buffer since the last Seek. | 425 // stream, yet we also had output no buffer since the last Seek. |
| 426 // Re-seek to prevent stall. | 426 // Re-seek to prevent stall. |
| 427 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 427 DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": re-seeking to " |
| 428 << ": re-seeking to " << seek_buffer_timestamp_ | 428 << seek_buffer_timestamp_ |
| 429 << " to prevent stall if this time becomes buffered again"; | 429 << " to prevent stall if this time becomes buffered again"; |
| 430 Seek(seek_buffer_timestamp_); | 430 Seek(seek_buffer_timestamp_); |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 | 434 |
| 435 DecodeTimestamp SourceBufferStream::PotentialNextAppendTimestamp() const { | 435 DecodeTimestamp SourceBufferStream::PotentialNextAppendTimestamp() const { |
| 436 // The next potential append will either be just at or after | 436 // The next potential append will either be just at or after |
| 437 // |last_appended_buffer_timestamp_| (if known), or if unknown and we are | 437 // |last_appended_buffer_timestamp_| (if known), or if unknown and we are |
| 438 // still at the beginning of a new coded frame group, then will be into the | 438 // still at the beginning of a new coded frame group, then will be into the |
| (...skipping 12 matching lines...) Expand all Loading... |
| 451 // removed the ranged to which it previously belonged and have not completed a | 451 // removed the ranged to which it previously belonged and have not completed a |
| 452 // subsequent append or received a subsequent OnStartOfCodedFrameGroup() | 452 // subsequent append or received a subsequent OnStartOfCodedFrameGroup() |
| 453 // signal. | 453 // signal. |
| 454 return kNoDecodeTimestamp(); | 454 return kNoDecodeTimestamp(); |
| 455 } | 455 } |
| 456 | 456 |
| 457 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, | 457 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, |
| 458 DecodeTimestamp end, | 458 DecodeTimestamp end, |
| 459 bool exclude_start, | 459 bool exclude_start, |
| 460 BufferQueue* deleted_buffers) { | 460 BufferQueue* deleted_buffers) { |
| 461 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << " (" | 461 DVLOG(2) << __func__ << " " << GetStreamTypeName() << " (" |
| 462 << start.InSecondsF() << ", " << end.InSecondsF() << ", " | 462 << start.InSecondsF() << ", " << end.InSecondsF() << ", " |
| 463 << exclude_start << ")"; | 463 << exclude_start << ")"; |
| 464 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 464 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
| 465 << ": before remove ranges_=" << RangesToString(ranges_); | 465 << ": before remove ranges_=" << RangesToString(ranges_); |
| 466 | 466 |
| 467 DCHECK(start >= DecodeTimestamp()); | 467 DCHECK(start >= DecodeTimestamp()); |
| 468 DCHECK(start < end) << "start " << start.InSecondsF() | 468 DCHECK(start < end) << "start " << start.InSecondsF() |
| 469 << " end " << end.InSecondsF(); | 469 << " end " << end.InSecondsF(); |
| 470 DCHECK(deleted_buffers); | 470 DCHECK(deleted_buffers); |
| 471 | 471 |
| 472 RangeList::iterator itr = ranges_.begin(); | 472 RangeList::iterator itr = ranges_.begin(); |
| 473 | 473 |
| 474 while (itr != ranges_.end()) { | 474 while (itr != ranges_.end()) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 << " can't add to the current range."; | 539 << " can't add to the current range."; |
| 540 range_for_next_append_ = | 540 range_for_next_append_ = |
| 541 FindExistingRangeFor(potential_next_append_timestamp); | 541 FindExistingRangeFor(potential_next_append_timestamp); |
| 542 } | 542 } |
| 543 } | 543 } |
| 544 | 544 |
| 545 // Move on to the next range. | 545 // Move on to the next range. |
| 546 ++itr; | 546 ++itr; |
| 547 } | 547 } |
| 548 | 548 |
| 549 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 549 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
| 550 << ": after remove ranges_=" << RangesToString(ranges_); | 550 << ": after remove ranges_=" << RangesToString(ranges_); |
| 551 | 551 |
| 552 DCHECK(IsRangeListSorted(ranges_)); | 552 DCHECK(IsRangeListSorted(ranges_)); |
| 553 DCHECK(OnlySelectedRangeIsSeeked()); | 553 DCHECK(OnlySelectedRangeIsSeeked()); |
| 554 } | 554 } |
| 555 | 555 |
| 556 void SourceBufferStream::ResetSeekState() { | 556 void SourceBufferStream::ResetSeekState() { |
| 557 SetSelectedRange(NULL); | 557 SetSelectedRange(NULL); |
| 558 track_buffer_.clear(); | 558 track_buffer_.clear(); |
| 559 config_change_pending_ = false; | 559 config_change_pending_ = false; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 << ", currently buffered ranges_size=" << ranges_size; | 678 << ", currently buffered ranges_size=" << ranges_size; |
| 679 return false; | 679 return false; |
| 680 } | 680 } |
| 681 | 681 |
| 682 // Return if we're under or at the memory limit. | 682 // Return if we're under or at the memory limit. |
| 683 if (ranges_size + newDataSize <= memory_limit_) | 683 if (ranges_size + newDataSize <= memory_limit_) |
| 684 return true; | 684 return true; |
| 685 | 685 |
| 686 size_t bytes_to_free = ranges_size + newDataSize - memory_limit_; | 686 size_t bytes_to_free = ranges_size + newDataSize - memory_limit_; |
| 687 | 687 |
| 688 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC" | 688 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 689 << " media_time=" << media_time.InSecondsF() | 689 << ": Before GC media_time=" << media_time.InSecondsF() |
| 690 << " ranges_=" << RangesToString(ranges_) | 690 << " ranges_=" << RangesToString(ranges_) |
| 691 << " seek_pending_=" << seek_pending_ | 691 << " seek_pending_=" << seek_pending_ |
| 692 << " ranges_size=" << ranges_size | 692 << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize |
| 693 << " newDataSize=" << newDataSize | |
| 694 << " memory_limit_=" << memory_limit_ | 693 << " memory_limit_=" << memory_limit_ |
| 695 << " last_appended_buffer_timestamp_=" | 694 << " last_appended_buffer_timestamp_=" |
| 696 << last_appended_buffer_timestamp_.InSecondsF(); | 695 << last_appended_buffer_timestamp_.InSecondsF(); |
| 697 | 696 |
| 698 if (selected_range_ && !seek_pending_ && | 697 if (selected_range_ && !seek_pending_ && |
| 699 media_time > selected_range_->GetBufferedEndTimestamp()) { | 698 media_time > selected_range_->GetBufferedEndTimestamp()) { |
| 700 // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime) | 699 // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime) |
| 701 // should always be in the buffered ranges, but media::Pipeline uses audio | 700 // should always be in the buffered ranges, but media::Pipeline uses audio |
| 702 // stream as the main time source, when audio is present. | 701 // stream as the main time source, when audio is present. |
| 703 // In cases when audio and video streams have different buffered ranges, the | 702 // In cases when audio and video streams have different buffered ranges, the |
| 704 // |media_time| value might be slightly outside of the video stream buffered | 703 // |media_time| value might be slightly outside of the video stream buffered |
| 705 // range. In those cases we need to clamp |media_time| value to the current | 704 // range. In those cases we need to clamp |media_time| value to the current |
| 706 // stream buffered ranges, to ensure the MSE garbage collection algorithm | 705 // stream buffered ranges, to ensure the MSE garbage collection algorithm |
| 707 // works correctly (see crbug.com/563292 for details). | 706 // works correctly (see crbug.com/563292 for details). |
| 708 DecodeTimestamp selected_buffered_end = | 707 DecodeTimestamp selected_buffered_end = |
| 709 selected_range_->GetBufferedEndTimestamp(); | 708 selected_range_->GetBufferedEndTimestamp(); |
| 710 | 709 |
| 711 DVLOG(2) << __FUNCTION__ << " media_time " << media_time.InSecondsF() | 710 DVLOG(2) << __func__ << " media_time " << media_time.InSecondsF() |
| 712 << " is outside of selected_range_=[" | 711 << " is outside of selected_range_=[" |
| 713 << selected_range_->GetStartTimestamp().InSecondsF() << ";" | 712 << selected_range_->GetStartTimestamp().InSecondsF() << ";" |
| 714 << selected_buffered_end.InSecondsF() | 713 << selected_buffered_end.InSecondsF() |
| 715 << "] clamping media_time to be " | 714 << "] clamping media_time to be " |
| 716 << selected_buffered_end.InSecondsF(); | 715 << selected_buffered_end.InSecondsF(); |
| 717 media_time = selected_buffered_end; | 716 media_time = selected_buffered_end; |
| 718 } | 717 } |
| 719 | 718 |
| 720 size_t bytes_freed = 0; | 719 size_t bytes_freed = 0; |
| 721 | 720 |
| 722 // If last appended buffer position was earlier than the current playback time | 721 // If last appended buffer position was earlier than the current playback time |
| 723 // then try deleting data between last append and current media_time. | 722 // then try deleting data between last append and current media_time. |
| 724 if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp() && | 723 if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp() && |
| 725 last_appended_buffer_duration_ != kNoTimestamp && | 724 last_appended_buffer_duration_ != kNoTimestamp && |
| 726 media_time > | 725 media_time > |
| 727 last_appended_buffer_timestamp_ + last_appended_buffer_duration_) { | 726 last_appended_buffer_timestamp_ + last_appended_buffer_duration_) { |
| 728 size_t between = FreeBuffersAfterLastAppended(bytes_to_free, media_time); | 727 size_t between = FreeBuffersAfterLastAppended(bytes_to_free, media_time); |
| 729 DVLOG(3) << __FUNCTION__ << " FreeBuffersAfterLastAppended " | 728 DVLOG(3) << __func__ << " FreeBuffersAfterLastAppended " |
| 730 << " released " << between << " bytes" | 729 << " released " << between << " bytes" |
| 731 << " ranges_=" << RangesToString(ranges_); | 730 << " ranges_=" << RangesToString(ranges_); |
| 732 bytes_freed += between; | 731 bytes_freed += between; |
| 733 | 732 |
| 734 // Some players start appending data at the new seek target position before | 733 // Some players start appending data at the new seek target position before |
| 735 // actually initiating the seek operation (i.e. they try to improve seek | 734 // actually initiating the seek operation (i.e. they try to improve seek |
| 736 // performance by prebuffering some data at the seek target position and | 735 // performance by prebuffering some data at the seek target position and |
| 737 // initiating seek once enough data is pre-buffered. In those cases we'll | 736 // initiating seek once enough data is pre-buffered. In those cases we'll |
| 738 // see that data is being appended at some new position, but there is no | 737 // see that data is being appended at some new position, but there is no |
| 739 // pending seek reported yet. In this situation we need to try preserving | 738 // pending seek reported yet. In this situation we need to try preserving |
| 740 // the most recently appended data, i.e. data belonging to the same buffered | 739 // the most recently appended data, i.e. data belonging to the same buffered |
| 741 // range as the most recent append. | 740 // range as the most recent append. |
| 742 if (range_for_next_append_ != ranges_.end()) { | 741 if (range_for_next_append_ != ranges_.end()) { |
| 743 DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time); | 742 DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time); |
| 744 media_time = (*range_for_next_append_)->GetStartTimestamp(); | 743 media_time = (*range_for_next_append_)->GetStartTimestamp(); |
| 745 DVLOG(3) << __FUNCTION__ << " media_time adjusted to " | 744 DVLOG(3) << __func__ << " media_time adjusted to " |
| 746 << media_time.InSecondsF(); | 745 << media_time.InSecondsF(); |
| 747 } | 746 } |
| 748 } | 747 } |
| 749 | 748 |
| 750 // If there is an unsatisfied pending seek, we can safely remove all data that | 749 // If there is an unsatisfied pending seek, we can safely remove all data that |
| 751 // is earlier than seek target, then remove from the back until we reach the | 750 // is earlier than seek target, then remove from the back until we reach the |
| 752 // most recently appended GOP and then remove from the front if we still don't | 751 // most recently appended GOP and then remove from the front if we still don't |
| 753 // have enough space for the upcoming append. | 752 // have enough space for the upcoming append. |
| 754 if (bytes_freed < bytes_to_free && seek_pending_) { | 753 if (bytes_freed < bytes_to_free && seek_pending_) { |
| 755 DCHECK(!ranges_.empty()); | 754 DCHECK(!ranges_.empty()); |
| 756 // All data earlier than the seek target |media_time| can be removed safely | 755 // All data earlier than the seek target |media_time| can be removed safely |
| 757 size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false); | 756 size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false); |
| 758 DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the" | 757 DVLOG(3) << __func__ << " Removed " << front |
| 759 << " front. ranges_=" << RangesToString(ranges_); | 758 << " bytes from the front. ranges_=" << RangesToString(ranges_); |
| 760 bytes_freed += front; | 759 bytes_freed += front; |
| 761 | 760 |
| 762 // If removing data earlier than |media_time| didn't free up enough space, | 761 // If removing data earlier than |media_time| didn't free up enough space, |
| 763 // then try deleting from the back until we reach most recently appended GOP | 762 // then try deleting from the back until we reach most recently appended GOP |
| 764 if (bytes_freed < bytes_to_free) { | 763 if (bytes_freed < bytes_to_free) { |
| 765 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); | 764 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); |
| 766 DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back" | 765 DVLOG(3) << __func__ << " Removed " << back |
| 767 << " ranges_=" << RangesToString(ranges_); | 766 << " bytes from the back. ranges_=" << RangesToString(ranges_); |
| 768 bytes_freed += back; | 767 bytes_freed += back; |
| 769 } | 768 } |
| 770 | 769 |
| 771 // If even that wasn't enough, then try greedily deleting from the front, | 770 // If even that wasn't enough, then try greedily deleting from the front, |
| 772 // that should allow us to remove as much data as necessary to succeed. | 771 // that should allow us to remove as much data as necessary to succeed. |
| 773 if (bytes_freed < bytes_to_free) { | 772 if (bytes_freed < bytes_to_free) { |
| 774 size_t front2 = FreeBuffers(bytes_to_free - bytes_freed, | 773 size_t front2 = FreeBuffers(bytes_to_free - bytes_freed, |
| 775 ranges_.back()->GetEndTimestamp(), false); | 774 ranges_.back()->GetEndTimestamp(), false); |
| 776 DVLOG(3) << __FUNCTION__ << " Removed " << front2 << " bytes from the" | 775 DVLOG(3) << __func__ << " Removed " << front2 |
| 777 << " front. ranges_=" << RangesToString(ranges_); | 776 << " bytes from the front. ranges_=" << RangesToString(ranges_); |
| 778 bytes_freed += front2; | 777 bytes_freed += front2; |
| 779 } | 778 } |
| 780 DCHECK(bytes_freed >= bytes_to_free); | 779 DCHECK(bytes_freed >= bytes_to_free); |
| 781 } | 780 } |
| 782 | 781 |
| 783 // Try removing data from the front of the SourceBuffer up to |media_time| | 782 // Try removing data from the front of the SourceBuffer up to |media_time| |
| 784 // position. | 783 // position. |
| 785 if (bytes_freed < bytes_to_free) { | 784 if (bytes_freed < bytes_to_free) { |
| 786 size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false); | 785 size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false); |
| 787 DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the" | 786 DVLOG(3) << __func__ << " Removed " << front |
| 788 << " front. ranges_=" << RangesToString(ranges_); | 787 << " bytes from the front. ranges_=" << RangesToString(ranges_); |
| 789 bytes_freed += front; | 788 bytes_freed += front; |
| 790 } | 789 } |
| 791 | 790 |
| 792 // Try removing data from the back of the SourceBuffer, until we reach the | 791 // Try removing data from the back of the SourceBuffer, until we reach the |
| 793 // most recent append position. | 792 // most recent append position. |
| 794 if (bytes_freed < bytes_to_free) { | 793 if (bytes_freed < bytes_to_free) { |
| 795 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); | 794 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); |
| 796 DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back." | 795 DVLOG(3) << __func__ << " Removed " << back |
| 797 << " ranges_=" << RangesToString(ranges_); | 796 << " bytes from the back. ranges_=" << RangesToString(ranges_); |
| 798 bytes_freed += back; | 797 bytes_freed += back; |
| 799 } | 798 } |
| 800 | 799 |
| 801 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": After GC" | 800 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 802 << " bytes_to_free=" << bytes_to_free | 801 << ": After GC bytes_to_free=" << bytes_to_free |
| 803 << " bytes_freed=" << bytes_freed | 802 << " bytes_freed=" << bytes_freed |
| 804 << " ranges_=" << RangesToString(ranges_); | 803 << " ranges_=" << RangesToString(ranges_); |
| 805 | 804 |
| 806 return bytes_freed >= bytes_to_free; | 805 return bytes_freed >= bytes_to_free; |
| 807 } | 806 } |
| 808 | 807 |
| 809 size_t SourceBufferStream::FreeBuffersAfterLastAppended( | 808 size_t SourceBufferStream::FreeBuffersAfterLastAppended( |
| 810 size_t total_bytes_to_free, DecodeTimestamp media_time) { | 809 size_t total_bytes_to_free, DecodeTimestamp media_time) { |
| 811 DVLOG(4) << __FUNCTION__ << " last_appended_buffer_timestamp_=" | 810 DVLOG(4) << __func__ << " last_appended_buffer_timestamp_=" |
| 812 << last_appended_buffer_timestamp_.InSecondsF() | 811 << last_appended_buffer_timestamp_.InSecondsF() |
| 813 << " media_time=" << media_time.InSecondsF(); | 812 << " media_time=" << media_time.InSecondsF(); |
| 814 | 813 |
| 815 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; | 814 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; |
| 816 if (last_appended_buffer_is_keyframe_) | 815 if (last_appended_buffer_is_keyframe_) |
| 817 remove_range_start += GetMaxInterbufferDistance(); | 816 remove_range_start += GetMaxInterbufferDistance(); |
| 818 | 817 |
| 819 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( | 818 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( |
| 820 remove_range_start); | 819 remove_range_start); |
| 821 if (remove_range_start_keyframe != kNoDecodeTimestamp()) | 820 if (remove_range_start_keyframe != kNoDecodeTimestamp()) |
| 822 remove_range_start = remove_range_start_keyframe; | 821 remove_range_start = remove_range_start_keyframe; |
| 823 if (remove_range_start >= media_time) | 822 if (remove_range_start >= media_time) |
| 824 return 0; | 823 return 0; |
| 825 | 824 |
| 826 DecodeTimestamp remove_range_end; | 825 DecodeTimestamp remove_range_end; |
| 827 size_t bytes_freed = GetRemovalRange(remove_range_start, | 826 size_t bytes_freed = GetRemovalRange(remove_range_start, |
| 828 media_time, | 827 media_time, |
| 829 total_bytes_to_free, | 828 total_bytes_to_free, |
| 830 &remove_range_end); | 829 &remove_range_end); |
| 831 if (bytes_freed > 0) { | 830 if (bytes_freed > 0) { |
| 832 DVLOG(4) << __FUNCTION__ << " removing [" | 831 DVLOG(4) << __func__ << " removing [" |
| 833 << remove_range_start.ToPresentationTime().InSecondsF() << ";" | 832 << remove_range_start.ToPresentationTime().InSecondsF() << ";" |
| 834 << remove_range_end.ToPresentationTime().InSecondsF() << "]"; | 833 << remove_range_end.ToPresentationTime().InSecondsF() << "]"; |
| 835 Remove(remove_range_start.ToPresentationTime(), | 834 Remove(remove_range_start.ToPresentationTime(), |
| 836 remove_range_end.ToPresentationTime(), | 835 remove_range_end.ToPresentationTime(), |
| 837 media_time.ToPresentationTime()); | 836 media_time.ToPresentationTime()); |
| 838 } | 837 } |
| 839 | 838 |
| 840 return bytes_freed; | 839 return bytes_freed; |
| 841 } | 840 } |
| 842 | 841 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 | 1035 |
| 1037 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { | 1036 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { |
| 1038 // If we don't have the next timestamp, we don't have anything to delete. | 1037 // If we don't have the next timestamp, we don't have anything to delete. |
| 1039 if (timestamp == kNoDecodeTimestamp()) | 1038 if (timestamp == kNoDecodeTimestamp()) |
| 1040 return; | 1039 return; |
| 1041 | 1040 |
| 1042 while (!track_buffer_.empty() && | 1041 while (!track_buffer_.empty() && |
| 1043 track_buffer_.back()->GetDecodeTimestamp() >= timestamp) { | 1042 track_buffer_.back()->GetDecodeTimestamp() >= timestamp) { |
| 1044 track_buffer_.pop_back(); | 1043 track_buffer_.pop_back(); |
| 1045 } | 1044 } |
| 1046 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 1045 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
| 1047 << " Removed all buffers with DTS >= " << timestamp.InSecondsF() | 1046 << " Removed all buffers with DTS >= " << timestamp.InSecondsF() |
| 1048 << ". New track buffer size:" << track_buffer_.size(); | 1047 << ". New track buffer size:" << track_buffer_.size(); |
| 1049 } | 1048 } |
| 1050 | 1049 |
| 1051 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( | 1050 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( |
| 1052 const RangeList::iterator& range_with_new_buffers_itr) { | 1051 const RangeList::iterator& range_with_new_buffers_itr) { |
| 1053 DCHECK(range_with_new_buffers_itr != ranges_.end()); | 1052 DCHECK(range_with_new_buffers_itr != ranges_.end()); |
| 1054 | 1053 |
| 1055 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 1054 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 1056 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 1055 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| 1057 ++next_range_itr; | 1056 ++next_range_itr; |
| 1058 | 1057 |
| 1059 if (next_range_itr == ranges_.end() || | 1058 if (next_range_itr == ranges_.end() || |
| 1060 !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) { | 1059 !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) { |
| 1061 return; | 1060 return; |
| 1062 } | 1061 } |
| 1063 | 1062 |
| 1064 bool transfer_current_position = selected_range_ == *next_range_itr; | 1063 bool transfer_current_position = selected_range_ == *next_range_itr; |
| 1065 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 1064 DVLOG(3) << __func__ << " " << GetStreamTypeName() << " merging " |
| 1066 << " merging " << RangeToString(*range_with_new_buffers) | 1065 << RangeToString(*range_with_new_buffers) << " into " |
| 1067 << " into " << RangeToString(**next_range_itr); | 1066 << RangeToString(**next_range_itr); |
| 1068 range_with_new_buffers->AppendRangeToEnd(**next_range_itr, | 1067 range_with_new_buffers->AppendRangeToEnd(**next_range_itr, |
| 1069 transfer_current_position); | 1068 transfer_current_position); |
| 1070 // Update |selected_range_| pointer if |range| has become selected after | 1069 // Update |selected_range_| pointer if |range| has become selected after |
| 1071 // merges. | 1070 // merges. |
| 1072 if (transfer_current_position) | 1071 if (transfer_current_position) |
| 1073 SetSelectedRange(range_with_new_buffers); | 1072 SetSelectedRange(range_with_new_buffers); |
| 1074 | 1073 |
| 1075 if (next_range_itr == range_for_next_append_) | 1074 if (next_range_itr == range_for_next_append_) |
| 1076 range_for_next_append_ = range_with_new_buffers_itr; | 1075 range_for_next_append_ = range_with_new_buffers_itr; |
| 1077 | 1076 |
| 1078 DeleteAndRemoveRange(&next_range_itr); | 1077 DeleteAndRemoveRange(&next_range_itr); |
| 1079 } | 1078 } |
| 1080 | 1079 |
| 1081 void SourceBufferStream::Seek(base::TimeDelta timestamp) { | 1080 void SourceBufferStream::Seek(base::TimeDelta timestamp) { |
| 1082 DCHECK(timestamp >= base::TimeDelta()); | 1081 DCHECK(timestamp >= base::TimeDelta()); |
| 1083 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 1082 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" |
| 1084 << " (" << timestamp.InSecondsF() << ")"; | 1083 << timestamp.InSecondsF() << ")"; |
| 1085 ResetSeekState(); | 1084 ResetSeekState(); |
| 1086 | 1085 |
| 1087 seek_buffer_timestamp_ = timestamp; | 1086 seek_buffer_timestamp_ = timestamp; |
| 1088 seek_pending_ = true; | 1087 seek_pending_ = true; |
| 1089 | 1088 |
| 1090 if (ShouldSeekToStartOfBuffered(timestamp)) { | 1089 if (ShouldSeekToStartOfBuffered(timestamp)) { |
| 1091 ranges_.front()->SeekToStart(); | 1090 ranges_.front()->SeekToStart(); |
| 1092 SetSelectedRange(ranges_.front()); | 1091 SetSelectedRange(ranges_.front()); |
| 1093 seek_pending_ = false; | 1092 seek_pending_ = false; |
| 1094 return; | 1093 return; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1109 seek_pending_ = false; | 1108 seek_pending_ = false; |
| 1110 } | 1109 } |
| 1111 | 1110 |
| 1112 bool SourceBufferStream::IsSeekPending() const { | 1111 bool SourceBufferStream::IsSeekPending() const { |
| 1113 return seek_pending_ && !IsEndOfStreamReached(); | 1112 return seek_pending_ && !IsEndOfStreamReached(); |
| 1114 } | 1113 } |
| 1115 | 1114 |
| 1116 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { | 1115 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { |
| 1117 DecodeTimestamp duration_dts = | 1116 DecodeTimestamp duration_dts = |
| 1118 DecodeTimestamp::FromPresentationTime(duration); | 1117 DecodeTimestamp::FromPresentationTime(duration); |
| 1119 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 1118 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" |
| 1120 << " (" << duration.InSecondsF() << ")"; | 1119 << duration.InSecondsF() << ")"; |
| 1121 | 1120 |
| 1122 RangeList::iterator itr = ranges_.end(); | 1121 RangeList::iterator itr = ranges_.end(); |
| 1123 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { | 1122 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { |
| 1124 if ((*itr)->GetEndTimestamp() > duration_dts) | 1123 if ((*itr)->GetEndTimestamp() > duration_dts) |
| 1125 break; | 1124 break; |
| 1126 } | 1125 } |
| 1127 if (itr == ranges_.end()) | 1126 if (itr == ranges_.end()) |
| 1128 return; | 1127 return; |
| 1129 | 1128 |
| 1130 // Need to partially truncate this range. | 1129 // Need to partially truncate this range. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1145 // If we're about to delete the selected range, also reset the seek state. | 1144 // If we're about to delete the selected range, also reset the seek state. |
| 1146 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); | 1145 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); |
| 1147 if (*itr == selected_range_) | 1146 if (*itr == selected_range_) |
| 1148 ResetSeekState(); | 1147 ResetSeekState(); |
| 1149 DeleteAndRemoveRange(&itr); | 1148 DeleteAndRemoveRange(&itr); |
| 1150 } | 1149 } |
| 1151 } | 1150 } |
| 1152 | 1151 |
| 1153 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1152 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
| 1154 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1153 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1155 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName(); | 1154 DVLOG(2) << __func__ << " " << GetStreamTypeName(); |
| 1156 if (!pending_buffer_.get()) { | 1155 if (!pending_buffer_.get()) { |
| 1157 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1156 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
| 1158 if (status != SourceBufferStream::kSuccess || | 1157 if (status != SourceBufferStream::kSuccess || |
| 1159 !SetPendingBuffer(out_buffer)) { | 1158 !SetPendingBuffer(out_buffer)) { |
| 1160 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1159 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1161 << ": no pending buffer, returning status " << status; | 1160 << ": no pending buffer, returning status " << status; |
| 1162 return status; | 1161 return status; |
| 1163 } | 1162 } |
| 1164 } | 1163 } |
| 1165 | 1164 |
| 1166 if (!pending_buffer_->splice_buffers().empty()) { | 1165 if (!pending_buffer_->splice_buffers().empty()) { |
| 1167 const SourceBufferStream::Status status = | 1166 const SourceBufferStream::Status status = |
| 1168 HandleNextBufferWithSplice(out_buffer); | 1167 HandleNextBufferWithSplice(out_buffer); |
| 1169 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1168 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1170 << ": handled next buffer with splice, returning status " | 1169 << ": handled next buffer with splice, returning status " |
| 1171 << status; | 1170 << status; |
| 1172 return status; | 1171 return status; |
| 1173 } | 1172 } |
| 1174 | 1173 |
| 1175 DCHECK(pending_buffer_->preroll_buffer().get()); | 1174 DCHECK(pending_buffer_->preroll_buffer().get()); |
| 1176 | 1175 |
| 1177 const SourceBufferStream::Status status = | 1176 const SourceBufferStream::Status status = |
| 1178 HandleNextBufferWithPreroll(out_buffer); | 1177 HandleNextBufferWithPreroll(out_buffer); |
| 1179 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1178 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1180 << ": handled next buffer with preroll, returning status " | 1179 << ": handled next buffer with preroll, returning status " << status; |
| 1181 << status; | |
| 1182 return status; | 1180 return status; |
| 1183 } | 1181 } |
| 1184 | 1182 |
| 1185 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( | 1183 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( |
| 1186 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1184 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1187 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); | 1185 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); |
| 1188 const size_t last_splice_buffer_index = splice_buffers.size() - 1; | 1186 const size_t last_splice_buffer_index = splice_buffers.size() - 1; |
| 1189 | 1187 |
| 1190 // Are there any splice buffers left to hand out? The last buffer should be | 1188 // Are there any splice buffers left to hand out? The last buffer should be |
| 1191 // handed out separately since it represents the first post-splice buffer. | 1189 // handed out separately since it represents the first post-splice buffer. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); | 1258 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); |
| 1261 | 1259 |
| 1262 // If the next buffer is an audio splice frame, the next effective config id | 1260 // If the next buffer is an audio splice frame, the next effective config id |
| 1263 // comes from the first splice buffer. | 1261 // comes from the first splice buffer. |
| 1264 if (next_buffer->GetSpliceBufferConfigId(0) != current_config_index_) { | 1262 if (next_buffer->GetSpliceBufferConfigId(0) != current_config_index_) { |
| 1265 config_change_pending_ = true; | 1263 config_change_pending_ = true; |
| 1266 DVLOG(1) << "Config change (track buffer config ID does not match)."; | 1264 DVLOG(1) << "Config change (track buffer config ID does not match)."; |
| 1267 return kConfigChange; | 1265 return kConfigChange; |
| 1268 } | 1266 } |
| 1269 | 1267 |
| 1270 DVLOG(3) << __FUNCTION__ << " Next buffer coming from track_buffer_"; | 1268 DVLOG(3) << __func__ << " Next buffer coming from track_buffer_"; |
| 1271 *out_buffer = next_buffer; | 1269 *out_buffer = next_buffer; |
| 1272 track_buffer_.pop_front(); | 1270 track_buffer_.pop_front(); |
| 1273 WarnIfTrackBufferExhaustionSkipsForward(*out_buffer); | 1271 WarnIfTrackBufferExhaustionSkipsForward(*out_buffer); |
| 1274 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); | 1272 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); |
| 1275 | 1273 |
| 1276 // If the track buffer becomes empty, then try to set the selected range | 1274 // If the track buffer becomes empty, then try to set the selected range |
| 1277 // based on the timestamp of this buffer being returned. | 1275 // based on the timestamp of this buffer being returned. |
| 1278 if (track_buffer_.empty()) { | 1276 if (track_buffer_.empty()) { |
| 1279 just_exhausted_track_buffer_ = true; | 1277 just_exhausted_track_buffer_ = true; |
| 1280 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); | 1278 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); |
| 1281 } | 1279 } |
| 1282 | 1280 |
| 1283 return kSuccess; | 1281 return kSuccess; |
| 1284 } | 1282 } |
| 1285 | 1283 |
| 1286 DCHECK(track_buffer_.empty()); | 1284 DCHECK(track_buffer_.empty()); |
| 1287 if (!selected_range_ || !selected_range_->HasNextBuffer()) { | 1285 if (!selected_range_ || !selected_range_->HasNextBuffer()) { |
| 1288 if (IsEndOfStreamReached()) { | 1286 if (IsEndOfStreamReached()) { |
| 1289 return kEndOfStream; | 1287 return kEndOfStream; |
| 1290 } | 1288 } |
| 1291 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 1289 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
| 1292 << ": returning kNeedBuffer " | 1290 << ": returning kNeedBuffer " |
| 1293 << (selected_range_ ? "(selected range has no next buffer)" | 1291 << (selected_range_ ? "(selected range has no next buffer)" |
| 1294 : "(no selected range)"); | 1292 : "(no selected range)"); |
| 1295 return kNeedBuffer; | 1293 return kNeedBuffer; |
| 1296 } | 1294 } |
| 1297 | 1295 |
| 1298 if (selected_range_->GetNextConfigId() != current_config_index_) { | 1296 if (selected_range_->GetNextConfigId() != current_config_index_) { |
| 1299 config_change_pending_ = true; | 1297 config_change_pending_ = true; |
| 1300 DVLOG(1) << "Config change (selected range config ID does not match)."; | 1298 DVLOG(1) << "Config change (selected range config ID does not match)."; |
| 1301 return kConfigChange; | 1299 return kConfigChange; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 } | 1372 } |
| 1375 | 1373 |
| 1376 void SourceBufferStream::SeekAndSetSelectedRange( | 1374 void SourceBufferStream::SeekAndSetSelectedRange( |
| 1377 SourceBufferRange* range, DecodeTimestamp seek_timestamp) { | 1375 SourceBufferRange* range, DecodeTimestamp seek_timestamp) { |
| 1378 if (range) | 1376 if (range) |
| 1379 range->Seek(seek_timestamp); | 1377 range->Seek(seek_timestamp); |
| 1380 SetSelectedRange(range); | 1378 SetSelectedRange(range); |
| 1381 } | 1379 } |
| 1382 | 1380 |
| 1383 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { | 1381 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { |
| 1384 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": " | 1382 DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": " << selected_range_ |
| 1385 << selected_range_ << " " | 1383 << " " << (selected_range_ ? RangeToString(*selected_range_) : "") |
| 1386 << (selected_range_ ? RangeToString(*selected_range_) : "") | |
| 1387 << " -> " << range << " " << (range ? RangeToString(*range) : ""); | 1384 << " -> " << range << " " << (range ? RangeToString(*range) : ""); |
| 1388 if (selected_range_) | 1385 if (selected_range_) |
| 1389 selected_range_->ResetNextBufferPosition(); | 1386 selected_range_->ResetNextBufferPosition(); |
| 1390 DCHECK(!range || range->HasNextBufferPosition()); | 1387 DCHECK(!range || range->HasNextBufferPosition()); |
| 1391 selected_range_ = range; | 1388 selected_range_ = range; |
| 1392 } | 1389 } |
| 1393 | 1390 |
| 1394 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { | 1391 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { |
| 1395 Ranges<base::TimeDelta> ranges; | 1392 Ranges<base::TimeDelta> ranges; |
| 1396 for (RangeList::const_iterator itr = ranges_.begin(); | 1393 for (RangeList::const_iterator itr = ranges_.begin(); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); | 1549 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); |
| 1553 return; | 1550 return; |
| 1554 } | 1551 } |
| 1555 | 1552 |
| 1556 if (selected_range_ && selected_range_->HasNextBuffer()) | 1553 if (selected_range_ && selected_range_->HasNextBuffer()) |
| 1557 current_config_index_ = selected_range_->GetNextConfigId(); | 1554 current_config_index_ = selected_range_->GetNextConfigId(); |
| 1558 } | 1555 } |
| 1559 | 1556 |
| 1560 void SourceBufferStream::SetSelectedRangeIfNeeded( | 1557 void SourceBufferStream::SetSelectedRangeIfNeeded( |
| 1561 const DecodeTimestamp timestamp) { | 1558 const DecodeTimestamp timestamp) { |
| 1562 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1559 DVLOG(2) << __func__ << " " << GetStreamTypeName() << "(" |
| 1563 << "(" << timestamp.InSecondsF() << ")"; | 1560 << timestamp.InSecondsF() << ")"; |
| 1564 | 1561 |
| 1565 if (selected_range_) { | 1562 if (selected_range_) { |
| 1566 DCHECK(track_buffer_.empty()); | 1563 DCHECK(track_buffer_.empty()); |
| 1567 return; | 1564 return; |
| 1568 } | 1565 } |
| 1569 | 1566 |
| 1570 if (!track_buffer_.empty()) { | 1567 if (!track_buffer_.empty()) { |
| 1571 DCHECK(!selected_range_); | 1568 DCHECK(!selected_range_); |
| 1572 return; | 1569 return; |
| 1573 } | 1570 } |
| 1574 | 1571 |
| 1575 DecodeTimestamp start_timestamp = timestamp; | 1572 DecodeTimestamp start_timestamp = timestamp; |
| 1576 | 1573 |
| 1577 // If the next buffer timestamp is not known then use a timestamp just after | 1574 // If the next buffer timestamp is not known then use a timestamp just after |
| 1578 // the timestamp on the last buffer returned by GetNextBuffer(). | 1575 // the timestamp on the last buffer returned by GetNextBuffer(). |
| 1579 if (start_timestamp == kNoDecodeTimestamp()) { | 1576 if (start_timestamp == kNoDecodeTimestamp()) { |
| 1580 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) { | 1577 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) { |
| 1581 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1578 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1582 << " no previous output timestamp"; | 1579 << " no previous output timestamp"; |
| 1583 return; | 1580 return; |
| 1584 } | 1581 } |
| 1585 | 1582 |
| 1586 start_timestamp = last_output_buffer_timestamp_ + | 1583 start_timestamp = last_output_buffer_timestamp_ + |
| 1587 base::TimeDelta::FromInternalValue(1); | 1584 base::TimeDelta::FromInternalValue(1); |
| 1588 } | 1585 } |
| 1589 | 1586 |
| 1590 DecodeTimestamp seek_timestamp = | 1587 DecodeTimestamp seek_timestamp = |
| 1591 FindNewSelectedRangeSeekTimestamp(start_timestamp); | 1588 FindNewSelectedRangeSeekTimestamp(start_timestamp); |
| 1592 | 1589 |
| 1593 // If we don't have buffered data to seek to, then return. | 1590 // If we don't have buffered data to seek to, then return. |
| 1594 if (seek_timestamp == kNoDecodeTimestamp()) { | 1591 if (seek_timestamp == kNoDecodeTimestamp()) { |
| 1595 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1592 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1596 << " couldn't find new selected range seek timestamp"; | 1593 << " couldn't find new selected range seek timestamp"; |
| 1597 return; | 1594 return; |
| 1598 } | 1595 } |
| 1599 | 1596 |
| 1600 DCHECK(track_buffer_.empty()); | 1597 DCHECK(track_buffer_.empty()); |
| 1601 SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp), | 1598 SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp), |
| 1602 seek_timestamp); | 1599 seek_timestamp); |
| 1603 } | 1600 } |
| 1604 | 1601 |
| 1605 DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp( | 1602 DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp( |
| 1606 const DecodeTimestamp start_timestamp) { | 1603 const DecodeTimestamp start_timestamp) { |
| 1607 DCHECK(start_timestamp != kNoDecodeTimestamp()); | 1604 DCHECK(start_timestamp != kNoDecodeTimestamp()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1627 if (start_timestamp < range_start && | 1624 if (start_timestamp < range_start && |
| 1628 start_timestamp_plus_fudge >= range_start) { | 1625 start_timestamp_plus_fudge >= range_start) { |
| 1629 search_timestamp = range_start; | 1626 search_timestamp = range_start; |
| 1630 } | 1627 } |
| 1631 DecodeTimestamp keyframe_timestamp = | 1628 DecodeTimestamp keyframe_timestamp = |
| 1632 (*itr)->NextKeyframeTimestamp(search_timestamp); | 1629 (*itr)->NextKeyframeTimestamp(search_timestamp); |
| 1633 if (keyframe_timestamp != kNoDecodeTimestamp()) | 1630 if (keyframe_timestamp != kNoDecodeTimestamp()) |
| 1634 return keyframe_timestamp; | 1631 return keyframe_timestamp; |
| 1635 } | 1632 } |
| 1636 | 1633 |
| 1637 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() | 1634 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1638 << " no buffered data for dts=" << start_timestamp.InSecondsF(); | 1635 << " no buffered data for dts=" << start_timestamp.InSecondsF(); |
| 1639 return kNoDecodeTimestamp(); | 1636 return kNoDecodeTimestamp(); |
| 1640 } | 1637 } |
| 1641 | 1638 |
| 1642 DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp( | 1639 DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp( |
| 1643 const DecodeTimestamp timestamp) { | 1640 const DecodeTimestamp timestamp) { |
| 1644 DCHECK(timestamp != kNoDecodeTimestamp()); | 1641 DCHECK(timestamp != kNoDecodeTimestamp()); |
| 1645 | 1642 |
| 1646 RangeList::iterator itr = FindExistingRangeFor(timestamp); | 1643 RangeList::iterator itr = FindExistingRangeFor(timestamp); |
| 1647 | 1644 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1669 SourceBufferStream::Type SourceBufferStream::GetType() const { | 1666 SourceBufferStream::Type SourceBufferStream::GetType() const { |
| 1670 if (!audio_configs_.empty()) | 1667 if (!audio_configs_.empty()) |
| 1671 return kAudio; | 1668 return kAudio; |
| 1672 if (!video_configs_.empty()) | 1669 if (!video_configs_.empty()) |
| 1673 return kVideo; | 1670 return kVideo; |
| 1674 DCHECK_NE(text_track_config_.kind(), kTextNone); | 1671 DCHECK_NE(text_track_config_.kind(), kTextNone); |
| 1675 return kText; | 1672 return kText; |
| 1676 } | 1673 } |
| 1677 | 1674 |
| 1678 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) { | 1675 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) { |
| 1679 DVLOG(1) << __FUNCTION__; | 1676 DVLOG(1) << __func__; |
| 1680 | 1677 |
| 1681 DCHECK(*itr != ranges_.end()); | 1678 DCHECK(*itr != ranges_.end()); |
| 1682 if (**itr == selected_range_) { | 1679 if (**itr == selected_range_) { |
| 1683 DVLOG(1) << __FUNCTION__ << " deleting selected range."; | 1680 DVLOG(1) << __func__ << " deleting selected range."; |
| 1684 SetSelectedRange(NULL); | 1681 SetSelectedRange(NULL); |
| 1685 } | 1682 } |
| 1686 | 1683 |
| 1687 if (*itr == range_for_next_append_) { | 1684 if (*itr == range_for_next_append_) { |
| 1688 DVLOG(1) << __FUNCTION__ << " deleting range_for_next_append_."; | 1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; |
| 1689 range_for_next_append_ = ranges_.end(); | 1686 range_for_next_append_ = ranges_.end(); |
| 1690 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); |
| 1691 last_appended_buffer_is_keyframe_ = false; | 1688 last_appended_buffer_is_keyframe_ = false; |
| 1692 } | 1689 } |
| 1693 | 1690 |
| 1694 delete **itr; | 1691 delete **itr; |
| 1695 *itr = ranges_.erase(*itr); | 1692 *itr = ranges_.erase(*itr); |
| 1696 } | 1693 } |
| 1697 | 1694 |
| 1698 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { | 1695 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 return false; | 1810 return false; |
| 1814 | 1811 |
| 1815 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 1816 splice_buffers_index_ = 0; | 1813 splice_buffers_index_ = 0; |
| 1817 pending_buffer_.swap(*out_buffer); | 1814 pending_buffer_.swap(*out_buffer); |
| 1818 pending_buffers_complete_ = false; | 1815 pending_buffers_complete_ = false; |
| 1819 return true; | 1816 return true; |
| 1820 } | 1817 } |
| 1821 | 1818 |
| 1822 } // namespace media | 1819 } // namespace media |
| OLD | NEW |