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 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 return SourceBufferRange::NO_GAPS_ALLOWED; | 87 return SourceBufferRange::NO_GAPS_ALLOWED; |
88 case SourceBufferStream::kText: | 88 case SourceBufferStream::kText: |
89 return SourceBufferRange::ALLOW_GAPS; | 89 return SourceBufferRange::ALLOW_GAPS; |
90 } | 90 } |
91 | 91 |
92 NOTREACHED(); | 92 NOTREACHED(); |
93 return SourceBufferRange::NO_GAPS_ALLOWED; | 93 return SourceBufferRange::NO_GAPS_ALLOWED; |
94 } | 94 } |
95 | 95 |
96 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 96 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
97 const LogCB& log_cb, | 97 const scoped_refptr<MediaLog>& media_log, |
98 bool splice_frames_enabled) | 98 bool splice_frames_enabled) |
99 : log_cb_(log_cb), | 99 : media_log_(media_log), |
100 current_config_index_(0), | 100 current_config_index_(0), |
101 append_config_index_(0), | 101 append_config_index_(0), |
102 seek_pending_(false), | 102 seek_pending_(false), |
103 end_of_stream_(false), | 103 end_of_stream_(false), |
104 seek_buffer_timestamp_(kNoTimestamp()), | 104 seek_buffer_timestamp_(kNoTimestamp()), |
105 selected_range_(NULL), | 105 selected_range_(NULL), |
106 media_segment_start_time_(kNoDecodeTimestamp()), | 106 media_segment_start_time_(kNoDecodeTimestamp()), |
107 range_for_next_append_(ranges_.end()), | 107 range_for_next_append_(ranges_.end()), |
108 new_media_segment_(false), | 108 new_media_segment_(false), |
109 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 109 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
110 last_appended_buffer_is_keyframe_(false), | 110 last_appended_buffer_is_keyframe_(false), |
111 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 111 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
112 max_interbuffer_distance_(kNoTimestamp()), | 112 max_interbuffer_distance_(kNoTimestamp()), |
113 memory_limit_(kSourceBufferAudioMemoryLimit), | 113 memory_limit_(kSourceBufferAudioMemoryLimit), |
114 config_change_pending_(false), | 114 config_change_pending_(false), |
115 splice_buffers_index_(0), | 115 splice_buffers_index_(0), |
116 pending_buffers_complete_(false), | 116 pending_buffers_complete_(false), |
117 splice_frames_enabled_(splice_frames_enabled) { | 117 splice_frames_enabled_(splice_frames_enabled) { |
118 DCHECK(audio_config.IsValidConfig()); | 118 DCHECK(audio_config.IsValidConfig()); |
119 audio_configs_.push_back(audio_config); | 119 audio_configs_.push_back(audio_config); |
120 } | 120 } |
121 | 121 |
122 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 122 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
123 const LogCB& log_cb, | 123 const scoped_refptr<MediaLog>& media_log, |
124 bool splice_frames_enabled) | 124 bool splice_frames_enabled) |
125 : log_cb_(log_cb), | 125 : media_log_(media_log), |
126 current_config_index_(0), | 126 current_config_index_(0), |
127 append_config_index_(0), | 127 append_config_index_(0), |
128 seek_pending_(false), | 128 seek_pending_(false), |
129 end_of_stream_(false), | 129 end_of_stream_(false), |
130 seek_buffer_timestamp_(kNoTimestamp()), | 130 seek_buffer_timestamp_(kNoTimestamp()), |
131 selected_range_(NULL), | 131 selected_range_(NULL), |
132 media_segment_start_time_(kNoDecodeTimestamp()), | 132 media_segment_start_time_(kNoDecodeTimestamp()), |
133 range_for_next_append_(ranges_.end()), | 133 range_for_next_append_(ranges_.end()), |
134 new_media_segment_(false), | 134 new_media_segment_(false), |
135 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 135 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
136 last_appended_buffer_is_keyframe_(false), | 136 last_appended_buffer_is_keyframe_(false), |
137 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 137 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
138 max_interbuffer_distance_(kNoTimestamp()), | 138 max_interbuffer_distance_(kNoTimestamp()), |
139 memory_limit_(kSourceBufferVideoMemoryLimit), | 139 memory_limit_(kSourceBufferVideoMemoryLimit), |
140 config_change_pending_(false), | 140 config_change_pending_(false), |
141 splice_buffers_index_(0), | 141 splice_buffers_index_(0), |
142 pending_buffers_complete_(false), | 142 pending_buffers_complete_(false), |
143 splice_frames_enabled_(splice_frames_enabled) { | 143 splice_frames_enabled_(splice_frames_enabled) { |
144 DCHECK(video_config.IsValidConfig()); | 144 DCHECK(video_config.IsValidConfig()); |
145 video_configs_.push_back(video_config); | 145 video_configs_.push_back(video_config); |
146 } | 146 } |
147 | 147 |
148 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 148 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
149 const LogCB& log_cb, | 149 const scoped_refptr<MediaLog>& media_log, |
150 bool splice_frames_enabled) | 150 bool splice_frames_enabled) |
151 : log_cb_(log_cb), | 151 : media_log_(media_log), |
152 current_config_index_(0), | 152 current_config_index_(0), |
153 append_config_index_(0), | 153 append_config_index_(0), |
154 text_track_config_(text_config), | 154 text_track_config_(text_config), |
155 seek_pending_(false), | 155 seek_pending_(false), |
156 end_of_stream_(false), | 156 end_of_stream_(false), |
157 seek_buffer_timestamp_(kNoTimestamp()), | 157 seek_buffer_timestamp_(kNoTimestamp()), |
158 selected_range_(NULL), | 158 selected_range_(NULL), |
159 media_segment_start_time_(kNoDecodeTimestamp()), | 159 media_segment_start_time_(kNoDecodeTimestamp()), |
160 range_for_next_append_(ranges_.end()), | 160 range_for_next_append_(ranges_.end()), |
161 new_media_segment_(false), | 161 new_media_segment_(false), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": buffers dts=[" | 216 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": buffers dts=[" |
217 << buffers.front()->GetDecodeTimestamp().InSecondsF() << ";" | 217 << buffers.front()->GetDecodeTimestamp().InSecondsF() << ";" |
218 << buffers.back()->GetDecodeTimestamp().InSecondsF() << "] pts=[" | 218 << buffers.back()->GetDecodeTimestamp().InSecondsF() << "] pts=[" |
219 << buffers.front()->timestamp().InSecondsF() << ";" | 219 << buffers.front()->timestamp().InSecondsF() << ";" |
220 << buffers.back()->timestamp().InSecondsF() << "(last frame dur=" | 220 << buffers.back()->timestamp().InSecondsF() << "(last frame dur=" |
221 << buffers.back()->duration().InSecondsF() << ")]"; | 221 << buffers.back()->duration().InSecondsF() << ")]"; |
222 | 222 |
223 // New media segments must begin with a keyframe. | 223 // New media segments must begin with a keyframe. |
224 // TODO(wolenetz): Relax this requirement. See http://crbug.com/229412. | 224 // TODO(wolenetz): Relax this requirement. See http://crbug.com/229412. |
225 if (new_media_segment_ && !buffers.front()->is_key_frame()) { | 225 if (new_media_segment_ && !buffers.front()->is_key_frame()) { |
226 MEDIA_LOG(ERROR, log_cb_) << "Media segment did not begin with key frame."; | 226 MEDIA_LOG(ERROR, media_log_) |
| 227 << "Media segment did not begin with key frame."; |
227 return false; | 228 return false; |
228 } | 229 } |
229 | 230 |
230 // Buffers within a media segment should be monotonically increasing. | 231 // Buffers within a media segment should be monotonically increasing. |
231 if (!IsMonotonicallyIncreasing(buffers)) | 232 if (!IsMonotonicallyIncreasing(buffers)) |
232 return false; | 233 return false; |
233 | 234 |
234 if (media_segment_start_time_ < DecodeTimestamp() || | 235 if (media_segment_start_time_ < DecodeTimestamp() || |
235 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { | 236 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { |
236 MEDIA_LOG(ERROR, log_cb_) | 237 MEDIA_LOG(ERROR, media_log_) |
237 << "Cannot append a media segment with negative timestamps."; | 238 << "Cannot append a media segment with negative timestamps."; |
238 return false; | 239 return false; |
239 } | 240 } |
240 | 241 |
241 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), | 242 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), |
242 buffers.front()->is_key_frame())) { | 243 buffers.front()->is_key_frame())) { |
243 const DecodeTimestamp& dts = buffers.front()->GetDecodeTimestamp(); | 244 const DecodeTimestamp& dts = buffers.front()->GetDecodeTimestamp(); |
244 MEDIA_LOG(ERROR, log_cb_) << "Invalid same timestamp construct detected at" | 245 MEDIA_LOG(ERROR, media_log_) |
245 << " time " << dts.InSecondsF(); | 246 << "Invalid same timestamp construct detected at" |
| 247 << " time " << dts.InSecondsF(); |
246 | 248 |
247 return false; | 249 return false; |
248 } | 250 } |
249 | 251 |
250 UpdateMaxInterbufferDistance(buffers); | 252 UpdateMaxInterbufferDistance(buffers); |
251 SetConfigIds(buffers); | 253 SetConfigIds(buffers); |
252 | 254 |
253 // Save a snapshot of stream state before range modifications are made. | 255 // Save a snapshot of stream state before range modifications are made. |
254 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 256 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
255 BufferQueue deleted_buffers; | 257 BufferQueue deleted_buffers; |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 bool current_is_keyframe = (*itr)->is_key_frame(); | 525 bool current_is_keyframe = (*itr)->is_key_frame(); |
524 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 526 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
525 DCHECK((*itr)->duration() >= base::TimeDelta()) | 527 DCHECK((*itr)->duration() >= base::TimeDelta()) |
526 << "Packet with invalid duration." | 528 << "Packet with invalid duration." |
527 << " pts " << (*itr)->timestamp().InSecondsF() | 529 << " pts " << (*itr)->timestamp().InSecondsF() |
528 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() | 530 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() |
529 << " dur " << (*itr)->duration().InSecondsF(); | 531 << " dur " << (*itr)->duration().InSecondsF(); |
530 | 532 |
531 if (prev_timestamp != kNoDecodeTimestamp()) { | 533 if (prev_timestamp != kNoDecodeTimestamp()) { |
532 if (current_timestamp < prev_timestamp) { | 534 if (current_timestamp < prev_timestamp) { |
533 MEDIA_LOG(ERROR, log_cb_) << "Buffers did not monotonically increase."; | 535 MEDIA_LOG(ERROR, media_log_) |
| 536 << "Buffers did not monotonically increase."; |
534 return false; | 537 return false; |
535 } | 538 } |
536 | 539 |
537 if (current_timestamp == prev_timestamp && | 540 if (current_timestamp == prev_timestamp && |
538 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, | 541 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, |
539 current_is_keyframe)) { | 542 current_is_keyframe)) { |
540 MEDIA_LOG(ERROR, log_cb_) << "Unexpected combination of buffers with" | 543 MEDIA_LOG(ERROR, media_log_) << "Unexpected combination of buffers with" |
541 << " the same timestamp detected at " | 544 << " the same timestamp detected at " |
542 << current_timestamp.InSecondsF(); | 545 << current_timestamp.InSecondsF(); |
543 return false; | 546 return false; |
544 } | 547 } |
545 } | 548 } |
546 | 549 |
547 prev_timestamp = current_timestamp; | 550 prev_timestamp = current_timestamp; |
548 prev_is_keyframe = current_is_keyframe; | 551 prev_is_keyframe = current_is_keyframe; |
549 } | 552 } |
550 return true; | 553 return true; |
551 } | 554 } |
552 | 555 |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1262 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
1260 return max_interbuffer_distance_; | 1263 return max_interbuffer_distance_; |
1261 } | 1264 } |
1262 | 1265 |
1263 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1266 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
1264 DCHECK(!audio_configs_.empty()); | 1267 DCHECK(!audio_configs_.empty()); |
1265 DCHECK(video_configs_.empty()); | 1268 DCHECK(video_configs_.empty()); |
1266 DVLOG(3) << "UpdateAudioConfig."; | 1269 DVLOG(3) << "UpdateAudioConfig."; |
1267 | 1270 |
1268 if (audio_configs_[0].codec() != config.codec()) { | 1271 if (audio_configs_[0].codec() != config.codec()) { |
1269 MEDIA_LOG(ERROR, log_cb_) << "Audio codec changes not allowed."; | 1272 MEDIA_LOG(ERROR, media_log_) << "Audio codec changes not allowed."; |
1270 return false; | 1273 return false; |
1271 } | 1274 } |
1272 | 1275 |
1273 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { | 1276 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { |
1274 MEDIA_LOG(ERROR, log_cb_) << "Audio encryption changes not allowed."; | 1277 MEDIA_LOG(ERROR, media_log_) << "Audio encryption changes not allowed."; |
1275 return false; | 1278 return false; |
1276 } | 1279 } |
1277 | 1280 |
1278 // Check to see if the new config matches an existing one. | 1281 // Check to see if the new config matches an existing one. |
1279 for (size_t i = 0; i < audio_configs_.size(); ++i) { | 1282 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
1280 if (config.Matches(audio_configs_[i])) { | 1283 if (config.Matches(audio_configs_[i])) { |
1281 append_config_index_ = i; | 1284 append_config_index_ = i; |
1282 return true; | 1285 return true; |
1283 } | 1286 } |
1284 } | 1287 } |
1285 | 1288 |
1286 // No matches found so let's add this one to the list. | 1289 // No matches found so let's add this one to the list. |
1287 append_config_index_ = audio_configs_.size(); | 1290 append_config_index_ = audio_configs_.size(); |
1288 DVLOG(2) << "New audio config - index: " << append_config_index_; | 1291 DVLOG(2) << "New audio config - index: " << append_config_index_; |
1289 audio_configs_.resize(audio_configs_.size() + 1); | 1292 audio_configs_.resize(audio_configs_.size() + 1); |
1290 audio_configs_[append_config_index_] = config; | 1293 audio_configs_[append_config_index_] = config; |
1291 return true; | 1294 return true; |
1292 } | 1295 } |
1293 | 1296 |
1294 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | 1297 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
1295 DCHECK(!video_configs_.empty()); | 1298 DCHECK(!video_configs_.empty()); |
1296 DCHECK(audio_configs_.empty()); | 1299 DCHECK(audio_configs_.empty()); |
1297 DVLOG(3) << "UpdateVideoConfig."; | 1300 DVLOG(3) << "UpdateVideoConfig."; |
1298 | 1301 |
1299 if (video_configs_[0].codec() != config.codec()) { | 1302 if (video_configs_[0].codec() != config.codec()) { |
1300 MEDIA_LOG(ERROR, log_cb_) << "Video codec changes not allowed."; | 1303 MEDIA_LOG(ERROR, media_log_) << "Video codec changes not allowed."; |
1301 return false; | 1304 return false; |
1302 } | 1305 } |
1303 | 1306 |
1304 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { | 1307 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { |
1305 MEDIA_LOG(ERROR, log_cb_) << "Video encryption changes not allowed."; | 1308 MEDIA_LOG(ERROR, media_log_) << "Video encryption changes not allowed."; |
1306 return false; | 1309 return false; |
1307 } | 1310 } |
1308 | 1311 |
1309 // Check to see if the new config matches an existing one. | 1312 // Check to see if the new config matches an existing one. |
1310 for (size_t i = 0; i < video_configs_.size(); ++i) { | 1313 for (size_t i = 0; i < video_configs_.size(); ++i) { |
1311 if (config.Matches(video_configs_[i])) { | 1314 if (config.Matches(video_configs_[i])) { |
1312 append_config_index_ = i; | 1315 append_config_index_ = i; |
1313 return true; | 1316 return true; |
1314 } | 1317 } |
1315 } | 1318 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 return false; | 1603 return false; |
1601 | 1604 |
1602 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1605 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1603 splice_buffers_index_ = 0; | 1606 splice_buffers_index_ = 0; |
1604 pending_buffer_.swap(*out_buffer); | 1607 pending_buffer_.swap(*out_buffer); |
1605 pending_buffers_complete_ = false; | 1608 pending_buffers_complete_ = false; |
1606 return true; | 1609 return true; |
1607 } | 1610 } |
1608 | 1611 |
1609 } // namespace media | 1612 } // namespace media |
OLD | NEW |