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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
334 seek_buffer_timestamp_(kNoTimestamp()), | 334 seek_buffer_timestamp_(kNoTimestamp()), |
335 selected_range_(NULL), | 335 selected_range_(NULL), |
336 media_segment_start_time_(kNoTimestamp()), | 336 media_segment_start_time_(kNoTimestamp()), |
337 range_for_next_append_(ranges_.end()), | 337 range_for_next_append_(ranges_.end()), |
338 new_media_segment_(false), | 338 new_media_segment_(false), |
339 last_appended_buffer_timestamp_(kNoTimestamp()), | 339 last_appended_buffer_timestamp_(kNoTimestamp()), |
340 last_appended_buffer_is_keyframe_(false), | 340 last_appended_buffer_is_keyframe_(false), |
341 last_output_buffer_timestamp_(kNoTimestamp()), | 341 last_output_buffer_timestamp_(kNoTimestamp()), |
342 max_interbuffer_distance_(kNoTimestamp()), | 342 max_interbuffer_distance_(kNoTimestamp()), |
343 memory_limit_(kDefaultAudioMemoryLimit), | 343 memory_limit_(kDefaultAudioMemoryLimit), |
344 config_change_pending_(false) { | 344 config_change_pending_(false), |
345 fade_out_preroll_index_(0) { | |
345 DCHECK(audio_config.IsValidConfig()); | 346 DCHECK(audio_config.IsValidConfig()); |
346 audio_configs_.push_back(audio_config); | 347 audio_configs_.push_back(audio_config); |
347 } | 348 } |
348 | 349 |
349 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 350 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
350 const LogCB& log_cb) | 351 const LogCB& log_cb) |
351 : log_cb_(log_cb), | 352 : log_cb_(log_cb), |
352 current_config_index_(0), | 353 current_config_index_(0), |
353 append_config_index_(0), | 354 append_config_index_(0), |
354 seek_pending_(false), | 355 seek_pending_(false), |
355 end_of_stream_(false), | 356 end_of_stream_(false), |
356 seek_buffer_timestamp_(kNoTimestamp()), | 357 seek_buffer_timestamp_(kNoTimestamp()), |
357 selected_range_(NULL), | 358 selected_range_(NULL), |
358 media_segment_start_time_(kNoTimestamp()), | 359 media_segment_start_time_(kNoTimestamp()), |
359 range_for_next_append_(ranges_.end()), | 360 range_for_next_append_(ranges_.end()), |
360 new_media_segment_(false), | 361 new_media_segment_(false), |
361 last_appended_buffer_timestamp_(kNoTimestamp()), | 362 last_appended_buffer_timestamp_(kNoTimestamp()), |
362 last_appended_buffer_is_keyframe_(false), | 363 last_appended_buffer_is_keyframe_(false), |
363 last_output_buffer_timestamp_(kNoTimestamp()), | 364 last_output_buffer_timestamp_(kNoTimestamp()), |
364 max_interbuffer_distance_(kNoTimestamp()), | 365 max_interbuffer_distance_(kNoTimestamp()), |
365 memory_limit_(kDefaultVideoMemoryLimit), | 366 memory_limit_(kDefaultVideoMemoryLimit), |
366 config_change_pending_(false) { | 367 config_change_pending_(false), |
368 fade_out_preroll_index_(0) { | |
367 DCHECK(video_config.IsValidConfig()); | 369 DCHECK(video_config.IsValidConfig()); |
368 video_configs_.push_back(video_config); | 370 video_configs_.push_back(video_config); |
369 } | 371 } |
370 | 372 |
371 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 373 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
372 const LogCB& log_cb) | 374 const LogCB& log_cb) |
373 : log_cb_(log_cb), | 375 : log_cb_(log_cb), |
374 current_config_index_(0), | 376 current_config_index_(0), |
375 append_config_index_(0), | 377 append_config_index_(0), |
376 text_track_config_(text_config), | 378 text_track_config_(text_config), |
377 seek_pending_(false), | 379 seek_pending_(false), |
378 end_of_stream_(false), | 380 end_of_stream_(false), |
379 seek_buffer_timestamp_(kNoTimestamp()), | 381 seek_buffer_timestamp_(kNoTimestamp()), |
380 selected_range_(NULL), | 382 selected_range_(NULL), |
381 media_segment_start_time_(kNoTimestamp()), | 383 media_segment_start_time_(kNoTimestamp()), |
382 range_for_next_append_(ranges_.end()), | 384 range_for_next_append_(ranges_.end()), |
383 new_media_segment_(false), | 385 new_media_segment_(false), |
384 last_appended_buffer_timestamp_(kNoTimestamp()), | 386 last_appended_buffer_timestamp_(kNoTimestamp()), |
385 last_appended_buffer_is_keyframe_(false), | 387 last_appended_buffer_is_keyframe_(false), |
386 last_output_buffer_timestamp_(kNoTimestamp()), | 388 last_output_buffer_timestamp_(kNoTimestamp()), |
387 max_interbuffer_distance_(kNoTimestamp()), | 389 max_interbuffer_distance_(kNoTimestamp()), |
388 memory_limit_(kDefaultAudioMemoryLimit), | 390 memory_limit_(kDefaultAudioMemoryLimit), |
389 config_change_pending_(false) { | 391 config_change_pending_(false), |
392 fade_out_preroll_index_(0) { | |
390 } | 393 } |
391 | 394 |
392 SourceBufferStream::~SourceBufferStream() { | 395 SourceBufferStream::~SourceBufferStream() { |
393 while (!ranges_.empty()) { | 396 while (!ranges_.empty()) { |
394 delete ranges_.front(); | 397 delete ranges_.front(); |
395 ranges_.pop_front(); | 398 ranges_.pop_front(); |
396 } | 399 } |
397 } | 400 } |
398 | 401 |
399 void SourceBufferStream::OnNewMediaSegment( | 402 void SourceBufferStream::OnNewMediaSegment( |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
663 DCHECK(IsRangeListSorted(ranges_)); | 666 DCHECK(IsRangeListSorted(ranges_)); |
664 DCHECK(OnlySelectedRangeIsSeeked()); | 667 DCHECK(OnlySelectedRangeIsSeeked()); |
665 DVLOG(1) << __FUNCTION__ << " : done"; | 668 DVLOG(1) << __FUNCTION__ << " : done"; |
666 } | 669 } |
667 | 670 |
668 void SourceBufferStream::ResetSeekState() { | 671 void SourceBufferStream::ResetSeekState() { |
669 SetSelectedRange(NULL); | 672 SetSelectedRange(NULL); |
670 track_buffer_.clear(); | 673 track_buffer_.clear(); |
671 config_change_pending_ = false; | 674 config_change_pending_ = false; |
672 last_output_buffer_timestamp_ = kNoTimestamp(); | 675 last_output_buffer_timestamp_ = kNoTimestamp(); |
676 fade_out_preroll_index_ = 0; | |
677 fade_in_buffer_ = NULL; | |
673 } | 678 } |
674 | 679 |
675 bool SourceBufferStream::ShouldSeekToStartOfBuffered( | 680 bool SourceBufferStream::ShouldSeekToStartOfBuffered( |
676 base::TimeDelta seek_timestamp) const { | 681 base::TimeDelta seek_timestamp) const { |
677 if (ranges_.empty()) | 682 if (ranges_.empty()) |
678 return false; | 683 return false; |
679 base::TimeDelta beginning_of_buffered = | 684 base::TimeDelta beginning_of_buffered = |
680 ranges_.front()->GetStartTimestamp(); | 685 ranges_.front()->GetStartTimestamp(); |
681 return (seek_timestamp <= beginning_of_buffered && | 686 return (seek_timestamp <= beginning_of_buffered && |
682 beginning_of_buffered < kSeekToStartFudgeRoom()); | 687 beginning_of_buffered < kSeekToStartFudgeRoom()); |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1085 // If we're about to delete the selected range, also reset the seek state. | 1090 // If we're about to delete the selected range, also reset the seek state. |
1086 DCHECK((*itr)->GetStartTimestamp() >= duration); | 1091 DCHECK((*itr)->GetStartTimestamp() >= duration); |
1087 if (*itr == selected_range_) | 1092 if (*itr == selected_range_) |
1088 ResetSeekState(); | 1093 ResetSeekState(); |
1089 DeleteAndRemoveRange(&itr); | 1094 DeleteAndRemoveRange(&itr); |
1090 } | 1095 } |
1091 } | 1096 } |
1092 | 1097 |
1093 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1098 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1094 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1099 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1100 if (!fade_in_buffer_) { | |
1101 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | |
1102 | |
1103 // Just return if GetNextBufferInternal() failed or there's no fade out | |
1104 // preroll, there's nothing else to do. | |
1105 if (status != SourceBufferStream::kSuccess || | |
1106 (*out_buffer)->GetFadeOutPreroll().empty()) { | |
1107 return status; | |
1108 } | |
1109 | |
1110 // Setup fade in buffer and fall through into splice frame buffer handling. | |
1111 fade_out_preroll_index_ = 0; | |
1112 fade_in_buffer_ = *out_buffer; | |
1113 } | |
1114 | |
1115 DCHECK(fade_in_buffer_); | |
1116 const std::vector<scoped_refptr<StreamParserBuffer> >& fade_out_preroll = | |
1117 fade_in_buffer_->GetFadeOutPreroll(); | |
1118 | |
1119 // Are there any fade out buffers left to hand out? | |
1120 if (fade_out_preroll_index_ < fade_out_preroll.size()) { | |
1121 // Account for config changes which occur between fade out buffers. | |
1122 if (current_config_index_ != | |
1123 fade_out_preroll[fade_out_preroll_index_]->GetConfigId()) { | |
1124 config_change_pending_ = true; | |
1125 DVLOG(1) << "Config change (fade out preroll config ID does not match)."; | |
1126 return SourceBufferStream::kConfigChange; | |
1127 } | |
1128 | |
1129 *out_buffer = fade_out_preroll[fade_out_preroll_index_++]; | |
1130 return SourceBufferStream::kSuccess; | |
1131 } | |
1132 | |
1133 // Did we hand out the last fade out buffer on the last call? | |
1134 if (fade_out_preroll_index_ == fade_out_preroll.size()) { | |
1135 fade_out_preroll_index_++; | |
1136 config_change_pending_ = true; | |
1137 DVLOG(1) << "Config change (forced for fade in of splice frame)."; | |
1138 return SourceBufferStream::kConfigChange; | |
1139 } | |
1140 | |
1141 // All fade out buffers have been handed out and a config change completed, so | |
1142 // hand out the final buffer for fade in. Because a config change is always | |
1143 // issued prior to handing out this buffer, any changes in config id have been | |
1144 // inherently handled. | |
1145 DCHECK_GT(fade_out_preroll_index_, fade_out_preroll.size()); | |
1146 *out_buffer = fade_in_buffer_; | |
1147 fade_in_buffer_ = NULL; | |
1148 fade_out_preroll_index_ = 0; | |
1149 return SourceBufferStream::kSuccess; | |
1150 } | |
1151 | |
1152 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( | |
1153 scoped_refptr<StreamParserBuffer>* out_buffer) { | |
1095 CHECK(!config_change_pending_); | 1154 CHECK(!config_change_pending_); |
1096 | 1155 |
1097 if (!track_buffer_.empty()) { | 1156 if (!track_buffer_.empty()) { |
1098 DCHECK(!selected_range_); | 1157 DCHECK(!selected_range_); |
1099 if (track_buffer_.front()->GetConfigId() != current_config_index_) { | 1158 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); |
1159 | |
1160 // If the next buffer is an audio splice frame, the next effective config id | |
1161 // comes from the first fade out preroll buffer. | |
1162 const int next_config_id = next_buffer->GetFadeOutPreroll().empty() ? | |
1163 next_buffer->GetConfigId() : | |
acolwell GONE FROM CHROMIUM
2014/01/14 02:01:26
It feels like a static helper function with a sign
DaleCurtis
2014/01/15 02:06:08
Done.
| |
1164 next_buffer->GetFadeOutPreroll()[0]->GetConfigId(); | |
1165 | |
1166 if (next_config_id != current_config_index_) { | |
1100 config_change_pending_ = true; | 1167 config_change_pending_ = true; |
1101 DVLOG(1) << "Config change (track buffer config ID does not match)."; | 1168 DVLOG(1) << "Config change (track buffer config ID does not match)."; |
1102 return kConfigChange; | 1169 return kConfigChange; |
1103 } | 1170 } |
1104 | 1171 |
1105 *out_buffer = track_buffer_.front(); | 1172 *out_buffer = next_buffer; |
1106 track_buffer_.pop_front(); | 1173 track_buffer_.pop_front(); |
1107 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); | 1174 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); |
1108 | 1175 |
1109 // If the track buffer becomes empty, then try to set the selected range | 1176 // If the track buffer becomes empty, then try to set the selected range |
1110 // based on the timestamp of this buffer being returned. | 1177 // based on the timestamp of this buffer being returned. |
1111 if (track_buffer_.empty()) | 1178 if (track_buffer_.empty()) |
1112 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); | 1179 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); |
1113 | 1180 |
1114 return kSuccess; | 1181 return kSuccess; |
1115 } | 1182 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1331 append_config_index_ = video_configs_.size(); | 1398 append_config_index_ = video_configs_.size(); |
1332 DVLOG(2) << "New video config - index: " << append_config_index_; | 1399 DVLOG(2) << "New video config - index: " << append_config_index_; |
1333 video_configs_.resize(video_configs_.size() + 1); | 1400 video_configs_.resize(video_configs_.size() + 1); |
1334 video_configs_[append_config_index_] = config; | 1401 video_configs_[append_config_index_] = config; |
1335 return true; | 1402 return true; |
1336 } | 1403 } |
1337 | 1404 |
1338 void SourceBufferStream::CompleteConfigChange() { | 1405 void SourceBufferStream::CompleteConfigChange() { |
1339 config_change_pending_ = false; | 1406 config_change_pending_ = false; |
1340 | 1407 |
1408 if (fade_in_buffer_) { | |
1409 const std::vector<scoped_refptr<StreamParserBuffer> >& fade_out_preroll = | |
1410 fade_in_buffer_->GetFadeOutPreroll(); | |
1411 current_config_index_ = fade_out_preroll_index_ < fade_out_preroll.size() ? | |
1412 fade_out_preroll[fade_out_preroll_index_]->GetConfigId() : | |
1413 fade_in_buffer_->GetConfigId(); | |
1414 return; | |
1415 } | |
1416 | |
1341 if (!track_buffer_.empty()) { | 1417 if (!track_buffer_.empty()) { |
1342 current_config_index_ = track_buffer_.front()->GetConfigId(); | 1418 current_config_index_ = track_buffer_.front()->GetConfigId(); |
1343 return; | 1419 return; |
1344 } | 1420 } |
1345 | 1421 |
1346 if (selected_range_ && selected_range_->HasNextBuffer()) | 1422 if (selected_range_ && selected_range_->HasNextBuffer()) |
1347 current_config_index_ = selected_range_->GetNextConfigId(); | 1423 current_config_index_ = selected_range_->GetNextConfigId(); |
1348 } | 1424 } |
1349 | 1425 |
1350 void SourceBufferStream::SetSelectedRangeIfNeeded( | 1426 void SourceBufferStream::SetSelectedRangeIfNeeded( |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1839 | 1915 |
1840 // Remove everything from |starting_point| onward. | 1916 // Remove everything from |starting_point| onward. |
1841 FreeBufferRange(starting_point, buffers_.end()); | 1917 FreeBufferRange(starting_point, buffers_.end()); |
1842 } | 1918 } |
1843 | 1919 |
1844 bool SourceBufferRange::GetNextBuffer( | 1920 bool SourceBufferRange::GetNextBuffer( |
1845 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1921 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1846 if (!HasNextBuffer()) | 1922 if (!HasNextBuffer()) |
1847 return false; | 1923 return false; |
1848 | 1924 |
1849 *out_buffer = buffers_.at(next_buffer_index_); | 1925 *out_buffer = buffers_[next_buffer_index_]; |
1850 next_buffer_index_++; | 1926 next_buffer_index_++; |
1851 return true; | 1927 return true; |
1852 } | 1928 } |
1853 | 1929 |
1854 bool SourceBufferRange::HasNextBuffer() const { | 1930 bool SourceBufferRange::HasNextBuffer() const { |
1855 return next_buffer_index_ >= 0 && | 1931 return next_buffer_index_ >= 0 && |
1856 next_buffer_index_ < static_cast<int>(buffers_.size()); | 1932 next_buffer_index_ < static_cast<int>(buffers_.size()); |
1857 } | 1933 } |
1858 | 1934 |
1859 int SourceBufferRange::GetNextConfigId() const { | 1935 int SourceBufferRange::GetNextConfigId() const { |
1860 DCHECK(HasNextBuffer()); | 1936 DCHECK(HasNextBuffer()); |
1861 return buffers_.at(next_buffer_index_)->GetConfigId(); | 1937 const scoped_refptr<StreamParserBuffer>& next_buffer = |
1938 buffers_[next_buffer_index_]; | |
1939 // If the next buffer is an audio splice frame, the next effective config id | |
1940 // comes from the first fade out preroll buffer. | |
1941 return next_buffer->GetFadeOutPreroll().empty() ? | |
1942 next_buffer->GetConfigId() : | |
1943 next_buffer->GetFadeOutPreroll()[0]->GetConfigId(); | |
1862 } | 1944 } |
1863 | 1945 |
1864 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 1946 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
1865 DCHECK(!buffers_.empty()); | 1947 DCHECK(!buffers_.empty()); |
1866 DCHECK(HasNextBufferPosition()); | 1948 DCHECK(HasNextBufferPosition()); |
1867 | 1949 |
1868 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 1950 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
1869 return kNoTimestamp(); | 1951 return kNoTimestamp(); |
1870 } | 1952 } |
1871 | 1953 |
1872 return buffers_.at(next_buffer_index_)->GetDecodeTimestamp(); | 1954 return buffers_[next_buffer_index_]->GetDecodeTimestamp(); |
1873 } | 1955 } |
1874 | 1956 |
1875 bool SourceBufferRange::HasNextBufferPosition() const { | 1957 bool SourceBufferRange::HasNextBufferPosition() const { |
1876 return next_buffer_index_ >= 0; | 1958 return next_buffer_index_ >= 0; |
1877 } | 1959 } |
1878 | 1960 |
1879 void SourceBufferRange::ResetNextBufferPosition() { | 1961 void SourceBufferRange::ResetNextBufferPosition() { |
1880 next_buffer_index_ = -1; | 1962 next_buffer_index_ = -1; |
1881 } | 1963 } |
1882 | 1964 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1984 return ComputeFudgeRoom(GetApproximateDuration()); | 2066 return ComputeFudgeRoom(GetApproximateDuration()); |
1985 } | 2067 } |
1986 | 2068 |
1987 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 2069 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
1988 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 2070 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
1989 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 2071 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
1990 return max_interbuffer_distance; | 2072 return max_interbuffer_distance; |
1991 } | 2073 } |
1992 | 2074 |
1993 } // namespace media | 2075 } // namespace media |
OLD | NEW |