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 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 // important for debugging splice generation. | 30 // important for debugging splice generation. |
31 const int kMaxSpliceGenerationWarningLogs = 50; | 31 const int kMaxSpliceGenerationWarningLogs = 50; |
32 const int kMaxSpliceGenerationSuccessLogs = 20; | 32 const int kMaxSpliceGenerationSuccessLogs = 20; |
33 | 33 |
34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. | 34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. |
35 const int kMaxTrackBufferGapWarningLogs = 20; | 35 const int kMaxTrackBufferGapWarningLogs = 20; |
36 | 36 |
37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. | 37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. |
38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; | 38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; |
39 | 39 |
| 40 // 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 |
| 42 // 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 |
| 44 // 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 |
| 46 // work or other side-effects. |
| 47 const int kMaxStrangeSameTimestampsLogs = 20; |
| 48 |
40 // Helper method that returns true if |ranges| is sorted in increasing order, | 49 // Helper method that returns true if |ranges| is sorted in increasing order, |
41 // false otherwise. | 50 // false otherwise. |
42 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { | 51 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { |
43 DecodeTimestamp prev = kNoDecodeTimestamp(); | 52 DecodeTimestamp prev = kNoDecodeTimestamp(); |
44 for (std::list<SourceBufferRange*>::const_iterator itr = | 53 for (std::list<SourceBufferRange*>::const_iterator itr = |
45 ranges.begin(); itr != ranges.end(); ++itr) { | 54 ranges.begin(); itr != ranges.end(); ++itr) { |
46 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) | 55 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
47 return false; | 56 return false; |
48 prev = (*itr)->GetEndTimestamp(); | 57 prev = (*itr)->GetEndTimestamp(); |
49 } | 58 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 return SourceBufferRange::NO_GAPS_ALLOWED; | 139 return SourceBufferRange::NO_GAPS_ALLOWED; |
131 } | 140 } |
132 | 141 |
133 } // namespace | 142 } // namespace |
134 | 143 |
135 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 144 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
136 const scoped_refptr<MediaLog>& media_log, | 145 const scoped_refptr<MediaLog>& media_log, |
137 bool splice_frames_enabled) | 146 bool splice_frames_enabled) |
138 : media_log_(media_log), | 147 : media_log_(media_log), |
139 seek_buffer_timestamp_(kNoTimestamp()), | 148 seek_buffer_timestamp_(kNoTimestamp()), |
140 media_segment_start_time_(kNoDecodeTimestamp()), | 149 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
141 range_for_next_append_(ranges_.end()), | 150 range_for_next_append_(ranges_.end()), |
142 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 151 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
143 max_interbuffer_distance_(kNoTimestamp()), | 152 max_interbuffer_distance_(kNoTimestamp()), |
144 memory_limit_(kSourceBufferAudioMemoryLimit), | 153 memory_limit_(kSourceBufferAudioMemoryLimit), |
145 splice_frames_enabled_(splice_frames_enabled) { | 154 splice_frames_enabled_(splice_frames_enabled) { |
146 DCHECK(audio_config.IsValidConfig()); | 155 DCHECK(audio_config.IsValidConfig()); |
147 audio_configs_.push_back(audio_config); | 156 audio_configs_.push_back(audio_config); |
148 } | 157 } |
149 | 158 |
150 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 159 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
151 const scoped_refptr<MediaLog>& media_log, | 160 const scoped_refptr<MediaLog>& media_log, |
152 bool splice_frames_enabled) | 161 bool splice_frames_enabled) |
153 : media_log_(media_log), | 162 : media_log_(media_log), |
154 seek_buffer_timestamp_(kNoTimestamp()), | 163 seek_buffer_timestamp_(kNoTimestamp()), |
155 media_segment_start_time_(kNoDecodeTimestamp()), | 164 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
156 range_for_next_append_(ranges_.end()), | 165 range_for_next_append_(ranges_.end()), |
157 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 166 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
158 max_interbuffer_distance_(kNoTimestamp()), | 167 max_interbuffer_distance_(kNoTimestamp()), |
159 memory_limit_(kSourceBufferVideoMemoryLimit), | 168 memory_limit_(kSourceBufferVideoMemoryLimit), |
160 splice_frames_enabled_(splice_frames_enabled) { | 169 splice_frames_enabled_(splice_frames_enabled) { |
161 DCHECK(video_config.IsValidConfig()); | 170 DCHECK(video_config.IsValidConfig()); |
162 video_configs_.push_back(video_config); | 171 video_configs_.push_back(video_config); |
163 } | 172 } |
164 | 173 |
165 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 174 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
166 const scoped_refptr<MediaLog>& media_log, | 175 const scoped_refptr<MediaLog>& media_log, |
167 bool splice_frames_enabled) | 176 bool splice_frames_enabled) |
168 : media_log_(media_log), | 177 : media_log_(media_log), |
169 text_track_config_(text_config), | 178 text_track_config_(text_config), |
170 seek_buffer_timestamp_(kNoTimestamp()), | 179 seek_buffer_timestamp_(kNoTimestamp()), |
171 media_segment_start_time_(kNoDecodeTimestamp()), | 180 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
172 range_for_next_append_(ranges_.end()), | 181 range_for_next_append_(ranges_.end()), |
173 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 182 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
174 max_interbuffer_distance_(kNoTimestamp()), | 183 max_interbuffer_distance_(kNoTimestamp()), |
175 memory_limit_(kSourceBufferAudioMemoryLimit), | 184 memory_limit_(kSourceBufferAudioMemoryLimit), |
176 splice_frames_enabled_(splice_frames_enabled) {} | 185 splice_frames_enabled_(splice_frames_enabled) {} |
177 | 186 |
178 SourceBufferStream::~SourceBufferStream() { | 187 SourceBufferStream::~SourceBufferStream() { |
179 while (!ranges_.empty()) { | 188 while (!ranges_.empty()) { |
180 delete ranges_.front(); | 189 delete ranges_.front(); |
181 ranges_.pop_front(); | 190 ranges_.pop_front(); |
182 } | 191 } |
183 } | 192 } |
184 | 193 |
185 void SourceBufferStream::OnNewMediaSegment( | 194 void SourceBufferStream::OnStartOfCodedFrameGroup( |
186 DecodeTimestamp media_segment_start_time) { | 195 DecodeTimestamp coded_frame_group_start_time) { |
187 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 196 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << " (" |
188 << " (" << media_segment_start_time.InSecondsF() << ")"; | 197 << coded_frame_group_start_time.InSecondsF() << ")"; |
189 DCHECK(!end_of_stream_); | 198 DCHECK(!end_of_stream_); |
190 media_segment_start_time_ = media_segment_start_time; | 199 coded_frame_group_start_time_ = coded_frame_group_start_time; |
191 new_media_segment_ = true; | 200 new_coded_frame_group_ = true; |
192 | 201 |
193 RangeList::iterator last_range = range_for_next_append_; | 202 RangeList::iterator last_range = range_for_next_append_; |
194 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time); |
195 | 204 |
196 // Only reset |last_appended_buffer_timestamp_| if this new media segment is | 205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group |
197 // not adjacent to the previous media segment appended to the stream. | 206 // is not adjacent to the previous coded frame group appended to the stream. |
198 if (range_for_next_append_ == ranges_.end() || | 207 if (range_for_next_append_ == ranges_.end() || |
199 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 208 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
200 media_segment_start_time)) { | 209 coded_frame_group_start_time)) { |
201 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 210 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); |
202 last_appended_buffer_duration_ = kNoTimestamp(); | 211 last_appended_buffer_duration_ = kNoTimestamp(); |
203 last_appended_buffer_is_keyframe_ = false; | 212 last_appended_buffer_is_keyframe_ = false; |
204 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range"; | 213 DVLOG(3) << __FUNCTION__ << " next appended buffers will " |
| 214 << (range_for_next_append_ == ranges_.end() |
| 215 ? "be in a new range" |
| 216 : "overlap an existing range"); |
205 } else if (last_range != ranges_.end()) { | 217 } else if (last_range != ranges_.end()) { |
206 DCHECK(last_range == range_for_next_append_); | 218 DCHECK(last_range == range_for_next_append_); |
207 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " | 219 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " |
208 << "unless intervening remove makes discontinuity"; | 220 << "unless intervening remove makes discontinuity"; |
209 } | 221 } |
210 } | 222 } |
211 | 223 |
212 bool SourceBufferStream::Append(const BufferQueue& buffers) { | 224 bool SourceBufferStream::Append(const BufferQueue& buffers) { |
213 TRACE_EVENT2("media", "SourceBufferStream::Append", | 225 TRACE_EVENT2("media", "SourceBufferStream::Append", |
214 "stream type", GetStreamTypeName(), | 226 "stream type", GetStreamTypeName(), |
215 "buffers to append", buffers.size()); | 227 "buffers to append", buffers.size()); |
216 | 228 |
217 DCHECK(!buffers.empty()); | 229 DCHECK(!buffers.empty()); |
218 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); | 230 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); |
219 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); | 231 DCHECK(coded_frame_group_start_time_ <= |
| 232 buffers.front()->GetDecodeTimestamp()); |
220 DCHECK(!end_of_stream_); | 233 DCHECK(!end_of_stream_); |
221 | 234 |
222 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 235 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
223 << ": buffers " << BufferQueueToLogString(buffers); | 236 << ": buffers " << BufferQueueToLogString(buffers); |
224 | 237 |
225 // New media segments must begin with a keyframe. | 238 // New coded frame groups emitted by the coded frame processor must begin with |
226 // TODO(wolenetz): Relax this requirement. See http://crbug.com/229412. | 239 // a keyframe. TODO(wolenetz): Change this to [DCHECK + MEDIA_LOG(ERROR...) + |
227 if (new_media_segment_ && !buffers.front()->is_key_frame()) { | 240 // return false] once the CHECK has baked in a stable release. See |
228 MEDIA_LOG(ERROR, media_log_) << "Media segment did not begin with key " | 241 // https://crbug.com/580621. |
229 "frame. Support for such segments will be " | 242 CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame()); |
230 "available in a future version. Please see " | 243 |
231 "https://crbug.com/229412."; | 244 // Buffers within a coded frame group should be monotonically increasing. |
| 245 if (!IsMonotonicallyIncreasing(buffers)) { |
232 return false; | 246 return false; |
233 } | 247 } |
234 | 248 |
235 // Buffers within a media segment should be monotonically increasing. | 249 if (coded_frame_group_start_time_ < DecodeTimestamp() || |
236 if (!IsMonotonicallyIncreasing(buffers)) | |
237 return false; | |
238 | |
239 if (media_segment_start_time_ < DecodeTimestamp() || | |
240 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { | 250 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { |
241 MEDIA_LOG(ERROR, media_log_) | 251 MEDIA_LOG(ERROR, media_log_) |
242 << "Cannot append a media segment with negative timestamps."; | 252 << "Cannot append a coded frame group with negative timestamps."; |
243 return false; | 253 return false; |
244 } | 254 } |
245 | 255 |
246 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), | |
247 buffers.front()->is_key_frame())) { | |
248 const DecodeTimestamp& dts = buffers.front()->GetDecodeTimestamp(); | |
249 MEDIA_LOG(ERROR, media_log_) | |
250 << "Invalid same timestamp construct detected at" | |
251 << " time " << dts.InSecondsF(); | |
252 | |
253 return false; | |
254 } | |
255 | |
256 UpdateMaxInterbufferDistance(buffers); | 256 UpdateMaxInterbufferDistance(buffers); |
257 SetConfigIds(buffers); | 257 SetConfigIds(buffers); |
258 | 258 |
259 // Save a snapshot of stream state before range modifications are made. | 259 // Save a snapshot of stream state before range modifications are made. |
260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
261 BufferQueue deleted_buffers; | 261 BufferQueue deleted_buffers; |
262 | 262 |
263 PrepareRangesForNextAppend(buffers, &deleted_buffers); | 263 PrepareRangesForNextAppend(buffers, &deleted_buffers); |
264 | 264 |
265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
266 // create a new range with |buffers|. | 266 // create a new range with |buffers|. |
267 if (range_for_next_append_ != ranges_.end()) { | 267 if (range_for_next_append_ != ranges_.end()) { |
268 (*range_for_next_append_)->AppendBuffersToEnd(buffers); | 268 if (new_coded_frame_group_ && (!splice_frames_enabled_ || |
| 269 buffers.front()->splice_buffers().empty())) { |
| 270 // 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 |
| 272 // 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 |
| 274 // a muxed set of streams (which share a common coded frame group start |
| 275 // 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_) |
| 281 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); |
| 282 } else { |
| 283 // Otherwise, use the first new buffer's timestamp as the proof of |
| 284 // adjacency. |
| 285 (*range_for_next_append_) |
| 286 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); |
| 287 } |
| 288 |
269 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 289 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
270 last_appended_buffer_duration_ = buffers.back()->duration(); | 290 last_appended_buffer_duration_ = buffers.back()->duration(); |
271 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); | 291 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); |
272 } else { | 292 } else { |
273 DecodeTimestamp new_range_start_time = std::min( | 293 DecodeTimestamp new_range_start_time = std::min( |
274 media_segment_start_time_, buffers.front()->GetDecodeTimestamp()); | 294 coded_frame_group_start_time_, buffers.front()->GetDecodeTimestamp()); |
275 const BufferQueue* buffers_for_new_range = &buffers; | 295 const BufferQueue* buffers_for_new_range = &buffers; |
276 BufferQueue trimmed_buffers; | 296 BufferQueue trimmed_buffers; |
277 | 297 |
278 // If the new range is not being created because of a new media | 298 // If the new range is not being created because of a new coded frame group, |
279 // segment, then we must make sure that we start with a key frame. | 299 // then we must make sure that we start with a key frame. This can happen |
280 // This can happen if the GOP in the previous append gets destroyed | 300 // if the GOP in the previous append gets destroyed by a Remove() call. |
281 // by a Remove() call. | 301 if (!new_coded_frame_group_) { |
282 if (!new_media_segment_) { | |
283 BufferQueue::const_iterator itr = buffers.begin(); | 302 BufferQueue::const_iterator itr = buffers.begin(); |
284 | 303 |
285 // Scan past all the non-key-frames. | 304 // Scan past all the non-key-frames. |
286 while (itr != buffers.end() && !(*itr)->is_key_frame()) { | 305 while (itr != buffers.end() && !(*itr)->is_key_frame()) { |
287 ++itr; | 306 ++itr; |
288 } | 307 } |
289 | 308 |
290 // If we didn't find a key frame, then update the last appended | 309 // If we didn't find a key frame, then update the last appended |
291 // buffer state and return. | 310 // buffer state and return. |
292 if (itr == buffers.end()) { | 311 if (itr == buffers.end()) { |
293 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 312 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
294 last_appended_buffer_duration_ = buffers.back()->duration(); | 313 last_appended_buffer_duration_ = buffers.back()->duration(); |
295 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); | 314 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); |
296 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 315 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
297 << ": new buffers in the middle of media segment depend on" | 316 << ": new buffers in the middle of coded frame group depend on" |
298 "keyframe that has been removed, and contain no keyframes." | 317 "keyframe that has been removed, and contain no keyframes." |
299 "Skipping further processing."; | 318 "Skipping further processing."; |
300 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 319 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
301 << ": done. ranges_=" << RangesToString(ranges_); | 320 << ": done. ranges_=" << RangesToString(ranges_); |
302 return true; | 321 return true; |
303 } else if (itr != buffers.begin()) { | 322 } else if (itr != buffers.begin()) { |
304 // Copy the first key frame and everything after it into | 323 // Copy the first key frame and everything after it into |
305 // |trimmed_buffers|. | 324 // |trimmed_buffers|. |
306 trimmed_buffers.assign(itr, buffers.end()); | 325 trimmed_buffers.assign(itr, buffers.end()); |
307 buffers_for_new_range = &trimmed_buffers; | 326 buffers_for_new_range = &trimmed_buffers; |
308 } | 327 } |
309 | 328 |
310 new_range_start_time = | 329 new_range_start_time = |
311 buffers_for_new_range->front()->GetDecodeTimestamp(); | 330 buffers_for_new_range->front()->GetDecodeTimestamp(); |
312 } | 331 } |
313 | 332 |
314 range_for_next_append_ = | 333 range_for_next_append_ = |
315 AddToRanges(new SourceBufferRange( | 334 AddToRanges(new SourceBufferRange( |
316 TypeToGapPolicy(GetType()), | 335 TypeToGapPolicy(GetType()), |
317 *buffers_for_new_range, new_range_start_time, | 336 *buffers_for_new_range, new_range_start_time, |
318 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, | 337 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
319 base::Unretained(this)))); | 338 base::Unretained(this)))); |
320 last_appended_buffer_timestamp_ = | 339 last_appended_buffer_timestamp_ = |
321 buffers_for_new_range->back()->GetDecodeTimestamp(); | 340 buffers_for_new_range->back()->GetDecodeTimestamp(); |
322 last_appended_buffer_duration_ = buffers_for_new_range->back()->duration(); | 341 last_appended_buffer_duration_ = buffers_for_new_range->back()->duration(); |
323 last_appended_buffer_is_keyframe_ = | 342 last_appended_buffer_is_keyframe_ = |
324 buffers_for_new_range->back()->is_key_frame(); | 343 buffers_for_new_range->back()->is_key_frame(); |
325 } | 344 } |
326 | 345 |
327 new_media_segment_ = false; | 346 new_coded_frame_group_ = false; |
328 | 347 |
329 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); | 348 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); |
330 | 349 |
331 // Seek to try to fulfill a previous call to Seek(). | 350 // Seek to try to fulfill a previous call to Seek(). |
332 if (seek_pending_) { | 351 if (seek_pending_) { |
333 DCHECK(!selected_range_); | 352 DCHECK(!selected_range_); |
334 DCHECK(deleted_buffers.empty()); | 353 DCHECK(deleted_buffers.empty()); |
335 Seek(seek_buffer_timestamp_); | 354 Seek(seek_buffer_timestamp_); |
336 } | 355 } |
337 | 356 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // stream, yet we also had output no buffer since the last Seek. | 425 // stream, yet we also had output no buffer since the last Seek. |
407 // Re-seek to prevent stall. | 426 // Re-seek to prevent stall. |
408 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 427 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
409 << ": re-seeking to " << seek_buffer_timestamp_ | 428 << ": re-seeking to " << seek_buffer_timestamp_ |
410 << " to prevent stall if this time becomes buffered again"; | 429 << " to prevent stall if this time becomes buffered again"; |
411 Seek(seek_buffer_timestamp_); | 430 Seek(seek_buffer_timestamp_); |
412 } | 431 } |
413 } | 432 } |
414 } | 433 } |
415 | 434 |
| 435 DecodeTimestamp SourceBufferStream::PotentialNextAppendTimestamp() const { |
| 436 // The next potential append will either be just at or after |
| 437 // |last_appended_buffer_timestamp_| (if known), or if unknown and we are |
| 438 // still at the beginning of a new coded frame group, then will be into the |
| 439 // range (if any) to which |coded_frame_group_start_time_| belongs. |
| 440 if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) { |
| 441 // TODO(wolenetz): Determine if this +1us is still necessary. See |
| 442 // https://crbug.com/589295. |
| 443 return last_appended_buffer_timestamp_ + |
| 444 base::TimeDelta::FromInternalValue(1); |
| 445 } |
| 446 |
| 447 if (new_coded_frame_group_) |
| 448 return coded_frame_group_start_time_; |
| 449 |
| 450 // If we still don't know a potential next append timestamp, then we have |
| 451 // removed the ranged to which it previously belonged and have not completed a |
| 452 // subsequent append or received a subsequent OnStartOfCodedFrameGroup() |
| 453 // signal. |
| 454 return kNoDecodeTimestamp(); |
| 455 } |
| 456 |
416 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, | 457 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, |
417 DecodeTimestamp end, | 458 DecodeTimestamp end, |
418 bool exclude_start, | 459 bool exclude_start, |
419 BufferQueue* deleted_buffers) { | 460 BufferQueue* deleted_buffers) { |
420 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << " (" | 461 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << " (" |
421 << start.InSecondsF() << ", " << end.InSecondsF() << ", " | 462 << start.InSecondsF() << ", " << end.InSecondsF() << ", " |
422 << exclude_start << ")"; | 463 << exclude_start << ")"; |
423 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() | 464 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() |
424 << ": before remove ranges_=" << RangesToString(ranges_); | 465 << ": before remove ranges_=" << RangesToString(ranges_); |
425 | 466 |
426 DCHECK(start >= DecodeTimestamp()); | 467 DCHECK(start >= DecodeTimestamp()); |
427 DCHECK(start < end) << "start " << start.InSecondsF() | 468 DCHECK(start < end) << "start " << start.InSecondsF() |
428 << " end " << end.InSecondsF(); | 469 << " end " << end.InSecondsF(); |
429 DCHECK(deleted_buffers); | 470 DCHECK(deleted_buffers); |
430 | 471 |
431 RangeList::iterator itr = ranges_.begin(); | 472 RangeList::iterator itr = ranges_.begin(); |
432 | 473 |
433 while (itr != ranges_.end()) { | 474 while (itr != ranges_.end()) { |
434 SourceBufferRange* range = *itr; | 475 SourceBufferRange* range = *itr; |
435 if (range->GetStartTimestamp() >= end) | 476 if (range->GetStartTimestamp() >= end) |
436 break; | 477 break; |
437 | 478 |
438 // Split off any remaining GOPs starting at or after |end| and add it to | 479 // Split off any remaining GOPs starting at or after |end| and add it to |
439 // |ranges_|. | 480 // |ranges_|. |
440 SourceBufferRange* new_range = range->SplitRange(end); | 481 SourceBufferRange* new_range = range->SplitRange(end); |
441 if (new_range) { | 482 if (new_range) { |
442 itr = ranges_.insert(++itr, new_range); | 483 itr = ranges_.insert(++itr, new_range); |
| 484 |
| 485 // Update |range_for_next_append_| if it was previously |range| and should |
| 486 // be |new_range| now. |
| 487 if (range_for_next_append_ != ranges_.end() && |
| 488 *range_for_next_append_ == range) { |
| 489 DecodeTimestamp potential_next_append_timestamp = |
| 490 PotentialNextAppendTimestamp(); |
| 491 if (potential_next_append_timestamp != kNoDecodeTimestamp() && |
| 492 new_range->BelongsToRange(potential_next_append_timestamp)) { |
| 493 range_for_next_append_ = itr; |
| 494 } |
| 495 } |
| 496 |
443 --itr; | 497 --itr; |
444 | 498 |
445 // Update the selected range if the next buffer position was transferred | 499 // Update the selected range if the next buffer position was transferred |
446 // to |new_range|. | 500 // to |new_range|. |
447 if (new_range->HasNextBufferPosition()) | 501 if (new_range->HasNextBufferPosition()) |
448 SetSelectedRange(new_range); | 502 SetSelectedRange(new_range); |
449 } | 503 } |
450 | 504 |
451 // Truncate the current range so that it only contains data before | 505 // Truncate the current range so that it only contains data before |
452 // the removal range. | 506 // the removal range. |
(...skipping 16 matching lines...) Expand all Loading... |
469 // range then delete it and move on. | 523 // range then delete it and move on. |
470 if (delete_range) { | 524 if (delete_range) { |
471 DeleteAndRemoveRange(&itr); | 525 DeleteAndRemoveRange(&itr); |
472 continue; | 526 continue; |
473 } | 527 } |
474 | 528 |
475 // Clear |range_for_next_append_| if we determine that the removal | 529 // Clear |range_for_next_append_| if we determine that the removal |
476 // operation makes it impossible for the next append to be added | 530 // operation makes it impossible for the next append to be added |
477 // to the current range. | 531 // to the current range. |
478 if (range_for_next_append_ != ranges_.end() && | 532 if (range_for_next_append_ != ranges_.end() && |
479 *range_for_next_append_ == range && | 533 *range_for_next_append_ == range) { |
480 last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) { | |
481 DecodeTimestamp potential_next_append_timestamp = | 534 DecodeTimestamp potential_next_append_timestamp = |
482 last_appended_buffer_timestamp_ + | 535 PotentialNextAppendTimestamp(); |
483 base::TimeDelta::FromInternalValue(1); | |
484 | 536 |
485 if (!range->BelongsToRange(potential_next_append_timestamp)) { | 537 if (!range->BelongsToRange(potential_next_append_timestamp)) { |
486 DVLOG(1) << "Resetting range_for_next_append_ since the next append" | 538 DVLOG(1) << "Resetting range_for_next_append_ since the next append" |
487 << " can't add to the current range."; | 539 << " can't add to the current range."; |
488 range_for_next_append_ = | 540 range_for_next_append_ = |
489 FindExistingRangeFor(potential_next_append_timestamp); | 541 FindExistingRangeFor(potential_next_append_timestamp); |
490 } | 542 } |
491 } | 543 } |
492 | 544 |
493 // Move on to the next range. | 545 // Move on to the next range. |
(...skipping 21 matching lines...) Expand all Loading... |
515 bool SourceBufferStream::ShouldSeekToStartOfBuffered( | 567 bool SourceBufferStream::ShouldSeekToStartOfBuffered( |
516 base::TimeDelta seek_timestamp) const { | 568 base::TimeDelta seek_timestamp) const { |
517 if (ranges_.empty()) | 569 if (ranges_.empty()) |
518 return false; | 570 return false; |
519 base::TimeDelta beginning_of_buffered = | 571 base::TimeDelta beginning_of_buffered = |
520 ranges_.front()->GetStartTimestamp().ToPresentationTime(); | 572 ranges_.front()->GetStartTimestamp().ToPresentationTime(); |
521 return (seek_timestamp <= beginning_of_buffered && | 573 return (seek_timestamp <= beginning_of_buffered && |
522 beginning_of_buffered < kSeekToStartFudgeRoom()); | 574 beginning_of_buffered < kSeekToStartFudgeRoom()); |
523 } | 575 } |
524 | 576 |
525 bool SourceBufferStream::IsMonotonicallyIncreasing( | 577 bool SourceBufferStream::IsMonotonicallyIncreasing(const BufferQueue& buffers) { |
526 const BufferQueue& buffers) const { | |
527 DCHECK(!buffers.empty()); | 578 DCHECK(!buffers.empty()); |
528 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 579 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
529 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | 580 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; |
530 for (BufferQueue::const_iterator itr = buffers.begin(); | 581 for (BufferQueue::const_iterator itr = buffers.begin(); |
531 itr != buffers.end(); ++itr) { | 582 itr != buffers.end(); ++itr) { |
532 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); | 583 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); |
533 bool current_is_keyframe = (*itr)->is_key_frame(); | 584 bool current_is_keyframe = (*itr)->is_key_frame(); |
534 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 585 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
535 DCHECK((*itr)->duration() >= base::TimeDelta()) | 586 DCHECK((*itr)->duration() >= base::TimeDelta()) |
536 << "Packet with invalid duration." | 587 << "Packet with invalid duration." |
537 << " pts " << (*itr)->timestamp().InSecondsF() | 588 << " pts " << (*itr)->timestamp().InSecondsF() |
538 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() | 589 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() |
539 << " dur " << (*itr)->duration().InSecondsF(); | 590 << " dur " << (*itr)->duration().InSecondsF(); |
540 | 591 |
541 if (prev_timestamp != kNoDecodeTimestamp()) { | 592 if (prev_timestamp != kNoDecodeTimestamp()) { |
542 if (current_timestamp < prev_timestamp) { | 593 if (current_timestamp < prev_timestamp) { |
543 MEDIA_LOG(ERROR, media_log_) | 594 MEDIA_LOG(ERROR, media_log_) |
544 << "Buffers did not monotonically increase."; | 595 << "Buffers did not monotonically increase."; |
545 return false; | 596 return false; |
546 } | 597 } |
547 | 598 |
548 if (current_timestamp == prev_timestamp && | 599 if (current_timestamp == prev_timestamp && |
549 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, | 600 SourceBufferRange::IsUncommonSameTimestampSequence( |
550 current_is_keyframe)) { | 601 prev_is_keyframe, current_is_keyframe)) { |
551 MEDIA_LOG(ERROR, media_log_) << "Unexpected combination of buffers with" | 602 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_strange_same_timestamps_logs_, |
552 << " the same timestamp detected at " | 603 kMaxStrangeSameTimestampsLogs) |
553 << current_timestamp.InSecondsF(); | 604 << "Detected an append sequence with keyframe following a " |
554 return false; | 605 "non-keyframe, both with the same decode timestamp of " |
| 606 << current_timestamp.InSecondsF(); |
555 } | 607 } |
556 } | 608 } |
557 | 609 |
558 prev_timestamp = current_timestamp; | 610 prev_timestamp = current_timestamp; |
559 prev_is_keyframe = current_is_keyframe; | 611 prev_is_keyframe = current_is_keyframe; |
560 } | 612 } |
561 return true; | 613 return true; |
562 } | 614 } |
563 | 615 |
564 bool SourceBufferStream::IsNextTimestampValid( | |
565 DecodeTimestamp next_timestamp, bool next_is_keyframe) const { | |
566 return (last_appended_buffer_timestamp_ != next_timestamp) || | |
567 new_media_segment_ || | |
568 SourceBufferRange::AllowSameTimestamp(last_appended_buffer_is_keyframe_, | |
569 next_is_keyframe); | |
570 } | |
571 | |
572 | |
573 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { | 616 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { |
574 for (RangeList::const_iterator itr = ranges_.begin(); | 617 for (RangeList::const_iterator itr = ranges_.begin(); |
575 itr != ranges_.end(); ++itr) { | 618 itr != ranges_.end(); ++itr) { |
576 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) | 619 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) |
577 return false; | 620 return false; |
578 } | 621 } |
579 return !selected_range_ || selected_range_->HasNextBufferPosition(); | 622 return !selected_range_ || selected_range_->HasNextBufferPosition(); |
580 } | 623 } |
581 | 624 |
582 void SourceBufferStream::UpdateMaxInterbufferDistance( | 625 void SourceBufferStream::UpdateMaxInterbufferDistance( |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { | 974 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { |
932 DCHECK(deleted_buffers); | 975 DCHECK(deleted_buffers); |
933 | 976 |
934 // Handle splices between the existing buffers and the new buffers. If a | 977 // Handle splices between the existing buffers and the new buffers. If a |
935 // splice is generated the timestamp and duration of the first buffer in | 978 // splice is generated the timestamp and duration of the first buffer in |
936 // |new_buffers| will be modified. | 979 // |new_buffers| will be modified. |
937 if (splice_frames_enabled_) | 980 if (splice_frames_enabled_) |
938 GenerateSpliceFrame(new_buffers); | 981 GenerateSpliceFrame(new_buffers); |
939 | 982 |
940 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 983 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
941 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | |
942 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); | 984 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); |
943 bool next_is_keyframe = new_buffers.front()->is_key_frame(); | |
944 | 985 |
945 if (prev_timestamp != kNoDecodeTimestamp() && | 986 if (prev_timestamp != kNoDecodeTimestamp() && |
946 prev_timestamp != next_timestamp) { | 987 prev_timestamp != next_timestamp) { |
947 // Clean up the old buffers between the last appended buffer and the | 988 // Clean up the old buffers between the last appended buffer and the |
948 // beginning of |new_buffers|. | 989 // beginning of |new_buffers|. |
949 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); | 990 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); |
950 } | 991 } |
951 | 992 |
952 // Make the delete range exclusive if we are dealing with an allowed same | 993 // Always make the start of the delete range exclusive for same timestamp |
953 // timestamp situation. This prevents the first buffer in the current append | 994 // across the last buffer in the previous append and the first buffer in the |
954 // from deleting the last buffer in the previous append if both buffers | 995 // current append. Never be exclusive if a splice frame was generated because |
955 // have the same timestamp. | 996 // we don't generate splice frames for same timestamp situations. |
956 // | |
957 // The delete range should never be exclusive if a splice frame was generated | |
958 // because we don't generate splice frames for same timestamp situations. | |
959 DCHECK(new_buffers.front()->splice_timestamp() != | 997 DCHECK(new_buffers.front()->splice_timestamp() != |
960 new_buffers.front()->timestamp()); | 998 new_buffers.front()->timestamp()); |
961 const bool exclude_start = | 999 const bool exclude_start = new_buffers.front()->splice_buffers().empty() && |
962 new_buffers.front()->splice_buffers().empty() && | 1000 prev_timestamp == next_timestamp; |
963 prev_timestamp == next_timestamp && | |
964 SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, next_is_keyframe); | |
965 | 1001 |
966 // Delete the buffers that |new_buffers| overlaps. | 1002 // Delete the buffers that |new_buffers| overlaps. |
967 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); | 1003 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); |
| 1004 if (new_coded_frame_group_) { |
| 1005 // Extend the deletion range earlier to the coded frame group start time if |
| 1006 // this is the first append in a new coded frame group. Note that |start| |
| 1007 // could already be less than |coded_frame_group_start_time_| if a splice |
| 1008 // was generated. |
| 1009 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); |
| 1010 start = std::min(coded_frame_group_start_time_, start); |
| 1011 } |
968 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); | 1012 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); |
969 base::TimeDelta duration = new_buffers.back()->duration(); | 1013 base::TimeDelta duration = new_buffers.back()->duration(); |
970 | 1014 |
971 // Set end time for remove to include the duration of last buffer. If the | 1015 // Set end time for remove to include the duration of last buffer. If the |
972 // duration is estimated, use 1 microsecond instead to ensure frames are not | 1016 // duration is estimated, use 1 microsecond instead to ensure frames are not |
973 // accidentally removed due to over-estimation. | 1017 // accidentally removed due to over-estimation. |
974 if (duration != kNoTimestamp() && duration > base::TimeDelta() && | 1018 if (duration != kNoTimestamp() && duration > base::TimeDelta() && |
975 !new_buffers.back()->is_duration_estimated()) { | 1019 !new_buffers.back()->is_duration_estimated()) { |
976 end += duration; | 1020 end += duration; |
977 } else { | 1021 } else { |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1793 return false; | 1837 return false; |
1794 | 1838 |
1795 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1839 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1796 splice_buffers_index_ = 0; | 1840 splice_buffers_index_ = 0; |
1797 pending_buffer_.swap(*out_buffer); | 1841 pending_buffer_.swap(*out_buffer); |
1798 pending_buffers_complete_ = false; | 1842 pending_buffers_complete_ = false; |
1799 return true; | 1843 return true; |
1800 } | 1844 } |
1801 | 1845 |
1802 } // namespace media | 1846 } // namespace media |
OLD | NEW |