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

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

Issue 2343543002: MSE: Replace crossfade splicing overlap trimming. (Closed)
Patch Set: Feedback Created 4 years, 1 month 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
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 #include <sstream> 9 #include <sstream>
10 #include <string>
10 11
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
14 #include "media/base/audio_splicer.h"
15 #include "media/base/timestamp_constants.h" 15 #include "media/base/timestamp_constants.h"
16 #include "media/filters/source_buffer_platform.h" 16 #include "media/filters/source_buffer_platform.h"
17 #include "media/filters/source_buffer_range.h" 17 #include "media/filters/source_buffer_range.h"
18 18
19 namespace media { 19 namespace media {
20 20
21 namespace { 21 namespace {
22 22
23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is 23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is
24 // set and there's not enough information to get a better estimate. 24 // set and there's not enough information to get a better estimate.
25 const int kDefaultBufferDurationInMs = 125; 25 const int kDefaultBufferDurationInMs = 125;
26 26
27 // Limit the number of MEDIA_LOG() logs for splice buffer generation warnings
28 // and successes. Though these values are high enough to possibly exhaust the
29 // media internals event cache (along with other events), these logs are
30 // important for debugging splice generation.
31 const int kMaxSpliceGenerationWarningLogs = 50;
32 const int kMaxSpliceGenerationSuccessLogs = 20;
33
34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. 27 // Limit the number of MEDIA_LOG() logs for track buffer time gaps.
35 const int kMaxTrackBufferGapWarningLogs = 20; 28 const int kMaxTrackBufferGapWarningLogs = 20;
36 29
37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. 30 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; 31 const int kMaxGarbageCollectAlgorithmWarningLogs = 20;
39 32
33 // Limit the number of MEDIA_LOG() logs for splice overlap trimming.
34 const int kMaxAudioSpliceLogs = 20;
35
40 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed 36 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed
41 // by keyframe. Prior to relaxing the "media segments must begin with a 37 // by keyframe. Prior to relaxing the "media segments must begin with a
42 // keyframe" requirement, we issued decode error for this situation. That was 38 // keyframe" requirement, we issued decode error for this situation. That was
43 // likely too strict, and now that the keyframe requirement is relaxed, we have 39 // likely too strict, and now that the keyframe requirement is relaxed, we have
44 // no knowledge of media segment boundaries here. Now, we log but don't trigger 40 // no knowledge of media segment boundaries here. Now, we log but don't trigger
45 // decode error, since we allow these sequences which may cause extra decoder 41 // decode error, since we allow these sequences which may cause extra decoder
46 // work or other side-effects. 42 // work or other side-effects.
47 const int kMaxStrangeSameTimestampsLogs = 20; 43 const int kMaxStrangeSameTimestampsLogs = 20;
48 44
49 // Helper method that returns true if |ranges| is sorted in increasing order, 45 // Helper method that returns true if |ranges| is sorted in increasing order,
50 // false otherwise. 46 // false otherwise.
51 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { 47 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) {
52 DecodeTimestamp prev = kNoDecodeTimestamp(); 48 DecodeTimestamp prev = kNoDecodeTimestamp();
53 for (std::list<SourceBufferRange*>::const_iterator itr = 49 for (std::list<SourceBufferRange*>::const_iterator itr =
54 ranges.begin(); itr != ranges.end(); ++itr) { 50 ranges.begin(); itr != ranges.end(); ++itr) {
55 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) 51 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
56 return false; 52 return false;
57 prev = (*itr)->GetEndTimestamp(); 53 prev = (*itr)->GetEndTimestamp();
58 } 54 }
59 return true; 55 return true;
60 } 56 }
61 57
62 // Returns an estimate of how far from the beginning or end of a range a buffer 58 // Returns an estimate of how far from the beginning or end of a range a buffer
63 // can be to still be considered in the range, given the |approximate_duration| 59 // can be to still be considered in the range, given the |approximate_duration|
64 // of a buffer in the stream. 60 // of a buffer in the stream.
65 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use 61 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use
66 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) 62 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp)
67 // instead of an overall maximum interbuffer delta for range discontinuity 63 // instead of an overall maximum interbuffer delta for range discontinuity
68 // detection, and adjust similarly for splice frame discontinuity detection. 64 // detection.
69 // See http://crbug.com/351489 and http://crbug.com/351166. 65 // See http://crbug.com/351489 and http://crbug.com/351166.
70 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { 66 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
71 // Because we do not know exactly when is the next timestamp, any buffer 67 // Because we do not know exactly when is the next timestamp, any buffer
72 // that starts within 2x the approximate duration of a buffer is considered 68 // that starts within 2x the approximate duration of a buffer is considered
73 // within this range. 69 // within this range.
74 return 2 * approximate_duration; 70 return 2 * approximate_duration;
75 } 71 }
76 72
77 // The amount of time the beginning of the buffered data can differ from the 73 // The amount of time the beginning of the buffered data can differ from the
78 // start time in order to still be considered the start of stream. 74 // start time in order to still be considered the start of stream.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 return SourceBufferRange::ALLOW_GAPS; 131 return SourceBufferRange::ALLOW_GAPS;
136 } 132 }
137 133
138 NOTREACHED(); 134 NOTREACHED();
139 return SourceBufferRange::NO_GAPS_ALLOWED; 135 return SourceBufferRange::NO_GAPS_ALLOWED;
140 } 136 }
141 137
142 } // namespace 138 } // namespace
143 139
144 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 140 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
145 const scoped_refptr<MediaLog>& media_log, 141 const scoped_refptr<MediaLog>& media_log)
146 bool splice_frames_enabled)
147 : media_log_(media_log), 142 : media_log_(media_log),
148 seek_buffer_timestamp_(kNoTimestamp), 143 seek_buffer_timestamp_(kNoTimestamp),
149 coded_frame_group_start_time_(kNoDecodeTimestamp()), 144 coded_frame_group_start_time_(kNoDecodeTimestamp()),
150 range_for_next_append_(ranges_.end()), 145 range_for_next_append_(ranges_.end()),
151 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 146 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
152 max_interbuffer_distance_(kNoTimestamp), 147 max_interbuffer_distance_(kNoTimestamp),
153 memory_limit_(kSourceBufferAudioMemoryLimit), 148 memory_limit_(kSourceBufferAudioMemoryLimit) {
154 splice_frames_enabled_(splice_frames_enabled) {
155 DCHECK(audio_config.IsValidConfig()); 149 DCHECK(audio_config.IsValidConfig());
156 audio_configs_.push_back(audio_config); 150 audio_configs_.push_back(audio_config);
157 } 151 }
158 152
159 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 153 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
160 const scoped_refptr<MediaLog>& media_log, 154 const scoped_refptr<MediaLog>& media_log)
161 bool splice_frames_enabled)
162 : media_log_(media_log), 155 : media_log_(media_log),
163 seek_buffer_timestamp_(kNoTimestamp), 156 seek_buffer_timestamp_(kNoTimestamp),
164 coded_frame_group_start_time_(kNoDecodeTimestamp()), 157 coded_frame_group_start_time_(kNoDecodeTimestamp()),
165 range_for_next_append_(ranges_.end()), 158 range_for_next_append_(ranges_.end()),
166 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 159 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
167 max_interbuffer_distance_(kNoTimestamp), 160 max_interbuffer_distance_(kNoTimestamp),
168 memory_limit_(kSourceBufferVideoMemoryLimit), 161 memory_limit_(kSourceBufferVideoMemoryLimit) {
169 splice_frames_enabled_(splice_frames_enabled) {
170 DCHECK(video_config.IsValidConfig()); 162 DCHECK(video_config.IsValidConfig());
171 video_configs_.push_back(video_config); 163 video_configs_.push_back(video_config);
172 } 164 }
173 165
174 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 166 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
175 const scoped_refptr<MediaLog>& media_log, 167 const scoped_refptr<MediaLog>& media_log)
176 bool splice_frames_enabled)
177 : media_log_(media_log), 168 : media_log_(media_log),
178 text_track_config_(text_config), 169 text_track_config_(text_config),
179 seek_buffer_timestamp_(kNoTimestamp), 170 seek_buffer_timestamp_(kNoTimestamp),
180 coded_frame_group_start_time_(kNoDecodeTimestamp()), 171 coded_frame_group_start_time_(kNoDecodeTimestamp()),
181 range_for_next_append_(ranges_.end()), 172 range_for_next_append_(ranges_.end()),
182 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 173 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
183 max_interbuffer_distance_(kNoTimestamp), 174 max_interbuffer_distance_(kNoTimestamp),
184 memory_limit_(kSourceBufferAudioMemoryLimit), 175 memory_limit_(kSourceBufferAudioMemoryLimit) {}
185 splice_frames_enabled_(splice_frames_enabled) {}
186 176
187 SourceBufferStream::~SourceBufferStream() { 177 SourceBufferStream::~SourceBufferStream() {
188 while (!ranges_.empty()) { 178 while (!ranges_.empty()) {
189 delete ranges_.front(); 179 delete ranges_.front();
190 ranges_.pop_front(); 180 ranges_.pop_front();
191 } 181 }
192 } 182 }
193 183
194 void SourceBufferStream::OnStartOfCodedFrameGroup( 184 void SourceBufferStream::OnStartOfCodedFrameGroup(
195 DecodeTimestamp coded_frame_group_start_time) { 185 DecodeTimestamp coded_frame_group_start_time) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 246
257 // Save a snapshot of stream state before range modifications are made. 247 // Save a snapshot of stream state before range modifications are made.
258 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 248 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
259 BufferQueue deleted_buffers; 249 BufferQueue deleted_buffers;
260 250
261 PrepareRangesForNextAppend(buffers, &deleted_buffers); 251 PrepareRangesForNextAppend(buffers, &deleted_buffers);
262 252
263 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 253 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
264 // create a new range with |buffers|. 254 // create a new range with |buffers|.
265 if (range_for_next_append_ != ranges_.end()) { 255 if (range_for_next_append_ != ranges_.end()) {
266 if (new_coded_frame_group_ && (!splice_frames_enabled_ || 256 if (new_coded_frame_group_) {
267 buffers.front()->splice_buffers().empty())) {
268 // If the first append to this stream in a new coded frame group continues 257 // If the first append to this stream in a new coded frame group continues
269 // a previous range, use the new group's start time instead of the first 258 // a previous range, use the new group's start time instead of the first
270 // new buffer's timestamp as the proof of adjacency to the existing range. 259 // new buffer's timestamp as the proof of adjacency to the existing range.
271 // A large gap (larger than our normal buffer adjacency test) can occur in 260 // A large gap (larger than our normal buffer adjacency test) can occur in
272 // a muxed set of streams (which share a common coded frame group start 261 // a muxed set of streams (which share a common coded frame group start
273 // time) with a significantly jagged start across the streams. 262 // time) with a significantly jagged start across the streams.
274 // Don't do this logic if there was a splice frame generated for the first
275 // new buffer, since splices are guaranteed to be in the same range and
276 // adjacent, and since the splice frame's timestamp can be less than
277 // |coded_frame_group_start_time_| due to the splicing.
278 (*range_for_next_append_) 263 (*range_for_next_append_)
279 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); 264 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_);
280 } else { 265 } else {
281 // Otherwise, use the first new buffer's timestamp as the proof of 266 // Otherwise, use the first new buffer's timestamp as the proof of
282 // adjacency. 267 // adjacency.
283 (*range_for_next_append_) 268 (*range_for_next_append_)
284 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); 269 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp());
285 } 270 }
286 271
287 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 272 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
(...skipping 17 matching lines...) Expand all
305 } 290 }
306 291
307 // If we didn't find a key frame, then update the last appended 292 // If we didn't find a key frame, then update the last appended
308 // buffer state and return. 293 // buffer state and return.
309 if (itr == buffers.end()) { 294 if (itr == buffers.end()) {
310 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 295 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
311 last_appended_buffer_duration_ = buffers.back()->duration(); 296 last_appended_buffer_duration_ = buffers.back()->duration();
312 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); 297 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
313 DVLOG(1) << __func__ << " " << GetStreamTypeName() 298 DVLOG(1) << __func__ << " " << GetStreamTypeName()
314 << ": new buffers in the middle of coded frame group depend on" 299 << ": new buffers in the middle of coded frame group depend on"
315 "keyframe that has been removed, and contain no keyframes." 300 " keyframe that has been removed, and contain no keyframes."
316 "Skipping further processing."; 301 " Skipping further processing.";
317 DVLOG(1) << __func__ << " " << GetStreamTypeName() 302 DVLOG(1) << __func__ << " " << GetStreamTypeName()
318 << ": done. ranges_=" << RangesToString(ranges_); 303 << ": done. ranges_=" << RangesToString(ranges_);
319 return true; 304 return true;
320 } else if (itr != buffers.begin()) { 305 } else if (itr != buffers.begin()) {
321 // Copy the first key frame and everything after it into 306 // Copy the first key frame and everything after it into
322 // |trimmed_buffers|. 307 // |trimmed_buffers|.
323 trimmed_buffers.assign(itr, buffers.end()); 308 trimmed_buffers.assign(itr, buffers.end());
324 buffers_for_new_range = &trimmed_buffers; 309 buffers_for_new_range = &trimmed_buffers;
325 } 310 }
326 311
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 DCHECK(IsRangeListSorted(ranges_)); 581 DCHECK(IsRangeListSorted(ranges_));
597 DCHECK(OnlySelectedRangeIsSeeked()); 582 DCHECK(OnlySelectedRangeIsSeeked());
598 } 583 }
599 584
600 void SourceBufferStream::ResetSeekState() { 585 void SourceBufferStream::ResetSeekState() {
601 SetSelectedRange(NULL); 586 SetSelectedRange(NULL);
602 track_buffer_.clear(); 587 track_buffer_.clear();
603 config_change_pending_ = false; 588 config_change_pending_ = false;
604 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); 589 last_output_buffer_timestamp_ = kNoDecodeTimestamp();
605 just_exhausted_track_buffer_ = false; 590 just_exhausted_track_buffer_ = false;
606 splice_buffers_index_ = 0;
607 pending_buffer_ = NULL; 591 pending_buffer_ = NULL;
608 pending_buffers_complete_ = false; 592 pending_buffers_complete_ = false;
609 } 593 }
610 594
611 void SourceBufferStream::ResetLastAppendedState() { 595 void SourceBufferStream::ResetLastAppendedState() {
612 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 596 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
613 last_appended_buffer_duration_ = kNoTimestamp; 597 last_appended_buffer_duration_ = kNoTimestamp;
614 last_appended_buffer_is_keyframe_ = false; 598 last_appended_buffer_is_keyframe_ = false;
615 } 599 }
616 600
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 if (range_for_next_append_ != ranges_.begin()) { 996 if (range_for_next_append_ != ranges_.begin()) {
1013 RangeList::iterator range_before_next = range_for_next_append_; 997 RangeList::iterator range_before_next = range_for_next_append_;
1014 --range_before_next; 998 --range_before_next;
1015 MergeWithAdjacentRangeIfNecessary(range_before_next); 999 MergeWithAdjacentRangeIfNecessary(range_before_next);
1016 } 1000 }
1017 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 1001 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
1018 } 1002 }
1019 return bytes_freed; 1003 return bytes_freed;
1020 } 1004 }
1021 1005
1006 void SourceBufferStream::TrimSpliceOverlap(const BufferQueue& new_buffers) {
1007 DCHECK(!new_buffers.empty());
1008 DCHECK_EQ(kAudio, GetType());
1009
1010 // Find the overlapped range (if any).
1011 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
1012 const DecodeTimestamp splice_dts =
1013 DecodeTimestamp::FromPresentationTime(splice_timestamp);
1014 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
1015 if (range_itr == ranges_.end()) {
1016 DVLOG(3) << __func__ << " No splice trimming. No range overlap at time "
1017 << splice_timestamp.InMicroseconds();
1018 return;
1019 }
1020
1021 // Search for overlapped buffer needs exclusive end value. Choosing smallest
1022 // possible value.
1023 const DecodeTimestamp end_dts =
1024 splice_dts + base::TimeDelta::FromInternalValue(1);
1025
1026 // Find if new buffer's start would overlap an existing buffer.
1027 BufferQueue overlapped_buffers;
1028 if (!(*range_itr)
1029 ->GetBuffersInRange(splice_dts, end_dts, &overlapped_buffers)) {
1030 // Bail if no overlapped buffers found.
1031 DVLOG(3) << __func__ << " No splice trimming. No buffer overlap at time "
1032 << splice_timestamp.InMicroseconds();
1033 return;
1034 }
1035
1036 // At most one buffer should exist containing the time of the newly appended
1037 // buffer's start. GetBuffersInRange does not currently return buffers with
1038 // zero duration.
1039 DCHECK_EQ(overlapped_buffers.size(), 1U)
1040 << __func__ << " Found more than one overlapped buffer";
1041 StreamParserBuffer* overlapped_buffer = overlapped_buffers.front().get();
1042
1043 if (overlapped_buffer->timestamp() == splice_timestamp) {
1044 // Ignore buffers with the same start time. They will be completely removed
1045 // in PrepareRangesForNextAppend().
1046 DVLOG(3) << __func__ << " No splice trimming at time "
1047 << splice_timestamp.InMicroseconds()
1048 << ". Overlapped buffer will be completely removed.";
1049 return;
1050 }
1051
1052 // Determine the duration of overlap.
1053 base::TimeDelta overlapped_end_time =
1054 overlapped_buffer->timestamp() + overlapped_buffer->duration();
1055 base::TimeDelta overlap_duration = overlapped_end_time - splice_timestamp;
1056
1057 // At this point overlap should be non-empty (ruled out same-timestamp above).
1058 DCHECK_NE(overlap_duration, base::TimeDelta());
wolenetz 2016/10/28 23:08:19 nit: s/NE/GT/ for extra safety :)
chcunningham 2016/11/02 01:28:42 Done.
1059
1060 // Don't trim for overlaps of less than one millisecond (which is frequently
1061 // the extent of timestamp resolution for poorly encoded media).
1062 if (overlap_duration < base::TimeDelta::FromMilliseconds(1)) {
1063 std::stringstream log_string;
1064 log_string << "Skipping audio splice trimming at PTS="
1065 << splice_timestamp.InMicroseconds() << "us. Found only "
1066 << overlap_duration.InMicroseconds()
1067 << "us of overlap, need at least 1000us. Multiple occurrences "
1068 << "may result in loss of A/V sync.";
1069 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs)
1070 << log_string.str();
1071 DVLOG(1) << __func__ << log_string.str();
1072 return;
1073 }
1074
1075 // Trim overlap from the existing buffer.
1076 DecoderBuffer::DiscardPadding discard_padding =
1077 overlapped_buffer->discard_padding();
1078 discard_padding.second += overlap_duration;
1079 overlapped_buffer->set_discard_padding(discard_padding);
1080 overlapped_buffer->set_duration(overlapped_buffer->duration() -
1081 overlap_duration);
1082
1083 std::stringstream log_string;
1084 log_string << "Audio buffer splice at PTS="
1085 << splice_timestamp.InMicroseconds()
1086 << "us. Trimmed tail of overlapped buffer (PTS="
1087 << overlapped_buffer->timestamp().InMicroseconds() << "us) by "
1088 << overlap_duration.InMicroseconds() << "us.";
1089 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs)
1090 << log_string.str();
1091 DVLOG(1) << __func__ << log_string.str();
1092 }
1093
1022 void SourceBufferStream::PrepareRangesForNextAppend( 1094 void SourceBufferStream::PrepareRangesForNextAppend(
1023 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 1095 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
1024 DCHECK(deleted_buffers); 1096 DCHECK(deleted_buffers);
1025 1097
1026 // Handle splices between the existing buffers and the new buffers. If a 1098 if (GetType() == kAudio)
1027 // splice is generated the timestamp and duration of the first buffer in 1099 TrimSpliceOverlap(new_buffers);
1028 // |new_buffers| will be modified.
1029 if (splice_frames_enabled_)
1030 GenerateSpliceFrame(new_buffers);
1031 1100
1101 base::TimeDelta prev_duration = last_appended_buffer_duration_;
1032 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 1102 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
1033 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 1103 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
1034 1104
1105 // 1. Clean up the old buffers between the last appended buffer and the
1106 // beginning of |new_buffers|.
1035 if (prev_timestamp != kNoDecodeTimestamp() && 1107 if (prev_timestamp != kNoDecodeTimestamp() &&
1036 prev_timestamp != next_timestamp) { 1108 prev_timestamp != next_timestamp) {
1037 // Clean up the old buffers between the last appended buffer and the
1038 // beginning of |new_buffers|.
1039 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 1109 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
1040 } 1110 }
1041 1111
1042 // Always make the start of the delete range exclusive for same timestamp 1112 // 2. Delete the buffers that |new_buffers| overlaps.
1043 // across the last buffer in the previous append and the first buffer in the
1044 // current append. Never be exclusive if a splice frame was generated because
1045 // we don't generate splice frames for same timestamp situations.
1046 DCHECK(new_buffers.front()->splice_timestamp() !=
1047 new_buffers.front()->timestamp());
1048 const bool exclude_start = new_buffers.front()->splice_buffers().empty() &&
1049 prev_timestamp == next_timestamp;
1050
1051 // Delete the buffers that |new_buffers| overlaps.
1052 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
1053 if (new_coded_frame_group_) { 1113 if (new_coded_frame_group_) {
1054 // Extend the deletion range earlier to the coded frame group start time if 1114 // Extend the deletion range earlier to the coded frame group start time if
1055 // this is the first append in a new coded frame group. Note that |start| 1115 // this is the first append in a new coded frame group.
1056 // could already be less than |coded_frame_group_start_time_| if a splice
1057 // was generated.
1058 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); 1116 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
1059 start = std::min(coded_frame_group_start_time_, start); 1117 next_timestamp = std::min(coded_frame_group_start_time_, next_timestamp);
1060 } 1118 }
1061 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 1119
1062 base::TimeDelta duration = new_buffers.back()->duration(); 1120 // Exclude the start from removal to avoid deleting the last appended buffer
1121 // in cases where the timestamps match. Only do this for when either:
1122 // A. Type is video. This may occur in cases of VP9 alt-ref frames or frames
1123 // with incorrect timestamps. Removing a frame may break decode
1124 // dependencies and there are no downsides to just keeping it.
wolenetz 2016/10/28 23:08:19 nit: s/no downsides/no downsides, other than poten
chcunningham 2016/11/02 01:28:42 Done.
1125 // B. Type is audio and overlapped duration is 0. We've encountered Vorbis
wolenetz 2016/10/28 23:08:19 nit: s/audio/audio or text/ + add a TODO+crbug, ab
chcunningham 2016/11/02 01:28:42 Done. For posterity, our f2f decision was to treat
1126 // streams containing zero-duration buffers (i.e. no real overlap). For
1127 // non-zero duration removing overlapped frames is important to preserve
1128 // A/V sync (see AudioClock).
1129 const bool exclude_start =
1130 prev_timestamp == next_timestamp &&
1131 (GetType() == kVideo || prev_duration == base::TimeDelta());
1063 1132
1064 // Set end time for remove to include the duration of last buffer. If the 1133 // Set end time for remove to include the duration of last buffer. If the
1065 // duration is estimated, use 1 microsecond instead to ensure frames are not 1134 // duration is estimated, use 1 microsecond instead to ensure frames are not
1066 // accidentally removed due to over-estimation. 1135 // accidentally removed due to over-estimation.
1136 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
1137 base::TimeDelta duration = new_buffers.back()->duration();
1067 if (duration != kNoTimestamp && duration > base::TimeDelta() && 1138 if (duration != kNoTimestamp && duration > base::TimeDelta() &&
1068 !new_buffers.back()->is_duration_estimated()) { 1139 !new_buffers.back()->is_duration_estimated()) {
1069 end += duration; 1140 end += duration;
1070 } else { 1141 } else {
1071 // TODO(chcunningham): Emit warning when 0ms durations are not expected. 1142 // TODO(chcunningham): Emit warning when 0ms durations are not expected.
1072 // http://crbug.com/312836 1143 // http://crbug.com/312836
1073 end += base::TimeDelta::FromInternalValue(1); 1144 end += base::TimeDelta::FromInternalValue(1);
1074 } 1145 }
1075 1146
1076 RemoveInternal(start, end, exclude_start, deleted_buffers); 1147 // Finally do the deletion of overlap.
1148 RemoveInternal(next_timestamp, end, exclude_start, deleted_buffers);
1077 } 1149 }
1078 1150
1079 bool SourceBufferStream::AreAdjacentInSequence( 1151 bool SourceBufferStream::AreAdjacentInSequence(
1080 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { 1152 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
1081 return first_timestamp < second_timestamp && 1153 return first_timestamp < second_timestamp &&
1082 second_timestamp <= 1154 second_timestamp <=
1083 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1155 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1084 } 1156 }
1085 1157
1086 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { 1158 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 if (!pending_buffer_.get()) { 1263 if (!pending_buffer_.get()) {
1192 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); 1264 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
1193 if (status != SourceBufferStream::kSuccess || 1265 if (status != SourceBufferStream::kSuccess ||
1194 !SetPendingBuffer(out_buffer)) { 1266 !SetPendingBuffer(out_buffer)) {
1195 DVLOG(2) << __func__ << " " << GetStreamTypeName() 1267 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1196 << ": no pending buffer, returning status " << status; 1268 << ": no pending buffer, returning status " << status;
1197 return status; 1269 return status;
1198 } 1270 }
1199 } 1271 }
1200 1272
1201 if (!pending_buffer_->splice_buffers().empty()) {
1202 const SourceBufferStream::Status status =
1203 HandleNextBufferWithSplice(out_buffer);
1204 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1205 << ": handled next buffer with splice, returning status "
1206 << status;
1207 return status;
1208 }
1209
1210 DCHECK(pending_buffer_->preroll_buffer().get()); 1273 DCHECK(pending_buffer_->preroll_buffer().get());
1211 1274
1212 const SourceBufferStream::Status status = 1275 const SourceBufferStream::Status status =
1213 HandleNextBufferWithPreroll(out_buffer); 1276 HandleNextBufferWithPreroll(out_buffer);
1214 DVLOG(2) << __func__ << " " << GetStreamTypeName() 1277 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1215 << ": handled next buffer with preroll, returning status " << status; 1278 << ": handled next buffer with preroll, returning status " << status;
1216 return status; 1279 return status;
1217 } 1280 }
1218 1281
1219 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
1220 scoped_refptr<StreamParserBuffer>* out_buffer) {
1221 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
1222 const size_t last_splice_buffer_index = splice_buffers.size() - 1;
1223
1224 // Are there any splice buffers left to hand out? The last buffer should be
1225 // handed out separately since it represents the first post-splice buffer.
1226 if (splice_buffers_index_ < last_splice_buffer_index) {
1227 // Account for config changes which occur between fade out buffers.
1228 if (current_config_index_ !=
1229 splice_buffers[splice_buffers_index_]->GetConfigId()) {
1230 config_change_pending_ = true;
1231 DVLOG(1) << "Config change (splice buffer config ID does not match).";
1232 return SourceBufferStream::kConfigChange;
1233 }
1234
1235 // Every pre splice buffer must have the same splice_timestamp().
1236 DCHECK(pending_buffer_->splice_timestamp() ==
1237 splice_buffers[splice_buffers_index_]->splice_timestamp());
1238
1239 // No pre splice buffers should have preroll.
1240 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get());
1241
1242 *out_buffer = splice_buffers[splice_buffers_index_++];
1243 return SourceBufferStream::kSuccess;
1244 }
1245
1246 // Did we hand out the last pre-splice buffer on the previous call?
1247 if (!pending_buffers_complete_) {
1248 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
1249 pending_buffers_complete_ = true;
1250 config_change_pending_ = true;
1251 DVLOG(1) << "Config change (forced for fade in of splice frame).";
1252 return SourceBufferStream::kConfigChange;
1253 }
1254
1255 // All pre-splice buffers have been handed out and a config change completed,
1256 // so hand out the final buffer for fade in. Because a config change is
1257 // always issued prior to handing out this buffer, any changes in config id
1258 // have been inherently handled.
1259 DCHECK(pending_buffers_complete_);
1260 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
1261 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp);
1262 *out_buffer = splice_buffers.back();
1263 pending_buffer_ = NULL;
1264
1265 // If the last splice buffer has preroll, hand off to the preroll handler.
1266 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
1267 : SourceBufferStream::kSuccess;
1268 }
1269
1270 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll( 1282 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
1271 scoped_refptr<StreamParserBuffer>* out_buffer) { 1283 scoped_refptr<StreamParserBuffer>* out_buffer) {
1272 // Any config change should have already been handled. 1284 // Any config change should have already been handled.
1273 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId()); 1285 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1274 1286
1275 // Check if the preroll buffer has already been handed out. 1287 // Check if the preroll buffer has already been handed out.
1276 if (!pending_buffers_complete_) { 1288 if (!pending_buffers_complete_) {
1277 pending_buffers_complete_ = true; 1289 pending_buffers_complete_ = true;
1278 *out_buffer = pending_buffer_->preroll_buffer(); 1290 *out_buffer = pending_buffer_->preroll_buffer();
1279 return SourceBufferStream::kSuccess; 1291 return SourceBufferStream::kSuccess;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 1343
1332 if (selected_range_->GetNextConfigId() != current_config_index_) { 1344 if (selected_range_->GetNextConfigId() != current_config_index_) {
1333 config_change_pending_ = true; 1345 config_change_pending_ = true;
1334 DVLOG(1) << "Config change (selected range config ID does not match)."; 1346 DVLOG(1) << "Config change (selected range config ID does not match).";
1335 return kConfigChange; 1347 return kConfigChange;
1336 } 1348 }
1337 1349
1338 CHECK(selected_range_->GetNextBuffer(out_buffer)); 1350 CHECK(selected_range_->GetNextBuffer(out_buffer));
1339 WarnIfTrackBufferExhaustionSkipsForward(*out_buffer); 1351 WarnIfTrackBufferExhaustionSkipsForward(*out_buffer);
1340 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1352 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
1353 DVLOG(3) << "Last output buffer DTS:"
wolenetz 2016/10/28 23:08:19 nit: Also include similar log in line 1328, and di
chcunningham 2016/11/02 01:28:42 I actually don't mean to land this log. Its a bit
1354 << last_output_buffer_timestamp_.InMicroseconds();
1341 return kSuccess; 1355 return kSuccess;
1342 } 1356 }
1343 1357
1344 void SourceBufferStream::WarnIfTrackBufferExhaustionSkipsForward( 1358 void SourceBufferStream::WarnIfTrackBufferExhaustionSkipsForward(
1345 const scoped_refptr<StreamParserBuffer>& next_buffer) { 1359 const scoped_refptr<StreamParserBuffer>& next_buffer) {
1346 if (!just_exhausted_track_buffer_) 1360 if (!just_exhausted_track_buffer_)
1347 return; 1361 return;
1348 1362
1349 just_exhausted_track_buffer_ = false; 1363 just_exhausted_track_buffer_ = false;
1350 DCHECK(next_buffer->is_key_frame()); 1364 DCHECK(next_buffer->is_key_frame());
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 append_config_index_ = video_configs_.size(); 1582 append_config_index_ = video_configs_.size();
1569 DVLOG(2) << "New video config - index: " << append_config_index_; 1583 DVLOG(2) << "New video config - index: " << append_config_index_;
1570 video_configs_.resize(video_configs_.size() + 1); 1584 video_configs_.resize(video_configs_.size() + 1);
1571 video_configs_[append_config_index_] = config; 1585 video_configs_[append_config_index_] = config;
1572 return true; 1586 return true;
1573 } 1587 }
1574 1588
1575 void SourceBufferStream::CompleteConfigChange() { 1589 void SourceBufferStream::CompleteConfigChange() {
1576 config_change_pending_ = false; 1590 config_change_pending_ = false;
1577 1591
1578 if (pending_buffer_.get()) {
1579 current_config_index_ =
1580 pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_);
1581 return;
1582 }
1583
1584 if (!track_buffer_.empty()) { 1592 if (!track_buffer_.empty()) {
1585 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); 1593 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0);
1586 return; 1594 return;
1587 } 1595 }
1588 1596
1589 if (selected_range_ && selected_range_->HasNextBuffer()) 1597 if (selected_range_ && selected_range_->HasNextBuffer())
1590 current_config_index_ = selected_range_->GetNextConfigId(); 1598 current_config_index_ = selected_range_->GetNextConfigId();
1591 } 1599 }
1592 1600
1593 void SourceBufferStream::SetSelectedRangeIfNeeded( 1601 void SourceBufferStream::SetSelectedRangeIfNeeded(
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 if (*itr == range_for_next_append_) { 1728 if (*itr == range_for_next_append_) {
1721 DVLOG(1) << __func__ << " deleting range_for_next_append_."; 1729 DVLOG(1) << __func__ << " deleting range_for_next_append_.";
1722 range_for_next_append_ = ranges_.end(); 1730 range_for_next_append_ = ranges_.end();
1723 ResetLastAppendedState(); 1731 ResetLastAppendedState();
1724 } 1732 }
1725 1733
1726 delete **itr; 1734 delete **itr;
1727 *itr = ranges_.erase(*itr); 1735 *itr = ranges_.erase(*itr);
1728 } 1736 }
1729 1737
1730 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) {
1731 DCHECK(!new_buffers.empty());
1732
1733 // Splice frames are only supported for audio.
1734 if (GetType() != kAudio)
1735 return;
1736
1737 // Find the overlapped range (if any).
1738 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
1739 const DecodeTimestamp splice_dts =
1740 DecodeTimestamp::FromPresentationTime(splice_timestamp);
1741 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
1742 if (range_itr == ranges_.end())
1743 return;
1744
1745 const DecodeTimestamp max_splice_end_dts =
1746 splice_dts + base::TimeDelta::FromMilliseconds(
1747 AudioSplicer::kCrossfadeDurationInMilliseconds);
1748
1749 // Find all buffers involved before the splice point.
1750 BufferQueue pre_splice_buffers;
1751 if (!(*range_itr)->GetBuffersInRange(
1752 splice_dts, max_splice_end_dts, &pre_splice_buffers)) {
1753 return;
1754 }
1755
1756 // If there are gaps in the timeline, it's possible that we only find buffers
1757 // after the splice point but within the splice range. For simplicity, we do
1758 // not generate splice frames in this case.
1759 //
1760 // We also do not want to generate splices if the first new buffer replaces an
1761 // existing buffer exactly.
1762 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) {
1763 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1764 kMaxSpliceGenerationWarningLogs)
1765 << "Skipping splice frame generation: first new buffer at "
1766 << splice_timestamp.InMicroseconds()
1767 << "us begins at or before existing buffer at "
1768 << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us.";
1769 DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the "
1770 "first new buffer.";
1771 return;
1772 }
1773
1774 // If any |pre_splice_buffers| are already splices or preroll, do not generate
1775 // a splice.
1776 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
1777 const BufferQueue& original_splice_buffers =
1778 pre_splice_buffers[i]->splice_buffers();
1779 if (!original_splice_buffers.empty()) {
1780 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1781 kMaxSpliceGenerationWarningLogs)
1782 << "Skipping splice frame generation: overlapped buffers at "
1783 << pre_splice_buffers[i]->timestamp().InMicroseconds()
1784 << "us are in a previously buffered splice.";
1785 DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
1786 "pre-existing splice.";
1787 return;
1788 }
1789
1790 if (pre_splice_buffers[i]->preroll_buffer().get()) {
1791 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1792 kMaxSpliceGenerationWarningLogs)
1793 << "Skipping splice frame generation: overlapped buffers at "
1794 << pre_splice_buffers[i]->timestamp().InMicroseconds()
1795 << "us contain preroll.";
1796 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
1797 return;
1798 }
1799 }
1800
1801 // Don't generate splice frames which represent less than a millisecond (which
1802 // is frequently the extent of timestamp resolution for poorly encoded media)
1803 // or less than two samples (need at least two to crossfade).
1804 const base::TimeDelta splice_duration =
1805 pre_splice_buffers.back()->timestamp() +
1806 pre_splice_buffers.back()->duration() - splice_timestamp;
1807 const base::TimeDelta minimum_splice_duration = std::max(
1808 base::TimeDelta::FromMilliseconds(1),
1809 base::TimeDelta::FromSecondsD(
1810 2.0 / audio_configs_[append_config_index_].samples_per_second()));
1811 if (splice_duration < minimum_splice_duration) {
1812 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1813 kMaxSpliceGenerationWarningLogs)
1814 << "Skipping splice frame generation: not enough samples for splicing "
1815 "new buffer at "
1816 << splice_timestamp.InMicroseconds() << "us. Have "
1817 << splice_duration.InMicroseconds() << "us, but need "
1818 << minimum_splice_duration.InMicroseconds() << "us.";
1819 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
1820 << splice_duration.InMicroseconds() << "us, but need "
1821 << minimum_splice_duration.InMicroseconds() << "us.";
1822 return;
1823 }
1824
1825 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp()
1826 << ", splice duration: " << splice_duration.InMicroseconds()
1827 << " us";
1828 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_,
1829 kMaxSpliceGenerationSuccessLogs)
1830 << "Generated splice of overlap duration "
1831 << splice_duration.InMicroseconds() << "us into new buffer at "
1832 << splice_timestamp.InMicroseconds() << "us.";
1833 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
1834 }
1835
1836 bool SourceBufferStream::SetPendingBuffer( 1738 bool SourceBufferStream::SetPendingBuffer(
1837 scoped_refptr<StreamParserBuffer>* out_buffer) { 1739 scoped_refptr<StreamParserBuffer>* out_buffer) {
1838 DCHECK(out_buffer->get()); 1740 DCHECK(out_buffer->get());
1839 DCHECK(!pending_buffer_.get()); 1741 DCHECK(!pending_buffer_.get());
1840 1742
1841 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
1842 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); 1743 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();
1843 1744
1844 if (!have_splice_buffers && !have_preroll_buffer) 1745 if (!have_preroll_buffer)
1845 return false; 1746 return false;
1846 1747
1847 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1848 splice_buffers_index_ = 0;
1849 pending_buffer_.swap(*out_buffer); 1748 pending_buffer_.swap(*out_buffer);
1850 pending_buffers_complete_ = false; 1749 pending_buffers_complete_ = false;
1851 return true; 1750 return true;
1852 } 1751 }
1853 1752
1854 } // namespace media 1753 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698