OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/filters/source_buffer_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |