| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |