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

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

Issue 2343543002: MSE: Replace crossfade splicing overlap trimming. (Closed)
Patch Set: No more silence, just trim the overlap. Created 4 years, 3 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
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | 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 #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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 248
259 // Save a snapshot of stream state before range modifications are made. 249 // Save a snapshot of stream state before range modifications are made.
260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 250 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
261 BufferQueue deleted_buffers; 251 BufferQueue deleted_buffers;
262 252
263 PrepareRangesForNextAppend(buffers, &deleted_buffers); 253 PrepareRangesForNextAppend(buffers, &deleted_buffers);
264 254
265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 255 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
266 // create a new range with |buffers|. 256 // create a new range with |buffers|.
267 if (range_for_next_append_ != ranges_.end()) { 257 if (range_for_next_append_ != ranges_.end()) {
268 if (new_coded_frame_group_ && (!splice_frames_enabled_ || 258 if (new_coded_frame_group_) {
269 buffers.front()->splice_buffers().empty())) {
270 // If the first append to this stream in a new coded frame group continues 259 // If the first append to this stream in a new coded frame group continues
271 // a previous range, use the new group's start time instead of the first 260 // a previous range, use the new group's start time instead of the first
272 // new buffer's timestamp as the proof of adjacency to the existing range. 261 // new buffer's timestamp as the proof of adjacency to the existing range.
273 // A large gap (larger than our normal buffer adjacency test) can occur in 262 // A large gap (larger than our normal buffer adjacency test) can occur in
274 // a muxed set of streams (which share a common coded frame group start 263 // a muxed set of streams (which share a common coded frame group start
275 // time) with a significantly jagged start across the streams. 264 // time) with a significantly jagged start across the streams.
276 // Don't do this logic if there was a splice frame generated for the first
277 // new buffer, since splices are guaranteed to be in the same range and
278 // adjacent, and since the splice frame's timestamp can be less than
279 // |coded_frame_group_start_time_| due to the splicing.
280 (*range_for_next_append_) 265 (*range_for_next_append_)
281 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); 266 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_);
282 } else { 267 } else {
283 // Otherwise, use the first new buffer's timestamp as the proof of 268 // Otherwise, use the first new buffer's timestamp as the proof of
284 // adjacency. 269 // adjacency.
285 (*range_for_next_append_) 270 (*range_for_next_append_)
286 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); 271 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp());
287 } 272 }
288 273
289 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 274 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 DCHECK(IsRangeListSorted(ranges_)); 537 DCHECK(IsRangeListSorted(ranges_));
553 DCHECK(OnlySelectedRangeIsSeeked()); 538 DCHECK(OnlySelectedRangeIsSeeked());
554 } 539 }
555 540
556 void SourceBufferStream::ResetSeekState() { 541 void SourceBufferStream::ResetSeekState() {
557 SetSelectedRange(NULL); 542 SetSelectedRange(NULL);
558 track_buffer_.clear(); 543 track_buffer_.clear();
559 config_change_pending_ = false; 544 config_change_pending_ = false;
560 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); 545 last_output_buffer_timestamp_ = kNoDecodeTimestamp();
561 just_exhausted_track_buffer_ = false; 546 just_exhausted_track_buffer_ = false;
562 splice_buffers_index_ = 0;
563 pending_buffer_ = NULL; 547 pending_buffer_ = NULL;
564 pending_buffers_complete_ = false; 548 pending_buffers_complete_ = false;
565 } 549 }
566 550
567 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 551 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
568 base::TimeDelta seek_timestamp) const { 552 base::TimeDelta seek_timestamp) const {
569 if (ranges_.empty()) 553 if (ranges_.empty())
570 return false; 554 return false;
571 base::TimeDelta beginning_of_buffered = 555 base::TimeDelta beginning_of_buffered =
572 ranges_.front()->GetStartTimestamp().ToPresentationTime(); 556 ranges_.front()->GetStartTimestamp().ToPresentationTime();
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 if (range_for_next_append_ != ranges_.begin()) { 946 if (range_for_next_append_ != ranges_.begin()) {
963 RangeList::iterator range_before_next = range_for_next_append_; 947 RangeList::iterator range_before_next = range_for_next_append_;
964 --range_before_next; 948 --range_before_next;
965 MergeWithAdjacentRangeIfNecessary(range_before_next); 949 MergeWithAdjacentRangeIfNecessary(range_before_next);
966 } 950 }
967 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 951 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
968 } 952 }
969 return bytes_freed; 953 return bytes_freed;
970 } 954 }
971 955
956 void SourceBufferStream::TrimSpliceOverlap(const BufferQueue& new_buffers) {
957 DCHECK(!new_buffers.empty());
958 DCHECK_EQ(kAudio, GetType());
959
960 // Find the overlapped range (if any).
961 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
962 const DecodeTimestamp splice_dts =
963 DecodeTimestamp::FromPresentationTime(splice_timestamp);
964 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
965 if (range_itr == ranges_.end()) {
966 DVLOG(3) << __func__ << " No splice trimming. No range overlap at time "
967 << splice_timestamp.InMicroseconds();
968 return;
969 }
970
971 // Search for overlapped buffer needs exclusive end value. Choosing smallest
972 // possible value.
973 const DecodeTimestamp end_dts =
974 splice_dts + base::TimeDelta::FromInternalValue(1);
975
976 // Find if new buffer's start would overlap an existing buffer.
977 BufferQueue overlapped_buffers;
978 if (!(*range_itr)
979 ->GetBuffersInRange(splice_dts, end_dts, &overlapped_buffers)) {
980 // Bail if no overlapped buffers found.
981 DVLOG(3) << __func__ << " No splice trimming. No buffer overlap at time "
982 << splice_timestamp.InMicroseconds();
983 return;
984 }
985
986 // At most one buffer should exist containing the time of the newly appended
987 // buffer's start. GetBuffersInRange does not currently return buffers with
988 // zero duration.
989 DCHECK_EQ(overlapped_buffers.size(), 1U)
990 << __func__ << " Found more than one overlapped buffer";
991 StreamParserBuffer* overlapped_buffer = overlapped_buffers.front().get();
992
993 if (overlapped_buffer->timestamp() == splice_timestamp) {
994 // Ignore buffers with the same start time. They will be completely removed
995 // in PreapreRangesForNextAppend().
996 DVLOG(3) << __func__ << " No splice trimming at time "
997 << splice_timestamp.InMicroseconds()
998 << ". Overlapped buffer will be completely removed.";
999 return;
1000 }
1001
1002 // Determine the duration of overlap.
1003 base::TimeDelta overlapped_end_time =
1004 overlapped_buffer->timestamp() + overlapped_buffer->duration();
1005 base::TimeDelta overlap_duration = overlapped_end_time - splice_timestamp;
1006
1007 // Trim overlap from the existing buffer.
1008 if (overlap_duration > base::TimeDelta()) {
1009 DecoderBuffer::DiscardPadding discard_padding =
1010 overlapped_buffer->discard_padding();
1011 discard_padding.second += overlap_duration;
1012 overlapped_buffer->set_discard_padding(discard_padding);
1013 overlapped_buffer->set_duration(overlapped_buffer->duration() -
1014 overlap_duration);
1015
1016 std::stringstream log_string;
1017 log_string << "Audio buffer splice at PTS="
1018 << splice_timestamp.InMicroseconds()
1019 << "us. Trimmed tail of overlapped buffer (PTS="
1020 << overlapped_buffer->timestamp().InMicroseconds() << "us) by "
1021 << overlap_duration.InMicroseconds() << "us.";
1022 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs)
1023 << log_string.str();
1024 DVLOG(1) << __func__ << log_string.str();
1025 }
1026 }
1027
972 void SourceBufferStream::PrepareRangesForNextAppend( 1028 void SourceBufferStream::PrepareRangesForNextAppend(
973 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 1029 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
974 DCHECK(deleted_buffers); 1030 DCHECK(deleted_buffers);
975 1031
976 // Handle splices between the existing buffers and the new buffers. If a 1032 if (GetType() == kAudio)
977 // splice is generated the timestamp and duration of the first buffer in 1033 TrimSpliceOverlap(new_buffers);
978 // |new_buffers| will be modified.
979 if (splice_frames_enabled_)
980 GenerateSpliceFrame(new_buffers);
981 1034
1035 base::TimeDelta prev_duration = last_appended_buffer_duration_;
982 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 1036 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
983 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 1037 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
984 1038
1039 // 1. Clean up the old buffers between the last appended buffer and the
1040 // beginning of |new_buffers|.
985 if (prev_timestamp != kNoDecodeTimestamp() && 1041 if (prev_timestamp != kNoDecodeTimestamp() &&
986 prev_timestamp != next_timestamp) { 1042 prev_timestamp != next_timestamp) {
987 // Clean up the old buffers between the last appended buffer and the
988 // beginning of |new_buffers|.
989 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 1043 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
990 } 1044 }
991 1045
992 // Always make the start of the delete range exclusive for same timestamp 1046 // 2. Delete the buffers that |new_buffers| overlaps.
993 // across the last buffer in the previous append and the first buffer in the
994 // current append. Never be exclusive if a splice frame was generated because
995 // we don't generate splice frames for same timestamp situations.
996 DCHECK(new_buffers.front()->splice_timestamp() !=
997 new_buffers.front()->timestamp());
998 const bool exclude_start = new_buffers.front()->splice_buffers().empty() &&
999 prev_timestamp == next_timestamp;
1000
1001 // Delete the buffers that |new_buffers| overlaps.
1002 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
1003 if (new_coded_frame_group_) { 1047 if (new_coded_frame_group_) {
1004 // Extend the deletion range earlier to the coded frame group start time if 1048 // Extend the deletion range earlier to the coded frame group start time if
1005 // this is the first append in a new coded frame group. Note that |start| 1049 // this is the first append in a new coded frame group.
1006 // could already be less than |coded_frame_group_start_time_| if a splice
1007 // was generated.
1008 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); 1050 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
1009 start = std::min(coded_frame_group_start_time_, start); 1051 next_timestamp = std::min(coded_frame_group_start_time_, next_timestamp);
1010 } 1052 }
1011 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 1053
1012 base::TimeDelta duration = new_buffers.back()->duration(); 1054 // Exclude the start timestamp from removal if the previous append is a zero
1055 // duration frame with the same timestamp as the current append. This avoids
1056 // deleting zero-duration VP9 alt-ref frames while still deleting frames
1057 // with non-zero duration that are now overlapped.
1058 const bool exclude_start =
1059 prev_timestamp == next_timestamp && prev_duration == base::TimeDelta();
1013 1060
1014 // Set end time for remove to include the duration of last buffer. If the 1061 // Set end time for remove to include the duration of last buffer. If the
1015 // duration is estimated, use 1 microsecond instead to ensure frames are not 1062 // duration is estimated, use 1 microsecond instead to ensure frames are not
1016 // accidentally removed due to over-estimation. 1063 // accidentally removed due to over-estimation.
1064 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
1065 base::TimeDelta duration = new_buffers.back()->duration();
1017 if (duration != kNoTimestamp && duration > base::TimeDelta() && 1066 if (duration != kNoTimestamp && duration > base::TimeDelta() &&
1018 !new_buffers.back()->is_duration_estimated()) { 1067 !new_buffers.back()->is_duration_estimated()) {
1019 end += duration; 1068 end += duration;
1020 } else { 1069 } else {
1021 // TODO(chcunningham): Emit warning when 0ms durations are not expected. 1070 // TODO(chcunningham): Emit warning when 0ms durations are not expected.
1022 // http://crbug.com/312836 1071 // http://crbug.com/312836
1023 end += base::TimeDelta::FromInternalValue(1); 1072 end += base::TimeDelta::FromInternalValue(1);
1024 } 1073 }
1025 1074
1026 RemoveInternal(start, end, exclude_start, deleted_buffers); 1075 // Finally do the deletion of overlap.
1076 RemoveInternal(next_timestamp, end, exclude_start, deleted_buffers);
1027 } 1077 }
1028 1078
1029 bool SourceBufferStream::AreAdjacentInSequence( 1079 bool SourceBufferStream::AreAdjacentInSequence(
1030 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { 1080 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
1031 return first_timestamp < second_timestamp && 1081 return first_timestamp < second_timestamp &&
1032 second_timestamp <= 1082 second_timestamp <=
1033 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1083 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1034 } 1084 }
1035 1085
1036 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { 1086 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 if (!pending_buffer_.get()) { 1205 if (!pending_buffer_.get()) {
1156 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); 1206 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
1157 if (status != SourceBufferStream::kSuccess || 1207 if (status != SourceBufferStream::kSuccess ||
1158 !SetPendingBuffer(out_buffer)) { 1208 !SetPendingBuffer(out_buffer)) {
1159 DVLOG(2) << __func__ << " " << GetStreamTypeName() 1209 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1160 << ": no pending buffer, returning status " << status; 1210 << ": no pending buffer, returning status " << status;
1161 return status; 1211 return status;
1162 } 1212 }
1163 } 1213 }
1164 1214
1165 if (!pending_buffer_->splice_buffers().empty()) {
1166 const SourceBufferStream::Status status =
1167 HandleNextBufferWithSplice(out_buffer);
1168 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1169 << ": handled next buffer with splice, returning status "
1170 << status;
1171 return status;
1172 }
1173
1174 DCHECK(pending_buffer_->preroll_buffer().get()); 1215 DCHECK(pending_buffer_->preroll_buffer().get());
1175 1216
1176 const SourceBufferStream::Status status = 1217 const SourceBufferStream::Status status =
1177 HandleNextBufferWithPreroll(out_buffer); 1218 HandleNextBufferWithPreroll(out_buffer);
1178 DVLOG(2) << __func__ << " " << GetStreamTypeName() 1219 DVLOG(2) << __func__ << " " << GetStreamTypeName()
1179 << ": handled next buffer with preroll, returning status " << status; 1220 << ": handled next buffer with preroll, returning status " << status;
1180 return status; 1221 return status;
1181 } 1222 }
1182 1223
1183 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
1184 scoped_refptr<StreamParserBuffer>* out_buffer) {
1185 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
1186 const size_t last_splice_buffer_index = splice_buffers.size() - 1;
1187
1188 // Are there any splice buffers left to hand out? The last buffer should be
1189 // handed out separately since it represents the first post-splice buffer.
1190 if (splice_buffers_index_ < last_splice_buffer_index) {
1191 // Account for config changes which occur between fade out buffers.
1192 if (current_config_index_ !=
1193 splice_buffers[splice_buffers_index_]->GetConfigId()) {
1194 config_change_pending_ = true;
1195 DVLOG(1) << "Config change (splice buffer config ID does not match).";
1196 return SourceBufferStream::kConfigChange;
1197 }
1198
1199 // Every pre splice buffer must have the same splice_timestamp().
1200 DCHECK(pending_buffer_->splice_timestamp() ==
1201 splice_buffers[splice_buffers_index_]->splice_timestamp());
1202
1203 // No pre splice buffers should have preroll.
1204 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get());
1205
1206 *out_buffer = splice_buffers[splice_buffers_index_++];
1207 return SourceBufferStream::kSuccess;
1208 }
1209
1210 // Did we hand out the last pre-splice buffer on the previous call?
1211 if (!pending_buffers_complete_) {
1212 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
1213 pending_buffers_complete_ = true;
1214 config_change_pending_ = true;
1215 DVLOG(1) << "Config change (forced for fade in of splice frame).";
1216 return SourceBufferStream::kConfigChange;
1217 }
1218
1219 // All pre-splice buffers have been handed out and a config change completed,
1220 // so hand out the final buffer for fade in. Because a config change is
1221 // always issued prior to handing out this buffer, any changes in config id
1222 // have been inherently handled.
1223 DCHECK(pending_buffers_complete_);
1224 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
1225 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp);
1226 *out_buffer = splice_buffers.back();
1227 pending_buffer_ = NULL;
1228
1229 // If the last splice buffer has preroll, hand off to the preroll handler.
1230 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
1231 : SourceBufferStream::kSuccess;
1232 }
1233
1234 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll( 1224 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
1235 scoped_refptr<StreamParserBuffer>* out_buffer) { 1225 scoped_refptr<StreamParserBuffer>* out_buffer) {
1236 // Any config change should have already been handled. 1226 // Any config change should have already been handled.
1237 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId()); 1227 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1238 1228
1239 // Check if the preroll buffer has already been handed out. 1229 // Check if the preroll buffer has already been handed out.
1240 if (!pending_buffers_complete_) { 1230 if (!pending_buffers_complete_) {
1241 pending_buffers_complete_ = true; 1231 pending_buffers_complete_ = true;
1242 *out_buffer = pending_buffer_->preroll_buffer(); 1232 *out_buffer = pending_buffer_->preroll_buffer();
1243 return SourceBufferStream::kSuccess; 1233 return SourceBufferStream::kSuccess;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 append_config_index_ = video_configs_.size(); 1522 append_config_index_ = video_configs_.size();
1533 DVLOG(2) << "New video config - index: " << append_config_index_; 1523 DVLOG(2) << "New video config - index: " << append_config_index_;
1534 video_configs_.resize(video_configs_.size() + 1); 1524 video_configs_.resize(video_configs_.size() + 1);
1535 video_configs_[append_config_index_] = config; 1525 video_configs_[append_config_index_] = config;
1536 return true; 1526 return true;
1537 } 1527 }
1538 1528
1539 void SourceBufferStream::CompleteConfigChange() { 1529 void SourceBufferStream::CompleteConfigChange() {
1540 config_change_pending_ = false; 1530 config_change_pending_ = false;
1541 1531
1542 if (pending_buffer_.get()) {
1543 current_config_index_ =
1544 pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_);
1545 return;
1546 }
1547
1548 if (!track_buffer_.empty()) { 1532 if (!track_buffer_.empty()) {
1549 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); 1533 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0);
1550 return; 1534 return;
1551 } 1535 }
1552 1536
1553 if (selected_range_ && selected_range_->HasNextBuffer()) 1537 if (selected_range_ && selected_range_->HasNextBuffer())
1554 current_config_index_ = selected_range_->GetNextConfigId(); 1538 current_config_index_ = selected_range_->GetNextConfigId();
1555 } 1539 }
1556 1540
1557 void SourceBufferStream::SetSelectedRangeIfNeeded( 1541 void SourceBufferStream::SetSelectedRangeIfNeeded(
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; 1669 DVLOG(1) << __func__ << " deleting range_for_next_append_.";
1686 range_for_next_append_ = ranges_.end(); 1670 range_for_next_append_ = ranges_.end();
1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 1671 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
1688 last_appended_buffer_is_keyframe_ = false; 1672 last_appended_buffer_is_keyframe_ = false;
1689 } 1673 }
1690 1674
1691 delete **itr; 1675 delete **itr;
1692 *itr = ranges_.erase(*itr); 1676 *itr = ranges_.erase(*itr);
1693 } 1677 }
1694 1678
1695 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) {
1696 DCHECK(!new_buffers.empty());
1697
1698 // Splice frames are only supported for audio.
1699 if (GetType() != kAudio)
1700 return;
1701
1702 // Find the overlapped range (if any).
1703 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
1704 const DecodeTimestamp splice_dts =
1705 DecodeTimestamp::FromPresentationTime(splice_timestamp);
1706 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
1707 if (range_itr == ranges_.end())
1708 return;
1709
1710 const DecodeTimestamp max_splice_end_dts =
1711 splice_dts + base::TimeDelta::FromMilliseconds(
1712 AudioSplicer::kCrossfadeDurationInMilliseconds);
1713
1714 // Find all buffers involved before the splice point.
1715 BufferQueue pre_splice_buffers;
1716 if (!(*range_itr)->GetBuffersInRange(
1717 splice_dts, max_splice_end_dts, &pre_splice_buffers)) {
1718 return;
1719 }
1720
1721 // If there are gaps in the timeline, it's possible that we only find buffers
1722 // after the splice point but within the splice range. For simplicity, we do
1723 // not generate splice frames in this case.
1724 //
1725 // We also do not want to generate splices if the first new buffer replaces an
1726 // existing buffer exactly.
1727 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) {
1728 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1729 kMaxSpliceGenerationWarningLogs)
1730 << "Skipping splice frame generation: first new buffer at "
1731 << splice_timestamp.InMicroseconds()
1732 << "us begins at or before existing buffer at "
1733 << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us.";
1734 DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the "
1735 "first new buffer.";
1736 return;
1737 }
1738
1739 // If any |pre_splice_buffers| are already splices or preroll, do not generate
1740 // a splice.
1741 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
1742 const BufferQueue& original_splice_buffers =
1743 pre_splice_buffers[i]->splice_buffers();
1744 if (!original_splice_buffers.empty()) {
1745 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1746 kMaxSpliceGenerationWarningLogs)
1747 << "Skipping splice frame generation: overlapped buffers at "
1748 << pre_splice_buffers[i]->timestamp().InMicroseconds()
1749 << "us are in a previously buffered splice.";
1750 DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
1751 "pre-existing splice.";
1752 return;
1753 }
1754
1755 if (pre_splice_buffers[i]->preroll_buffer().get()) {
1756 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1757 kMaxSpliceGenerationWarningLogs)
1758 << "Skipping splice frame generation: overlapped buffers at "
1759 << pre_splice_buffers[i]->timestamp().InMicroseconds()
1760 << "us contain preroll.";
1761 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
1762 return;
1763 }
1764 }
1765
1766 // Don't generate splice frames which represent less than a millisecond (which
DaleCurtis 2016/09/16 21:01:04 Probably you want to carry this over to avoid bad
chcunningham 2016/09/16 22:25:24 Done.
1767 // is frequently the extent of timestamp resolution for poorly encoded media)
1768 // or less than two samples (need at least two to crossfade).
1769 const base::TimeDelta splice_duration =
1770 pre_splice_buffers.back()->timestamp() +
1771 pre_splice_buffers.back()->duration() - splice_timestamp;
1772 const base::TimeDelta minimum_splice_duration = std::max(
1773 base::TimeDelta::FromMilliseconds(1),
1774 base::TimeDelta::FromSecondsD(
1775 2.0 / audio_configs_[append_config_index_].samples_per_second()));
1776 if (splice_duration < minimum_splice_duration) {
1777 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
1778 kMaxSpliceGenerationWarningLogs)
1779 << "Skipping splice frame generation: not enough samples for splicing "
1780 "new buffer at "
1781 << splice_timestamp.InMicroseconds() << "us. Have "
1782 << splice_duration.InMicroseconds() << "us, but need "
1783 << minimum_splice_duration.InMicroseconds() << "us.";
1784 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
1785 << splice_duration.InMicroseconds() << "us, but need "
1786 << minimum_splice_duration.InMicroseconds() << "us.";
1787 return;
1788 }
1789
1790 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp()
1791 << ", splice duration: " << splice_duration.InMicroseconds()
1792 << " us";
1793 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_,
1794 kMaxSpliceGenerationSuccessLogs)
1795 << "Generated splice of overlap duration "
1796 << splice_duration.InMicroseconds() << "us into new buffer at "
1797 << splice_timestamp.InMicroseconds() << "us.";
1798 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
1799 }
1800
1801 bool SourceBufferStream::SetPendingBuffer( 1679 bool SourceBufferStream::SetPendingBuffer(
1802 scoped_refptr<StreamParserBuffer>* out_buffer) { 1680 scoped_refptr<StreamParserBuffer>* out_buffer) {
1803 DCHECK(out_buffer->get()); 1681 DCHECK(out_buffer->get());
1804 DCHECK(!pending_buffer_.get()); 1682 DCHECK(!pending_buffer_.get());
1805 1683
1806 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
1807 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); 1684 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();
1808 1685
1809 if (!have_splice_buffers && !have_preroll_buffer) 1686 if (!have_preroll_buffer)
1810 return false; 1687 return false;
1811 1688
1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1813 splice_buffers_index_ = 0;
1814 pending_buffer_.swap(*out_buffer); 1689 pending_buffer_.swap(*out_buffer);
1815 pending_buffers_complete_ = false; 1690 pending_buffers_complete_ = false;
1816 return true; 1691 return true;
1817 } 1692 }
1818 1693
1819 } // namespace media 1694 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698