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

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

Issue 1670033002: Reland: MSE: Relax the 'media segment must begin with keyframe' requirement (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase plus handling item #7 from CL description Created 4 years, 10 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 10
(...skipping 19 matching lines...) Expand all
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
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
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 return last_appended_buffer_timestamp_ +
442 base::TimeDelta::FromInternalValue(1);
chcunningham 2016/02/12 22:46:40 What if the next timestamp is the same as the last
chcunningham 2016/02/12 23:25:36 We chatted. Please make a todo && crbug. This is a
wolenetz 2016/02/24 00:34:46 I think this +1us was useful when we previously ha
chcunningham 2016/02/24 19:06:26 Acknowledged.
443 }
444
445 if (new_coded_frame_group_)
446 return coded_frame_group_start_time_;
447
448 // If we still don't know a potential next append timestamp, then we have
449 // removed the ranged to which it previously belonged and have not completed a
450 // subsequent append or received a subsequent OnStartOfCodedFrameGroup()
451 // signal.
452 return kNoDecodeTimestamp();
453 }
454
416 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, 455 void SourceBufferStream::RemoveInternal(DecodeTimestamp start,
417 DecodeTimestamp end, 456 DecodeTimestamp end,
418 bool exclude_start, 457 bool exclude_start,
419 BufferQueue* deleted_buffers) { 458 BufferQueue* deleted_buffers) {
420 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << " (" 459 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << " ("
421 << start.InSecondsF() << ", " << end.InSecondsF() << ", " 460 << start.InSecondsF() << ", " << end.InSecondsF() << ", "
422 << exclude_start << ")"; 461 << exclude_start << ")";
423 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() 462 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName()
424 << ": before remove ranges_=" << RangesToString(ranges_); 463 << ": before remove ranges_=" << RangesToString(ranges_);
425 464
426 DCHECK(start >= DecodeTimestamp()); 465 DCHECK(start >= DecodeTimestamp());
427 DCHECK(start < end) << "start " << start.InSecondsF() 466 DCHECK(start < end) << "start " << start.InSecondsF()
428 << " end " << end.InSecondsF(); 467 << " end " << end.InSecondsF();
429 DCHECK(deleted_buffers); 468 DCHECK(deleted_buffers);
430 469
431 RangeList::iterator itr = ranges_.begin(); 470 RangeList::iterator itr = ranges_.begin();
432 471
433 while (itr != ranges_.end()) { 472 while (itr != ranges_.end()) {
434 SourceBufferRange* range = *itr; 473 SourceBufferRange* range = *itr;
435 if (range->GetStartTimestamp() >= end) 474 if (range->GetStartTimestamp() >= end)
436 break; 475 break;
437 476
438 // Split off any remaining GOPs starting at or after |end| and add it to 477 // Split off any remaining GOPs starting at or after |end| and add it to
439 // |ranges_|. 478 // |ranges_|.
440 SourceBufferRange* new_range = range->SplitRange(end); 479 SourceBufferRange* new_range = range->SplitRange(end);
441 if (new_range) { 480 if (new_range) {
442 itr = ranges_.insert(++itr, new_range); 481 itr = ranges_.insert(++itr, new_range);
482
483 // Update |range_for_next_append_| if it was previously |range| and should
484 // be |new_range| now.
485 if (range_for_next_append_ != ranges_.end() &&
486 *range_for_next_append_ == range) {
487 DecodeTimestamp potential_next_append_timestamp =
488 PotentialNextAppendTimestamp();
489 if (potential_next_append_timestamp != kNoDecodeTimestamp() &&
490 new_range->BelongsToRange(potential_next_append_timestamp)) {
491 range_for_next_append_ = itr;
492 }
493 }
494
443 --itr; 495 --itr;
444 496
445 // Update the selected range if the next buffer position was transferred 497 // Update the selected range if the next buffer position was transferred
446 // to |new_range|. 498 // to |new_range|.
447 if (new_range->HasNextBufferPosition()) 499 if (new_range->HasNextBufferPosition())
448 SetSelectedRange(new_range); 500 SetSelectedRange(new_range);
449 } 501 }
450 502
451 // Truncate the current range so that it only contains data before 503 // Truncate the current range so that it only contains data before
452 // the removal range. 504 // the removal range.
(...skipping 16 matching lines...) Expand all
469 // range then delete it and move on. 521 // range then delete it and move on.
470 if (delete_range) { 522 if (delete_range) {
471 DeleteAndRemoveRange(&itr); 523 DeleteAndRemoveRange(&itr);
472 continue; 524 continue;
473 } 525 }
474 526
475 // Clear |range_for_next_append_| if we determine that the removal 527 // Clear |range_for_next_append_| if we determine that the removal
476 // operation makes it impossible for the next append to be added 528 // operation makes it impossible for the next append to be added
477 // to the current range. 529 // to the current range.
478 if (range_for_next_append_ != ranges_.end() && 530 if (range_for_next_append_ != ranges_.end() &&
479 *range_for_next_append_ == range && 531 *range_for_next_append_ == range) {
480 last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
481 DecodeTimestamp potential_next_append_timestamp = 532 DecodeTimestamp potential_next_append_timestamp =
482 last_appended_buffer_timestamp_ + 533 PotentialNextAppendTimestamp();
483 base::TimeDelta::FromInternalValue(1);
484 534
485 if (!range->BelongsToRange(potential_next_append_timestamp)) { 535 if (!range->BelongsToRange(potential_next_append_timestamp)) {
486 DVLOG(1) << "Resetting range_for_next_append_ since the next append" 536 DVLOG(1) << "Resetting range_for_next_append_ since the next append"
487 << " can't add to the current range."; 537 << " can't add to the current range.";
488 range_for_next_append_ = 538 range_for_next_append_ =
489 FindExistingRangeFor(potential_next_append_timestamp); 539 FindExistingRangeFor(potential_next_append_timestamp);
490 } 540 }
491 } 541 }
492 542
493 // Move on to the next range. 543 // Move on to the next range.
(...skipping 21 matching lines...) Expand all
515 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 565 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
516 base::TimeDelta seek_timestamp) const { 566 base::TimeDelta seek_timestamp) const {
517 if (ranges_.empty()) 567 if (ranges_.empty())
518 return false; 568 return false;
519 base::TimeDelta beginning_of_buffered = 569 base::TimeDelta beginning_of_buffered =
520 ranges_.front()->GetStartTimestamp().ToPresentationTime(); 570 ranges_.front()->GetStartTimestamp().ToPresentationTime();
521 return (seek_timestamp <= beginning_of_buffered && 571 return (seek_timestamp <= beginning_of_buffered &&
522 beginning_of_buffered < kSeekToStartFudgeRoom()); 572 beginning_of_buffered < kSeekToStartFudgeRoom());
523 } 573 }
524 574
525 bool SourceBufferStream::IsMonotonicallyIncreasing( 575 bool SourceBufferStream::IsMonotonicallyIncreasing(const BufferQueue& buffers) {
526 const BufferQueue& buffers) const {
527 DCHECK(!buffers.empty()); 576 DCHECK(!buffers.empty());
528 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 577 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
529 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 578 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
530 for (BufferQueue::const_iterator itr = buffers.begin(); 579 for (BufferQueue::const_iterator itr = buffers.begin();
531 itr != buffers.end(); ++itr) { 580 itr != buffers.end(); ++itr) {
532 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); 581 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
533 bool current_is_keyframe = (*itr)->is_key_frame(); 582 bool current_is_keyframe = (*itr)->is_key_frame();
534 DCHECK(current_timestamp != kNoDecodeTimestamp()); 583 DCHECK(current_timestamp != kNoDecodeTimestamp());
535 DCHECK((*itr)->duration() >= base::TimeDelta()) 584 DCHECK((*itr)->duration() >= base::TimeDelta())
536 << "Packet with invalid duration." 585 << "Packet with invalid duration."
537 << " pts " << (*itr)->timestamp().InSecondsF() 586 << " pts " << (*itr)->timestamp().InSecondsF()
538 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() 587 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF()
539 << " dur " << (*itr)->duration().InSecondsF(); 588 << " dur " << (*itr)->duration().InSecondsF();
540 589
541 if (prev_timestamp != kNoDecodeTimestamp()) { 590 if (prev_timestamp != kNoDecodeTimestamp()) {
542 if (current_timestamp < prev_timestamp) { 591 if (current_timestamp < prev_timestamp) {
543 MEDIA_LOG(ERROR, media_log_) 592 MEDIA_LOG(ERROR, media_log_)
544 << "Buffers did not monotonically increase."; 593 << "Buffers did not monotonically increase.";
545 return false; 594 return false;
546 } 595 }
547 596
548 if (current_timestamp == prev_timestamp && 597 if (current_timestamp == prev_timestamp &&
549 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, 598 SourceBufferRange::IsUncommonSameTimestampSequence(
550 current_is_keyframe)) { 599 prev_is_keyframe, current_is_keyframe)) {
551 MEDIA_LOG(ERROR, media_log_) << "Unexpected combination of buffers with" 600 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_strange_same_timestamps_logs_,
552 << " the same timestamp detected at " 601 kMaxStrangeSameTimestampsLogs)
553 << current_timestamp.InSecondsF(); 602 << "Detected an append sequence with keyframe following a "
554 return false; 603 "non-keyframe, both with the same decode timestamp of "
604 << current_timestamp.InSecondsF();
555 } 605 }
556 } 606 }
557 607
558 prev_timestamp = current_timestamp; 608 prev_timestamp = current_timestamp;
559 prev_is_keyframe = current_is_keyframe; 609 prev_is_keyframe = current_is_keyframe;
560 } 610 }
561 return true; 611 return true;
562 } 612 }
563 613
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 { 614 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
574 for (RangeList::const_iterator itr = ranges_.begin(); 615 for (RangeList::const_iterator itr = ranges_.begin();
575 itr != ranges_.end(); ++itr) { 616 itr != ranges_.end(); ++itr) {
576 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) 617 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
577 return false; 618 return false;
578 } 619 }
579 return !selected_range_ || selected_range_->HasNextBufferPosition(); 620 return !selected_range_ || selected_range_->HasNextBufferPosition();
580 } 621 }
581 622
582 void SourceBufferStream::UpdateMaxInterbufferDistance( 623 void SourceBufferStream::UpdateMaxInterbufferDistance(
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 961 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
921 DCHECK(deleted_buffers); 962 DCHECK(deleted_buffers);
922 963
923 // Handle splices between the existing buffers and the new buffers. If a 964 // Handle splices between the existing buffers and the new buffers. If a
924 // splice is generated the timestamp and duration of the first buffer in 965 // splice is generated the timestamp and duration of the first buffer in
925 // |new_buffers| will be modified. 966 // |new_buffers| will be modified.
926 if (splice_frames_enabled_) 967 if (splice_frames_enabled_)
927 GenerateSpliceFrame(new_buffers); 968 GenerateSpliceFrame(new_buffers);
928 969
929 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 970 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
930 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
931 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 971 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
932 bool next_is_keyframe = new_buffers.front()->is_key_frame();
933 972
934 if (prev_timestamp != kNoDecodeTimestamp() && 973 if (prev_timestamp != kNoDecodeTimestamp() &&
935 prev_timestamp != next_timestamp) { 974 prev_timestamp != next_timestamp) {
936 // Clean up the old buffers between the last appended buffer and the 975 // Clean up the old buffers between the last appended buffer and the
937 // beginning of |new_buffers|. 976 // beginning of |new_buffers|.
938 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 977 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
939 } 978 }
940 979
941 // Make the delete range exclusive if we are dealing with an allowed same 980 // Always make the start of the delete range exclusive for same timestamp
942 // timestamp situation. This prevents the first buffer in the current append 981 // across the last buffer in the previous append and the first buffer in the
943 // from deleting the last buffer in the previous append if both buffers 982 // current append. Never be exclusive if a splice frame was generated because
944 // have the same timestamp. 983 // we don't generate splice frames for same timestamp situations.
945 //
946 // The delete range should never be exclusive if a splice frame was generated
947 // because we don't generate splice frames for same timestamp situations.
948 DCHECK(new_buffers.front()->splice_timestamp() != 984 DCHECK(new_buffers.front()->splice_timestamp() !=
949 new_buffers.front()->timestamp()); 985 new_buffers.front()->timestamp());
950 const bool exclude_start = 986 const bool exclude_start = new_buffers.front()->splice_buffers().empty() &&
951 new_buffers.front()->splice_buffers().empty() && 987 prev_timestamp == next_timestamp;
952 prev_timestamp == next_timestamp &&
953 SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, next_is_keyframe);
954 988
955 // Delete the buffers that |new_buffers| overlaps. 989 // Delete the buffers that |new_buffers| overlaps.
956 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); 990 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
991 if (new_coded_frame_group_) {
992 // Extend the deletion range earlier to the coded frame group start time if
993 // this is the first append in a new coded frame group. Note that |start|
994 // could already be less than |coded_frame_group_start_time_| if a splice
995 // was generated.
996 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
997 start = std::min(coded_frame_group_start_time_, start);
998 }
957 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 999 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
958 base::TimeDelta duration = new_buffers.back()->duration(); 1000 base::TimeDelta duration = new_buffers.back()->duration();
959 1001
960 // Set end time for remove to include the duration of last buffer. If the 1002 // Set end time for remove to include the duration of last buffer. If the
961 // duration is estimated, use 1 microsecond instead to ensure frames are not 1003 // duration is estimated, use 1 microsecond instead to ensure frames are not
962 // accidentally removed due to over-estimation. 1004 // accidentally removed due to over-estimation.
963 if (duration != kNoTimestamp() && duration > base::TimeDelta() && 1005 if (duration != kNoTimestamp() && duration > base::TimeDelta() &&
964 !new_buffers.back()->is_duration_estimated()) { 1006 !new_buffers.back()->is_duration_estimated()) {
965 end += duration; 1007 end += duration;
966 } else { 1008 } else {
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 return false; 1824 return false;
1783 1825
1784 DCHECK_NE(have_splice_buffers, have_preroll_buffer); 1826 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1785 splice_buffers_index_ = 0; 1827 splice_buffers_index_ = 0;
1786 pending_buffer_.swap(*out_buffer); 1828 pending_buffer_.swap(*out_buffer);
1787 pending_buffers_complete_ = false; 1829 pending_buffers_complete_ = false;
1788 return true; 1830 return true;
1789 } 1831 }
1790 1832
1791 } // namespace media 1833 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698