Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 341083004: Introduce the playback time into the MSE garbage collection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698