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

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

Issue 2343543002: MSE: Replace crossfade splicing overlap trimming. (Closed)
Patch Set: 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
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/audio_splicer.h"
15 #include "media/base/timestamp_constants.h" 16 #include "media/base/timestamp_constants.h"
16 #include "media/filters/source_buffer_platform.h" 17 #include "media/filters/source_buffer_platform.h"
17 #include "media/filters/source_buffer_range.h" 18 #include "media/filters/source_buffer_range.h"
18 19
19 namespace media { 20 namespace media {
20 21
21 namespace { 22 namespace {
22 23
23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is 24 // 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. 25 // set and there's not enough information to get a better estimate.
25 const int kDefaultBufferDurationInMs = 125; 26 const int kDefaultBufferDurationInMs = 125;
26 27
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. 28 // Limit the number of MEDIA_LOG() logs for track buffer time gaps.
35 const int kMaxTrackBufferGapWarningLogs = 20; 29 const int kMaxTrackBufferGapWarningLogs = 20;
36 30
37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. 31 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; 32 const int kMaxGarbageCollectAlgorithmWarningLogs = 20;
39 33
34 // Limit the number of MEDIA_LOG() logs for generated splice silence.
35 const int kMaxSpliceGenerationLogs = 20;
36
40 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed 37 // 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 38 // by keyframe. Prior to relaxing the "media segments must begin with a
42 // keyframe" requirement, we issued decode error for this situation. That was 39 // 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 40 // 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 41 // 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 42 // decode error, since we allow these sequences which may cause extra decoder
46 // work or other side-effects. 43 // work or other side-effects.
47 const int kMaxStrangeSameTimestampsLogs = 20; 44 const int kMaxStrangeSameTimestampsLogs = 20;
48 45
49 // Helper method that returns true if |ranges| is sorted in increasing order, 46 // Helper method that returns true if |ranges| is sorted in increasing order,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 return SourceBufferRange::ALLOW_GAPS; 132 return SourceBufferRange::ALLOW_GAPS;
136 } 133 }
137 134
138 NOTREACHED(); 135 NOTREACHED();
139 return SourceBufferRange::NO_GAPS_ALLOWED; 136 return SourceBufferRange::NO_GAPS_ALLOWED;
140 } 137 }
141 138
142 } // namespace 139 } // namespace
143 140
144 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 141 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
145 const scoped_refptr<MediaLog>& media_log, 142 const scoped_refptr<MediaLog>& media_log)
146 bool splice_frames_enabled)
147 : media_log_(media_log), 143 : media_log_(media_log),
148 seek_buffer_timestamp_(kNoTimestamp), 144 seek_buffer_timestamp_(kNoTimestamp),
149 coded_frame_group_start_time_(kNoDecodeTimestamp()), 145 coded_frame_group_start_time_(kNoDecodeTimestamp()),
150 range_for_next_append_(ranges_.end()), 146 range_for_next_append_(ranges_.end()),
151 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 147 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
152 max_interbuffer_distance_(kNoTimestamp), 148 max_interbuffer_distance_(kNoTimestamp),
153 memory_limit_(kSourceBufferAudioMemoryLimit), 149 memory_limit_(kSourceBufferAudioMemoryLimit) {
154 splice_frames_enabled_(splice_frames_enabled) {
155 DCHECK(audio_config.IsValidConfig()); 150 DCHECK(audio_config.IsValidConfig());
156 audio_configs_.push_back(audio_config); 151 audio_configs_.push_back(audio_config);
157 } 152 }
158 153
159 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 154 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
160 const scoped_refptr<MediaLog>& media_log, 155 const scoped_refptr<MediaLog>& media_log)
161 bool splice_frames_enabled)
162 : media_log_(media_log), 156 : media_log_(media_log),
163 seek_buffer_timestamp_(kNoTimestamp), 157 seek_buffer_timestamp_(kNoTimestamp),
164 coded_frame_group_start_time_(kNoDecodeTimestamp()), 158 coded_frame_group_start_time_(kNoDecodeTimestamp()),
165 range_for_next_append_(ranges_.end()), 159 range_for_next_append_(ranges_.end()),
166 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 160 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
167 max_interbuffer_distance_(kNoTimestamp), 161 max_interbuffer_distance_(kNoTimestamp),
168 memory_limit_(kSourceBufferVideoMemoryLimit), 162 memory_limit_(kSourceBufferVideoMemoryLimit) {
169 splice_frames_enabled_(splice_frames_enabled) {
170 DCHECK(video_config.IsValidConfig()); 163 DCHECK(video_config.IsValidConfig());
171 video_configs_.push_back(video_config); 164 video_configs_.push_back(video_config);
172 } 165 }
173 166
174 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 167 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
175 const scoped_refptr<MediaLog>& media_log, 168 const scoped_refptr<MediaLog>& media_log)
176 bool splice_frames_enabled)
177 : media_log_(media_log), 169 : media_log_(media_log),
178 text_track_config_(text_config), 170 text_track_config_(text_config),
179 seek_buffer_timestamp_(kNoTimestamp), 171 seek_buffer_timestamp_(kNoTimestamp),
180 coded_frame_group_start_time_(kNoDecodeTimestamp()), 172 coded_frame_group_start_time_(kNoDecodeTimestamp()),
181 range_for_next_append_(ranges_.end()), 173 range_for_next_append_(ranges_.end()),
182 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 174 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
183 max_interbuffer_distance_(kNoTimestamp), 175 max_interbuffer_distance_(kNoTimestamp),
184 memory_limit_(kSourceBufferAudioMemoryLimit), 176 memory_limit_(kSourceBufferAudioMemoryLimit) {}
185 splice_frames_enabled_(splice_frames_enabled) {}
186 177
187 SourceBufferStream::~SourceBufferStream() { 178 SourceBufferStream::~SourceBufferStream() {
188 while (!ranges_.empty()) { 179 while (!ranges_.empty()) {
189 delete ranges_.front(); 180 delete ranges_.front();
190 ranges_.pop_front(); 181 ranges_.pop_front();
191 } 182 }
192 } 183 }
193 184
194 void SourceBufferStream::OnStartOfCodedFrameGroup( 185 void SourceBufferStream::OnStartOfCodedFrameGroup(
195 DecodeTimestamp coded_frame_group_start_time) { 186 DecodeTimestamp coded_frame_group_start_time) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 249
259 // Save a snapshot of stream state before range modifications are made. 250 // Save a snapshot of stream state before range modifications are made.
260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 251 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
261 BufferQueue deleted_buffers; 252 BufferQueue deleted_buffers;
262 253
263 PrepareRangesForNextAppend(buffers, &deleted_buffers); 254 PrepareRangesForNextAppend(buffers, &deleted_buffers);
264 255
265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 256 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
266 // create a new range with |buffers|. 257 // create a new range with |buffers|.
267 if (range_for_next_append_ != ranges_.end()) { 258 if (range_for_next_append_ != ranges_.end()) {
268 if (new_coded_frame_group_ && (!splice_frames_enabled_ || 259 if (new_coded_frame_group_ &&
269 buffers.front()->splice_buffers().empty())) { 260 buffers.front()->leading_silence() == base::TimeDelta()) {
270 // If the first append to this stream in a new coded frame group continues 261 // 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 262 // 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. 263 // 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 264 // 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 265 // a muxed set of streams (which share a common coded frame group start
275 // time) with a significantly jagged start across the streams. 266 // 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 267 // Don't do this logic if splice silence was generated for the first
277 // new buffer, since splices are guaranteed to be in the same range and 268 // 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 269 // adjacent, and since the splice frame's timestamp can be less than
279 // |coded_frame_group_start_time_| due to the splicing. 270 // |coded_frame_group_start_time_| due to the splicing.
280 (*range_for_next_append_) 271 (*range_for_next_append_)
281 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); 272 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_);
282 } else { 273 } else {
283 // Otherwise, use the first new buffer's timestamp as the proof of 274 // Otherwise, use the first new buffer's timestamp as the proof of
284 // adjacency. 275 // adjacency.
285 (*range_for_next_append_) 276 (*range_for_next_append_)
286 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); 277 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp());
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 if (range_for_next_append_ != ranges_.begin()) { 953 if (range_for_next_append_ != ranges_.begin()) {
963 RangeList::iterator range_before_next = range_for_next_append_; 954 RangeList::iterator range_before_next = range_for_next_append_;
964 --range_before_next; 955 --range_before_next;
965 MergeWithAdjacentRangeIfNecessary(range_before_next); 956 MergeWithAdjacentRangeIfNecessary(range_before_next);
966 } 957 }
967 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 958 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
968 } 959 }
969 return bytes_freed; 960 return bytes_freed;
970 } 961 }
971 962
963 void SourceBufferStream::GenerateSpliceSilence(const BufferQueue& new_buffers) {
964 DCHECK(!new_buffers.empty());
965
966 // Find the overlapped range (if any).
967 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
968 const DecodeTimestamp splice_dts =
969 DecodeTimestamp::FromPresentationTime(splice_timestamp);
970 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
971 if (range_itr == ranges_.end()) {
972 DVLOG(3) << __func__ << " Not generating splice. No range overlap at time "
973 << splice_timestamp.InMicroseconds();
974 return;
975 }
976
977 // Search for overlapped buffer needs exclusive end value. Choosing smallest
978 // possible value.
979 const DecodeTimestamp end_dts =
980 splice_dts + base::TimeDelta::FromInternalValue(1);
981
982 // Find if new buffer's start would overlap an existing buffer.
983 BufferQueue pre_splice_buffers;
984 if (!(*range_itr)
985 ->GetBuffersInRange(splice_dts, end_dts, &pre_splice_buffers)) {
986 // Bail if no overlapped buffers found.
987 DVLOG(3) << __func__ << " Not generating splice. No buffer overlap at time "
988 << splice_timestamp.InMicroseconds();
989 return;
990 }
991
992 // At most one buffer should exist containing the time of the newly appended
993 // buffer's start. GetBuffersInRange does not currently return buffers with
994 // zero duration.
995 DCHECK_EQ(pre_splice_buffers.size(), 1U)
996 << __func__ << " Found more than one overlapped buffer";
997
998 base::TimeDelta leading_silence = new_buffers.front()->timestamp() -
999 pre_splice_buffers.front()->timestamp();
1000 DCHECK_GE(leading_silence, base::TimeDelta());
1001
1002 if (leading_silence == base::TimeDelta()) {
1003 DVLOG(3) << __func__ << " Not generating splice for exact overlap at time "
1004 << splice_timestamp.InMicroseconds();
1005 return;
1006 }
1007
1008 // Pad front of new buffers with leading silence and update front timestamp
1009 // and duration. The overlapped buffer will be deleted in
1010 // PrepareRangesForNewAppend.
1011 new_buffers.front()->set_leading_silence(leading_silence);
1012 new_buffers.front()->SetDecodeTimestamp(
1013 new_buffers.front()->GetDecodeTimestamp() - leading_silence);
1014 new_buffers.front()->set_timestamp(new_buffers.front()->timestamp() -
1015 leading_silence);
1016 new_buffers.front()->set_duration(new_buffers.front()->duration() +
1017 leading_silence);
1018
1019 std::stringstream log_string;
1020 log_string << "Generated splice for overlapping audio buffer at time:"
1021 << splice_timestamp.InMicroseconds()
1022 << "mu. Adding silence of length:"
1023 << leading_silence.InMicroseconds()
1024 << "mu to replace overlapped buffer at time:"
1025 << pre_splice_buffers.front()->timestamp().InMicroseconds()
1026 << "mu.";
1027 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_logs_,
1028 kMaxSpliceGenerationLogs)
1029 << log_string.str();
1030 LOG(ERROR) << __func__ << log_string.str();
1031 }
1032
972 void SourceBufferStream::PrepareRangesForNextAppend( 1033 void SourceBufferStream::PrepareRangesForNextAppend(
973 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 1034 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
974 DCHECK(deleted_buffers); 1035 DCHECK(deleted_buffers);
975 1036
976 // Handle splices between the existing buffers and the new buffers. If a 1037 if (GetType() == kAudio)
977 // splice is generated the timestamp and duration of the first buffer in 1038 GenerateSpliceSilence(new_buffers);
978 // |new_buffers| will be modified.
979 if (splice_frames_enabled_)
980 GenerateSpliceFrame(new_buffers);
981 1039
1040 base::TimeDelta prev_duration = last_appended_buffer_duration_;
982 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 1041 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
983 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 1042 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
984 1043
1044 // 1. Clean up the old buffers between the last appended buffer and the
1045 // beginning of |new_buffers|.
985 if (prev_timestamp != kNoDecodeTimestamp() && 1046 if (prev_timestamp != kNoDecodeTimestamp() &&
986 prev_timestamp != next_timestamp) { 1047 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); 1048 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
990 } 1049 }
991 1050
992 // Always make the start of the delete range exclusive for same timestamp 1051 // 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_) { 1052 if (new_coded_frame_group_) {
1004 // Extend the deletion range earlier to the coded frame group start time if 1053 // 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| 1054 // this is the first append in a new coded frame group. Note that
1006 // could already be less than |coded_frame_group_start_time_| if a splice 1055 // |next_timestamp| could already be less than
1007 // was generated. 1056 // |coded_frame_group_start_time_| if splice silence was generated.
1008 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); 1057 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
1009 start = std::min(coded_frame_group_start_time_, start); 1058 next_timestamp = std::min(coded_frame_group_start_time_, next_timestamp);
1010 } 1059 }
1011 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 1060
1012 base::TimeDelta duration = new_buffers.back()->duration(); 1061 // Exclude the start timestamp from removal if the previous append is a zero
1062 // duration frame with the same timestamp as the current append. This avoids
1063 // deleting zero-duration VP9 alt-ref frames while still deleting frames
1064 // with non-zero duration that are now overlapped (potentially due to
1065 // generated splice silence).
1066 const bool exclude_start =
1067 prev_timestamp == next_timestamp && prev_duration == base::TimeDelta();
1013 1068
1014 // Set end time for remove to include the duration of last buffer. If the 1069 // 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 1070 // duration is estimated, use 1 microsecond instead to ensure frames are not
1016 // accidentally removed due to over-estimation. 1071 // accidentally removed due to over-estimation.
1072 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
1073 base::TimeDelta duration = new_buffers.back()->duration();
1017 if (duration != kNoTimestamp && duration > base::TimeDelta() && 1074 if (duration != kNoTimestamp && duration > base::TimeDelta() &&
1018 !new_buffers.back()->is_duration_estimated()) { 1075 !new_buffers.back()->is_duration_estimated()) {
1019 end += duration; 1076 end += duration;
1020 } else { 1077 } else {
1021 // TODO(chcunningham): Emit warning when 0ms durations are not expected. 1078 // TODO(chcunningham): Emit warning when 0ms durations are not expected.
1022 // http://crbug.com/312836 1079 // http://crbug.com/312836
1023 end += base::TimeDelta::FromInternalValue(1); 1080 end += base::TimeDelta::FromInternalValue(1);
1024 } 1081 }
1025 1082
1026 RemoveInternal(start, end, exclude_start, deleted_buffers); 1083 // Finally do the deletion of overlap.
1084 RemoveInternal(next_timestamp, end, exclude_start, deleted_buffers);
1027 } 1085 }
1028 1086
1029 bool SourceBufferStream::AreAdjacentInSequence( 1087 bool SourceBufferStream::AreAdjacentInSequence(
1030 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { 1088 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
1031 return first_timestamp < second_timestamp && 1089 return first_timestamp < second_timestamp &&
1032 second_timestamp <= 1090 second_timestamp <=
1033 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); 1091 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1034 } 1092 }
1035 1093
1036 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { 1094 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; 1743 DVLOG(1) << __func__ << " deleting range_for_next_append_.";
1686 range_for_next_append_ = ranges_.end(); 1744 range_for_next_append_ = ranges_.end();
1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 1745 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
1688 last_appended_buffer_is_keyframe_ = false; 1746 last_appended_buffer_is_keyframe_ = false;
1689 } 1747 }
1690 1748
1691 delete **itr; 1749 delete **itr;
1692 *itr = ranges_.erase(*itr); 1750 *itr = ranges_.erase(*itr);
1693 } 1751 }
1694 1752
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
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( 1753 bool SourceBufferStream::SetPendingBuffer(
1802 scoped_refptr<StreamParserBuffer>* out_buffer) { 1754 scoped_refptr<StreamParserBuffer>* out_buffer) {
1803 DCHECK(out_buffer->get()); 1755 DCHECK(out_buffer->get());
1804 DCHECK(!pending_buffer_.get()); 1756 DCHECK(!pending_buffer_.get());
1805 1757
1806 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); 1758 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
1807 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); 1759 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();
1808 1760
1809 if (!have_splice_buffers && !have_preroll_buffer) 1761 if (!have_splice_buffers && !have_preroll_buffer)
1810 return false; 1762 return false;
1811 1763
1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer); 1764 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1813 splice_buffers_index_ = 0; 1765 splice_buffers_index_ = 0;
1814 pending_buffer_.swap(*out_buffer); 1766 pending_buffer_.swap(*out_buffer);
1815 pending_buffers_complete_ = false; 1767 pending_buffers_complete_ = false;
1816 return true; 1768 return true;
1817 } 1769 }
1818 1770
1819 } // namespace media 1771 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698