| 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(log_cb_, ERROR) << "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(log_cb_, ERROR) |
| 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(log_cb_, ERROR) << "Invalid same timestamp construct detected at" |
| 244 << " time " |
| 245 << dts.InSecondsF(); |
| 243 | 246 |
| 244 return false; | 247 return false; |
| 245 } | 248 } |
| 246 | 249 |
| 247 UpdateMaxInterbufferDistance(buffers); | 250 UpdateMaxInterbufferDistance(buffers); |
| 248 SetConfigIds(buffers); | 251 SetConfigIds(buffers); |
| 249 | 252 |
| 250 // Save a snapshot of stream state before range modifications are made. | 253 // Save a snapshot of stream state before range modifications are made. |
| 251 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 254 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
| 252 BufferQueue deleted_buffers; | 255 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(); | 505 bool current_is_keyframe = (*itr)->is_key_frame(); |
| 503 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 506 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
| 504 DCHECK((*itr)->duration() >= base::TimeDelta()) | 507 DCHECK((*itr)->duration() >= base::TimeDelta()) |
| 505 << "Packet with invalid duration." | 508 << "Packet with invalid duration." |
| 506 << " pts " << (*itr)->timestamp().InSecondsF() | 509 << " pts " << (*itr)->timestamp().InSecondsF() |
| 507 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() | 510 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() |
| 508 << " dur " << (*itr)->duration().InSecondsF(); | 511 << " dur " << (*itr)->duration().InSecondsF(); |
| 509 | 512 |
| 510 if (prev_timestamp != kNoDecodeTimestamp()) { | 513 if (prev_timestamp != kNoDecodeTimestamp()) { |
| 511 if (current_timestamp < prev_timestamp) { | 514 if (current_timestamp < prev_timestamp) { |
| 512 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; | 515 MEDIA_LOG(log_cb_, ERROR) << "Buffers did not monotonically increase."; |
| 513 return false; | 516 return false; |
| 514 } | 517 } |
| 515 | 518 |
| 516 if (current_timestamp == prev_timestamp && | 519 if (current_timestamp == prev_timestamp && |
| 517 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, | 520 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, |
| 518 current_is_keyframe)) { | 521 current_is_keyframe)) { |
| 519 MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the" | 522 MEDIA_LOG(log_cb_, ERROR) << "Unexpected combination of buffers with" |
| 520 << " same timestamp detected at " | 523 << " the same timestamp detected at " |
| 521 << current_timestamp.InSecondsF(); | 524 << current_timestamp.InSecondsF(); |
| 522 return false; | 525 return false; |
| 523 } | 526 } |
| 524 } | 527 } |
| 525 | 528 |
| 526 prev_timestamp = current_timestamp; | 529 prev_timestamp = current_timestamp; |
| 527 prev_is_keyframe = current_is_keyframe; | 530 prev_is_keyframe = current_is_keyframe; |
| 528 } | 531 } |
| 529 return true; | 532 return true; |
| 530 } | 533 } |
| 531 | 534 |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1229 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
| 1227 return max_interbuffer_distance_; | 1230 return max_interbuffer_distance_; |
| 1228 } | 1231 } |
| 1229 | 1232 |
| 1230 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1233 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
| 1231 DCHECK(!audio_configs_.empty()); | 1234 DCHECK(!audio_configs_.empty()); |
| 1232 DCHECK(video_configs_.empty()); | 1235 DCHECK(video_configs_.empty()); |
| 1233 DVLOG(3) << "UpdateAudioConfig."; | 1236 DVLOG(3) << "UpdateAudioConfig."; |
| 1234 | 1237 |
| 1235 if (audio_configs_[0].codec() != config.codec()) { | 1238 if (audio_configs_[0].codec() != config.codec()) { |
| 1236 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed."; | 1239 MEDIA_LOG(log_cb_, ERROR) << "Audio codec changes not allowed."; |
| 1237 return false; | 1240 return false; |
| 1238 } | 1241 } |
| 1239 | 1242 |
| 1240 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { | 1243 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) { |
| 1241 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed."; | 1244 MEDIA_LOG(log_cb_, ERROR) << "Audio encryption changes not allowed."; |
| 1242 return false; | 1245 return false; |
| 1243 } | 1246 } |
| 1244 | 1247 |
| 1245 // Check to see if the new config matches an existing one. | 1248 // Check to see if the new config matches an existing one. |
| 1246 for (size_t i = 0; i < audio_configs_.size(); ++i) { | 1249 for (size_t i = 0; i < audio_configs_.size(); ++i) { |
| 1247 if (config.Matches(audio_configs_[i])) { | 1250 if (config.Matches(audio_configs_[i])) { |
| 1248 append_config_index_ = i; | 1251 append_config_index_ = i; |
| 1249 return true; | 1252 return true; |
| 1250 } | 1253 } |
| 1251 } | 1254 } |
| 1252 | 1255 |
| 1253 // No matches found so let's add this one to the list. | 1256 // No matches found so let's add this one to the list. |
| 1254 append_config_index_ = audio_configs_.size(); | 1257 append_config_index_ = audio_configs_.size(); |
| 1255 DVLOG(2) << "New audio config - index: " << append_config_index_; | 1258 DVLOG(2) << "New audio config - index: " << append_config_index_; |
| 1256 audio_configs_.resize(audio_configs_.size() + 1); | 1259 audio_configs_.resize(audio_configs_.size() + 1); |
| 1257 audio_configs_[append_config_index_] = config; | 1260 audio_configs_[append_config_index_] = config; |
| 1258 return true; | 1261 return true; |
| 1259 } | 1262 } |
| 1260 | 1263 |
| 1261 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { | 1264 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) { |
| 1262 DCHECK(!video_configs_.empty()); | 1265 DCHECK(!video_configs_.empty()); |
| 1263 DCHECK(audio_configs_.empty()); | 1266 DCHECK(audio_configs_.empty()); |
| 1264 DVLOG(3) << "UpdateVideoConfig."; | 1267 DVLOG(3) << "UpdateVideoConfig."; |
| 1265 | 1268 |
| 1266 if (video_configs_[0].codec() != config.codec()) { | 1269 if (video_configs_[0].codec() != config.codec()) { |
| 1267 MEDIA_LOG(log_cb_) << "Video codec changes not allowed."; | 1270 MEDIA_LOG(log_cb_, ERROR) << "Video codec changes not allowed."; |
| 1268 return false; | 1271 return false; |
| 1269 } | 1272 } |
| 1270 | 1273 |
| 1271 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { | 1274 if (video_configs_[0].is_encrypted() != config.is_encrypted()) { |
| 1272 MEDIA_LOG(log_cb_) << "Video encryption changes not allowed."; | 1275 MEDIA_LOG(log_cb_, ERROR) << "Video encryption changes not allowed."; |
| 1273 return false; | 1276 return false; |
| 1274 } | 1277 } |
| 1275 | 1278 |
| 1276 // Check to see if the new config matches an existing one. | 1279 // Check to see if the new config matches an existing one. |
| 1277 for (size_t i = 0; i < video_configs_.size(); ++i) { | 1280 for (size_t i = 0; i < video_configs_.size(); ++i) { |
| 1278 if (config.Matches(video_configs_[i])) { | 1281 if (config.Matches(video_configs_[i])) { |
| 1279 append_config_index_ = i; | 1282 append_config_index_ = i; |
| 1280 return true; | 1283 return true; |
| 1281 } | 1284 } |
| 1282 } | 1285 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 return false; | 1565 return false; |
| 1563 | 1566 |
| 1564 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1567 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 1565 splice_buffers_index_ = 0; | 1568 splice_buffers_index_ = 0; |
| 1566 pending_buffer_.swap(*out_buffer); | 1569 pending_buffer_.swap(*out_buffer); |
| 1567 pending_buffers_complete_ = false; | 1570 pending_buffers_complete_ = false; |
| 1568 return true; | 1571 return true; |
| 1569 } | 1572 } |
| 1570 | 1573 |
| 1571 } // namespace media | 1574 } // namespace media |
| OLD | NEW |