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 |