| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/stl_util.h" |
| 12 | 13 |
| 13 namespace media { | 14 namespace media { |
| 14 | 15 |
| 15 // Helper class representing a range of buffered data. All buffers in a | 16 // Helper class representing a range of buffered data. All buffers in a |
| 16 // SourceBufferRange are ordered sequentially in presentation order with no | 17 // SourceBufferRange are ordered sequentially in presentation order with no |
| 17 // gaps. | 18 // gaps. |
| 18 class SourceBufferRange { | 19 class SourceBufferRange { |
| 19 public: | 20 public: |
| 20 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 21 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
| 21 | 22 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 bool DeleteAll(BufferQueue* deleted_buffers); | 87 bool DeleteAll(BufferQueue* deleted_buffers); |
| 87 | 88 |
| 88 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 89 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
| 89 // must be called before calls to GetNextBuffer(), and buffers are returned | 90 // must be called before calls to GetNextBuffer(), and buffers are returned |
| 90 // in order from the last call to Seek(). Returns true if |out_buffer| is | 91 // in order from the last call to Seek(). Returns true if |out_buffer| is |
| 91 // filled with a valid buffer, false if there is not enough data to fulfill | 92 // filled with a valid buffer, false if there is not enough data to fulfill |
| 92 // the request. | 93 // the request. |
| 93 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); | 94 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); |
| 94 bool HasNextBuffer() const; | 95 bool HasNextBuffer() const; |
| 95 | 96 |
| 97 // Returns the config ID for the buffer that will be returned by |
| 98 // GetNextBuffer(). |
| 99 int GetNextConfigId() const; |
| 100 |
| 96 // Returns true if the range knows the position of the next buffer it should | 101 // Returns true if the range knows the position of the next buffer it should |
| 97 // return, i.e. it has been Seek()ed. This does not necessarily mean that it | 102 // return, i.e. it has been Seek()ed. This does not necessarily mean that it |
| 98 // has the next buffer yet. | 103 // has the next buffer yet. |
| 99 bool HasNextBufferPosition() const; | 104 bool HasNextBufferPosition() const; |
| 100 | 105 |
| 101 // Resets this range to an "unseeked" state. | 106 // Resets this range to an "unseeked" state. |
| 102 void ResetNextBufferPosition(); | 107 void ResetNextBufferPosition(); |
| 103 | 108 |
| 104 // Returns the timestamp of the next buffer that will be returned from | 109 // Returns the timestamp of the next buffer that will be returned from |
| 105 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. | 110 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); | 227 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); |
| 223 } | 228 } |
| 224 | 229 |
| 225 // An arbitrarily-chosen number to estimate the duration of a buffer if none | 230 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
| 226 // is set and there's not enough information to get a better estimate. | 231 // is set and there's not enough information to get a better estimate. |
| 227 static int kDefaultBufferDurationInMs = 125; | 232 static int kDefaultBufferDurationInMs = 125; |
| 228 | 233 |
| 229 namespace media { | 234 namespace media { |
| 230 | 235 |
| 231 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) | 236 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) |
| 232 : stream_start_time_(kNoTimestamp()), | 237 : current_config_index_(0), |
| 238 append_config_index_(0), |
| 239 audio_configs_(1), |
| 240 video_configs_(0), |
| 241 stream_start_time_(kNoTimestamp()), |
| 233 seek_pending_(false), | 242 seek_pending_(false), |
| 234 seek_buffer_timestamp_(kNoTimestamp()), | 243 seek_buffer_timestamp_(kNoTimestamp()), |
| 235 selected_range_(NULL), | 244 selected_range_(NULL), |
| 236 media_segment_start_time_(kNoTimestamp()), | 245 media_segment_start_time_(kNoTimestamp()), |
| 237 range_for_next_append_(ranges_.end()), | 246 range_for_next_append_(ranges_.end()), |
| 238 new_media_segment_(false), | 247 new_media_segment_(false), |
| 239 last_buffer_timestamp_(kNoTimestamp()), | 248 last_buffer_timestamp_(kNoTimestamp()), |
| 240 max_interbuffer_distance_(kNoTimestamp()) { | 249 max_interbuffer_distance_(kNoTimestamp()) { |
| 241 audio_config_.CopyFrom(audio_config); | 250 audio_configs_[0] = new AudioDecoderConfig(); |
| 251 audio_configs_[0]->CopyFrom(audio_config); |
| 242 } | 252 } |
| 243 | 253 |
| 244 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) | 254 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) |
| 245 : stream_start_time_(kNoTimestamp()), | 255 : current_config_index_(0), |
| 256 append_config_index_(0), |
| 257 audio_configs_(0), |
| 258 video_configs_(1), |
| 259 stream_start_time_(kNoTimestamp()), |
| 246 seek_pending_(false), | 260 seek_pending_(false), |
| 247 seek_buffer_timestamp_(kNoTimestamp()), | 261 seek_buffer_timestamp_(kNoTimestamp()), |
| 248 selected_range_(NULL), | 262 selected_range_(NULL), |
| 249 media_segment_start_time_(kNoTimestamp()), | 263 media_segment_start_time_(kNoTimestamp()), |
| 250 range_for_next_append_(ranges_.end()), | 264 range_for_next_append_(ranges_.end()), |
| 251 new_media_segment_(false), | 265 new_media_segment_(false), |
| 252 last_buffer_timestamp_(kNoTimestamp()), | 266 last_buffer_timestamp_(kNoTimestamp()), |
| 253 max_interbuffer_distance_(kNoTimestamp()) { | 267 max_interbuffer_distance_(kNoTimestamp()) { |
| 254 video_config_.CopyFrom(video_config); | 268 video_configs_[0] = new VideoDecoderConfig(); |
| 269 video_configs_[0]->CopyFrom(video_config); |
| 255 } | 270 } |
| 256 | 271 |
| 257 SourceBufferStream::~SourceBufferStream() { | 272 SourceBufferStream::~SourceBufferStream() { |
| 258 while (!ranges_.empty()) { | 273 while (!ranges_.empty()) { |
| 259 delete ranges_.front(); | 274 delete ranges_.front(); |
| 260 ranges_.pop_front(); | 275 ranges_.pop_front(); |
| 261 } | 276 } |
| 277 |
| 278 STLDeleteElements(&audio_configs_); |
| 279 STLDeleteElements(&video_configs_); |
| 262 } | 280 } |
| 263 | 281 |
| 264 void SourceBufferStream::OnNewMediaSegment( | 282 void SourceBufferStream::OnNewMediaSegment( |
| 265 base::TimeDelta media_segment_start_time) { | 283 base::TimeDelta media_segment_start_time) { |
| 266 media_segment_start_time_ = media_segment_start_time; | 284 media_segment_start_time_ = media_segment_start_time; |
| 267 | 285 |
| 268 // Find the range that will house the buffers appended through the next | 286 // Find the range that will house the buffers appended through the next |
| 269 // Append() call. | 287 // Append() call. |
| 270 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 288 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
| 271 new_media_segment_ = true; | 289 new_media_segment_ = true; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 298 return false; | 316 return false; |
| 299 } | 317 } |
| 300 | 318 |
| 301 if (stream_start_time_ != kNoTimestamp() && | 319 if (stream_start_time_ != kNoTimestamp() && |
| 302 media_segment_start_time_ < stream_start_time_) { | 320 media_segment_start_time_ < stream_start_time_) { |
| 303 DVLOG(1) << "Cannot append a media segment before the start of stream."; | 321 DVLOG(1) << "Cannot append a media segment before the start of stream."; |
| 304 return false; | 322 return false; |
| 305 } | 323 } |
| 306 | 324 |
| 307 UpdateMaxInterbufferDistance(buffers); | 325 UpdateMaxInterbufferDistance(buffers); |
| 326 SetConfigIds(buffers); |
| 308 | 327 |
| 309 // Save a snapshot of stream state before range modifications are made. | 328 // Save a snapshot of stream state before range modifications are made. |
| 310 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | 329 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
| 311 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); | 330 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); |
| 312 | 331 |
| 313 bool deleted_next_buffer = false; | 332 bool deleted_next_buffer = false; |
| 314 BufferQueue deleted_buffers; | 333 BufferQueue deleted_buffers; |
| 315 | 334 |
| 316 RangeList::iterator range_for_new_buffers = range_for_next_append_; | 335 RangeList::iterator range_for_new_buffers = range_for_next_append_; |
| 317 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 336 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 max_interbuffer_distance_ = interbuffer_distance; | 435 max_interbuffer_distance_ = interbuffer_distance; |
| 417 } else { | 436 } else { |
| 418 max_interbuffer_distance_ = | 437 max_interbuffer_distance_ = |
| 419 std::max(max_interbuffer_distance_, interbuffer_distance); | 438 std::max(max_interbuffer_distance_, interbuffer_distance); |
| 420 } | 439 } |
| 421 } | 440 } |
| 422 prev_timestamp = current_timestamp; | 441 prev_timestamp = current_timestamp; |
| 423 } | 442 } |
| 424 } | 443 } |
| 425 | 444 |
| 445 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { |
| 446 for (BufferQueue::const_iterator itr = buffers.begin(); |
| 447 itr != buffers.end(); ++itr) { |
| 448 (*itr)->SetConfigId(append_config_index_); |
| 449 } |
| 450 } |
| 451 |
| 426 void SourceBufferStream::InsertIntoExistingRange( | 452 void SourceBufferStream::InsertIntoExistingRange( |
| 427 const RangeList::iterator& range_for_new_buffers_itr, | 453 const RangeList::iterator& range_for_new_buffers_itr, |
| 428 const BufferQueue& new_buffers, | 454 const BufferQueue& new_buffers, |
| 429 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 455 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 430 DCHECK(deleted_next_buffer); | 456 DCHECK(deleted_next_buffer); |
| 431 DCHECK(deleted_buffers); | 457 DCHECK(deleted_buffers); |
| 432 | 458 |
| 433 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 459 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
| 434 | 460 |
| 435 // If this is a simple case where we can just append to the end of the range, | 461 // If this is a simple case where we can just append to the end of the range, |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 | 672 |
| 647 SetSelectedRange(*itr); | 673 SetSelectedRange(*itr); |
| 648 selected_range_->Seek(timestamp); | 674 selected_range_->Seek(timestamp); |
| 649 seek_pending_ = false; | 675 seek_pending_ = false; |
| 650 } | 676 } |
| 651 | 677 |
| 652 bool SourceBufferStream::IsSeekPending() const { | 678 bool SourceBufferStream::IsSeekPending() const { |
| 653 return seek_pending_; | 679 return seek_pending_; |
| 654 } | 680 } |
| 655 | 681 |
| 656 bool SourceBufferStream::GetNextBuffer( | 682 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
| 657 scoped_refptr<StreamParserBuffer>* out_buffer) { | 683 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 658 if (!track_buffer_.empty()) { | 684 if (!track_buffer_.empty()) { |
| 685 if (track_buffer_.front()->GetConfigId() != current_config_index_) |
| 686 return kConfigChange; |
| 687 |
| 659 *out_buffer = track_buffer_.front(); | 688 *out_buffer = track_buffer_.front(); |
| 660 track_buffer_.pop_front(); | 689 track_buffer_.pop_front(); |
| 661 return true; | 690 return kSuccess; |
| 662 } | 691 } |
| 663 | 692 |
| 664 return selected_range_ && selected_range_->GetNextBuffer(out_buffer); | 693 if (!selected_range_ || !selected_range_->HasNextBuffer()) |
| 694 return kNeedBuffer; |
| 695 |
| 696 if (selected_range_->GetNextConfigId() != current_config_index_) |
| 697 return kConfigChange; |
| 698 |
| 699 CHECK(selected_range_->GetNextBuffer(out_buffer)); |
| 700 return kSuccess; |
| 665 } | 701 } |
| 666 | 702 |
| 667 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { | 703 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { |
| 668 if (!selected_range_) | 704 if (!selected_range_) |
| 669 return kNoTimestamp(); | 705 return kNoTimestamp(); |
| 670 | 706 |
| 671 DCHECK(selected_range_->HasNextBufferPosition()); | 707 DCHECK(selected_range_->HasNextBufferPosition()); |
| 672 return selected_range_->GetNextTimestamp(); | 708 return selected_range_->GetNextTimestamp(); |
| 673 } | 709 } |
| 674 | 710 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 itr != ranges_.end(); ++itr) { | 758 itr != ranges_.end(); ++itr) { |
| 723 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp()); | 759 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp()); |
| 724 } | 760 } |
| 725 return ranges; | 761 return ranges; |
| 726 } | 762 } |
| 727 | 763 |
| 728 bool SourceBufferStream::IsEndSelected() const { | 764 bool SourceBufferStream::IsEndSelected() const { |
| 729 return ranges_.empty() || selected_range_ == ranges_.back(); | 765 return ranges_.empty() || selected_range_ == ranges_.back(); |
| 730 } | 766 } |
| 731 | 767 |
| 768 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { |
| 769 CompleteConfigChange(); |
| 770 return *audio_configs_[current_config_index_]; |
| 771 } |
| 772 |
| 773 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { |
| 774 CompleteConfigChange(); |
| 775 return *video_configs_[current_config_index_]; |
| 776 } |
| 777 |
| 732 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { | 778 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { |
| 733 if (max_interbuffer_distance_ == kNoTimestamp()) | 779 if (max_interbuffer_distance_ == kNoTimestamp()) |
| 734 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 780 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
| 735 return max_interbuffer_distance_; | 781 return max_interbuffer_distance_; |
| 736 } | 782 } |
| 737 | 783 |
| 784 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
| 785 DCHECK(!audio_configs_.empty()); |
| 786 DCHECK(video_configs_.empty()); |
| 787 |
| 788 if (audio_configs_[0]->codec() != config.codec()) { |
| 789 DVLOG(1) << "UpdateAudioConfig() : Codec changes not allowed."; |
| 790 return false; |
| 791 } |
| 792 |
| 793 if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { |
| 794 DVLOG(1) << "UpdateAudioConfig() : Sample rate changes not allowed."; |
| 795 return false; |
| 796 } |
| 797 |
| 798 if (audio_configs_[0]->channel_layout() != config.channel_layout()) { |
| 799 DVLOG(1) << "UpdateAudioConfig() : Channel layout changes not allowed."; |
| 800 return false; |
| 801 } |
| 802 |
| 803 if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { |
| 804 DVLOG(1) << "UpdateAudioConfig() : Bits per channel changes not allowed."; |
| 805 return false; |
| 806 } |
| 807 |
| 808 // Check to see if the new config matches an existing one. |
| 809 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
| 810 if (config.Matches(*audio_configs_[i])) { |
| 811 append_config_index_ = i; |
| 812 return true; |
| 813 } |
| 814 } |
| 815 |
| 816 // No matches found so let's add this one to the list. |
| 817 append_config_index_ = audio_configs_.size(); |
| 818 audio_configs_.resize(audio_configs_.size() + 1); |
| 819 audio_configs_[append_config_index_] = new AudioDecoderConfig(); |
| 820 audio_configs_[append_config_index_]->CopyFrom(config); |
| 821 return true; |
| 822 } |
| 823 |
| 824 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
| 825 DCHECK(!video_configs_.empty()); |
| 826 DCHECK(audio_configs_.empty()); |
| 827 |
| 828 if (video_configs_[0]->codec() != config.codec()) { |
| 829 DVLOG(1) << "UpdateVideoConfig() : Codec changes not allowed."; |
| 830 return false; |
| 831 } |
| 832 |
| 833 // Check to see if the new config matches an existing one. |
| 834 for (size_t i = 0; i < video_configs_.size(); ++i) { |
| 835 if (config.Matches(*video_configs_[i])) { |
| 836 append_config_index_ = i; |
| 837 return true; |
| 838 } |
| 839 } |
| 840 |
| 841 // No matches found so let's add this one to the list. |
| 842 append_config_index_ = video_configs_.size(); |
| 843 video_configs_.resize(video_configs_.size() + 1); |
| 844 video_configs_[append_config_index_] = new VideoDecoderConfig(); |
| 845 video_configs_[append_config_index_]->CopyFrom(config); |
| 846 return true; |
| 847 } |
| 848 |
| 849 void SourceBufferStream::CompleteConfigChange() { |
| 850 if (!track_buffer_.empty()) { |
| 851 current_config_index_ = track_buffer_.front()->GetConfigId(); |
| 852 return; |
| 853 } |
| 854 |
| 855 if (!selected_range_ || !selected_range_->HasNextBuffer()) |
| 856 return; |
| 857 |
| 858 current_config_index_ = selected_range_->GetNextConfigId(); |
| 859 } |
| 860 |
| 738 SourceBufferRange::SourceBufferRange( | 861 SourceBufferRange::SourceBufferRange( |
| 739 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, | 862 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, |
| 740 const InterbufferDistanceCB& interbuffer_distance_cb) | 863 const InterbufferDistanceCB& interbuffer_distance_cb) |
| 741 : next_buffer_index_(-1), | 864 : next_buffer_index_(-1), |
| 742 waiting_for_keyframe_(false), | 865 waiting_for_keyframe_(false), |
| 743 next_keyframe_timestamp_(kNoTimestamp()), | 866 next_keyframe_timestamp_(kNoTimestamp()), |
| 744 media_segment_start_time_(media_segment_start_time), | 867 media_segment_start_time_(media_segment_start_time), |
| 745 interbuffer_distance_cb_(interbuffer_distance_cb) { | 868 interbuffer_distance_cb_(interbuffer_distance_cb) { |
| 746 DCHECK(!new_buffers.empty()); | 869 DCHECK(!new_buffers.empty()); |
| 747 DCHECK(new_buffers.front()->IsKeyframe()); | 870 DCHECK(new_buffers.front()->IsKeyframe()); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); | 1041 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); |
| 919 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); | 1042 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); |
| 920 | 1043 |
| 921 // Remove everything from |starting_point| onward. | 1044 // Remove everything from |starting_point| onward. |
| 922 buffers_.erase(starting_point, buffers_.end()); | 1045 buffers_.erase(starting_point, buffers_.end()); |
| 923 return removed_next_buffer; | 1046 return removed_next_buffer; |
| 924 } | 1047 } |
| 925 | 1048 |
| 926 bool SourceBufferRange::GetNextBuffer( | 1049 bool SourceBufferRange::GetNextBuffer( |
| 927 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1050 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 928 if (waiting_for_keyframe_ || | 1051 if (!HasNextBuffer()) |
| 929 next_buffer_index_ >= static_cast<int>(buffers_.size())) { | |
| 930 return false; | 1052 return false; |
| 931 } | |
| 932 | 1053 |
| 933 DCHECK_GE(next_buffer_index_, 0); | |
| 934 *out_buffer = buffers_.at(next_buffer_index_); | 1054 *out_buffer = buffers_.at(next_buffer_index_); |
| 935 next_buffer_index_++; | 1055 next_buffer_index_++; |
| 936 return true; | 1056 return true; |
| 937 } | 1057 } |
| 938 | 1058 |
| 939 bool SourceBufferRange::HasNextBuffer() const { | 1059 bool SourceBufferRange::HasNextBuffer() const { |
| 940 return next_buffer_index_ >= 0 && | 1060 return next_buffer_index_ >= 0 && |
| 941 next_buffer_index_ < static_cast<int>(buffers_.size()); | 1061 next_buffer_index_ < static_cast<int>(buffers_.size()) && |
| 1062 !waiting_for_keyframe_; |
| 942 } | 1063 } |
| 943 | 1064 |
| 1065 int SourceBufferRange::GetNextConfigId() const { |
| 1066 DCHECK(HasNextBuffer()); |
| 1067 return buffers_.at(next_buffer_index_)->GetConfigId(); |
| 1068 } |
| 1069 |
| 1070 |
| 944 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 1071 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
| 945 DCHECK(!buffers_.empty()); | 1072 DCHECK(!buffers_.empty()); |
| 946 DCHECK(HasNextBufferPosition()); | 1073 DCHECK(HasNextBufferPosition()); |
| 947 | 1074 |
| 948 if (waiting_for_keyframe_) | 1075 if (waiting_for_keyframe_) |
| 949 return next_keyframe_timestamp_; | 1076 return next_keyframe_timestamp_; |
| 950 | 1077 |
| 951 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) | 1078 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) |
| 952 return kNoTimestamp(); | 1079 return kNoTimestamp(); |
| 953 | 1080 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 return 2 * GetApproximateDuration(); | 1174 return 2 * GetApproximateDuration(); |
| 1048 } | 1175 } |
| 1049 | 1176 |
| 1050 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1177 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
| 1051 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1178 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
| 1052 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1179 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
| 1053 return max_interbuffer_distance; | 1180 return max_interbuffer_distance; |
| 1054 } | 1181 } |
| 1055 | 1182 |
| 1056 } // namespace media | 1183 } // namespace media |
| OLD | NEW |