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

Side by Side Diff: media/filters/source_buffer_range.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_range.h ('k') | media/filters/source_buffer_stream.h » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_range.h" 5 #include "media/filters/source_buffer_range.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "media/base/timestamp_constants.h" 9 #include "media/base/timestamp_constants.h"
10 10
11 namespace media { 11 namespace media {
12 12
13 // Comparison operators for std::upper_bound() and std::lower_bound(). 13 // Comparison operators for std::upper_bound() and std::lower_bound().
14 static bool CompareTimeDeltaToStreamParserBuffer( 14 static bool CompareTimeDeltaToStreamParserBuffer(
15 const DecodeTimestamp& decode_timestamp, 15 const DecodeTimestamp& decode_timestamp,
16 const scoped_refptr<StreamParserBuffer>& buffer) { 16 const scoped_refptr<StreamParserBuffer>& buffer) {
17 return decode_timestamp < buffer->GetDecodeTimestamp(); 17 return decode_timestamp < buffer->GetDecodeTimestamp();
18 } 18 }
19 static bool CompareStreamParserBufferToTimeDelta( 19 static bool CompareStreamParserBufferToTimeDelta(
20 const scoped_refptr<StreamParserBuffer>& buffer, 20 const scoped_refptr<StreamParserBuffer>& buffer,
21 const DecodeTimestamp& decode_timestamp) { 21 const DecodeTimestamp& decode_timestamp) {
22 return buffer->GetDecodeTimestamp() < decode_timestamp; 22 return buffer->GetDecodeTimestamp() < decode_timestamp;
23 } 23 }
24 24
25 bool SourceBufferRange::AllowSameTimestamp( 25 bool SourceBufferRange::IsUncommonSameTimestampSequence(
26 bool prev_is_keyframe, bool current_is_keyframe) { 26 bool prev_is_keyframe,
27 return prev_is_keyframe || !current_is_keyframe; 27 bool current_is_keyframe) {
28 return current_is_keyframe && !prev_is_keyframe;
28 } 29 }
29 30
30 SourceBufferRange::SourceBufferRange( 31 SourceBufferRange::SourceBufferRange(
31 GapPolicy gap_policy, const BufferQueue& new_buffers, 32 GapPolicy gap_policy,
32 DecodeTimestamp media_segment_start_time, 33 const BufferQueue& new_buffers,
34 DecodeTimestamp range_start_time,
33 const InterbufferDistanceCB& interbuffer_distance_cb) 35 const InterbufferDistanceCB& interbuffer_distance_cb)
34 : gap_policy_(gap_policy), 36 : gap_policy_(gap_policy),
35 keyframe_map_index_base_(0), 37 keyframe_map_index_base_(0),
36 next_buffer_index_(-1), 38 next_buffer_index_(-1),
37 media_segment_start_time_(media_segment_start_time), 39 range_start_time_(range_start_time),
38 interbuffer_distance_cb_(interbuffer_distance_cb), 40 interbuffer_distance_cb_(interbuffer_distance_cb),
39 size_in_bytes_(0) { 41 size_in_bytes_(0) {
40 CHECK(!new_buffers.empty()); 42 CHECK(!new_buffers.empty());
41 DCHECK(new_buffers.front()->is_key_frame()); 43 DCHECK(new_buffers.front()->is_key_frame());
42 DCHECK(!interbuffer_distance_cb.is_null()); 44 DCHECK(!interbuffer_distance_cb.is_null());
43 AppendBuffersToEnd(new_buffers); 45 AppendBuffersToEnd(new_buffers, range_start_time_);
44 } 46 }
45 47
46 SourceBufferRange::~SourceBufferRange() {} 48 SourceBufferRange::~SourceBufferRange() {}
47 49
48 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { 50 void SourceBufferRange::AppendBuffersToEnd(
49 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); 51 const BufferQueue& new_buffers,
50 DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() || 52 DecodeTimestamp new_buffers_group_start_timestamp) {
51 media_segment_start_time_ <= 53 CHECK(buffers_.empty() ||
52 new_buffers.front()->GetDecodeTimestamp()); 54 CanAppendBuffersToEnd(new_buffers, new_buffers_group_start_timestamp));
55 DCHECK(range_start_time_ == kNoDecodeTimestamp() ||
56 range_start_time_ <= new_buffers.front()->GetDecodeTimestamp());
53 57
54 AdjustEstimatedDurationForNewAppend(new_buffers); 58 AdjustEstimatedDurationForNewAppend(new_buffers);
55 59
56 for (BufferQueue::const_iterator itr = new_buffers.begin(); 60 for (BufferQueue::const_iterator itr = new_buffers.begin();
57 itr != new_buffers.end(); 61 itr != new_buffers.end();
58 ++itr) { 62 ++itr) {
59 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); 63 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp());
60 buffers_.push_back(*itr); 64 buffers_.push_back(*itr);
61 size_in_bytes_ += (*itr)->data_size(); 65 size_in_bytes_ += (*itr)->data_size();
62 66
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // into |removed_buffers|. 151 // into |removed_buffers|.
148 int keyframe_index = 152 int keyframe_index =
149 new_beginning_keyframe->second - keyframe_map_index_base_; 153 new_beginning_keyframe->second - keyframe_map_index_base_;
150 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 154 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
151 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 155 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
152 BufferQueue removed_buffers(starting_point, buffers_.end()); 156 BufferQueue removed_buffers(starting_point, buffers_.end());
153 157
154 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp(); 158 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp();
155 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() && 159 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() &&
156 timestamp < removed_buffers.front()->GetDecodeTimestamp()) { 160 timestamp < removed_buffers.front()->GetDecodeTimestamp()) {
157 // The split is in the gap between |media_segment_start_time_| and 161 // The split is in the gap between |range_start_time_| and the first buffer
158 // the first buffer of the new range so we should set the start 162 // of the new range so we should set the start time of the new range to
159 // time of the new range to |timestamp| so we preserve part of the 163 // |timestamp| so we preserve part of the gap in the new range.
160 // gap in the new range.
161 new_range_start_timestamp = timestamp; 164 new_range_start_timestamp = timestamp;
162 } 165 }
163 166
164 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); 167 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
165 FreeBufferRange(starting_point, buffers_.end()); 168 FreeBufferRange(starting_point, buffers_.end());
166 169
167 // Create a new range with |removed_buffers|. 170 // Create a new range with |removed_buffers|.
168 SourceBufferRange* split_range = 171 SourceBufferRange* split_range =
169 new SourceBufferRange( 172 new SourceBufferRange(
170 gap_policy_, removed_buffers, new_range_start_timestamp, 173 gap_policy_, removed_buffers, new_range_start_timestamp,
171 interbuffer_distance_cb_); 174 interbuffer_distance_cb_);
172 175
173 // If the next buffer position is now in |split_range|, update the state of 176 // If the next buffer position is now in |split_range|, update the state of
174 // this range and |split_range| accordingly. 177 // this range and |split_range| accordingly.
175 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 178 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
176 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; 179 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
177 CHECK_GE(split_range->next_buffer_index_, 0) 180
178 << split_range->next_buffer_index_; 181 int split_range_next_buffer_index = split_range->next_buffer_index_;
182 CHECK_GE(split_range_next_buffer_index, 0);
183 // Note that a SourceBufferRange's |next_buffer_index_| can be the index
184 // of a buffer one beyond what is currently in |buffers_|.
185 CHECK_LE(split_range_next_buffer_index,
186 static_cast<int>(split_range->buffers_.size()));
187
179 ResetNextBufferPosition(); 188 ResetNextBufferPosition();
180 } 189 }
181 190
182 return split_range; 191 return split_range;
183 } 192 }
184 193
185 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt( 194 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
186 DecodeTimestamp timestamp, 195 DecodeTimestamp timestamp,
187 bool skip_given_timestamp) { 196 bool skip_given_timestamp) {
188 return skip_given_timestamp 197 return skip_given_timestamp
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 273
265 // Update |keyframe_map_index_base_| to account for the deleted buffers. 274 // Update |keyframe_map_index_base_| to account for the deleted buffers.
266 keyframe_map_index_base_ += buffers_deleted; 275 keyframe_map_index_base_ += buffers_deleted;
267 276
268 if (next_buffer_index_ > -1) { 277 if (next_buffer_index_ > -1) {
269 next_buffer_index_ -= buffers_deleted; 278 next_buffer_index_ -= buffers_deleted;
270 CHECK_GE(next_buffer_index_, 0) << next_buffer_index_ << ", deleted " 279 CHECK_GE(next_buffer_index_, 0) << next_buffer_index_ << ", deleted "
271 << buffers_deleted; 280 << buffers_deleted;
272 } 281 }
273 282
274 // Invalidate media segment start time if we've deleted the first buffer of 283 // Invalidate range start time if we've deleted the first buffer of the range.
275 // the range.
276 if (buffers_deleted > 0) 284 if (buffers_deleted > 0)
277 media_segment_start_time_ = kNoDecodeTimestamp(); 285 range_start_time_ = kNoDecodeTimestamp();
278 286
279 return total_bytes_deleted; 287 return total_bytes_deleted;
280 } 288 }
281 289
282 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { 290 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
283 DCHECK(!buffers_.empty()); 291 DCHECK(!buffers_.empty());
284 DCHECK(!LastGOPContainsNextBufferPosition()); 292 DCHECK(!LastGOPContainsNextBufferPosition());
285 DCHECK(deleted_buffers); 293 DCHECK(deleted_buffers);
286 294
287 // Remove the last GOP's keyframe from the |keyframe_map_|. 295 // Remove the last GOP's keyframe from the |keyframe_map_|.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 484 }
477 485
478 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range, 486 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
479 bool transfer_current_position) { 487 bool transfer_current_position) {
480 DCHECK(CanAppendRangeToEnd(range)); 488 DCHECK(CanAppendRangeToEnd(range));
481 DCHECK(!buffers_.empty()); 489 DCHECK(!buffers_.empty());
482 490
483 if (transfer_current_position && range.next_buffer_index_ >= 0) 491 if (transfer_current_position && range.next_buffer_index_ >= 0)
484 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); 492 next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
485 493
486 AppendBuffersToEnd(range.buffers_); 494 AppendBuffersToEnd(range.buffers_, kNoDecodeTimestamp());
487 } 495 }
488 496
489 bool SourceBufferRange::CanAppendRangeToEnd( 497 bool SourceBufferRange::CanAppendRangeToEnd(
490 const SourceBufferRange& range) const { 498 const SourceBufferRange& range) const {
491 return CanAppendBuffersToEnd(range.buffers_); 499 return CanAppendBuffersToEnd(range.buffers_, kNoDecodeTimestamp());
492 } 500 }
493 501
494 bool SourceBufferRange::CanAppendBuffersToEnd( 502 bool SourceBufferRange::CanAppendBuffersToEnd(
495 const BufferQueue& buffers) const { 503 const BufferQueue& buffers,
504 DecodeTimestamp new_buffers_group_start_timestamp) const {
496 DCHECK(!buffers_.empty()); 505 DCHECK(!buffers_.empty());
497 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), 506 if (new_buffers_group_start_timestamp == kNoDecodeTimestamp()) {
498 buffers.front()->is_key_frame()); 507 return IsNextInSequence(buffers.front()->GetDecodeTimestamp());
508 }
509 DCHECK(new_buffers_group_start_timestamp >= GetEndTimestamp());
510 DCHECK(buffers.front()->GetDecodeTimestamp() >=
511 new_buffers_group_start_timestamp);
512 return IsNextInSequence(new_buffers_group_start_timestamp);
499 } 513 }
500 514
501 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { 515 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const {
502 DCHECK(!buffers_.empty()); 516 DCHECK(!buffers_.empty());
503 517
504 return (IsNextInSequence(timestamp, false) || 518 return (IsNextInSequence(timestamp) ||
505 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 519 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
506 } 520 }
507 521
508 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { 522 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const {
509 DecodeTimestamp start_timestamp = 523 DecodeTimestamp start_timestamp =
510 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); 524 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom());
511 return !keyframe_map_.empty() && start_timestamp <= timestamp && 525 return !keyframe_map_.empty() && start_timestamp <= timestamp &&
512 timestamp < GetBufferedEndTimestamp(); 526 timestamp < GetBufferedEndTimestamp();
513 } 527 }
514 528
515 bool SourceBufferRange::CompletelyOverlaps( 529 bool SourceBufferRange::CompletelyOverlaps(
516 const SourceBufferRange& range) const { 530 const SourceBufferRange& range) const {
517 return GetStartTimestamp() <= range.GetStartTimestamp() && 531 return GetStartTimestamp() <= range.GetStartTimestamp() &&
518 GetEndTimestamp() >= range.GetEndTimestamp(); 532 GetEndTimestamp() >= range.GetEndTimestamp();
519 } 533 }
520 534
521 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { 535 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
522 return range.GetStartTimestamp() <= GetEndTimestamp() && 536 return range.GetStartTimestamp() <= GetEndTimestamp() &&
523 GetEndTimestamp() < range.GetEndTimestamp(); 537 GetEndTimestamp() < range.GetEndTimestamp();
524 } 538 }
525 539
526 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const { 540 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const {
527 DCHECK(!buffers_.empty()); 541 DCHECK(!buffers_.empty());
528 DecodeTimestamp start_timestamp = media_segment_start_time_; 542 DecodeTimestamp start_timestamp = range_start_time_;
529 if (start_timestamp == kNoDecodeTimestamp()) 543 if (start_timestamp == kNoDecodeTimestamp())
530 start_timestamp = buffers_.front()->GetDecodeTimestamp(); 544 start_timestamp = buffers_.front()->GetDecodeTimestamp();
531 return start_timestamp; 545 return start_timestamp;
532 } 546 }
533 547
534 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const { 548 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const {
535 DCHECK(!buffers_.empty()); 549 DCHECK(!buffers_.empty());
536 return buffers_.back()->GetDecodeTimestamp(); 550 return buffers_.back()->GetDecodeTimestamp();
537 } 551 }
538 552
539 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const { 553 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const {
540 DCHECK(!buffers_.empty()); 554 DCHECK(!buffers_.empty());
541 base::TimeDelta duration = buffers_.back()->duration(); 555 base::TimeDelta duration = buffers_.back()->duration();
542 if (duration == kNoTimestamp() || duration == base::TimeDelta()) 556 if (duration == kNoTimestamp() || duration == base::TimeDelta())
543 duration = GetApproximateDuration(); 557 duration = GetApproximateDuration();
544 return GetEndTimestamp() + duration; 558 return GetEndTimestamp() + duration;
545 } 559 }
546 560
547 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp( 561 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp(
548 DecodeTimestamp timestamp) { 562 DecodeTimestamp timestamp) {
549 DCHECK(!keyframe_map_.empty()); 563 DCHECK(!keyframe_map_.empty());
550 564
551 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 565 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
552 return kNoDecodeTimestamp(); 566 return kNoDecodeTimestamp();
553 567
554 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); 568 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false);
555 if (itr == keyframe_map_.end()) 569 if (itr == keyframe_map_.end())
556 return kNoDecodeTimestamp(); 570 return kNoDecodeTimestamp();
557 571
558 // If the timestamp is inside the gap between the start of the media 572 // If the timestamp is inside the gap between the start of the coded frame
559 // segment and the first buffer, then just pretend there is a 573 // group and the first buffer, then just pretend there is a keyframe at the
560 // keyframe at the specified timestamp. 574 // specified timestamp.
561 if (itr == keyframe_map_.begin() && 575 if (itr == keyframe_map_.begin() && timestamp > range_start_time_ &&
562 timestamp > media_segment_start_time_ &&
563 timestamp < itr->first) { 576 timestamp < itr->first) {
564 return timestamp; 577 return timestamp;
565 } 578 }
566 579
567 return itr->first; 580 return itr->first;
568 } 581 }
569 582
570 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( 583 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp(
571 DecodeTimestamp timestamp) { 584 DecodeTimestamp timestamp) {
572 DCHECK(!keyframe_map_.empty()); 585 DCHECK(!keyframe_map_.empty());
573 586
574 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 587 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
575 return kNoDecodeTimestamp(); 588 return kNoDecodeTimestamp();
576 589
577 return GetFirstKeyframeAtOrBefore(timestamp)->first; 590 return GetFirstKeyframeAtOrBefore(timestamp)->first;
578 } 591 }
579 592
580 bool SourceBufferRange::IsNextInSequence( 593 bool SourceBufferRange::IsNextInSequence(DecodeTimestamp timestamp) const {
581 DecodeTimestamp timestamp, bool is_key_frame) const {
582 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); 594 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp();
583 if (end < timestamp && 595 return (end == timestamp ||
584 (gap_policy_ == ALLOW_GAPS || 596 (end < timestamp &&
585 timestamp <= end + GetFudgeRoom())) { 597 (gap_policy_ == ALLOW_GAPS || timestamp <= end + GetFudgeRoom())));
586 return true;
587 }
588
589 return timestamp == end && AllowSameTimestamp(
590 buffers_.back()->is_key_frame(), is_key_frame);
591 } 598 }
592 599
593 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 600 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
594 // Because we do not know exactly when is the next timestamp, any buffer 601 // Because we do not know exactly when is the next timestamp, any buffer
595 // that starts within 2x the approximate duration of a buffer is considered 602 // that starts within 2x the approximate duration of a buffer is considered
596 // within this range. 603 // within this range.
597 return 2 * GetApproximateDuration(); 604 return 2 * GetApproximateDuration();
598 } 605 }
599 606
600 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 607 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
(...skipping 27 matching lines...) Expand all
628 } 635 }
629 636
630 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) 637 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime())
631 continue; 638 continue;
632 buffers->push_back(buffer); 639 buffers->push_back(buffer);
633 } 640 }
634 return previous_size < buffers->size(); 641 return previous_size < buffers->size();
635 } 642 }
636 643
637 } // namespace media 644 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/source_buffer_range.h ('k') | media/filters/source_buffer_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698