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

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: Rebase plus interim patch set with a new test demonstrating there's more failure that needs fixing 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 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, const BufferQueue& new_buffers,
32 DecodeTimestamp media_segment_start_time, 33 DecodeTimestamp media_segment_start_time,
33 const InterbufferDistanceCB& interbuffer_distance_cb) 34 const InterbufferDistanceCB& interbuffer_distance_cb)
34 : gap_policy_(gap_policy), 35 : gap_policy_(gap_policy),
35 keyframe_map_index_base_(0), 36 keyframe_map_index_base_(0),
36 next_buffer_index_(-1), 37 next_buffer_index_(-1),
37 media_segment_start_time_(media_segment_start_time), 38 media_segment_start_time_(media_segment_start_time),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 92 }
92 } 93 }
93 } 94 }
94 95
95 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { 96 void SourceBufferRange::Seek(DecodeTimestamp timestamp) {
96 DCHECK(CanSeekTo(timestamp)); 97 DCHECK(CanSeekTo(timestamp));
97 DCHECK(!keyframe_map_.empty()); 98 DCHECK(!keyframe_map_.empty());
98 99
99 KeyframeMap::iterator result = GetFirstKeyframeAtOrBefore(timestamp); 100 KeyframeMap::iterator result = GetFirstKeyframeAtOrBefore(timestamp);
100 next_buffer_index_ = result->second - keyframe_map_index_base_; 101 next_buffer_index_ = result->second - keyframe_map_index_base_;
101 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 102 CHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()))
103 << next_buffer_index_ << ", size = " << buffers_.size();
102 } 104 }
103 105
104 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { 106 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) {
105 SeekAhead(timestamp, false); 107 SeekAhead(timestamp, false);
106 } 108 }
107 109
108 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { 110 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) {
109 SeekAhead(timestamp, true); 111 SeekAhead(timestamp, true);
110 } 112 }
111 113
112 void SourceBufferRange::SeekAhead(DecodeTimestamp timestamp, 114 void SourceBufferRange::SeekAhead(DecodeTimestamp timestamp,
113 bool skip_given_timestamp) { 115 bool skip_given_timestamp) {
114 DCHECK(!keyframe_map_.empty()); 116 DCHECK(!keyframe_map_.empty());
115 117
116 KeyframeMap::iterator result = 118 KeyframeMap::iterator result =
117 GetFirstKeyframeAt(timestamp, skip_given_timestamp); 119 GetFirstKeyframeAt(timestamp, skip_given_timestamp);
118 120
119 // If there isn't a keyframe after |timestamp|, then seek to end and return 121 // If there isn't a keyframe after |timestamp|, then seek to end and return
120 // kNoTimestamp to signal such. 122 // kNoTimestamp to signal such.
121 if (result == keyframe_map_.end()) { 123 if (result == keyframe_map_.end()) {
122 next_buffer_index_ = -1; 124 next_buffer_index_ = -1;
123 return; 125 return;
124 } 126 }
125 next_buffer_index_ = result->second - keyframe_map_index_base_; 127 next_buffer_index_ = result->second - keyframe_map_index_base_;
126 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 128 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
127 } 129 }
128 130
129 void SourceBufferRange::SeekToStart() { 131 void SourceBufferRange::SeekToStart() {
130 DCHECK(!buffers_.empty()); 132 CHECK(!buffers_.empty());
131 next_buffer_index_ = 0; 133 next_buffer_index_ = 0;
132 } 134 }
133 135
134 SourceBufferRange* SourceBufferRange::SplitRange(DecodeTimestamp timestamp) { 136 SourceBufferRange* SourceBufferRange::SplitRange(DecodeTimestamp timestamp) {
135 CHECK(!buffers_.empty()); 137 CHECK(!buffers_.empty());
136 138
137 // Find the first keyframe at or after |timestamp|. 139 // Find the first keyframe at or after |timestamp|.
138 KeyframeMap::iterator new_beginning_keyframe = 140 KeyframeMap::iterator new_beginning_keyframe =
139 GetFirstKeyframeAt(timestamp, false); 141 GetFirstKeyframeAt(timestamp, false);
140 142
141 // If there is no keyframe after |timestamp|, we can't split the range. 143 // If there is no keyframe after |timestamp|, we can't split the range.
142 if (new_beginning_keyframe == keyframe_map_.end()) 144 if (new_beginning_keyframe == keyframe_map_.end())
143 return NULL; 145 return NULL;
144 146
145 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 147 // Remove the data beginning at |keyframe_index| from |buffers_| and save it
146 // into |removed_buffers|. 148 // into |removed_buffers|.
147 int keyframe_index = 149 int keyframe_index =
148 new_beginning_keyframe->second - keyframe_map_index_base_; 150 new_beginning_keyframe->second - keyframe_map_index_base_;
149 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 151 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
150 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 152 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
151 BufferQueue removed_buffers(starting_point, buffers_.end()); 153 BufferQueue removed_buffers(starting_point, buffers_.end());
152 154
153 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp(); 155 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp();
154 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() && 156 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() &&
155 timestamp < removed_buffers.front()->GetDecodeTimestamp()) { 157 timestamp < removed_buffers.front()->GetDecodeTimestamp()) {
156 // The split is in the gap between |media_segment_start_time_| and 158 // The split is in the gap between |media_segment_start_time_| and
157 // the first buffer of the new range so we should set the start 159 // the first buffer of the new range so we should set the start
158 // time of the new range to |timestamp| so we preserve part of the 160 // time of the new range to |timestamp| so we preserve part of the
159 // gap in the new range. 161 // gap in the new range.
160 new_range_start_timestamp = timestamp; 162 new_range_start_timestamp = timestamp;
chcunningham 2016/02/12 22:46:40 I might be missing something here, but this sounds
wolenetz 2016/02/24 00:34:46 Hmm. This doesn't appear to be broken, though is a
chcunningham 2016/02/24 19:06:26 Acknowledged.
161 } 163 }
162 164
163 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); 165 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
164 FreeBufferRange(starting_point, buffers_.end()); 166 FreeBufferRange(starting_point, buffers_.end());
165 167
166 // Create a new range with |removed_buffers|. 168 // Create a new range with |removed_buffers|.
167 SourceBufferRange* split_range = 169 SourceBufferRange* split_range =
168 new SourceBufferRange( 170 new SourceBufferRange(
169 gap_policy_, removed_buffers, new_range_start_timestamp, 171 gap_policy_, removed_buffers, new_range_start_timestamp,
170 interbuffer_distance_cb_); 172 interbuffer_distance_cb_);
171 173
172 // If the next buffer position is now in |split_range|, update the state of 174 // If the next buffer position is now in |split_range|, update the state of
173 // this range and |split_range| accordingly. 175 // this range and |split_range| accordingly.
174 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 176 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
175 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; 177 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
178 CHECK_GE(split_range->next_buffer_index_, 0)
chcunningham 2016/02/12 22:46:40 You might also add a check for next_buffer_index <
wolenetz 2016/02/24 00:34:46 Done.... BUT: the new CHECK_LT triggered a crash i
chcunningham 2016/02/24 19:06:26 Acknowledged. Will be interesting to see whats goi
chcunningham 2016/02/24 19:12:54 We chatted. For posterity: You made needed to make
179 << split_range->next_buffer_index_;
176 ResetNextBufferPosition(); 180 ResetNextBufferPosition();
177 } 181 }
178 182
179 return split_range; 183 return split_range;
180 } 184 }
181 185
182 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt( 186 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
183 DecodeTimestamp timestamp, 187 DecodeTimestamp timestamp,
184 bool skip_given_timestamp) { 188 bool skip_given_timestamp) {
185 return skip_given_timestamp 189 return skip_given_timestamp
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 deleted_buffers->push_back(buffers_.front()); 260 deleted_buffers->push_back(buffers_.front());
257 buffers_.pop_front(); 261 buffers_.pop_front();
258 ++buffers_deleted; 262 ++buffers_deleted;
259 } 263 }
260 264
261 // Update |keyframe_map_index_base_| to account for the deleted buffers. 265 // Update |keyframe_map_index_base_| to account for the deleted buffers.
262 keyframe_map_index_base_ += buffers_deleted; 266 keyframe_map_index_base_ += buffers_deleted;
263 267
264 if (next_buffer_index_ > -1) { 268 if (next_buffer_index_ > -1) {
265 next_buffer_index_ -= buffers_deleted; 269 next_buffer_index_ -= buffers_deleted;
266 DCHECK_GE(next_buffer_index_, 0); 270 CHECK_GE(next_buffer_index_, 0) << next_buffer_index_ << ", deleted "
271 << buffers_deleted;
267 } 272 }
268 273
269 // Invalidate media segment start time if we've deleted the first buffer of 274 // Invalidate media segment start time if we've deleted the first buffer of
270 // the range. 275 // the range.
271 if (buffers_deleted > 0) 276 if (buffers_deleted > 0)
272 media_segment_start_time_ = kNoDecodeTimestamp(); 277 media_segment_start_time_ = kNoDecodeTimestamp();
273 278
274 return total_bytes_deleted; 279 return total_bytes_deleted;
275 } 280 }
276 281
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 next_buffer_index_++; 441 next_buffer_index_++;
437 return true; 442 return true;
438 } 443 }
439 444
440 bool SourceBufferRange::HasNextBuffer() const { 445 bool SourceBufferRange::HasNextBuffer() const {
441 return next_buffer_index_ >= 0 && 446 return next_buffer_index_ >= 0 &&
442 next_buffer_index_ < static_cast<int>(buffers_.size()); 447 next_buffer_index_ < static_cast<int>(buffers_.size());
443 } 448 }
444 449
445 int SourceBufferRange::GetNextConfigId() const { 450 int SourceBufferRange::GetNextConfigId() const {
446 DCHECK(HasNextBuffer()); 451 CHECK(HasNextBuffer()) << next_buffer_index_;
447 // If the next buffer is an audio splice frame, the next effective config id 452 // If the next buffer is an audio splice frame, the next effective config id
448 // comes from the first fade out preroll buffer. 453 // comes from the first fade out preroll buffer.
449 return buffers_[next_buffer_index_]->GetSpliceBufferConfigId(0); 454 return buffers_[next_buffer_index_]->GetSpliceBufferConfigId(0);
450 } 455 }
451 456
452 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const { 457 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const {
453 DCHECK(!buffers_.empty()); 458 CHECK(!buffers_.empty()) << next_buffer_index_;
454 DCHECK(HasNextBufferPosition()); 459 CHECK(HasNextBufferPosition()) << next_buffer_index_
460 << ", size=" << buffers_.size();
455 461
456 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 462 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
457 return kNoDecodeTimestamp(); 463 return kNoDecodeTimestamp();
458 } 464 }
459 465
460 return buffers_[next_buffer_index_]->GetDecodeTimestamp(); 466 return buffers_[next_buffer_index_]->GetDecodeTimestamp();
461 } 467 }
462 468
463 bool SourceBufferRange::HasNextBufferPosition() const { 469 bool SourceBufferRange::HasNextBufferPosition() const {
464 return next_buffer_index_ >= 0; 470 return next_buffer_index_ >= 0;
(...skipping 15 matching lines...) Expand all
480 } 486 }
481 487
482 bool SourceBufferRange::CanAppendRangeToEnd( 488 bool SourceBufferRange::CanAppendRangeToEnd(
483 const SourceBufferRange& range) const { 489 const SourceBufferRange& range) const {
484 return CanAppendBuffersToEnd(range.buffers_); 490 return CanAppendBuffersToEnd(range.buffers_);
485 } 491 }
486 492
487 bool SourceBufferRange::CanAppendBuffersToEnd( 493 bool SourceBufferRange::CanAppendBuffersToEnd(
488 const BufferQueue& buffers) const { 494 const BufferQueue& buffers) const {
489 DCHECK(!buffers_.empty()); 495 DCHECK(!buffers_.empty());
490 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), 496 return IsNextInSequence(buffers.front()->GetDecodeTimestamp());
491 buffers.front()->is_key_frame());
492 } 497 }
493 498
494 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { 499 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const {
495 DCHECK(!buffers_.empty()); 500 DCHECK(!buffers_.empty());
496 501
497 return (IsNextInSequence(timestamp, false) || 502 return (IsNextInSequence(timestamp) ||
498 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 503 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
499 } 504 }
500 505
501 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { 506 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const {
502 DecodeTimestamp start_timestamp = 507 DecodeTimestamp start_timestamp =
503 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); 508 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom());
504 return !keyframe_map_.empty() && start_timestamp <= timestamp && 509 return !keyframe_map_.empty() && start_timestamp <= timestamp &&
505 timestamp < GetBufferedEndTimestamp(); 510 timestamp < GetBufferedEndTimestamp();
506 } 511 }
507 512
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( 568 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp(
564 DecodeTimestamp timestamp) { 569 DecodeTimestamp timestamp) {
565 DCHECK(!keyframe_map_.empty()); 570 DCHECK(!keyframe_map_.empty());
566 571
567 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 572 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
568 return kNoDecodeTimestamp(); 573 return kNoDecodeTimestamp();
569 574
570 return GetFirstKeyframeAtOrBefore(timestamp)->first; 575 return GetFirstKeyframeAtOrBefore(timestamp)->first;
571 } 576 }
572 577
573 bool SourceBufferRange::IsNextInSequence( 578 bool SourceBufferRange::IsNextInSequence(DecodeTimestamp timestamp) const {
574 DecodeTimestamp timestamp, bool is_key_frame) const {
575 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); 579 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp();
576 if (end < timestamp && 580 return (end == timestamp ||
577 (gap_policy_ == ALLOW_GAPS || 581 (end < timestamp &&
578 timestamp <= end + GetFudgeRoom())) { 582 (gap_policy_ == ALLOW_GAPS || timestamp <= end + GetFudgeRoom())));
579 return true;
580 }
581
582 return timestamp == end && AllowSameTimestamp(
583 buffers_.back()->is_key_frame(), is_key_frame);
584 } 583 }
585 584
586 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 585 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
587 // Because we do not know exactly when is the next timestamp, any buffer 586 // Because we do not know exactly when is the next timestamp, any buffer
588 // that starts within 2x the approximate duration of a buffer is considered 587 // that starts within 2x the approximate duration of a buffer is considered
589 // within this range. 588 // within this range.
590 return 2 * GetApproximateDuration(); 589 return 2 * GetApproximateDuration();
591 } 590 }
592 591
593 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 592 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
(...skipping 27 matching lines...) Expand all
621 } 620 }
622 621
623 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) 622 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime())
624 continue; 623 continue;
625 buffers->push_back(buffer); 624 buffers->push_back(buffer);
626 } 625 }
627 return previous_size < buffers->size(); 626 return previous_size < buffers->size();
628 } 627 }
629 628
630 } // namespace media 629 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698