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 11 matching lines...) Expand all Loading... |
22 // same timestamp situation that is allowed. False is returned otherwise. | 22 // same timestamp situation that is allowed. False is returned otherwise. |
23 static bool AllowSameTimestamp( | 23 static bool AllowSameTimestamp( |
24 bool prev_is_keyframe, bool current_is_keyframe, | 24 bool prev_is_keyframe, bool current_is_keyframe, |
25 SourceBufferStream::Type type) { | 25 SourceBufferStream::Type type) { |
26 if (type == SourceBufferStream::kVideo) | 26 if (type == SourceBufferStream::kVideo) |
27 return !prev_is_keyframe && !current_is_keyframe; | 27 return !prev_is_keyframe && !current_is_keyframe; |
28 | 28 |
29 return prev_is_keyframe || !current_is_keyframe; | 29 return prev_is_keyframe || !current_is_keyframe; |
30 } | 30 } |
31 | 31 |
| 32 // Returns the config ID of |buffer| if |buffer| has no fade out preroll or |
| 33 // |index| is out of range. Otherwise returns the config ID for the fade out |
| 34 // preroll buffer at position |index|. |
| 35 static int GetConfigId(StreamParserBuffer* buffer, size_t index) { |
| 36 return index < buffer->GetFadeOutPreroll().size() |
| 37 ? buffer->GetFadeOutPreroll()[index]->GetConfigId() |
| 38 : buffer->GetConfigId(); |
| 39 } |
| 40 |
32 // Helper class representing a range of buffered data. All buffers in a | 41 // Helper class representing a range of buffered data. All buffers in a |
33 // SourceBufferRange are ordered sequentially in presentation order with no | 42 // SourceBufferRange are ordered sequentially in presentation order with no |
34 // gaps. | 43 // gaps. |
35 class SourceBufferRange { | 44 class SourceBufferRange { |
36 public: | 45 public: |
37 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 46 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
38 | 47 |
39 // Returns the maximum distance in time between any buffer seen in this | 48 // Returns the maximum distance in time between any buffer seen in this |
40 // stream. Used to estimate the duration of a buffer if its duration is not | 49 // stream. Used to estimate the duration of a buffer if its duration is not |
41 // known. | 50 // known. |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 seek_buffer_timestamp_(kNoTimestamp()), | 348 seek_buffer_timestamp_(kNoTimestamp()), |
340 selected_range_(NULL), | 349 selected_range_(NULL), |
341 media_segment_start_time_(kNoTimestamp()), | 350 media_segment_start_time_(kNoTimestamp()), |
342 range_for_next_append_(ranges_.end()), | 351 range_for_next_append_(ranges_.end()), |
343 new_media_segment_(false), | 352 new_media_segment_(false), |
344 last_appended_buffer_timestamp_(kNoTimestamp()), | 353 last_appended_buffer_timestamp_(kNoTimestamp()), |
345 last_appended_buffer_is_keyframe_(false), | 354 last_appended_buffer_is_keyframe_(false), |
346 last_output_buffer_timestamp_(kNoTimestamp()), | 355 last_output_buffer_timestamp_(kNoTimestamp()), |
347 max_interbuffer_distance_(kNoTimestamp()), | 356 max_interbuffer_distance_(kNoTimestamp()), |
348 memory_limit_(kDefaultAudioMemoryLimit), | 357 memory_limit_(kDefaultAudioMemoryLimit), |
349 config_change_pending_(false) { | 358 config_change_pending_(false), |
| 359 fade_out_preroll_index_(0) { |
350 DCHECK(audio_config.IsValidConfig()); | 360 DCHECK(audio_config.IsValidConfig()); |
351 audio_configs_.push_back(audio_config); | 361 audio_configs_.push_back(audio_config); |
352 } | 362 } |
353 | 363 |
354 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 364 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
355 const LogCB& log_cb) | 365 const LogCB& log_cb) |
356 : log_cb_(log_cb), | 366 : log_cb_(log_cb), |
357 current_config_index_(0), | 367 current_config_index_(0), |
358 append_config_index_(0), | 368 append_config_index_(0), |
359 seek_pending_(false), | 369 seek_pending_(false), |
360 end_of_stream_(false), | 370 end_of_stream_(false), |
361 seek_buffer_timestamp_(kNoTimestamp()), | 371 seek_buffer_timestamp_(kNoTimestamp()), |
362 selected_range_(NULL), | 372 selected_range_(NULL), |
363 media_segment_start_time_(kNoTimestamp()), | 373 media_segment_start_time_(kNoTimestamp()), |
364 range_for_next_append_(ranges_.end()), | 374 range_for_next_append_(ranges_.end()), |
365 new_media_segment_(false), | 375 new_media_segment_(false), |
366 last_appended_buffer_timestamp_(kNoTimestamp()), | 376 last_appended_buffer_timestamp_(kNoTimestamp()), |
367 last_appended_buffer_is_keyframe_(false), | 377 last_appended_buffer_is_keyframe_(false), |
368 last_output_buffer_timestamp_(kNoTimestamp()), | 378 last_output_buffer_timestamp_(kNoTimestamp()), |
369 max_interbuffer_distance_(kNoTimestamp()), | 379 max_interbuffer_distance_(kNoTimestamp()), |
370 memory_limit_(kDefaultVideoMemoryLimit), | 380 memory_limit_(kDefaultVideoMemoryLimit), |
371 config_change_pending_(false) { | 381 config_change_pending_(false), |
| 382 fade_out_preroll_index_(0) { |
372 DCHECK(video_config.IsValidConfig()); | 383 DCHECK(video_config.IsValidConfig()); |
373 video_configs_.push_back(video_config); | 384 video_configs_.push_back(video_config); |
374 } | 385 } |
375 | 386 |
376 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 387 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
377 const LogCB& log_cb) | 388 const LogCB& log_cb) |
378 : log_cb_(log_cb), | 389 : log_cb_(log_cb), |
379 current_config_index_(0), | 390 current_config_index_(0), |
380 append_config_index_(0), | 391 append_config_index_(0), |
381 text_track_config_(text_config), | 392 text_track_config_(text_config), |
382 seek_pending_(false), | 393 seek_pending_(false), |
383 end_of_stream_(false), | 394 end_of_stream_(false), |
384 seek_buffer_timestamp_(kNoTimestamp()), | 395 seek_buffer_timestamp_(kNoTimestamp()), |
385 selected_range_(NULL), | 396 selected_range_(NULL), |
386 media_segment_start_time_(kNoTimestamp()), | 397 media_segment_start_time_(kNoTimestamp()), |
387 range_for_next_append_(ranges_.end()), | 398 range_for_next_append_(ranges_.end()), |
388 new_media_segment_(false), | 399 new_media_segment_(false), |
389 last_appended_buffer_timestamp_(kNoTimestamp()), | 400 last_appended_buffer_timestamp_(kNoTimestamp()), |
390 last_appended_buffer_is_keyframe_(false), | 401 last_appended_buffer_is_keyframe_(false), |
391 last_output_buffer_timestamp_(kNoTimestamp()), | 402 last_output_buffer_timestamp_(kNoTimestamp()), |
392 max_interbuffer_distance_(kNoTimestamp()), | 403 max_interbuffer_distance_(kNoTimestamp()), |
393 memory_limit_(kDefaultAudioMemoryLimit), | 404 memory_limit_(kDefaultAudioMemoryLimit), |
394 config_change_pending_(false) { | 405 config_change_pending_(false), |
| 406 fade_out_preroll_index_(0) { |
395 } | 407 } |
396 | 408 |
397 SourceBufferStream::~SourceBufferStream() { | 409 SourceBufferStream::~SourceBufferStream() { |
398 while (!ranges_.empty()) { | 410 while (!ranges_.empty()) { |
399 delete ranges_.front(); | 411 delete ranges_.front(); |
400 ranges_.pop_front(); | 412 ranges_.pop_front(); |
401 } | 413 } |
402 } | 414 } |
403 | 415 |
404 void SourceBufferStream::OnNewMediaSegment( | 416 void SourceBufferStream::OnNewMediaSegment( |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 DCHECK(IsRangeListSorted(ranges_)); | 675 DCHECK(IsRangeListSorted(ranges_)); |
664 DCHECK(OnlySelectedRangeIsSeeked()); | 676 DCHECK(OnlySelectedRangeIsSeeked()); |
665 DVLOG(1) << __FUNCTION__ << " : done"; | 677 DVLOG(1) << __FUNCTION__ << " : done"; |
666 } | 678 } |
667 | 679 |
668 void SourceBufferStream::ResetSeekState() { | 680 void SourceBufferStream::ResetSeekState() { |
669 SetSelectedRange(NULL); | 681 SetSelectedRange(NULL); |
670 track_buffer_.clear(); | 682 track_buffer_.clear(); |
671 config_change_pending_ = false; | 683 config_change_pending_ = false; |
672 last_output_buffer_timestamp_ = kNoTimestamp(); | 684 last_output_buffer_timestamp_ = kNoTimestamp(); |
| 685 fade_out_preroll_index_ = 0; |
| 686 fade_in_buffer_ = NULL; |
673 } | 687 } |
674 | 688 |
675 bool SourceBufferStream::ShouldSeekToStartOfBuffered( | 689 bool SourceBufferStream::ShouldSeekToStartOfBuffered( |
676 base::TimeDelta seek_timestamp) const { | 690 base::TimeDelta seek_timestamp) const { |
677 if (ranges_.empty()) | 691 if (ranges_.empty()) |
678 return false; | 692 return false; |
679 base::TimeDelta beginning_of_buffered = | 693 base::TimeDelta beginning_of_buffered = |
680 ranges_.front()->GetStartTimestamp(); | 694 ranges_.front()->GetStartTimestamp(); |
681 return (seek_timestamp <= beginning_of_buffered && | 695 return (seek_timestamp <= beginning_of_buffered && |
682 beginning_of_buffered < kSeekToStartFudgeRoom()); | 696 beginning_of_buffered < kSeekToStartFudgeRoom()); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 // If we're about to delete the selected range, also reset the seek state. | 1104 // If we're about to delete the selected range, also reset the seek state. |
1091 DCHECK((*itr)->GetStartTimestamp() >= duration); | 1105 DCHECK((*itr)->GetStartTimestamp() >= duration); |
1092 if (*itr == selected_range_) | 1106 if (*itr == selected_range_) |
1093 ResetSeekState(); | 1107 ResetSeekState(); |
1094 DeleteAndRemoveRange(&itr); | 1108 DeleteAndRemoveRange(&itr); |
1095 } | 1109 } |
1096 } | 1110 } |
1097 | 1111 |
1098 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1112 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1099 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1113 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1114 if (!fade_in_buffer_) { |
| 1115 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
| 1116 |
| 1117 // Just return if GetNextBufferInternal() failed or there's no fade out |
| 1118 // preroll, there's nothing else to do. |
| 1119 if (status != SourceBufferStream::kSuccess || |
| 1120 (*out_buffer)->GetFadeOutPreroll().empty()) { |
| 1121 return status; |
| 1122 } |
| 1123 |
| 1124 // Setup fade in buffer and fall through into splice frame buffer handling. |
| 1125 fade_out_preroll_index_ = 0; |
| 1126 fade_in_buffer_.swap(*out_buffer); |
| 1127 } |
| 1128 |
| 1129 DCHECK(fade_in_buffer_); |
| 1130 const std::vector<scoped_refptr<StreamParserBuffer> >& fade_out_preroll = |
| 1131 fade_in_buffer_->GetFadeOutPreroll(); |
| 1132 |
| 1133 // Are there any fade out buffers left to hand out? |
| 1134 if (fade_out_preroll_index_ < fade_out_preroll.size()) { |
| 1135 // Account for config changes which occur between fade out buffers. |
| 1136 if (current_config_index_ != |
| 1137 fade_out_preroll[fade_out_preroll_index_]->GetConfigId()) { |
| 1138 config_change_pending_ = true; |
| 1139 DVLOG(1) << "Config change (fade out preroll config ID does not match)."; |
| 1140 return SourceBufferStream::kConfigChange; |
| 1141 } |
| 1142 |
| 1143 *out_buffer = fade_out_preroll[fade_out_preroll_index_++]; |
| 1144 return SourceBufferStream::kSuccess; |
| 1145 } |
| 1146 |
| 1147 // Did we hand out the last fade out buffer on the last call? |
| 1148 if (fade_out_preroll_index_ == fade_out_preroll.size()) { |
| 1149 fade_out_preroll_index_++; |
| 1150 config_change_pending_ = true; |
| 1151 DVLOG(1) << "Config change (forced for fade in of splice frame)."; |
| 1152 return SourceBufferStream::kConfigChange; |
| 1153 } |
| 1154 |
| 1155 // All fade out buffers have been handed out and a config change completed, so |
| 1156 // hand out the final buffer for fade in. Because a config change is always |
| 1157 // issued prior to handing out this buffer, any changes in config id have been |
| 1158 // inherently handled. |
| 1159 DCHECK_GT(fade_out_preroll_index_, fade_out_preroll.size()); |
| 1160 out_buffer->swap(fade_in_buffer_); |
| 1161 fade_in_buffer_ = NULL; |
| 1162 fade_out_preroll_index_ = 0; |
| 1163 return SourceBufferStream::kSuccess; |
| 1164 } |
| 1165 |
| 1166 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( |
| 1167 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1100 CHECK(!config_change_pending_); | 1168 CHECK(!config_change_pending_); |
1101 | 1169 |
1102 if (!track_buffer_.empty()) { | 1170 if (!track_buffer_.empty()) { |
1103 DCHECK(!selected_range_); | 1171 DCHECK(!selected_range_); |
1104 if (track_buffer_.front()->GetConfigId() != current_config_index_) { | 1172 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); |
| 1173 |
| 1174 // If the next buffer is an audio splice frame, the next effective config id |
| 1175 // comes from the first fade out preroll buffer. |
| 1176 if (GetConfigId(next_buffer, 0) != current_config_index_) { |
1105 config_change_pending_ = true; | 1177 config_change_pending_ = true; |
1106 DVLOG(1) << "Config change (track buffer config ID does not match)."; | 1178 DVLOG(1) << "Config change (track buffer config ID does not match)."; |
1107 return kConfigChange; | 1179 return kConfigChange; |
1108 } | 1180 } |
1109 | 1181 |
1110 *out_buffer = track_buffer_.front(); | 1182 *out_buffer = next_buffer; |
1111 track_buffer_.pop_front(); | 1183 track_buffer_.pop_front(); |
1112 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); | 1184 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); |
1113 | 1185 |
1114 // If the track buffer becomes empty, then try to set the selected range | 1186 // If the track buffer becomes empty, then try to set the selected range |
1115 // based on the timestamp of this buffer being returned. | 1187 // based on the timestamp of this buffer being returned. |
1116 if (track_buffer_.empty()) | 1188 if (track_buffer_.empty()) |
1117 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); | 1189 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); |
1118 | 1190 |
1119 return kSuccess; | 1191 return kSuccess; |
1120 } | 1192 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 append_config_index_ = video_configs_.size(); | 1408 append_config_index_ = video_configs_.size(); |
1337 DVLOG(2) << "New video config - index: " << append_config_index_; | 1409 DVLOG(2) << "New video config - index: " << append_config_index_; |
1338 video_configs_.resize(video_configs_.size() + 1); | 1410 video_configs_.resize(video_configs_.size() + 1); |
1339 video_configs_[append_config_index_] = config; | 1411 video_configs_[append_config_index_] = config; |
1340 return true; | 1412 return true; |
1341 } | 1413 } |
1342 | 1414 |
1343 void SourceBufferStream::CompleteConfigChange() { | 1415 void SourceBufferStream::CompleteConfigChange() { |
1344 config_change_pending_ = false; | 1416 config_change_pending_ = false; |
1345 | 1417 |
1346 if (!track_buffer_.empty()) { | 1418 if (fade_in_buffer_) { |
1347 current_config_index_ = track_buffer_.front()->GetConfigId(); | 1419 current_config_index_ = |
| 1420 GetConfigId(fade_in_buffer_, fade_out_preroll_index_); |
1348 return; | 1421 return; |
1349 } | 1422 } |
1350 | 1423 |
| 1424 if (!track_buffer_.empty()) { |
| 1425 current_config_index_ = GetConfigId(track_buffer_.front(), 0); |
| 1426 return; |
| 1427 } |
| 1428 |
1351 if (selected_range_ && selected_range_->HasNextBuffer()) | 1429 if (selected_range_ && selected_range_->HasNextBuffer()) |
1352 current_config_index_ = selected_range_->GetNextConfigId(); | 1430 current_config_index_ = selected_range_->GetNextConfigId(); |
1353 } | 1431 } |
1354 | 1432 |
1355 void SourceBufferStream::SetSelectedRangeIfNeeded( | 1433 void SourceBufferStream::SetSelectedRangeIfNeeded( |
1356 const base::TimeDelta timestamp) { | 1434 const base::TimeDelta timestamp) { |
1357 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; | 1435 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; |
1358 | 1436 |
1359 if (selected_range_) { | 1437 if (selected_range_) { |
1360 DCHECK(track_buffer_.empty()); | 1438 DCHECK(track_buffer_.empty()); |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1857 // Remove everything from |starting_point| onward. | 1935 // Remove everything from |starting_point| onward. |
1858 FreeBufferRange(starting_point, buffers_.end()); | 1936 FreeBufferRange(starting_point, buffers_.end()); |
1859 return buffers_.empty(); | 1937 return buffers_.empty(); |
1860 } | 1938 } |
1861 | 1939 |
1862 bool SourceBufferRange::GetNextBuffer( | 1940 bool SourceBufferRange::GetNextBuffer( |
1863 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1941 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1864 if (!HasNextBuffer()) | 1942 if (!HasNextBuffer()) |
1865 return false; | 1943 return false; |
1866 | 1944 |
1867 *out_buffer = buffers_.at(next_buffer_index_); | 1945 *out_buffer = buffers_[next_buffer_index_]; |
1868 next_buffer_index_++; | 1946 next_buffer_index_++; |
1869 return true; | 1947 return true; |
1870 } | 1948 } |
1871 | 1949 |
1872 bool SourceBufferRange::HasNextBuffer() const { | 1950 bool SourceBufferRange::HasNextBuffer() const { |
1873 return next_buffer_index_ >= 0 && | 1951 return next_buffer_index_ >= 0 && |
1874 next_buffer_index_ < static_cast<int>(buffers_.size()); | 1952 next_buffer_index_ < static_cast<int>(buffers_.size()); |
1875 } | 1953 } |
1876 | 1954 |
1877 int SourceBufferRange::GetNextConfigId() const { | 1955 int SourceBufferRange::GetNextConfigId() const { |
1878 DCHECK(HasNextBuffer()); | 1956 DCHECK(HasNextBuffer()); |
1879 return buffers_.at(next_buffer_index_)->GetConfigId(); | 1957 // If the next buffer is an audio splice frame, the next effective config id |
| 1958 // comes from the first fade out preroll buffer. |
| 1959 return GetConfigId(buffers_[next_buffer_index_], 0); |
1880 } | 1960 } |
1881 | 1961 |
1882 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 1962 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
1883 DCHECK(!buffers_.empty()); | 1963 DCHECK(!buffers_.empty()); |
1884 DCHECK(HasNextBufferPosition()); | 1964 DCHECK(HasNextBufferPosition()); |
1885 | 1965 |
1886 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 1966 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
1887 return kNoTimestamp(); | 1967 return kNoTimestamp(); |
1888 } | 1968 } |
1889 | 1969 |
1890 return buffers_.at(next_buffer_index_)->GetDecodeTimestamp(); | 1970 return buffers_[next_buffer_index_]->GetDecodeTimestamp(); |
1891 } | 1971 } |
1892 | 1972 |
1893 bool SourceBufferRange::HasNextBufferPosition() const { | 1973 bool SourceBufferRange::HasNextBufferPosition() const { |
1894 return next_buffer_index_ >= 0; | 1974 return next_buffer_index_ >= 0; |
1895 } | 1975 } |
1896 | 1976 |
1897 void SourceBufferRange::ResetNextBufferPosition() { | 1977 void SourceBufferRange::ResetNextBufferPosition() { |
1898 next_buffer_index_ = -1; | 1978 next_buffer_index_ = -1; |
1899 } | 1979 } |
1900 | 1980 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 return ComputeFudgeRoom(GetApproximateDuration()); | 2087 return ComputeFudgeRoom(GetApproximateDuration()); |
2008 } | 2088 } |
2009 | 2089 |
2010 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 2090 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
2011 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 2091 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
2012 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 2092 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
2013 return max_interbuffer_distance; | 2093 return max_interbuffer_distance; |
2014 } | 2094 } |
2015 | 2095 |
2016 } // namespace media | 2096 } // namespace media |
OLD | NEW |