| 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 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 119 |
| 120 // Gets the range of GOP to secure at least |bytes_to_free| from | 120 // Gets the range of GOP to secure at least |bytes_to_free| from |
| 121 // [|start_timestamp|, |end_timestamp|). | 121 // [|start_timestamp|, |end_timestamp|). |
| 122 // Returns the size of the buffers to secure if the buffers of | 122 // Returns the size of the buffers to secure if the buffers of |
| 123 // [|start_timestamp|, |end_removal_timestamp|) is removed. | 123 // [|start_timestamp|, |end_removal_timestamp|) is removed. |
| 124 // Will not update |end_removal_timestamp| if the returned size is 0. | 124 // Will not update |end_removal_timestamp| if the returned size is 0. |
| 125 int GetRemovalGOP( | 125 int GetRemovalGOP( |
| 126 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, | 126 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, |
| 127 int bytes_to_free, base::TimeDelta* end_removal_timestamp); | 127 int bytes_to_free, base::TimeDelta* end_removal_timestamp); |
| 128 | 128 |
| 129 // Indicates whether the GOP at the beginning of the range |
| 130 // has timestamps all lower than |media_time|. |
| 131 bool FirstGOPEarlierThanMediaTime(base::TimeDelta media_time) const; |
| 132 |
| 129 // Indicates whether the GOP at the beginning or end of the range contains the | 133 // Indicates whether the GOP at the beginning or end of the range contains the |
| 130 // next buffer position. | 134 // next buffer position. |
| 131 bool FirstGOPContainsNextBufferPosition() const; | 135 bool FirstGOPContainsNextBufferPosition() const; |
| 132 bool LastGOPContainsNextBufferPosition() const; | 136 bool LastGOPContainsNextBufferPosition() const; |
| 133 | 137 |
| 134 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 138 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
| 135 // must be called before calls to GetNextBuffer(), and buffers are returned | 139 // must be called before calls to GetNextBuffer(), and buffers are returned |
| 136 // in order from the last call to Seek(). Returns true if |out_buffer| is | 140 // in order from the last call to Seek(). Returns true if |out_buffer| is |
| 137 // filled with a valid buffer, false if there is not enough data to fulfill | 141 // filled with a valid buffer, false if there is not enough data to fulfill |
| 138 // the request. | 142 // the request. |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 348 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
| 345 const LogCB& log_cb, | 349 const LogCB& log_cb, |
| 346 bool splice_frames_enabled) | 350 bool splice_frames_enabled) |
| 347 : log_cb_(log_cb), | 351 : log_cb_(log_cb), |
| 348 current_config_index_(0), | 352 current_config_index_(0), |
| 349 append_config_index_(0), | 353 append_config_index_(0), |
| 350 seek_pending_(false), | 354 seek_pending_(false), |
| 351 end_of_stream_(false), | 355 end_of_stream_(false), |
| 352 seek_buffer_timestamp_(kNoTimestamp()), | 356 seek_buffer_timestamp_(kNoTimestamp()), |
| 353 selected_range_(NULL), | 357 selected_range_(NULL), |
| 358 current_media_time_(kNoTimestamp()), |
| 354 media_segment_start_time_(kNoTimestamp()), | 359 media_segment_start_time_(kNoTimestamp()), |
| 355 range_for_next_append_(ranges_.end()), | 360 range_for_next_append_(ranges_.end()), |
| 356 new_media_segment_(false), | 361 new_media_segment_(false), |
| 357 last_appended_buffer_timestamp_(kNoTimestamp()), | 362 last_appended_buffer_timestamp_(kNoTimestamp()), |
| 358 last_appended_buffer_is_keyframe_(false), | 363 last_appended_buffer_is_keyframe_(false), |
| 359 last_output_buffer_timestamp_(kNoTimestamp()), | 364 last_output_buffer_timestamp_(kNoTimestamp()), |
| 360 max_interbuffer_distance_(kNoTimestamp()), | 365 max_interbuffer_distance_(kNoTimestamp()), |
| 361 memory_limit_(kDefaultAudioMemoryLimit), | 366 memory_limit_(kDefaultAudioMemoryLimit), |
| 362 config_change_pending_(false), | 367 config_change_pending_(false), |
| 363 splice_buffers_index_(0), | 368 splice_buffers_index_(0), |
| 364 pending_buffers_complete_(false), | 369 pending_buffers_complete_(false), |
| 365 splice_frames_enabled_(splice_frames_enabled) { | 370 splice_frames_enabled_(splice_frames_enabled) { |
| 366 DCHECK(audio_config.IsValidConfig()); | 371 DCHECK(audio_config.IsValidConfig()); |
| 367 audio_configs_.push_back(audio_config); | 372 audio_configs_.push_back(audio_config); |
| 368 } | 373 } |
| 369 | 374 |
| 370 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 375 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
| 371 const LogCB& log_cb, | 376 const LogCB& log_cb, |
| 372 bool splice_frames_enabled) | 377 bool splice_frames_enabled) |
| 373 : log_cb_(log_cb), | 378 : log_cb_(log_cb), |
| 374 current_config_index_(0), | 379 current_config_index_(0), |
| 375 append_config_index_(0), | 380 append_config_index_(0), |
| 376 seek_pending_(false), | 381 seek_pending_(false), |
| 377 end_of_stream_(false), | 382 end_of_stream_(false), |
| 378 seek_buffer_timestamp_(kNoTimestamp()), | 383 seek_buffer_timestamp_(kNoTimestamp()), |
| 379 selected_range_(NULL), | 384 selected_range_(NULL), |
| 385 current_media_time_(kNoTimestamp()), |
| 380 media_segment_start_time_(kNoTimestamp()), | 386 media_segment_start_time_(kNoTimestamp()), |
| 381 range_for_next_append_(ranges_.end()), | 387 range_for_next_append_(ranges_.end()), |
| 382 new_media_segment_(false), | 388 new_media_segment_(false), |
| 383 last_appended_buffer_timestamp_(kNoTimestamp()), | 389 last_appended_buffer_timestamp_(kNoTimestamp()), |
| 384 last_appended_buffer_is_keyframe_(false), | 390 last_appended_buffer_is_keyframe_(false), |
| 385 last_output_buffer_timestamp_(kNoTimestamp()), | 391 last_output_buffer_timestamp_(kNoTimestamp()), |
| 386 max_interbuffer_distance_(kNoTimestamp()), | 392 max_interbuffer_distance_(kNoTimestamp()), |
| 387 memory_limit_(kDefaultVideoMemoryLimit), | 393 memory_limit_(kDefaultVideoMemoryLimit), |
| 388 config_change_pending_(false), | 394 config_change_pending_(false), |
| 389 splice_buffers_index_(0), | 395 splice_buffers_index_(0), |
| 390 pending_buffers_complete_(false), | 396 pending_buffers_complete_(false), |
| 391 splice_frames_enabled_(splice_frames_enabled) { | 397 splice_frames_enabled_(splice_frames_enabled) { |
| 392 DCHECK(video_config.IsValidConfig()); | 398 DCHECK(video_config.IsValidConfig()); |
| 393 video_configs_.push_back(video_config); | 399 video_configs_.push_back(video_config); |
| 394 } | 400 } |
| 395 | 401 |
| 396 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 402 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
| 397 const LogCB& log_cb, | 403 const LogCB& log_cb, |
| 398 bool splice_frames_enabled) | 404 bool splice_frames_enabled) |
| 399 : log_cb_(log_cb), | 405 : log_cb_(log_cb), |
| 400 current_config_index_(0), | 406 current_config_index_(0), |
| 401 append_config_index_(0), | 407 append_config_index_(0), |
| 402 text_track_config_(text_config), | 408 text_track_config_(text_config), |
| 403 seek_pending_(false), | 409 seek_pending_(false), |
| 404 end_of_stream_(false), | 410 end_of_stream_(false), |
| 405 seek_buffer_timestamp_(kNoTimestamp()), | 411 seek_buffer_timestamp_(kNoTimestamp()), |
| 406 selected_range_(NULL), | 412 selected_range_(NULL), |
| 413 current_media_time_(kNoTimestamp()), |
| 407 media_segment_start_time_(kNoTimestamp()), | 414 media_segment_start_time_(kNoTimestamp()), |
| 408 range_for_next_append_(ranges_.end()), | 415 range_for_next_append_(ranges_.end()), |
| 409 new_media_segment_(false), | 416 new_media_segment_(false), |
| 410 last_appended_buffer_timestamp_(kNoTimestamp()), | 417 last_appended_buffer_timestamp_(kNoTimestamp()), |
| 411 last_appended_buffer_is_keyframe_(false), | 418 last_appended_buffer_is_keyframe_(false), |
| 412 last_output_buffer_timestamp_(kNoTimestamp()), | 419 last_output_buffer_timestamp_(kNoTimestamp()), |
| 413 max_interbuffer_distance_(kNoTimestamp()), | 420 max_interbuffer_distance_(kNoTimestamp()), |
| 414 memory_limit_(kDefaultAudioMemoryLimit), | 421 memory_limit_(kDefaultAudioMemoryLimit), |
| 415 config_change_pending_(false), | 422 config_change_pending_(false), |
| 416 splice_buffers_index_(0), | 423 splice_buffers_index_(0), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 438 if (range_for_next_append_ == ranges_.end() || | 445 if (range_for_next_append_ == ranges_.end() || |
| 439 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 446 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
| 440 media_segment_start_time)) { | 447 media_segment_start_time)) { |
| 441 last_appended_buffer_timestamp_ = kNoTimestamp(); | 448 last_appended_buffer_timestamp_ = kNoTimestamp(); |
| 442 last_appended_buffer_is_keyframe_ = false; | 449 last_appended_buffer_is_keyframe_ = false; |
| 443 } else if (last_range != ranges_.end()) { | 450 } else if (last_range != ranges_.end()) { |
| 444 DCHECK(last_range == range_for_next_append_); | 451 DCHECK(last_range == range_for_next_append_); |
| 445 } | 452 } |
| 446 } | 453 } |
| 447 | 454 |
| 448 bool SourceBufferStream::Append(const BufferQueue& buffers) { | 455 bool SourceBufferStream::Append(const BufferQueue& buffers, |
| 456 base::TimeDelta media_time) { |
| 449 TRACE_EVENT2("media", "SourceBufferStream::Append", | 457 TRACE_EVENT2("media", "SourceBufferStream::Append", |
| 450 "stream type", GetStreamTypeName(), | 458 "stream type", GetStreamTypeName(), |
| 451 "buffers to append", buffers.size()); | 459 "buffers to append", buffers.size()); |
| 452 | 460 |
| 453 DCHECK(!buffers.empty()); | 461 DCHECK(!buffers.empty()); |
| 454 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 462 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
| 455 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); | 463 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); |
| 456 DCHECK(!end_of_stream_); | 464 DCHECK(!end_of_stream_); |
| 457 | 465 |
| 458 // New media segments must begin with a keyframe. | 466 // New media segments must begin with a keyframe. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 // are appended to the range covered by |track_buffer_|. | 578 // are appended to the range covered by |track_buffer_|. |
| 571 if (!track_buffer_.empty()) { | 579 if (!track_buffer_.empty()) { |
| 572 base::TimeDelta keyframe_timestamp = | 580 base::TimeDelta keyframe_timestamp = |
| 573 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); | 581 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); |
| 574 if (keyframe_timestamp != kNoTimestamp()) | 582 if (keyframe_timestamp != kNoTimestamp()) |
| 575 PruneTrackBuffer(keyframe_timestamp); | 583 PruneTrackBuffer(keyframe_timestamp); |
| 576 } | 584 } |
| 577 | 585 |
| 578 SetSelectedRangeIfNeeded(next_buffer_timestamp); | 586 SetSelectedRangeIfNeeded(next_buffer_timestamp); |
| 579 | 587 |
| 580 GarbageCollectIfNeeded(); | 588 GarbageCollectIfNeeded(media_time); |
| 581 | 589 |
| 582 DCHECK(IsRangeListSorted(ranges_)); | 590 DCHECK(IsRangeListSorted(ranges_)); |
| 583 DCHECK(OnlySelectedRangeIsSeeked()); | 591 DCHECK(OnlySelectedRangeIsSeeked()); |
| 584 return true; | 592 return true; |
| 585 } | 593 } |
| 586 | 594 |
| 587 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, | 595 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, |
| 588 base::TimeDelta duration) { | 596 base::TimeDelta duration) { |
| 589 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() | 597 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF() |
| 590 << ", " << end.InSecondsF() | 598 << ", " << end.InSecondsF() |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 } | 792 } |
| 785 } | 793 } |
| 786 | 794 |
| 787 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { | 795 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { |
| 788 for (BufferQueue::const_iterator itr = buffers.begin(); | 796 for (BufferQueue::const_iterator itr = buffers.begin(); |
| 789 itr != buffers.end(); ++itr) { | 797 itr != buffers.end(); ++itr) { |
| 790 (*itr)->SetConfigId(append_config_index_); | 798 (*itr)->SetConfigId(append_config_index_); |
| 791 } | 799 } |
| 792 } | 800 } |
| 793 | 801 |
| 794 void SourceBufferStream::GarbageCollectIfNeeded() { | 802 void SourceBufferStream::GarbageCollectIfNeeded(base::TimeDelta media_time) { |
| 795 // Compute size of |ranges_|. | 803 // Compute size of |ranges_|. |
| 796 int ranges_size = 0; | 804 int ranges_size = 0; |
| 797 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) | 805 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) |
| 798 ranges_size += (*itr)->size_in_bytes(); | 806 ranges_size += (*itr)->size_in_bytes(); |
| 799 | 807 |
| 800 // Return if we're under or at the memory limit. | 808 // Return if we're under or at the memory limit. |
| 801 if (ranges_size <= memory_limit_) | 809 if (ranges_size <= memory_limit_) |
| 802 return; | 810 return; |
| 803 | 811 |
| 804 int bytes_to_free = ranges_size - memory_limit_; | 812 int bytes_to_free = ranges_size - memory_limit_; |
| 805 | 813 |
| 806 // Begin deleting after the last appended buffer. | 814 // Begin deleting after the last appended buffer. |
| 807 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); | 815 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); |
| 808 | 816 |
| 809 // Begin deleting from the front. | 817 // Begin deleting from the front. |
| 810 if (bytes_to_free - bytes_freed > 0) | 818 if (bytes_to_free - bytes_freed > 0) |
| 811 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); | 819 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false, media_time); |
| 812 | 820 |
| 813 // Begin deleting from the back. | 821 // Begin deleting from the back. |
| 814 if (bytes_to_free - bytes_freed > 0) | 822 if (bytes_to_free - bytes_freed > 0) |
| 815 FreeBuffers(bytes_to_free - bytes_freed, true); | 823 FreeBuffers(bytes_to_free - bytes_freed, true, media_time); |
| 816 } | 824 } |
| 817 | 825 |
| 818 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) { | 826 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) { |
| 819 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | 827 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
| 820 if (last_appended_buffer_timestamp_ == kNoTimestamp() || | 828 if (last_appended_buffer_timestamp_ == kNoTimestamp() || |
| 821 next_buffer_timestamp == kNoTimestamp() || | 829 next_buffer_timestamp == kNoTimestamp() || |
| 822 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { | 830 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { |
| 823 return 0; | 831 return 0; |
| 824 } | 832 } |
| 825 | 833 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 | 872 |
| 865 int bytes_removed = range->GetRemovalGOP( | 873 int bytes_removed = range->GetRemovalGOP( |
| 866 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); | 874 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); |
| 867 bytes_to_free -= bytes_removed; | 875 bytes_to_free -= bytes_removed; |
| 868 bytes_freed += bytes_removed; | 876 bytes_freed += bytes_removed; |
| 869 } | 877 } |
| 870 return bytes_freed; | 878 return bytes_freed; |
| 871 } | 879 } |
| 872 | 880 |
| 873 int SourceBufferStream::FreeBuffers(int total_bytes_to_free, | 881 int SourceBufferStream::FreeBuffers(int total_bytes_to_free, |
| 874 bool reverse_direction) { | 882 bool reverse_direction, |
| 883 base::TimeDelta media_time) { |
| 875 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", | 884 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", |
| 876 "total bytes to free", total_bytes_to_free, | 885 "total bytes to free", total_bytes_to_free, |
| 877 "reverse direction", reverse_direction); | 886 "reverse direction", reverse_direction); |
| 878 | 887 |
| 879 DCHECK_GT(total_bytes_to_free, 0); | 888 DCHECK_GT(total_bytes_to_free, 0); |
| 880 int bytes_to_free = total_bytes_to_free; | 889 int bytes_to_free = total_bytes_to_free; |
| 881 int bytes_freed = 0; | 890 int bytes_freed = 0; |
| 882 | 891 |
| 883 // This range will save the last GOP appended to |range_for_next_append_| | 892 // This range will save the last GOP appended to |range_for_next_append_| |
| 884 // if the buffers surrounding it get deleted during garbage collection. | 893 // if the buffers surrounding it get deleted during garbage collection. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 895 DCHECK_EQ(current_range, selected_range_); | 904 DCHECK_EQ(current_range, selected_range_); |
| 896 break; | 905 break; |
| 897 } | 906 } |
| 898 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); | 907 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); |
| 899 } else { | 908 } else { |
| 900 current_range = ranges_.front(); | 909 current_range = ranges_.front(); |
| 901 if (current_range->FirstGOPContainsNextBufferPosition()) { | 910 if (current_range->FirstGOPContainsNextBufferPosition()) { |
| 902 DCHECK_EQ(current_range, selected_range_); | 911 DCHECK_EQ(current_range, selected_range_); |
| 903 break; | 912 break; |
| 904 } | 913 } |
| 914 if (current_media_time_ != kNoTimestamp() && |
| 915 !current_range->FirstGOPEarlierThanMediaTime(media_time)) { |
| 916 break; |
| 917 } |
| 905 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); | 918 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); |
| 906 } | 919 } |
| 907 | 920 |
| 908 // Check to see if we've just deleted the GOP that was last appended. | 921 // Check to see if we've just deleted the GOP that was last appended. |
| 909 base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp(); | 922 base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp(); |
| 910 if (end_timestamp == last_appended_buffer_timestamp_) { | 923 if (end_timestamp == last_appended_buffer_timestamp_) { |
| 911 DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp()); | 924 DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp()); |
| 912 DCHECK(!new_range_for_append); | 925 DCHECK(!new_range_for_append); |
| 913 // Create a new range containing these buffers. | 926 // Create a new range containing these buffers. |
| 914 new_range_for_append = new SourceBufferRange( | 927 new_range_for_append = new SourceBufferRange( |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 // merges. | 1080 // merges. |
| 1068 if (transfer_current_position) | 1081 if (transfer_current_position) |
| 1069 SetSelectedRange(range_with_new_buffers); | 1082 SetSelectedRange(range_with_new_buffers); |
| 1070 | 1083 |
| 1071 if (next_range_itr == range_for_next_append_) | 1084 if (next_range_itr == range_for_next_append_) |
| 1072 range_for_next_append_ = range_with_new_buffers_itr; | 1085 range_for_next_append_ = range_with_new_buffers_itr; |
| 1073 | 1086 |
| 1074 DeleteAndRemoveRange(&next_range_itr); | 1087 DeleteAndRemoveRange(&next_range_itr); |
| 1075 } | 1088 } |
| 1076 | 1089 |
| 1090 void SourceBufferStream::NotifyMediaTimeUpdate(base::TimeDelta media_time) { |
| 1091 if (current_media_time_ != kNoTimestamp() && |
| 1092 media_time < current_media_time_) { |
| 1093 LOG(WARNING) << "Time should be monotonically increasing: " |
| 1094 << media_time.InMilliseconds() |
| 1095 << " " << current_media_time_.InMilliseconds(); |
| 1096 return; |
| 1097 } |
| 1098 current_media_time_ = media_time; |
| 1099 } |
| 1100 |
| 1077 void SourceBufferStream::Seek(base::TimeDelta timestamp) { | 1101 void SourceBufferStream::Seek(base::TimeDelta timestamp) { |
| 1078 DCHECK(timestamp >= base::TimeDelta()); | 1102 DCHECK(timestamp >= base::TimeDelta()); |
| 1079 ResetSeekState(); | 1103 ResetSeekState(); |
| 1080 | 1104 |
| 1105 current_media_time_ = kNoTimestamp(); |
| 1106 |
| 1081 if (ShouldSeekToStartOfBuffered(timestamp)) { | 1107 if (ShouldSeekToStartOfBuffered(timestamp)) { |
| 1082 ranges_.front()->SeekToStart(); | 1108 ranges_.front()->SeekToStart(); |
| 1083 SetSelectedRange(ranges_.front()); | 1109 SetSelectedRange(ranges_.front()); |
| 1084 seek_pending_ = false; | 1110 seek_pending_ = false; |
| 1085 return; | 1111 return; |
| 1086 } | 1112 } |
| 1087 | 1113 |
| 1088 seek_buffer_timestamp_ = timestamp; | 1114 seek_buffer_timestamp_ = timestamp; |
| 1089 seek_pending_ = true; | 1115 seek_pending_ = true; |
| 1090 | 1116 |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1981 bytes_removed += gop_size; | 2007 bytes_removed += gop_size; |
| 1982 bytes_to_free -= gop_size; | 2008 bytes_to_free -= gop_size; |
| 1983 } | 2009 } |
| 1984 if (bytes_removed > 0) { | 2010 if (bytes_removed > 0) { |
| 1985 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? | 2011 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? |
| 1986 GetBufferedEndTimestamp() : gop_itr->first; | 2012 GetBufferedEndTimestamp() : gop_itr->first; |
| 1987 } | 2013 } |
| 1988 return bytes_removed; | 2014 return bytes_removed; |
| 1989 } | 2015 } |
| 1990 | 2016 |
| 2017 bool SourceBufferRange::FirstGOPEarlierThanMediaTime( |
| 2018 base::TimeDelta media_time) const { |
| 2019 if (keyframe_map_.size() == 1u) |
| 2020 return (GetEndTimestamp() < media_time); |
| 2021 |
| 2022 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); |
| 2023 ++second_gop; |
| 2024 return second_gop->first <= media_time; |
| 2025 } |
| 2026 |
| 1991 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { | 2027 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { |
| 1992 if (!HasNextBufferPosition()) | 2028 if (!HasNextBufferPosition()) |
| 1993 return false; | 2029 return false; |
| 1994 | 2030 |
| 1995 // If there is only one GOP, it must contain the next buffer position. | 2031 // If there is only one GOP, it must contain the next buffer position. |
| 1996 if (keyframe_map_.size() == 1u) | 2032 if (keyframe_map_.size() == 1u) |
| 1997 return true; | 2033 return true; |
| 1998 | 2034 |
| 1999 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); | 2035 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); |
| 2000 ++second_gop; | 2036 ++second_gop; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 return false; | 2302 return false; |
| 2267 | 2303 |
| 2268 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 2304 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 2269 splice_buffers_index_ = 0; | 2305 splice_buffers_index_ = 0; |
| 2270 pending_buffer_.swap(*out_buffer); | 2306 pending_buffer_.swap(*out_buffer); |
| 2271 pending_buffers_complete_ = false; | 2307 pending_buffers_complete_ = false; |
| 2272 return true; | 2308 return true; |
| 2273 } | 2309 } |
| 2274 | 2310 |
| 2275 } // namespace media | 2311 } // namespace media |
| OLD | NEW |