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

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: Undid patch set 9's test change, since FrameProcessor *can* produce that output 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
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <sstream> 9 #include <sstream>
10 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 // 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
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
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
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
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
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698