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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 | 119 |
120 // Gets the range of GOP to secure at least |bytes_to_free| from | 120 // Gets the range of GOP to secure at least |bytes_to_free| from |
121 // [|start_timestamp|, |end_timestamp|). | 121 // [|start_timestamp|, |end_timestamp|). |
122 // Returns the size of the buffers to secure if the buffers of | 122 // Returns the size of the buffers to secure if the buffers of |
123 // [|start_timestamp|, |end_removal_timestamp|) is removed. | 123 // [|start_timestamp|, |end_removal_timestamp|) is removed. |
124 // Will not update |end_removal_timestamp| if the returned size is 0. | 124 // Will not update |end_removal_timestamp| if the returned size is 0. |
125 int GetRemovalGOP( | 125 int GetRemovalGOP( |
126 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, | 126 base::TimeDelta start_timestamp, base::TimeDelta end_timestamp, |
127 int bytes_to_free, base::TimeDelta* end_removal_timestamp); | 127 int bytes_to_free, base::TimeDelta* end_removal_timestamp); |
128 | 128 |
129 // Indicates whether the GOP at the beginning of the range | |
130 // has timestamps all lower than |media_time|. | |
131 bool FirstGOPEarlierThanMediaTime(base::TimeDelta media_time) const; | |
132 | |
129 // Indicates whether the GOP at the beginning or end of the range contains the | 133 // Indicates whether the GOP at the beginning or end of the range contains the |
130 // next buffer position. | 134 // next buffer position. |
131 bool FirstGOPContainsNextBufferPosition() const; | 135 bool FirstGOPContainsNextBufferPosition() const; |
132 bool LastGOPContainsNextBufferPosition() const; | 136 bool LastGOPContainsNextBufferPosition() const; |
133 | 137 |
134 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 138 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
135 // must be called before calls to GetNextBuffer(), and buffers are returned | 139 // must be called before calls to GetNextBuffer(), and buffers are returned |
136 // in order from the last call to Seek(). Returns true if |out_buffer| is | 140 // in order from the last call to Seek(). Returns true if |out_buffer| is |
137 // filled with a valid buffer, false if there is not enough data to fulfill | 141 // filled with a valid buffer, false if there is not enough data to fulfill |
138 // the request. | 142 // the request. |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 348 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
345 const LogCB& log_cb, | 349 const LogCB& log_cb, |
346 bool splice_frames_enabled) | 350 bool splice_frames_enabled) |
347 : log_cb_(log_cb), | 351 : log_cb_(log_cb), |
348 current_config_index_(0), | 352 current_config_index_(0), |
349 append_config_index_(0), | 353 append_config_index_(0), |
350 seek_pending_(false), | 354 seek_pending_(false), |
351 end_of_stream_(false), | 355 end_of_stream_(false), |
352 seek_buffer_timestamp_(kNoTimestamp()), | 356 seek_buffer_timestamp_(kNoTimestamp()), |
353 selected_range_(NULL), | 357 selected_range_(NULL), |
358 current_media_time_(kNoTimestamp()), | |
354 media_segment_start_time_(kNoTimestamp()), | 359 media_segment_start_time_(kNoTimestamp()), |
355 range_for_next_append_(ranges_.end()), | 360 range_for_next_append_(ranges_.end()), |
356 new_media_segment_(false), | 361 new_media_segment_(false), |
357 last_appended_buffer_timestamp_(kNoTimestamp()), | 362 last_appended_buffer_timestamp_(kNoTimestamp()), |
358 last_appended_buffer_is_keyframe_(false), | 363 last_appended_buffer_is_keyframe_(false), |
359 last_output_buffer_timestamp_(kNoTimestamp()), | 364 last_output_buffer_timestamp_(kNoTimestamp()), |
360 max_interbuffer_distance_(kNoTimestamp()), | 365 max_interbuffer_distance_(kNoTimestamp()), |
361 memory_limit_(kDefaultAudioMemoryLimit), | 366 memory_limit_(kDefaultAudioMemoryLimit), |
362 config_change_pending_(false), | 367 config_change_pending_(false), |
363 splice_buffers_index_(0), | 368 splice_buffers_index_(0), |
364 pending_buffers_complete_(false), | 369 pending_buffers_complete_(false), |
365 splice_frames_enabled_(splice_frames_enabled) { | 370 splice_frames_enabled_(splice_frames_enabled) { |
366 DCHECK(audio_config.IsValidConfig()); | 371 DCHECK(audio_config.IsValidConfig()); |
367 audio_configs_.push_back(audio_config); | 372 audio_configs_.push_back(audio_config); |
368 } | 373 } |
369 | 374 |
370 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 375 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
371 const LogCB& log_cb, | 376 const LogCB& log_cb, |
372 bool splice_frames_enabled) | 377 bool splice_frames_enabled) |
373 : log_cb_(log_cb), | 378 : log_cb_(log_cb), |
374 current_config_index_(0), | 379 current_config_index_(0), |
375 append_config_index_(0), | 380 append_config_index_(0), |
376 seek_pending_(false), | 381 seek_pending_(false), |
377 end_of_stream_(false), | 382 end_of_stream_(false), |
378 seek_buffer_timestamp_(kNoTimestamp()), | 383 seek_buffer_timestamp_(kNoTimestamp()), |
379 selected_range_(NULL), | 384 selected_range_(NULL), |
385 current_media_time_(kNoTimestamp()), | |
380 media_segment_start_time_(kNoTimestamp()), | 386 media_segment_start_time_(kNoTimestamp()), |
381 range_for_next_append_(ranges_.end()), | 387 range_for_next_append_(ranges_.end()), |
382 new_media_segment_(false), | 388 new_media_segment_(false), |
383 last_appended_buffer_timestamp_(kNoTimestamp()), | 389 last_appended_buffer_timestamp_(kNoTimestamp()), |
384 last_appended_buffer_is_keyframe_(false), | 390 last_appended_buffer_is_keyframe_(false), |
385 last_output_buffer_timestamp_(kNoTimestamp()), | 391 last_output_buffer_timestamp_(kNoTimestamp()), |
386 max_interbuffer_distance_(kNoTimestamp()), | 392 max_interbuffer_distance_(kNoTimestamp()), |
387 memory_limit_(kDefaultVideoMemoryLimit), | 393 memory_limit_(kDefaultVideoMemoryLimit), |
388 config_change_pending_(false), | 394 config_change_pending_(false), |
389 splice_buffers_index_(0), | 395 splice_buffers_index_(0), |
390 pending_buffers_complete_(false), | 396 pending_buffers_complete_(false), |
391 splice_frames_enabled_(splice_frames_enabled) { | 397 splice_frames_enabled_(splice_frames_enabled) { |
392 DCHECK(video_config.IsValidConfig()); | 398 DCHECK(video_config.IsValidConfig()); |
393 video_configs_.push_back(video_config); | 399 video_configs_.push_back(video_config); |
394 } | 400 } |
395 | 401 |
396 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 402 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
397 const LogCB& log_cb, | 403 const LogCB& log_cb, |
398 bool splice_frames_enabled) | 404 bool splice_frames_enabled) |
399 : log_cb_(log_cb), | 405 : log_cb_(log_cb), |
400 current_config_index_(0), | 406 current_config_index_(0), |
401 append_config_index_(0), | 407 append_config_index_(0), |
402 text_track_config_(text_config), | 408 text_track_config_(text_config), |
403 seek_pending_(false), | 409 seek_pending_(false), |
404 end_of_stream_(false), | 410 end_of_stream_(false), |
405 seek_buffer_timestamp_(kNoTimestamp()), | 411 seek_buffer_timestamp_(kNoTimestamp()), |
406 selected_range_(NULL), | 412 selected_range_(NULL), |
413 current_media_time_(kNoTimestamp()), | |
407 media_segment_start_time_(kNoTimestamp()), | 414 media_segment_start_time_(kNoTimestamp()), |
408 range_for_next_append_(ranges_.end()), | 415 range_for_next_append_(ranges_.end()), |
409 new_media_segment_(false), | 416 new_media_segment_(false), |
410 last_appended_buffer_timestamp_(kNoTimestamp()), | 417 last_appended_buffer_timestamp_(kNoTimestamp()), |
411 last_appended_buffer_is_keyframe_(false), | 418 last_appended_buffer_is_keyframe_(false), |
412 last_output_buffer_timestamp_(kNoTimestamp()), | 419 last_output_buffer_timestamp_(kNoTimestamp()), |
413 max_interbuffer_distance_(kNoTimestamp()), | 420 max_interbuffer_distance_(kNoTimestamp()), |
414 memory_limit_(kDefaultAudioMemoryLimit), | 421 memory_limit_(kDefaultAudioMemoryLimit), |
415 config_change_pending_(false), | 422 config_change_pending_(false), |
416 splice_buffers_index_(0), | 423 splice_buffers_index_(0), |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 while (!ranges_.empty() && bytes_to_free > 0) { | 894 while (!ranges_.empty() && bytes_to_free > 0) { |
888 SourceBufferRange* current_range = NULL; | 895 SourceBufferRange* current_range = NULL; |
889 BufferQueue buffers; | 896 BufferQueue buffers; |
890 int bytes_deleted = 0; | 897 int bytes_deleted = 0; |
891 | 898 |
892 if (reverse_direction) { | 899 if (reverse_direction) { |
893 current_range = ranges_.back(); | 900 current_range = ranges_.back(); |
894 if (current_range->LastGOPContainsNextBufferPosition()) { | 901 if (current_range->LastGOPContainsNextBufferPosition()) { |
895 DCHECK_EQ(current_range, selected_range_); | 902 DCHECK_EQ(current_range, selected_range_); |
896 break; | 903 break; |
897 } | 904 } |
acolwell GONE FROM CHROMIUM
2014/06/19 16:00:25
I think you need a LastGOP equivalent so that the
| |
898 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); | 905 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); |
899 } else { | 906 } else { |
900 current_range = ranges_.front(); | 907 current_range = ranges_.front(); |
901 if (current_range->FirstGOPContainsNextBufferPosition()) { | 908 if (current_range->FirstGOPContainsNextBufferPosition()) { |
902 DCHECK_EQ(current_range, selected_range_); | 909 DCHECK_EQ(current_range, selected_range_); |
903 break; | 910 break; |
904 } | 911 } |
912 if (current_media_time_ != kNoTimestamp() && | |
913 !current_range->FirstGOPEarlierThanMediaTime(current_media_time_)) { | |
acolwell GONE FROM CHROMIUM
2014/06/19 16:00:25
Don't you really want FirstGOPContainsMediaTime(cu
| |
914 break; | |
915 } | |
905 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); | 916 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); |
906 } | 917 } |
907 | 918 |
908 // Check to see if we've just deleted the GOP that was last appended. | 919 // Check to see if we've just deleted the GOP that was last appended. |
909 base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp(); | 920 base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp(); |
910 if (end_timestamp == last_appended_buffer_timestamp_) { | 921 if (end_timestamp == last_appended_buffer_timestamp_) { |
911 DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp()); | 922 DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp()); |
912 DCHECK(!new_range_for_append); | 923 DCHECK(!new_range_for_append); |
913 // Create a new range containing these buffers. | 924 // Create a new range containing these buffers. |
914 new_range_for_append = new SourceBufferRange( | 925 new_range_for_append = new SourceBufferRange( |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1067 // merges. | 1078 // merges. |
1068 if (transfer_current_position) | 1079 if (transfer_current_position) |
1069 SetSelectedRange(range_with_new_buffers); | 1080 SetSelectedRange(range_with_new_buffers); |
1070 | 1081 |
1071 if (next_range_itr == range_for_next_append_) | 1082 if (next_range_itr == range_for_next_append_) |
1072 range_for_next_append_ = range_with_new_buffers_itr; | 1083 range_for_next_append_ = range_with_new_buffers_itr; |
1073 | 1084 |
1074 DeleteAndRemoveRange(&next_range_itr); | 1085 DeleteAndRemoveRange(&next_range_itr); |
1075 } | 1086 } |
1076 | 1087 |
1088 void SourceBufferStream::NotifyMediaTimeUpdate(base::TimeDelta media_time) { | |
1089 if (current_media_time_ != kNoTimestamp() && | |
1090 media_time < current_media_time_) { | |
1091 LOG(WARNING) << "Time should be monotonically increasing: " | |
1092 << media_time.InMilliseconds() | |
1093 << " " << current_media_time_.InMilliseconds(); | |
1094 return; | |
1095 } | |
1096 current_media_time_ = media_time; | |
1097 } | |
1098 | |
1077 void SourceBufferStream::Seek(base::TimeDelta timestamp) { | 1099 void SourceBufferStream::Seek(base::TimeDelta timestamp) { |
1078 DCHECK(timestamp >= base::TimeDelta()); | 1100 DCHECK(timestamp >= base::TimeDelta()); |
1079 ResetSeekState(); | 1101 ResetSeekState(); |
1080 | 1102 |
1103 current_media_time_ = kNoTimestamp(); | |
1104 | |
1081 if (ShouldSeekToStartOfBuffered(timestamp)) { | 1105 if (ShouldSeekToStartOfBuffered(timestamp)) { |
1082 ranges_.front()->SeekToStart(); | 1106 ranges_.front()->SeekToStart(); |
1083 SetSelectedRange(ranges_.front()); | 1107 SetSelectedRange(ranges_.front()); |
1084 seek_pending_ = false; | 1108 seek_pending_ = false; |
1085 return; | 1109 return; |
1086 } | 1110 } |
1087 | 1111 |
1088 seek_buffer_timestamp_ = timestamp; | 1112 seek_buffer_timestamp_ = timestamp; |
1089 seek_pending_ = true; | 1113 seek_pending_ = true; |
1090 | 1114 |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1981 bytes_removed += gop_size; | 2005 bytes_removed += gop_size; |
1982 bytes_to_free -= gop_size; | 2006 bytes_to_free -= gop_size; |
1983 } | 2007 } |
1984 if (bytes_removed > 0) { | 2008 if (bytes_removed > 0) { |
1985 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? | 2009 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? |
1986 GetBufferedEndTimestamp() : gop_itr->first; | 2010 GetBufferedEndTimestamp() : gop_itr->first; |
1987 } | 2011 } |
1988 return bytes_removed; | 2012 return bytes_removed; |
1989 } | 2013 } |
1990 | 2014 |
2015 bool SourceBufferRange::FirstGOPEarlierThanMediaTime( | |
2016 base::TimeDelta media_time) const { | |
2017 if (keyframe_map_.size() == 1u) | |
2018 return (GetEndTimestamp() < media_time); | |
2019 | |
2020 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); | |
2021 ++second_gop; | |
2022 return second_gop->first <= media_time; | |
2023 } | |
2024 | |
1991 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { | 2025 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { |
1992 if (!HasNextBufferPosition()) | 2026 if (!HasNextBufferPosition()) |
1993 return false; | 2027 return false; |
1994 | 2028 |
1995 // If there is only one GOP, it must contain the next buffer position. | 2029 // If there is only one GOP, it must contain the next buffer position. |
1996 if (keyframe_map_.size() == 1u) | 2030 if (keyframe_map_.size() == 1u) |
1997 return true; | 2031 return true; |
1998 | 2032 |
1999 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); | 2033 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); |
2000 ++second_gop; | 2034 ++second_gop; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2266 return false; | 2300 return false; |
2267 | 2301 |
2268 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 2302 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
2269 splice_buffers_index_ = 0; | 2303 splice_buffers_index_ = 0; |
2270 pending_buffer_.swap(*out_buffer); | 2304 pending_buffer_.swap(*out_buffer); |
2271 pending_buffers_complete_ = false; | 2305 pending_buffers_complete_ = false; |
2272 return true; | 2306 return true; |
2273 } | 2307 } |
2274 | 2308 |
2275 } // namespace media | 2309 } // namespace media |
OLD | NEW |