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/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/stl_util.h" | 13 |
14 namespace media { | 14 namespace media { |
15 // Helper class representing a range of buffered data. All buffers in a | 15 // Helper class representing a range of buffered data. All buffers in a |
16 // SourceBufferRange are ordered sequentially in presentation order with no | 16 // SourceBufferRange are ordered sequentially in presentation order with no |
17 // gaps. | 17 // gaps. |
18 class SourceBufferRange { | 18 class SourceBufferRange { |
19 public: | 19 public: |
20 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 20 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
21 | 21 |
22 // Returns the maximum distance in time between any buffer seen in this | 22 // Returns the maximum distance in time between any buffer seen in this |
23 // stream. Used to estimate the duration of a buffer if its duration is not | 23 // stream. Used to estimate the duration of a buffer if its duration is not |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 media_segment_start_time_(kNoTimestamp()), | 299 media_segment_start_time_(kNoTimestamp()), |
300 range_for_next_append_(ranges_.end()), | 300 range_for_next_append_(ranges_.end()), |
301 new_media_segment_(false), | 301 new_media_segment_(false), |
302 last_appended_buffer_timestamp_(kNoTimestamp()), | 302 last_appended_buffer_timestamp_(kNoTimestamp()), |
303 last_appended_buffer_is_keyframe_(false), | 303 last_appended_buffer_is_keyframe_(false), |
304 last_output_buffer_timestamp_(kNoTimestamp()), | 304 last_output_buffer_timestamp_(kNoTimestamp()), |
305 max_interbuffer_distance_(kNoTimestamp()), | 305 max_interbuffer_distance_(kNoTimestamp()), |
306 memory_limit_(kDefaultAudioMemoryLimit), | 306 memory_limit_(kDefaultAudioMemoryLimit), |
307 config_change_pending_(false) { | 307 config_change_pending_(false) { |
308 DCHECK(audio_config.IsValidConfig()); | 308 DCHECK(audio_config.IsValidConfig()); |
309 audio_configs_.push_back(new AudioDecoderConfig()); | 309 audio_configs_.push_back(audio_config); |
310 audio_configs_.back()->CopyFrom(audio_config); | |
311 } | 310 } |
312 | 311 |
313 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 312 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
314 const LogCB& log_cb) | 313 const LogCB& log_cb) |
315 : log_cb_(log_cb), | 314 : log_cb_(log_cb), |
316 current_config_index_(0), | 315 current_config_index_(0), |
317 append_config_index_(0), | 316 append_config_index_(0), |
318 seek_pending_(false), | 317 seek_pending_(false), |
319 seek_buffer_timestamp_(kNoTimestamp()), | 318 seek_buffer_timestamp_(kNoTimestamp()), |
320 selected_range_(NULL), | 319 selected_range_(NULL), |
321 media_segment_start_time_(kNoTimestamp()), | 320 media_segment_start_time_(kNoTimestamp()), |
322 range_for_next_append_(ranges_.end()), | 321 range_for_next_append_(ranges_.end()), |
323 new_media_segment_(false), | 322 new_media_segment_(false), |
324 last_appended_buffer_timestamp_(kNoTimestamp()), | 323 last_appended_buffer_timestamp_(kNoTimestamp()), |
325 last_appended_buffer_is_keyframe_(false), | 324 last_appended_buffer_is_keyframe_(false), |
326 last_output_buffer_timestamp_(kNoTimestamp()), | 325 last_output_buffer_timestamp_(kNoTimestamp()), |
327 max_interbuffer_distance_(kNoTimestamp()), | 326 max_interbuffer_distance_(kNoTimestamp()), |
328 memory_limit_(kDefaultVideoMemoryLimit), | 327 memory_limit_(kDefaultVideoMemoryLimit), |
329 config_change_pending_(false) { | 328 config_change_pending_(false) { |
330 DCHECK(video_config.IsValidConfig()); | 329 DCHECK(video_config.IsValidConfig()); |
331 video_configs_.push_back(video_config); | 330 video_configs_.push_back(video_config); |
332 } | 331 } |
333 | 332 |
334 SourceBufferStream::~SourceBufferStream() { | 333 SourceBufferStream::~SourceBufferStream() { |
335 while (!ranges_.empty()) { | 334 while (!ranges_.empty()) { |
336 delete ranges_.front(); | 335 delete ranges_.front(); |
337 ranges_.pop_front(); | 336 ranges_.pop_front(); |
338 } | 337 } |
339 | |
340 STLDeleteElements(&audio_configs_); | |
341 } | 338 } |
342 | 339 |
343 void SourceBufferStream::OnNewMediaSegment( | 340 void SourceBufferStream::OnNewMediaSegment( |
344 base::TimeDelta media_segment_start_time) { | 341 base::TimeDelta media_segment_start_time) { |
345 media_segment_start_time_ = media_segment_start_time; | 342 media_segment_start_time_ = media_segment_start_time; |
346 new_media_segment_ = true; | 343 new_media_segment_ = true; |
347 | 344 |
348 RangeList::iterator last_range = range_for_next_append_; | 345 RangeList::iterator last_range = range_for_next_append_; |
349 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 346 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
350 | 347 |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 return ranges; | 1032 return ranges; |
1036 } | 1033 } |
1037 | 1034 |
1038 bool SourceBufferStream::IsEndSelected() const { | 1035 bool SourceBufferStream::IsEndSelected() const { |
1039 return ranges_.empty() || selected_range_ == ranges_.back(); | 1036 return ranges_.empty() || selected_range_ == ranges_.back(); |
1040 } | 1037 } |
1041 | 1038 |
1042 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { | 1039 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() { |
1043 if (config_change_pending_) | 1040 if (config_change_pending_) |
1044 CompleteConfigChange(); | 1041 CompleteConfigChange(); |
1045 return *audio_configs_[current_config_index_]; | 1042 return audio_configs_[current_config_index_]; |
1046 } | 1043 } |
1047 | 1044 |
1048 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { | 1045 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() { |
1049 if (config_change_pending_) | 1046 if (config_change_pending_) |
1050 CompleteConfigChange(); | 1047 CompleteConfigChange(); |
1051 return video_configs_[current_config_index_]; | 1048 return video_configs_[current_config_index_]; |
1052 } | 1049 } |
1053 | 1050 |
1054 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { | 1051 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { |
1055 if (max_interbuffer_distance_ == kNoTimestamp()) | 1052 if (max_interbuffer_distance_ == kNoTimestamp()) |
1056 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1053 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
1057 return max_interbuffer_distance_; | 1054 return max_interbuffer_distance_; |
1058 } | 1055 } |
1059 | 1056 |
1060 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1057 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
1061 DCHECK(!audio_configs_.empty()); | 1058 DCHECK(!audio_configs_.empty()); |
1062 DCHECK(video_configs_.empty()); | 1059 DCHECK(video_configs_.empty()); |
1063 DVLOG(3) << "UpdateAudioConfig."; | 1060 DVLOG(3) << "UpdateAudioConfig."; |
1064 | 1061 |
1065 if (audio_configs_[0]->codec() != config.codec()) { | 1062 if (audio_configs_[0].codec() != config.codec()) { |
1066 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; | 1063 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; |
1067 return false; | 1064 return false; |
1068 } | 1065 } |
1069 | 1066 |
1070 if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { | 1067 if (audio_configs_[0].samples_per_second() != config.samples_per_second()) { |
1071 MEDIA_LOG(log_cb_) << "Audio sample rate changes not allowed."; | 1068 MEDIA_LOG(log_cb_) << "Audio sample rate changes not allowed."; |
1072 return false; | 1069 return false; |
1073 } | 1070 } |
1074 | 1071 |
1075 if (audio_configs_[0]->channel_layout() != config.channel_layout()) { | 1072 if (audio_configs_[0].channel_layout() != config.channel_layout()) { |
1076 MEDIA_LOG(log_cb_) << "Audio channel layout changes not allowed."; | 1073 MEDIA_LOG(log_cb_) << "Audio channel layout changes not allowed."; |
1077 return false; | 1074 return false; |
1078 } | 1075 } |
1079 | 1076 |
1080 if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { | 1077 if (audio_configs_[0].bits_per_channel() != config.bits_per_channel()) { |
1081 MEDIA_LOG(log_cb_) << "Audio bits per channel changes not allowed."; | 1078 MEDIA_LOG(log_cb_) << "Audio bits per channel changes not allowed."; |
1082 return false; | 1079 return false; |
1083 } | 1080 } |
1084 | 1081 |
1085 if (audio_configs_[0]->is_encrypted() != config.is_encrypted()) { | 1082 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { |
1086 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; | 1083 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; |
1087 return false; | 1084 return false; |
1088 } | 1085 } |
1089 | 1086 |
1090 // Check to see if the new config matches an existing one. | 1087 // Check to see if the new config matches an existing one. |
1091 for (size_t i = 0; i < audio_configs_.size(); ++i) { | 1088 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
1092 if (config.Matches(*audio_configs_[i])) { | 1089 if (config.Matches(audio_configs_[i])) { |
1093 append_config_index_ = i; | 1090 append_config_index_ = i; |
1094 return true; | 1091 return true; |
1095 } | 1092 } |
1096 } | 1093 } |
1097 | 1094 |
1098 // No matches found so let's add this one to the list. | 1095 // No matches found so let's add this one to the list. |
1099 append_config_index_ = audio_configs_.size(); | 1096 append_config_index_ = audio_configs_.size(); |
1100 DVLOG(2) << "New audio config - index: " << append_config_index_; | 1097 DVLOG(2) << "New audio config - index: " << append_config_index_; |
1101 audio_configs_.resize(audio_configs_.size() + 1); | 1098 audio_configs_.resize(audio_configs_.size() + 1); |
1102 audio_configs_[append_config_index_] = new AudioDecoderConfig(); | 1099 audio_configs_[append_config_index_] = config; |
1103 audio_configs_[append_config_index_]->CopyFrom(config); | |
1104 return true; | 1100 return true; |
1105 } | 1101 } |
1106 | 1102 |
1107 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | 1103 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
1108 DCHECK(!video_configs_.empty()); | 1104 DCHECK(!video_configs_.empty()); |
1109 DCHECK(audio_configs_.empty()); | 1105 DCHECK(audio_configs_.empty()); |
1110 DVLOG(3) << "UpdateVideoConfig."; | 1106 DVLOG(3) << "UpdateVideoConfig."; |
1111 | 1107 |
1112 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { | 1108 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { |
1113 MEDIA_LOG(log_cb_) << "Video Encryption changes not allowed."; | 1109 MEDIA_LOG(log_cb_) << "Video Encryption changes not allowed."; |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 return ComputeFudgeRoom(GetApproximateDuration()); | 1724 return ComputeFudgeRoom(GetApproximateDuration()); |
1729 } | 1725 } |
1730 | 1726 |
1731 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1727 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
1732 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1728 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
1733 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1729 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
1734 return max_interbuffer_distance; | 1730 return max_interbuffer_distance; |
1735 } | 1731 } |
1736 | 1732 |
1737 } // namespace media | 1733 } // namespace media |
OLD | NEW |