| 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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 DCHECK(!end_of_stream_); | 213 DCHECK(!end_of_stream_); |
| 214 | 214 |
| 215 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": buffers dts=[" | 215 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": buffers dts=[" |
| 216 << buffers.front()->GetDecodeTimestamp().InSecondsF() << ";" | 216 << buffers.front()->GetDecodeTimestamp().InSecondsF() << ";" |
| 217 << buffers.back()->GetDecodeTimestamp().InSecondsF() << "] pts=[" | 217 << buffers.back()->GetDecodeTimestamp().InSecondsF() << "] pts=[" |
| 218 << buffers.front()->timestamp().InSecondsF() << ";" | 218 << buffers.front()->timestamp().InSecondsF() << ";" |
| 219 << buffers.back()->timestamp().InSecondsF() << "(last frame dur=" | 219 << buffers.back()->timestamp().InSecondsF() << "(last frame dur=" |
| 220 << buffers.back()->duration().InSecondsF() << ")]"; | 220 << buffers.back()->duration().InSecondsF() << ")]"; |
| 221 | 221 |
| 222 // New media segments must begin with a keyframe. | 222 // New media segments must begin with a keyframe. |
| 223 // TODO(wolenetz): Relax this requirement. See http://crbug.com/229412. |
| 223 if (new_media_segment_ && !buffers.front()->is_key_frame()) { | 224 if (new_media_segment_ && !buffers.front()->is_key_frame()) { |
| 224 MEDIA_LOG(log_cb_) << "Media segment did not begin with key frame."; | 225 MEDIA_LOG(ERROR, log_cb_) << "Media segment did not begin with key frame."; |
| 225 return false; | 226 return false; |
| 226 } | 227 } |
| 227 | 228 |
| 228 // Buffers within a media segment should be monotonically increasing. | 229 // Buffers within a media segment should be monotonically increasing. |
| 229 if (!IsMonotonicallyIncreasing(buffers)) | 230 if (!IsMonotonicallyIncreasing(buffers)) |
| 230 return false; | 231 return false; |
| 231 | 232 |
| 232 if (media_segment_start_time_ < DecodeTimestamp() || | 233 if (media_segment_start_time_ < DecodeTimestamp() || |
| 233 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { | 234 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { |
| 234 MEDIA_LOG(log_cb_) | 235 MEDIA_LOG(ERROR, log_cb_) |
| 235 << "Cannot append a media segment with negative timestamps."; | 236 << "Cannot append a media segment with negative timestamps."; |
| 236 return false; | 237 return false; |
| 237 } | 238 } |
| 238 | 239 |
| 239 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), | 240 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), |
| 240 buffers.front()->is_key_frame())) { | 241 buffers.front()->is_key_frame())) { |
| 241 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time " | 242 const DecodeTimestamp& dts = buffers.front()->GetDecodeTimestamp(); |
| 242 << buffers.front()->GetDecodeTimestamp().InSecondsF(); | 243 MEDIA_LOG(ERROR, log_cb_) << "Invalid same timestamp construct detected at" |
| 244 << " time " << dts.InSecondsF(); |
| 243 | 245 |
| 244 return false; | 246 return false; |
| 245 } | 247 } |
| 246 | 248 |
| 247 UpdateMaxInterbufferDistance(buffers); | 249 UpdateMaxInterbufferDistance(buffers); |
| 248 SetConfigIds(buffers); | 250 SetConfigIds(buffers); |
| 249 | 251 |
| 250 // Save a snapshot of stream state before range modifications are made. | 252 // Save a snapshot of stream state before range modifications are made. |
| 251 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 253 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
| 252 BufferQueue deleted_buffers; | 254 BufferQueue deleted_buffers; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 bool current_is_keyframe = (*itr)->is_key_frame(); | 504 bool current_is_keyframe = (*itr)->is_key_frame(); |
| 503 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 505 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
| 504 DCHECK((*itr)->duration() >= base::TimeDelta()) | 506 DCHECK((*itr)->duration() >= base::TimeDelta()) |
| 505 << "Packet with invalid duration." | 507 << "Packet with invalid duration." |
| 506 << " pts " << (*itr)->timestamp().InSecondsF() | 508 << " pts " << (*itr)->timestamp().InSecondsF() |
| 507 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() | 509 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() |
| 508 << " dur " << (*itr)->duration().InSecondsF(); | 510 << " dur " << (*itr)->duration().InSecondsF(); |
| 509 | 511 |
| 510 if (prev_timestamp != kNoDecodeTimestamp()) { | 512 if (prev_timestamp != kNoDecodeTimestamp()) { |
| 511 if (current_timestamp < prev_timestamp) { | 513 if (current_timestamp < prev_timestamp) { |
| 512 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; | 514 MEDIA_LOG(ERROR, log_cb_) << "Buffers did not monotonically increase."; |
| 513 return false; | 515 return false; |
| 514 } | 516 } |
| 515 | 517 |
| 516 if (current_timestamp == prev_timestamp && | 518 if (current_timestamp == prev_timestamp && |
| 517 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, | 519 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, |
| 518 current_is_keyframe)) { | 520 current_is_keyframe)) { |
| 519 MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the" | 521 MEDIA_LOG(ERROR, log_cb_) << "Unexpected combination of buffers with" |
| 520 << " same timestamp detected at " | 522 << " the same timestamp detected at " |
| 521 << current_timestamp.InSecondsF(); | 523 << current_timestamp.InSecondsF(); |
| 522 return false; | 524 return false; |
| 523 } | 525 } |
| 524 } | 526 } |
| 525 | 527 |
| 526 prev_timestamp = current_timestamp; | 528 prev_timestamp = current_timestamp; |
| 527 prev_is_keyframe = current_is_keyframe; | 529 prev_is_keyframe = current_is_keyframe; |
| 528 } | 530 } |
| 529 return true; | 531 return true; |
| 530 } | 532 } |
| 531 | 533 |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1228 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
| 1227 return max_interbuffer_distance_; | 1229 return max_interbuffer_distance_; |
| 1228 } | 1230 } |
| 1229 | 1231 |
| 1230 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1232 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
| 1231 DCHECK(!audio_configs_.empty()); | 1233 DCHECK(!audio_configs_.empty()); |
| 1232 DCHECK(video_configs_.empty()); | 1234 DCHECK(video_configs_.empty()); |
| 1233 DVLOG(3) << "UpdateAudioConfig."; | 1235 DVLOG(3) << "UpdateAudioConfig."; |
| 1234 | 1236 |
| 1235 if (audio_configs_[0].codec() != config.codec()) { | 1237 if (audio_configs_[0].codec() != config.codec()) { |
| 1236 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; | 1238 MEDIA_LOG(ERROR, log_cb_) << "Audio codec changes not allowed."; |
| 1237 return false; | 1239 return false; |
| 1238 } | 1240 } |
| 1239 | 1241 |
| 1240 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { | 1242 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { |
| 1241 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; | 1243 MEDIA_LOG(ERROR, log_cb_) << "Audio encryption changes not allowed."; |
| 1242 return false; | 1244 return false; |
| 1243 } | 1245 } |
| 1244 | 1246 |
| 1245 // Check to see if the new config matches an existing one. | 1247 // Check to see if the new config matches an existing one. |
| 1246 for (size_t i = 0; i < audio_configs_.size(); ++i) { | 1248 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
| 1247 if (config.Matches(audio_configs_[i])) { | 1249 if (config.Matches(audio_configs_[i])) { |
| 1248 append_config_index_ = i; | 1250 append_config_index_ = i; |
| 1249 return true; | 1251 return true; |
| 1250 } | 1252 } |
| 1251 } | 1253 } |
| 1252 | 1254 |
| 1253 // No matches found so let's add this one to the list. | 1255 // No matches found so let's add this one to the list. |
| 1254 append_config_index_ = audio_configs_.size(); | 1256 append_config_index_ = audio_configs_.size(); |
| 1255 DVLOG(2) << "New audio config - index: " << append_config_index_; | 1257 DVLOG(2) << "New audio config - index: " << append_config_index_; |
| 1256 audio_configs_.resize(audio_configs_.size() + 1); | 1258 audio_configs_.resize(audio_configs_.size() + 1); |
| 1257 audio_configs_[append_config_index_] = config; | 1259 audio_configs_[append_config_index_] = config; |
| 1258 return true; | 1260 return true; |
| 1259 } | 1261 } |
| 1260 | 1262 |
| 1261 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | 1263 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
| 1262 DCHECK(!video_configs_.empty()); | 1264 DCHECK(!video_configs_.empty()); |
| 1263 DCHECK(audio_configs_.empty()); | 1265 DCHECK(audio_configs_.empty()); |
| 1264 DVLOG(3) << "UpdateVideoConfig."; | 1266 DVLOG(3) << "UpdateVideoConfig."; |
| 1265 | 1267 |
| 1266 if (video_configs_[0].codec() != config.codec()) { | 1268 if (video_configs_[0].codec() != config.codec()) { |
| 1267 MEDIA_LOG(log_cb_) << "Video codec changes not allowed."; | 1269 MEDIA_LOG(ERROR, log_cb_) << "Video codec changes not allowed."; |
| 1268 return false; | 1270 return false; |
| 1269 } | 1271 } |
| 1270 | 1272 |
| 1271 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { | 1273 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { |
| 1272 MEDIA_LOG(log_cb_) << "Video encryption changes not allowed."; | 1274 MEDIA_LOG(ERROR, log_cb_) << "Video encryption changes not allowed."; |
| 1273 return false; | 1275 return false; |
| 1274 } | 1276 } |
| 1275 | 1277 |
| 1276 // Check to see if the new config matches an existing one. | 1278 // Check to see if the new config matches an existing one. |
| 1277 for (size_t i = 0; i < video_configs_.size(); ++i) { | 1279 for (size_t i = 0; i < video_configs_.size(); ++i) { |
| 1278 if (config.Matches(video_configs_[i])) { | 1280 if (config.Matches(video_configs_[i])) { |
| 1279 append_config_index_ = i; | 1281 append_config_index_ = i; |
| 1280 return true; | 1282 return true; |
| 1281 } | 1283 } |
| 1282 } | 1284 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 return false; | 1564 return false; |
| 1563 | 1565 |
| 1564 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1566 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 1565 splice_buffers_index_ = 0; | 1567 splice_buffers_index_ = 0; |
| 1566 pending_buffer_.swap(*out_buffer); | 1568 pending_buffer_.swap(*out_buffer); |
| 1567 pending_buffers_complete_ = false; | 1569 pending_buffers_complete_ = false; |
| 1568 return true; | 1570 return true; |
| 1569 } | 1571 } |
| 1570 | 1572 |
| 1571 } // namespace media | 1573 } // namespace media |
| OLD | NEW |