Chromium Code Reviews| 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; | |
|
chcunningham
2016/02/09 00:21:08
Just to note: I wasn't sure how (un)common this is
wolenetz
2016/02/09 00:47:19
Acknowledged.
| |
| 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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 } | 481 } |
| 481 | 482 |
| 482 bool SourceBufferRange::CanAppendRangeToEnd( | 483 bool SourceBufferRange::CanAppendRangeToEnd( |
| 483 const SourceBufferRange& range) const { | 484 const SourceBufferRange& range) const { |
| 484 return CanAppendBuffersToEnd(range.buffers_); | 485 return CanAppendBuffersToEnd(range.buffers_); |
| 485 } | 486 } |
| 486 | 487 |
| 487 bool SourceBufferRange::CanAppendBuffersToEnd( | 488 bool SourceBufferRange::CanAppendBuffersToEnd( |
| 488 const BufferQueue& buffers) const { | 489 const BufferQueue& buffers) const { |
| 489 DCHECK(!buffers_.empty()); | 490 DCHECK(!buffers_.empty()); |
| 490 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), | 491 return IsNextInSequence(buffers.front()->GetDecodeTimestamp()); |
| 491 buffers.front()->is_key_frame()); | |
| 492 } | 492 } |
| 493 | 493 |
| 494 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { | 494 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { |
| 495 DCHECK(!buffers_.empty()); | 495 DCHECK(!buffers_.empty()); |
| 496 | 496 |
| 497 return (IsNextInSequence(timestamp, false) || | 497 return (IsNextInSequence(timestamp) || |
| 498 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); | 498 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); |
| 499 } | 499 } |
| 500 | 500 |
| 501 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { | 501 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { |
| 502 DecodeTimestamp start_timestamp = | 502 DecodeTimestamp start_timestamp = |
| 503 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); | 503 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); |
| 504 return !keyframe_map_.empty() && start_timestamp <= timestamp && | 504 return !keyframe_map_.empty() && start_timestamp <= timestamp && |
| 505 timestamp < GetBufferedEndTimestamp(); | 505 timestamp < GetBufferedEndTimestamp(); |
| 506 } | 506 } |
| 507 | 507 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( | 563 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( |
| 564 DecodeTimestamp timestamp) { | 564 DecodeTimestamp timestamp) { |
| 565 DCHECK(!keyframe_map_.empty()); | 565 DCHECK(!keyframe_map_.empty()); |
| 566 | 566 |
| 567 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 567 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
| 568 return kNoDecodeTimestamp(); | 568 return kNoDecodeTimestamp(); |
| 569 | 569 |
| 570 return GetFirstKeyframeAtOrBefore(timestamp)->first; | 570 return GetFirstKeyframeAtOrBefore(timestamp)->first; |
| 571 } | 571 } |
| 572 | 572 |
| 573 bool SourceBufferRange::IsNextInSequence( | 573 bool SourceBufferRange::IsNextInSequence(DecodeTimestamp timestamp) const { |
| 574 DecodeTimestamp timestamp, bool is_key_frame) const { | |
| 575 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); | 574 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); |
| 576 if (end < timestamp && | 575 return (end == timestamp || |
| 577 (gap_policy_ == ALLOW_GAPS || | 576 (end < timestamp && |
| 578 timestamp <= end + GetFudgeRoom())) { | 577 (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 } | 578 } |
| 585 | 579 |
| 586 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { | 580 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { |
| 587 // Because we do not know exactly when is the next timestamp, any buffer | 581 // 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 | 582 // that starts within 2x the approximate duration of a buffer is considered |
| 589 // within this range. | 583 // within this range. |
| 590 return 2 * GetApproximateDuration(); | 584 return 2 * GetApproximateDuration(); |
| 591 } | 585 } |
| 592 | 586 |
| 593 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 587 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 621 } | 615 } |
| 622 | 616 |
| 623 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) | 617 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) |
| 624 continue; | 618 continue; |
| 625 buffers->push_back(buffer); | 619 buffers->push_back(buffer); |
| 626 } | 620 } |
| 627 return previous_size < buffers->size(); | 621 return previous_size < buffers->size(); |
| 628 } | 622 } |
| 629 | 623 |
| 630 } // namespace media | 624 } // namespace media |
| OLD | NEW |