Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 10836304: Add support for config changes during playback to FFmpegVideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 stream_start_time_(kNoTimestamp()), 275 stream_start_time_(kNoTimestamp()),
276 seek_pending_(false), 276 seek_pending_(false),
277 seek_buffer_timestamp_(kNoTimestamp()), 277 seek_buffer_timestamp_(kNoTimestamp()),
278 selected_range_(NULL), 278 selected_range_(NULL),
279 media_segment_start_time_(kNoTimestamp()), 279 media_segment_start_time_(kNoTimestamp()),
280 range_for_next_append_(ranges_.end()), 280 range_for_next_append_(ranges_.end()),
281 new_media_segment_(false), 281 new_media_segment_(false),
282 last_buffer_timestamp_(kNoTimestamp()), 282 last_buffer_timestamp_(kNoTimestamp()),
283 max_interbuffer_distance_(kNoTimestamp()), 283 max_interbuffer_distance_(kNoTimestamp()),
284 memory_limit_(kDefaultAudioMemoryLimit) { 284 memory_limit_(kDefaultAudioMemoryLimit) {
285 DCHECK(audio_config.IsValidConfig());
285 audio_configs_[0] = new AudioDecoderConfig(); 286 audio_configs_[0] = new AudioDecoderConfig();
Ami GONE FROM CHROMIUM 2012/08/17 15:16:59 FWIW, you could audio_configs_.push_back(new Audio
acolwell GONE FROM CHROMIUM 2012/08/20 23:10:12 Done.
286 audio_configs_[0]->CopyFrom(audio_config); 287 audio_configs_[0]->CopyFrom(audio_config);
287 } 288 }
288 289
289 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) 290 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config)
290 : current_config_index_(0), 291 : current_config_index_(0),
291 append_config_index_(0), 292 append_config_index_(0),
292 audio_configs_(0), 293 audio_configs_(0),
293 video_configs_(1), 294 video_configs_(1),
294 stream_start_time_(kNoTimestamp()), 295 stream_start_time_(kNoTimestamp()),
295 seek_pending_(false), 296 seek_pending_(false),
296 seek_buffer_timestamp_(kNoTimestamp()), 297 seek_buffer_timestamp_(kNoTimestamp()),
297 selected_range_(NULL), 298 selected_range_(NULL),
298 media_segment_start_time_(kNoTimestamp()), 299 media_segment_start_time_(kNoTimestamp()),
299 range_for_next_append_(ranges_.end()), 300 range_for_next_append_(ranges_.end()),
300 new_media_segment_(false), 301 new_media_segment_(false),
301 last_buffer_timestamp_(kNoTimestamp()), 302 last_buffer_timestamp_(kNoTimestamp()),
302 max_interbuffer_distance_(kNoTimestamp()), 303 max_interbuffer_distance_(kNoTimestamp()),
303 memory_limit_(kDefaultVideoMemoryLimit) { 304 memory_limit_(kDefaultVideoMemoryLimit) {
305 DCHECK(video_config.IsValidConfig());
304 video_configs_[0] = new VideoDecoderConfig(); 306 video_configs_[0] = new VideoDecoderConfig();
305 video_configs_[0]->CopyFrom(video_config); 307 video_configs_[0]->CopyFrom(video_config);
306 } 308 }
307 309
308 SourceBufferStream::~SourceBufferStream() { 310 SourceBufferStream::~SourceBufferStream() {
309 while (!ranges_.empty()) { 311 while (!ranges_.empty()) {
310 delete ranges_.front(); 312 delete ranges_.front();
311 ranges_.pop_front(); 313 ranges_.pop_front();
312 } 314 }
313 315
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 delete *next_range_itr; 731 delete *next_range_itr;
730 ranges_.erase(next_range_itr); 732 ranges_.erase(next_range_itr);
731 } 733 }
732 } 734 }
733 735
734 void SourceBufferStream::Seek(base::TimeDelta timestamp) { 736 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
735 DCHECK(stream_start_time_ != kNoTimestamp()); 737 DCHECK(stream_start_time_ != kNoTimestamp());
736 DCHECK(timestamp >= stream_start_time_); 738 DCHECK(timestamp >= stream_start_time_);
737 SetSelectedRange(NULL); 739 SetSelectedRange(NULL);
738 track_buffer_.clear(); 740 track_buffer_.clear();
741 config_change_pending_ = false;
739 742
740 if (ShouldSeekToStartOfBuffered(timestamp)) { 743 if (ShouldSeekToStartOfBuffered(timestamp)) {
741 SetSelectedRange(ranges_.front()); 744 SetSelectedRange(ranges_.front());
742 ranges_.front()->SeekToStart(); 745 ranges_.front()->SeekToStart();
743 seek_pending_ = false; 746 seek_pending_ = false;
744 return; 747 return;
745 } 748 }
746 749
747 seek_buffer_timestamp_ = timestamp; 750 seek_buffer_timestamp_ = timestamp;
748 seek_pending_ = true; 751 seek_pending_ = true;
(...skipping 12 matching lines...) Expand all
761 seek_pending_ = false; 764 seek_pending_ = false;
762 } 765 }
763 766
764 bool SourceBufferStream::IsSeekPending() const { 767 bool SourceBufferStream::IsSeekPending() const {
765 return seek_pending_; 768 return seek_pending_;
766 } 769 }
767 770
768 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( 771 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
769 scoped_refptr<StreamParserBuffer>* out_buffer) { 772 scoped_refptr<StreamParserBuffer>* out_buffer) {
770 if (!track_buffer_.empty()) { 773 if (!track_buffer_.empty()) {
771 if (track_buffer_.front()->GetConfigId() != current_config_index_) 774 if (track_buffer_.front()->GetConfigId() != current_config_index_) {
775 config_change_pending_ = true;
772 return kConfigChange; 776 return kConfigChange;
777 }
773 778
774 *out_buffer = track_buffer_.front(); 779 *out_buffer = track_buffer_.front();
775 track_buffer_.pop_front(); 780 track_buffer_.pop_front();
776 return kSuccess; 781 return kSuccess;
777 } 782 }
778 783
779 if (!selected_range_ || !selected_range_->HasNextBuffer()) 784 if (!selected_range_ || !selected_range_->HasNextBuffer())
780 return kNeedBuffer; 785 return kNeedBuffer;
781 786
782 if (selected_range_->GetNextConfigId() != current_config_index_) 787 if (selected_range_->GetNextConfigId() != current_config_index_) {
788 config_change_pending_ = true;
783 return kConfigChange; 789 return kConfigChange;
790 }
784 791
785 CHECK(selected_range_->GetNextBuffer(out_buffer)); 792 CHECK(selected_range_->GetNextBuffer(out_buffer));
786 return kSuccess; 793 return kSuccess;
787 } 794 }
788 795
789 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { 796 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() {
790 if (!selected_range_) 797 if (!selected_range_)
791 return kNoTimestamp(); 798 return kNoTimestamp();
792 799
793 DCHECK(selected_range_->HasNextBufferPosition()); 800 DCHECK(selected_range_->HasNextBufferPosition());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp()); 852 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp());
846 } 853 }
847 return ranges; 854 return ranges;
848 } 855 }
849 856
850 bool SourceBufferStream::IsEndSelected() const { 857 bool SourceBufferStream::IsEndSelected() const {
851 return ranges_.empty() || selected_range_ == ranges_.back(); 858 return ranges_.empty() || selected_range_ == ranges_.back();
852 } 859 }
853 860
854 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { 861 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
855 CompleteConfigChange(); 862 if (config_change_pending_)
863 CompleteConfigChange();
856 return *audio_configs_[current_config_index_]; 864 return *audio_configs_[current_config_index_];
857 } 865 }
858 866
859 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { 867 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
860 CompleteConfigChange(); 868 if (config_change_pending_)
869 CompleteConfigChange();
861 return *video_configs_[current_config_index_]; 870 return *video_configs_[current_config_index_];
862 } 871 }
863 872
864 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { 873 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
865 if (max_interbuffer_distance_ == kNoTimestamp()) 874 if (max_interbuffer_distance_ == kNoTimestamp())
866 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); 875 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
867 return max_interbuffer_distance_; 876 return max_interbuffer_distance_;
868 } 877 }
869 878
870 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { 879 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 append_config_index_ = video_configs_.size(); 937 append_config_index_ = video_configs_.size();
929 video_configs_.resize(video_configs_.size() + 1); 938 video_configs_.resize(video_configs_.size() + 1);
930 video_configs_[append_config_index_] = new VideoDecoderConfig(); 939 video_configs_[append_config_index_] = new VideoDecoderConfig();
931 video_configs_[append_config_index_]->CopyFrom(config); 940 video_configs_[append_config_index_]->CopyFrom(config);
932 return true; 941 return true;
933 } 942 }
934 943
935 void SourceBufferStream::CompleteConfigChange() { 944 void SourceBufferStream::CompleteConfigChange() {
936 if (!track_buffer_.empty()) { 945 if (!track_buffer_.empty()) {
937 current_config_index_ = track_buffer_.front()->GetConfigId(); 946 current_config_index_ = track_buffer_.front()->GetConfigId();
947 config_change_pending_ = false;
938 return; 948 return;
939 } 949 }
940 950
941 if (!selected_range_ || !selected_range_->HasNextBuffer()) 951 if (!selected_range_ || !selected_range_->HasNextBuffer())
Ami GONE FROM CHROMIUM 2012/08/17 15:16:59 Can this really happen? If not, then you can uncon
acolwell GONE FROM CHROMIUM 2012/08/20 23:10:12 I believe it can happen with an unfortunate end ov
942 return; 952 return;
943 953
944 current_config_index_ = selected_range_->GetNextConfigId(); 954 current_config_index_ = selected_range_->GetNextConfigId();
955 config_change_pending_ = false;
945 } 956 }
946 957
947 SourceBufferRange::SourceBufferRange( 958 SourceBufferRange::SourceBufferRange(
948 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, 959 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time,
949 const InterbufferDistanceCB& interbuffer_distance_cb) 960 const InterbufferDistanceCB& interbuffer_distance_cb)
950 : next_buffer_index_(-1), 961 : next_buffer_index_(-1),
951 waiting_for_keyframe_(false), 962 waiting_for_keyframe_(false),
952 next_keyframe_timestamp_(kNoTimestamp()), 963 next_keyframe_timestamp_(kNoTimestamp()),
953 media_segment_start_time_(media_segment_start_time), 964 media_segment_start_time_(media_segment_start_time),
954 interbuffer_distance_cb_(interbuffer_distance_cb), 965 interbuffer_distance_cb_(interbuffer_distance_cb),
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 return 2 * GetApproximateDuration(); 1389 return 2 * GetApproximateDuration();
1379 } 1390 }
1380 1391
1381 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 1392 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
1382 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 1393 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
1383 DCHECK(max_interbuffer_distance != kNoTimestamp()); 1394 DCHECK(max_interbuffer_distance != kNoTimestamp());
1384 return max_interbuffer_distance; 1395 return max_interbuffer_distance;
1385 } 1396 }
1386 1397
1387 } // namespace media 1398 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698