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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 bool DeleteAll(BufferQueue* deleted_buffers); | 83 bool DeleteAll(BufferQueue* deleted_buffers); |
84 | 84 |
85 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 85 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
86 // must be called before calls to GetNextBuffer(), and buffers are returned | 86 // must be called before calls to GetNextBuffer(), and buffers are returned |
87 // in order from the last call to Seek(). Returns true if |out_buffer| is | 87 // in order from the last call to Seek(). Returns true if |out_buffer| is |
88 // filled with a valid buffer, false if there is not enough data to fulfill | 88 // filled with a valid buffer, false if there is not enough data to fulfill |
89 // the request. | 89 // the request. |
90 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); | 90 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); |
91 bool HasNextBuffer() const; | 91 bool HasNextBuffer() const; |
92 | 92 |
93 // Returns the config ID for the buffer that will be returned by | |
94 // GetNextBuffer(). | |
95 int GetNextConfigID() const; | |
xhwang
2012/07/12 18:09:12
s/ID/Id?
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
96 | |
93 // Returns true if the range knows the position of the next buffer it should | 97 // Returns true if the range knows the position of the next buffer it should |
94 // return, i.e. it has been Seek()ed. This does not necessarily mean that it | 98 // return, i.e. it has been Seek()ed. This does not necessarily mean that it |
95 // has the next buffer yet. | 99 // has the next buffer yet. |
96 bool HasNextBufferPosition() const; | 100 bool HasNextBufferPosition() const; |
97 | 101 |
98 // Returns the timestamp of the next buffer that will be returned from | 102 // Returns the timestamp of the next buffer that will be returned from |
99 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. | 103 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. |
100 base::TimeDelta GetNextTimestamp() const; | 104 base::TimeDelta GetNextTimestamp() const; |
101 | 105 |
102 // Returns the start timestamp of the range. | 106 // Returns the start timestamp of the range. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); | 220 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); |
217 } | 221 } |
218 | 222 |
219 // An arbitrarily-chosen number to estimate the duration of a buffer if none | 223 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
220 // is set and there's not enough information to get a better estimate. | 224 // is set and there's not enough information to get a better estimate. |
221 static int kDefaultBufferDurationInMs = 125; | 225 static int kDefaultBufferDurationInMs = 125; |
222 | 226 |
223 namespace media { | 227 namespace media { |
224 | 228 |
225 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) | 229 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) |
226 : seek_pending_(false), | 230 : current_config_index_(0), |
231 append_config_index_(0), | |
232 audio_configs_(1), | |
233 video_configs_(0), | |
234 seek_pending_(false), | |
227 seek_buffer_timestamp_(kNoTimestamp()), | 235 seek_buffer_timestamp_(kNoTimestamp()), |
228 selected_range_(NULL), | 236 selected_range_(NULL), |
229 end_of_stream_(false), | 237 end_of_stream_(false), |
230 media_segment_start_time_(kNoTimestamp()), | 238 media_segment_start_time_(kNoTimestamp()), |
231 range_for_next_append_(ranges_.end()), | 239 range_for_next_append_(ranges_.end()), |
232 new_media_segment_(false), | 240 new_media_segment_(false), |
233 last_buffer_timestamp_(kNoTimestamp()), | 241 last_buffer_timestamp_(kNoTimestamp()), |
234 max_interbuffer_distance_(kNoTimestamp()) { | 242 max_interbuffer_distance_(kNoTimestamp()) { |
235 audio_config_.CopyFrom(audio_config); | 243 audio_configs_[0] = new AudioDecoderConfig(); |
244 audio_configs_[0]->CopyFrom(audio_config); | |
236 } | 245 } |
237 | 246 |
238 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) | 247 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) |
239 : seek_pending_(false), | 248 : current_config_index_(0), |
249 append_config_index_(0), | |
250 audio_configs_(0), | |
251 video_configs_(1), | |
252 seek_pending_(false), | |
240 seek_buffer_timestamp_(kNoTimestamp()), | 253 seek_buffer_timestamp_(kNoTimestamp()), |
241 selected_range_(NULL), | 254 selected_range_(NULL), |
242 end_of_stream_(false), | 255 end_of_stream_(false), |
243 media_segment_start_time_(kNoTimestamp()), | 256 media_segment_start_time_(kNoTimestamp()), |
244 range_for_next_append_(ranges_.end()), | 257 range_for_next_append_(ranges_.end()), |
245 new_media_segment_(false), | 258 new_media_segment_(false), |
246 last_buffer_timestamp_(kNoTimestamp()), | 259 last_buffer_timestamp_(kNoTimestamp()), |
247 max_interbuffer_distance_(kNoTimestamp()) { | 260 max_interbuffer_distance_(kNoTimestamp()) { |
248 video_config_.CopyFrom(video_config); | 261 video_configs_[0] = new VideoDecoderConfig(); |
262 video_configs_[0]->CopyFrom(video_config); | |
249 } | 263 } |
250 | 264 |
251 SourceBufferStream::~SourceBufferStream() { | 265 SourceBufferStream::~SourceBufferStream() { |
252 while (!ranges_.empty()) { | 266 while (!ranges_.empty()) { |
253 delete ranges_.front(); | 267 delete ranges_.front(); |
254 ranges_.pop_front(); | 268 ranges_.pop_front(); |
255 } | 269 } |
270 | |
271 for (size_t i = 0; i < audio_configs_.size(); ++i) | |
272 delete audio_configs_[i]; | |
273 audio_configs_.clear(); | |
274 | |
275 for (size_t i = 0; i < video_configs_.size(); ++i) | |
276 delete video_configs_[i]; | |
277 video_configs_.clear(); | |
xhwang
2012/07/12 18:09:12
Use STLDeleteElements here and above?
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
256 } | 278 } |
257 | 279 |
258 void SourceBufferStream::OnNewMediaSegment( | 280 void SourceBufferStream::OnNewMediaSegment( |
259 base::TimeDelta media_segment_start_time) { | 281 base::TimeDelta media_segment_start_time) { |
260 media_segment_start_time_ = media_segment_start_time; | 282 media_segment_start_time_ = media_segment_start_time; |
261 | 283 |
262 // Find the range that will house the buffers appended through the next | 284 // Find the range that will house the buffers appended through the next |
263 // Append() call. | 285 // Append() call. |
264 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 286 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
265 new_media_segment_ = true; | 287 new_media_segment_ = true; |
(...skipping 11 matching lines...) Expand all Loading... | |
277 return false; | 299 return false; |
278 } | 300 } |
279 | 301 |
280 // Buffers within a media segment should be monotonically increasing. | 302 // Buffers within a media segment should be monotonically increasing. |
281 if (!IsMonotonicallyIncreasing(buffers)) { | 303 if (!IsMonotonicallyIncreasing(buffers)) { |
282 DVLOG(1) << "Buffers were not monotonically increasing."; | 304 DVLOG(1) << "Buffers were not monotonically increasing."; |
283 return false; | 305 return false; |
284 } | 306 } |
285 | 307 |
286 UpdateMaxInterbufferDistance(buffers); | 308 UpdateMaxInterbufferDistance(buffers); |
309 SetConfigIDs(buffers); | |
287 | 310 |
288 // Save a snapshot of the |selected_range_| state before range modifications | 311 // Save a snapshot of the |selected_range_| state before range modifications |
289 // are made. | 312 // are made. |
290 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | 313 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
291 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); | 314 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); |
292 | 315 |
293 bool deleted_next_buffer = false; | 316 bool deleted_next_buffer = false; |
294 BufferQueue deleted_buffers; | 317 BufferQueue deleted_buffers; |
295 | 318 |
296 RangeList::iterator range_for_new_buffers = range_for_next_append_; | 319 RangeList::iterator range_for_new_buffers = range_for_next_append_; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 max_interbuffer_distance_ = interbuffer_distance; | 411 max_interbuffer_distance_ = interbuffer_distance; |
389 } else { | 412 } else { |
390 max_interbuffer_distance_ = | 413 max_interbuffer_distance_ = |
391 std::max(max_interbuffer_distance_, interbuffer_distance); | 414 std::max(max_interbuffer_distance_, interbuffer_distance); |
392 } | 415 } |
393 } | 416 } |
394 prev_timestamp = current_timestamp; | 417 prev_timestamp = current_timestamp; |
395 } | 418 } |
396 } | 419 } |
397 | 420 |
421 void SourceBufferStream::SetConfigIDs(const BufferQueue& buffers) { | |
422 for (BufferQueue::const_iterator itr = buffers.begin(); | |
423 itr != buffers.end(); ++itr) { | |
424 (*itr)->SetConfigID(append_config_index_); | |
xhwang
2012/07/12 18:09:12
The comment in .h file uses set_config_id, which s
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
I just fixed the comment to reflect the SetConfigI
| |
425 } | |
426 } | |
427 | |
398 void SourceBufferStream::InsertIntoExistingRange( | 428 void SourceBufferStream::InsertIntoExistingRange( |
399 const RangeList::iterator& range_for_new_buffers_itr, | 429 const RangeList::iterator& range_for_new_buffers_itr, |
400 const BufferQueue& new_buffers, | 430 const BufferQueue& new_buffers, |
401 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 431 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
402 DCHECK(deleted_next_buffer); | 432 DCHECK(deleted_next_buffer); |
403 DCHECK(deleted_buffers); | 433 DCHECK(deleted_buffers); |
404 | 434 |
405 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 435 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
406 | 436 |
407 // If this is a simple case where we can just append to the end of the range, | 437 // If this is a simple case where we can just append to the end of the range, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 selected_range_ = *itr; | 629 selected_range_ = *itr; |
600 selected_range_->Seek(timestamp); | 630 selected_range_->Seek(timestamp); |
601 seek_pending_ = false; | 631 seek_pending_ = false; |
602 end_of_stream_ = false; | 632 end_of_stream_ = false; |
603 } | 633 } |
604 | 634 |
605 bool SourceBufferStream::IsSeekPending() const { | 635 bool SourceBufferStream::IsSeekPending() const { |
606 return seek_pending_; | 636 return seek_pending_; |
607 } | 637 } |
608 | 638 |
609 bool SourceBufferStream::GetNextBuffer( | 639 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
610 scoped_refptr<StreamParserBuffer>* out_buffer) { | 640 scoped_refptr<StreamParserBuffer>* out_buffer) { |
611 if (!track_buffer_.empty()) { | 641 if (!track_buffer_.empty()) { |
642 if (track_buffer_.front()->GetConfigID() != current_config_index_) | |
643 return kConfigChange; | |
644 | |
612 *out_buffer = track_buffer_.front(); | 645 *out_buffer = track_buffer_.front(); |
613 track_buffer_.pop_front(); | 646 track_buffer_.pop_front(); |
614 return true; | 647 return kSuccess; |
615 } | 648 } |
616 | 649 |
617 if (end_of_stream_ && (!selected_range_ || | 650 if (end_of_stream_ && (!selected_range_ || |
618 !selected_range_->HasNextBuffer())) { | 651 !selected_range_->HasNextBuffer())) { |
619 *out_buffer = StreamParserBuffer::CreateEOSBuffer(); | 652 *out_buffer = StreamParserBuffer::CreateEOSBuffer(); |
620 return true; | 653 return kSuccess; |
621 } | 654 } |
622 | 655 |
623 return selected_range_ && selected_range_->GetNextBuffer(out_buffer); | 656 if (!selected_range_ || !selected_range_->HasNextBuffer()) |
657 return kNeedBuffer; | |
658 | |
659 if (selected_range_->GetNextConfigID() != current_config_index_) | |
660 return kConfigChange; | |
661 | |
662 return selected_range_->GetNextBuffer(out_buffer) ? kSuccess : kNeedBuffer; | |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
At this point, shouldn't selected_range_->GetNextB
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
I wasn't sure. The guard in SourceBufferRange::Get
| |
624 } | 663 } |
625 | 664 |
626 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { | 665 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { |
627 if (!selected_range_) | 666 if (!selected_range_) |
628 return kNoTimestamp(); | 667 return kNoTimestamp(); |
629 | 668 |
630 DCHECK(selected_range_->HasNextBufferPosition()); | 669 DCHECK(selected_range_->HasNextBufferPosition()); |
631 return selected_range_->GetNextTimestamp(); | 670 return selected_range_->GetNextTimestamp(); |
632 } | 671 } |
633 | 672 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 bool SourceBufferStream::CanEndOfStream() const { | 725 bool SourceBufferStream::CanEndOfStream() const { |
687 return ranges_.empty() || selected_range_ == ranges_.back(); | 726 return ranges_.empty() || selected_range_ == ranges_.back(); |
688 } | 727 } |
689 | 728 |
690 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { | 729 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { |
691 if (max_interbuffer_distance_ == kNoTimestamp()) | 730 if (max_interbuffer_distance_ == kNoTimestamp()) |
692 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 731 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
693 return max_interbuffer_distance_; | 732 return max_interbuffer_distance_; |
694 } | 733 } |
695 | 734 |
735 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | |
736 DCHECK(!audio_configs_.empty()); | |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
DCHECK(video_configs_.empty())?
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
737 | |
738 if (audio_configs_[0]->codec() != config.codec()) { | |
739 DVLOG(1) << "UpdateAudioConfig() : Codec changes not allowed."; | |
740 return false; | |
741 } | |
742 | |
743 if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { | |
744 DVLOG(1) << "UpdateAudioConfig() : Sample rate changes not allowed."; | |
745 return false; | |
746 } | |
747 | |
748 if (audio_configs_[0]->channel_layout() != config.channel_layout()) { | |
749 DVLOG(1) << "UpdateAudioConfig() : Channel layout changes not allowed."; | |
750 return false; | |
751 } | |
752 | |
753 if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { | |
754 DVLOG(1) << "UpdateAudioConfig() : Bits per channel changes not allowed."; | |
755 return false; | |
756 } | |
757 | |
758 // Check to see if the new config matches an existing one. | |
759 for (size_t i = 0; i < audio_configs_.size(); ++i) { | |
760 const AudioDecoderConfig& existing_config = *audio_configs_[i]; | |
761 if ((existing_config.codec() == config.codec()) && | |
762 (existing_config.bits_per_channel() == config.bits_per_channel()) && | |
763 (existing_config.channel_layout() == config.channel_layout()) && | |
764 (existing_config.samples_per_second() == config.samples_per_second()) && | |
765 (existing_config.extra_data_size() == config.extra_data_size()) && | |
766 (!existing_config.extra_data() || | |
767 !memcmp(existing_config.extra_data(), config.extra_data(), | |
768 existing_config.extra_data_size()))) { | |
xhwang
2012/07/12 18:09:12
How about having helper functions for this and bel
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
769 append_config_index_ = i; | |
770 return true; | |
771 } | |
772 } | |
773 | |
774 // No matches found so lets add this one to the list. | |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
nit: "let's"
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
775 append_config_index_ = audio_configs_.size(); | |
776 audio_configs_.resize(audio_configs_.size() + 1); | |
777 audio_configs_[append_config_index_] = new AudioDecoderConfig(); | |
778 audio_configs_[append_config_index_]->CopyFrom(config); | |
779 return true; | |
780 } | |
781 | |
782 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | |
783 DCHECK(!video_configs_.empty()); | |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
DCHECK(audio_configs_.empty())?
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
784 | |
785 if (video_configs_[0]->codec() != config.codec()) { | |
786 DVLOG(1) << "UpdateVideoConfig() : Codec changes not allowed."; | |
787 return false; | |
788 } | |
789 | |
790 // Check to see if the new config matches an existing one. | |
791 for (size_t i = 0; i < video_configs_.size(); ++i) { | |
792 const VideoDecoderConfig& existing_config = *video_configs_[i]; | |
793 if ((existing_config.codec() == config.codec()) && | |
794 (existing_config.format() == config.format()) && | |
795 (existing_config.profile() == config.profile()) && | |
796 (existing_config.coded_size() == config.coded_size()) && | |
797 (existing_config.visible_rect() == config.visible_rect()) && | |
798 (existing_config.natural_size() == config.natural_size()) && | |
799 (existing_config.extra_data_size() == config.extra_data_size()) && | |
800 (!existing_config.extra_data() || | |
801 !memcmp(existing_config.extra_data(), config.extra_data(), | |
802 existing_config.extra_data_size()))) { | |
803 append_config_index_ = i; | |
804 return true; | |
805 } | |
806 } | |
807 | |
808 // No matches found so lets add this one to the list. | |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
nit: "let's"
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done.
| |
809 append_config_index_ = video_configs_.size(); | |
810 video_configs_.resize(video_configs_.size() + 1); | |
811 video_configs_[append_config_index_] = new VideoDecoderConfig(); | |
812 video_configs_[append_config_index_]->CopyFrom(config); | |
813 return true; | |
814 } | |
815 | |
816 void SourceBufferStream::UpdateCurrentConfigIndex() { | |
817 if (!track_buffer_.empty()) { | |
818 current_config_index_ = track_buffer_.front()->GetConfigID(); | |
819 return; | |
820 } | |
821 | |
822 if (!selected_range_ || !selected_range_->HasNextBuffer()) | |
823 return; | |
824 | |
825 current_config_index_ = selected_range_->GetNextConfigID(); | |
826 } | |
827 | |
696 SourceBufferRange::SourceBufferRange( | 828 SourceBufferRange::SourceBufferRange( |
697 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, | 829 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, |
698 const InterbufferDistanceCB& interbuffer_distance_cb) | 830 const InterbufferDistanceCB& interbuffer_distance_cb) |
699 : next_buffer_index_(-1), | 831 : next_buffer_index_(-1), |
700 waiting_for_keyframe_(false), | 832 waiting_for_keyframe_(false), |
701 next_keyframe_timestamp_(kNoTimestamp()), | 833 next_keyframe_timestamp_(kNoTimestamp()), |
702 media_segment_start_time_(media_segment_start_time), | 834 media_segment_start_time_(media_segment_start_time), |
703 interbuffer_distance_cb_(interbuffer_distance_cb) { | 835 interbuffer_distance_cb_(interbuffer_distance_cb) { |
704 DCHECK(!new_buffers.empty()); | 836 DCHECK(!new_buffers.empty()); |
705 DCHECK(new_buffers.front()->IsKeyframe()); | 837 DCHECK(new_buffers.front()->IsKeyframe()); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 } | 1010 } |
879 | 1011 |
880 DCHECK_GE(next_buffer_index_, 0); | 1012 DCHECK_GE(next_buffer_index_, 0); |
881 *out_buffer = buffers_.at(next_buffer_index_); | 1013 *out_buffer = buffers_.at(next_buffer_index_); |
882 next_buffer_index_++; | 1014 next_buffer_index_++; |
883 return true; | 1015 return true; |
884 } | 1016 } |
885 | 1017 |
886 bool SourceBufferRange::HasNextBuffer() const { | 1018 bool SourceBufferRange::HasNextBuffer() const { |
887 return next_buffer_index_ >= 0 && | 1019 return next_buffer_index_ >= 0 && |
888 next_buffer_index_ < static_cast<int>(buffers_.size()); | 1020 next_buffer_index_ < static_cast<int>(buffers_.size()); |
vrk (LEFT CHROMIUM)
2012/07/12 19:37:55
nit: indentation + add "&& !waiting_for_keyframe_"
acolwell GONE FROM CHROMIUM
2012/07/12 23:07:58
Done. Changed GetNextBuffer() to use this now that
| |
889 } | 1021 } |
890 | 1022 |
1023 int SourceBufferRange::GetNextConfigID() const { | |
1024 DCHECK(HasNextBuffer()); | |
1025 return buffers_.at(next_buffer_index_)->GetConfigID(); | |
1026 } | |
1027 | |
1028 | |
891 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 1029 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
892 DCHECK(!buffers_.empty()); | 1030 DCHECK(!buffers_.empty()); |
893 DCHECK(HasNextBufferPosition()); | 1031 DCHECK(HasNextBufferPosition()); |
894 | 1032 |
895 if (waiting_for_keyframe_) | 1033 if (waiting_for_keyframe_) |
896 return next_keyframe_timestamp_; | 1034 return next_keyframe_timestamp_; |
897 | 1035 |
898 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) | 1036 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) |
899 return kNoTimestamp(); | 1037 return kNoTimestamp(); |
900 | 1038 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 return 2 * GetApproximateDuration(); | 1124 return 2 * GetApproximateDuration(); |
987 } | 1125 } |
988 | 1126 |
989 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1127 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
990 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1128 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
991 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1129 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
992 return max_interbuffer_distance; | 1130 return max_interbuffer_distance; |
993 } | 1131 } |
994 | 1132 |
995 } // namespace media | 1133 } // namespace media |
OLD | NEW |