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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 return base::TimeDelta::FromMilliseconds(1000); | 279 return base::TimeDelta::FromMilliseconds(1000); |
280 } | 280 } |
281 // The maximum amount of data in bytes the stream will keep in memory. | 281 // The maximum amount of data in bytes the stream will keep in memory. |
282 // 12MB: approximately 5 minutes of 320Kbps content. | 282 // 12MB: approximately 5 minutes of 320Kbps content. |
283 // 150MB: approximately 5 minutes of 4Mbps content. | 283 // 150MB: approximately 5 minutes of 4Mbps content. |
284 static int kDefaultAudioMemoryLimit = 12 * 1024 * 1024; | 284 static int kDefaultAudioMemoryLimit = 12 * 1024 * 1024; |
285 static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024; | 285 static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024; |
286 | 286 |
287 namespace media { | 287 namespace media { |
288 | 288 |
289 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) | 289 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
290 : current_config_index_(0), | 290 const LogCB& log_cb) |
| 291 : log_cb_(log_cb), |
| 292 current_config_index_(0), |
291 append_config_index_(0), | 293 append_config_index_(0), |
292 seek_pending_(false), | 294 seek_pending_(false), |
293 seek_buffer_timestamp_(kNoTimestamp()), | 295 seek_buffer_timestamp_(kNoTimestamp()), |
294 selected_range_(NULL), | 296 selected_range_(NULL), |
295 media_segment_start_time_(kNoTimestamp()), | 297 media_segment_start_time_(kNoTimestamp()), |
296 range_for_next_append_(ranges_.end()), | 298 range_for_next_append_(ranges_.end()), |
297 new_media_segment_(false), | 299 new_media_segment_(false), |
298 last_buffer_timestamp_(kNoTimestamp()), | 300 last_buffer_timestamp_(kNoTimestamp()), |
299 max_interbuffer_distance_(kNoTimestamp()), | 301 max_interbuffer_distance_(kNoTimestamp()), |
300 memory_limit_(kDefaultAudioMemoryLimit), | 302 memory_limit_(kDefaultAudioMemoryLimit), |
301 config_change_pending_(false) { | 303 config_change_pending_(false) { |
302 DCHECK(audio_config.IsValidConfig()); | 304 DCHECK(audio_config.IsValidConfig()); |
303 audio_configs_.push_back(new AudioDecoderConfig()); | 305 audio_configs_.push_back(new AudioDecoderConfig()); |
304 audio_configs_.back()->CopyFrom(audio_config); | 306 audio_configs_.back()->CopyFrom(audio_config); |
305 } | 307 } |
306 | 308 |
307 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) | 309 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
308 : current_config_index_(0), | 310 const LogCB& log_cb) |
| 311 : log_cb_(log_cb), |
| 312 current_config_index_(0), |
309 append_config_index_(0), | 313 append_config_index_(0), |
310 seek_pending_(false), | 314 seek_pending_(false), |
311 seek_buffer_timestamp_(kNoTimestamp()), | 315 seek_buffer_timestamp_(kNoTimestamp()), |
312 selected_range_(NULL), | 316 selected_range_(NULL), |
313 media_segment_start_time_(kNoTimestamp()), | 317 media_segment_start_time_(kNoTimestamp()), |
314 range_for_next_append_(ranges_.end()), | 318 range_for_next_append_(ranges_.end()), |
315 new_media_segment_(false), | 319 new_media_segment_(false), |
316 last_buffer_timestamp_(kNoTimestamp()), | 320 last_buffer_timestamp_(kNoTimestamp()), |
317 max_interbuffer_distance_(kNoTimestamp()), | 321 max_interbuffer_distance_(kNoTimestamp()), |
318 memory_limit_(kDefaultVideoMemoryLimit), | 322 memory_limit_(kDefaultVideoMemoryLimit), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 } | 355 } |
352 } | 356 } |
353 | 357 |
354 bool SourceBufferStream::Append( | 358 bool SourceBufferStream::Append( |
355 const SourceBufferStream::BufferQueue& buffers) { | 359 const SourceBufferStream::BufferQueue& buffers) { |
356 DCHECK(!buffers.empty()); | 360 DCHECK(!buffers.empty()); |
357 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 361 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
358 | 362 |
359 // New media segments must begin with a keyframe. | 363 // New media segments must begin with a keyframe. |
360 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { | 364 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { |
361 DVLOG(1) << "Media segment did not begin with keyframe."; | 365 MEDIA_LOG(log_cb_) <<"Media segment did not begin with keyframe."; |
362 return false; | 366 return false; |
363 } | 367 } |
364 | 368 |
365 // Buffers within a media segment should be monotonically increasing. | 369 // Buffers within a media segment should be monotonically increasing. |
366 if (!IsMonotonicallyIncreasing(buffers)) { | 370 if (!IsMonotonicallyIncreasing(buffers)) { |
367 DVLOG(1) << "Buffers were not monotonically increasing."; | 371 MEDIA_LOG(log_cb_) <<"Buffers were not monotonically increasing."; |
368 return false; | 372 return false; |
369 } | 373 } |
370 | 374 |
371 if (media_segment_start_time_ < base::TimeDelta() || | 375 if (media_segment_start_time_ < base::TimeDelta() || |
372 buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { | 376 buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { |
373 DVLOG(1) << "Cannot append a media segment with negative timestamps."; | 377 MEDIA_LOG(log_cb_) |
| 378 << "Cannot append a media segment with negative timestamps."; |
374 return false; | 379 return false; |
375 } | 380 } |
376 | 381 |
377 UpdateMaxInterbufferDistance(buffers); | 382 UpdateMaxInterbufferDistance(buffers); |
378 SetConfigIds(buffers); | 383 SetConfigIds(buffers); |
379 | 384 |
380 // Save a snapshot of stream state before range modifications are made. | 385 // Save a snapshot of stream state before range modifications are made. |
381 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | 386 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
382 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); | 387 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); |
383 | 388 |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 if (max_interbuffer_distance_ == kNoTimestamp()) | 1035 if (max_interbuffer_distance_ == kNoTimestamp()) |
1031 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1036 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
1032 return max_interbuffer_distance_; | 1037 return max_interbuffer_distance_; |
1033 } | 1038 } |
1034 | 1039 |
1035 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1040 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
1036 DCHECK(!audio_configs_.empty()); | 1041 DCHECK(!audio_configs_.empty()); |
1037 DCHECK(video_configs_.empty()); | 1042 DCHECK(video_configs_.empty()); |
1038 | 1043 |
1039 if (audio_configs_[0]->codec() != config.codec()) { | 1044 if (audio_configs_[0]->codec() != config.codec()) { |
1040 DVLOG(1) << "UpdateAudioConfig() : Codec changes not allowed."; | 1045 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; |
1041 return false; | 1046 return false; |
1042 } | 1047 } |
1043 | 1048 |
1044 if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { | 1049 if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) { |
1045 DVLOG(1) << "UpdateAudioConfig() : Sample rate changes not allowed."; | 1050 MEDIA_LOG(log_cb_) << "Audio sample rate changes not allowed."; |
1046 return false; | 1051 return false; |
1047 } | 1052 } |
1048 | 1053 |
1049 if (audio_configs_[0]->channel_layout() != config.channel_layout()) { | 1054 if (audio_configs_[0]->channel_layout() != config.channel_layout()) { |
1050 DVLOG(1) << "UpdateAudioConfig() : Channel layout changes not allowed."; | 1055 MEDIA_LOG(log_cb_) << "Audio channel layout changes not allowed."; |
1051 return false; | 1056 return false; |
1052 } | 1057 } |
1053 | 1058 |
1054 if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { | 1059 if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) { |
1055 DVLOG(1) << "UpdateAudioConfig() : Bits per channel changes not allowed."; | 1060 MEDIA_LOG(log_cb_) << "Audio bits per channel changes not allowed."; |
1056 return false; | 1061 return false; |
1057 } | 1062 } |
1058 | 1063 |
1059 // Check to see if the new config matches an existing one. | 1064 // Check to see if the new config matches an existing one. |
1060 for (size_t i = 0; i < audio_configs_.size(); ++i) { | 1065 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
1061 if (config.Matches(*audio_configs_[i])) { | 1066 if (config.Matches(*audio_configs_[i])) { |
1062 append_config_index_ = i; | 1067 append_config_index_ = i; |
1063 return true; | 1068 return true; |
1064 } | 1069 } |
1065 } | 1070 } |
1066 | 1071 |
1067 // No matches found so let's add this one to the list. | 1072 // No matches found so let's add this one to the list. |
1068 append_config_index_ = audio_configs_.size(); | 1073 append_config_index_ = audio_configs_.size(); |
1069 audio_configs_.resize(audio_configs_.size() + 1); | 1074 audio_configs_.resize(audio_configs_.size() + 1); |
1070 audio_configs_[append_config_index_] = new AudioDecoderConfig(); | 1075 audio_configs_[append_config_index_] = new AudioDecoderConfig(); |
1071 audio_configs_[append_config_index_]->CopyFrom(config); | 1076 audio_configs_[append_config_index_]->CopyFrom(config); |
1072 return true; | 1077 return true; |
1073 } | 1078 } |
1074 | 1079 |
1075 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | 1080 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
1076 DCHECK(!video_configs_.empty()); | 1081 DCHECK(!video_configs_.empty()); |
1077 DCHECK(audio_configs_.empty()); | 1082 DCHECK(audio_configs_.empty()); |
1078 | 1083 |
1079 if (video_configs_[0]->is_encrypted() != config.is_encrypted()) { | 1084 if (video_configs_[0]->is_encrypted() != config.is_encrypted()) { |
1080 DVLOG(1) << "UpdateVideoConfig() : Encryption changes not allowed."; | 1085 MEDIA_LOG(log_cb_) <<"Video Encryption changes not allowed."; |
1081 return false; | 1086 return false; |
1082 } | 1087 } |
1083 | 1088 |
1084 if (video_configs_[0]->codec() != config.codec()) { | 1089 if (video_configs_[0]->codec() != config.codec()) { |
1085 DVLOG(1) << "UpdateVideoConfig() : Codec changes not allowed."; | 1090 MEDIA_LOG(log_cb_) <<"Video codec changes not allowed."; |
1086 return false; | 1091 return false; |
1087 } | 1092 } |
1088 | 1093 |
1089 // Check to see if the new config matches an existing one. | 1094 // Check to see if the new config matches an existing one. |
1090 for (size_t i = 0; i < video_configs_.size(); ++i) { | 1095 for (size_t i = 0; i < video_configs_.size(); ++i) { |
1091 if (config.Matches(*video_configs_[i])) { | 1096 if (config.Matches(*video_configs_[i])) { |
1092 append_config_index_ = i; | 1097 append_config_index_ = i; |
1093 return true; | 1098 return true; |
1094 } | 1099 } |
1095 } | 1100 } |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 return ComputeFudgeRoom(GetApproximateDuration()); | 1564 return ComputeFudgeRoom(GetApproximateDuration()); |
1560 } | 1565 } |
1561 | 1566 |
1562 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1567 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
1563 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1568 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
1564 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1569 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
1565 return max_interbuffer_distance; | 1570 return max_interbuffer_distance; |
1566 } | 1571 } |
1567 | 1572 |
1568 } // namespace media | 1573 } // namespace media |
OLD | NEW |