| Index: media/filters/source_buffer_range.cc
|
| diff --git a/media/filters/source_buffer_range.cc b/media/filters/source_buffer_range.cc
|
| index 6e664f974854dca4a1e9d8fdf8202fd049985128..ba6b66c27ad3f2f5a7d8c14479ddb6f4f7778b47 100644
|
| --- a/media/filters/source_buffer_range.cc
|
| +++ b/media/filters/source_buffer_range.cc
|
| @@ -22,34 +22,38 @@ static bool CompareStreamParserBufferToTimeDelta(
|
| return buffer->GetDecodeTimestamp() < decode_timestamp;
|
| }
|
|
|
| -bool SourceBufferRange::AllowSameTimestamp(
|
| - bool prev_is_keyframe, bool current_is_keyframe) {
|
| - return prev_is_keyframe || !current_is_keyframe;
|
| +bool SourceBufferRange::IsUncommonSameTimestampSequence(
|
| + bool prev_is_keyframe,
|
| + bool current_is_keyframe) {
|
| + return current_is_keyframe && !prev_is_keyframe;
|
| }
|
|
|
| SourceBufferRange::SourceBufferRange(
|
| - GapPolicy gap_policy, const BufferQueue& new_buffers,
|
| - DecodeTimestamp media_segment_start_time,
|
| + GapPolicy gap_policy,
|
| + const BufferQueue& new_buffers,
|
| + DecodeTimestamp range_start_time,
|
| const InterbufferDistanceCB& interbuffer_distance_cb)
|
| : gap_policy_(gap_policy),
|
| keyframe_map_index_base_(0),
|
| next_buffer_index_(-1),
|
| - media_segment_start_time_(media_segment_start_time),
|
| + range_start_time_(range_start_time),
|
| interbuffer_distance_cb_(interbuffer_distance_cb),
|
| size_in_bytes_(0) {
|
| CHECK(!new_buffers.empty());
|
| DCHECK(new_buffers.front()->is_key_frame());
|
| DCHECK(!interbuffer_distance_cb.is_null());
|
| - AppendBuffersToEnd(new_buffers);
|
| + AppendBuffersToEnd(new_buffers, range_start_time_);
|
| }
|
|
|
| SourceBufferRange::~SourceBufferRange() {}
|
|
|
| -void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) {
|
| - DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers));
|
| - DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() ||
|
| - media_segment_start_time_ <=
|
| - new_buffers.front()->GetDecodeTimestamp());
|
| +void SourceBufferRange::AppendBuffersToEnd(
|
| + const BufferQueue& new_buffers,
|
| + DecodeTimestamp new_buffers_group_start_timestamp) {
|
| + CHECK(buffers_.empty() ||
|
| + CanAppendBuffersToEnd(new_buffers, new_buffers_group_start_timestamp));
|
| + DCHECK(range_start_time_ == kNoDecodeTimestamp() ||
|
| + range_start_time_ <= new_buffers.front()->GetDecodeTimestamp());
|
|
|
| AdjustEstimatedDurationForNewAppend(new_buffers);
|
|
|
| @@ -154,10 +158,9 @@ SourceBufferRange* SourceBufferRange::SplitRange(DecodeTimestamp timestamp) {
|
| DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp();
|
| if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() &&
|
| timestamp < removed_buffers.front()->GetDecodeTimestamp()) {
|
| - // The split is in the gap between |media_segment_start_time_| and
|
| - // the first buffer of the new range so we should set the start
|
| - // time of the new range to |timestamp| so we preserve part of the
|
| - // gap in the new range.
|
| + // The split is in the gap between |range_start_time_| and the first buffer
|
| + // of the new range so we should set the start time of the new range to
|
| + // |timestamp| so we preserve part of the gap in the new range.
|
| new_range_start_timestamp = timestamp;
|
| }
|
|
|
| @@ -174,8 +177,14 @@ SourceBufferRange* SourceBufferRange::SplitRange(DecodeTimestamp timestamp) {
|
| // this range and |split_range| accordingly.
|
| if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
|
| split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
|
| - CHECK_GE(split_range->next_buffer_index_, 0)
|
| - << split_range->next_buffer_index_;
|
| +
|
| + int split_range_next_buffer_index = split_range->next_buffer_index_;
|
| + CHECK_GE(split_range_next_buffer_index, 0);
|
| + // Note that a SourceBufferRange's |next_buffer_index_| can be the index
|
| + // of a buffer one beyond what is currently in |buffers_|.
|
| + CHECK_LE(split_range_next_buffer_index,
|
| + static_cast<int>(split_range->buffers_.size()));
|
| +
|
| ResetNextBufferPosition();
|
| }
|
|
|
| @@ -271,10 +280,9 @@ size_t SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
|
| << buffers_deleted;
|
| }
|
|
|
| - // Invalidate media segment start time if we've deleted the first buffer of
|
| - // the range.
|
| + // Invalidate range start time if we've deleted the first buffer of the range.
|
| if (buffers_deleted > 0)
|
| - media_segment_start_time_ = kNoDecodeTimestamp();
|
| + range_start_time_ = kNoDecodeTimestamp();
|
|
|
| return total_bytes_deleted;
|
| }
|
| @@ -483,25 +491,31 @@ void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
|
| if (transfer_current_position && range.next_buffer_index_ >= 0)
|
| next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
|
|
|
| - AppendBuffersToEnd(range.buffers_);
|
| + AppendBuffersToEnd(range.buffers_, kNoDecodeTimestamp());
|
| }
|
|
|
| bool SourceBufferRange::CanAppendRangeToEnd(
|
| const SourceBufferRange& range) const {
|
| - return CanAppendBuffersToEnd(range.buffers_);
|
| + return CanAppendBuffersToEnd(range.buffers_, kNoDecodeTimestamp());
|
| }
|
|
|
| bool SourceBufferRange::CanAppendBuffersToEnd(
|
| - const BufferQueue& buffers) const {
|
| + const BufferQueue& buffers,
|
| + DecodeTimestamp new_buffers_group_start_timestamp) const {
|
| DCHECK(!buffers_.empty());
|
| - return IsNextInSequence(buffers.front()->GetDecodeTimestamp(),
|
| - buffers.front()->is_key_frame());
|
| + if (new_buffers_group_start_timestamp == kNoDecodeTimestamp()) {
|
| + return IsNextInSequence(buffers.front()->GetDecodeTimestamp());
|
| + }
|
| + DCHECK(new_buffers_group_start_timestamp >= GetEndTimestamp());
|
| + DCHECK(buffers.front()->GetDecodeTimestamp() >=
|
| + new_buffers_group_start_timestamp);
|
| + return IsNextInSequence(new_buffers_group_start_timestamp);
|
| }
|
|
|
| bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const {
|
| DCHECK(!buffers_.empty());
|
|
|
| - return (IsNextInSequence(timestamp, false) ||
|
| + return (IsNextInSequence(timestamp) ||
|
| (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
|
| }
|
|
|
| @@ -525,7 +539,7 @@ bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
|
|
|
| DecodeTimestamp SourceBufferRange::GetStartTimestamp() const {
|
| DCHECK(!buffers_.empty());
|
| - DecodeTimestamp start_timestamp = media_segment_start_time_;
|
| + DecodeTimestamp start_timestamp = range_start_time_;
|
| if (start_timestamp == kNoDecodeTimestamp())
|
| start_timestamp = buffers_.front()->GetDecodeTimestamp();
|
| return start_timestamp;
|
| @@ -555,11 +569,10 @@ DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp(
|
| if (itr == keyframe_map_.end())
|
| return kNoDecodeTimestamp();
|
|
|
| - // If the timestamp is inside the gap between the start of the media
|
| - // segment and the first buffer, then just pretend there is a
|
| - // keyframe at the specified timestamp.
|
| - if (itr == keyframe_map_.begin() &&
|
| - timestamp > media_segment_start_time_ &&
|
| + // If the timestamp is inside the gap between the start of the coded frame
|
| + // group and the first buffer, then just pretend there is a keyframe at the
|
| + // specified timestamp.
|
| + if (itr == keyframe_map_.begin() && timestamp > range_start_time_ &&
|
| timestamp < itr->first) {
|
| return timestamp;
|
| }
|
| @@ -577,17 +590,11 @@ DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp(
|
| return GetFirstKeyframeAtOrBefore(timestamp)->first;
|
| }
|
|
|
| -bool SourceBufferRange::IsNextInSequence(
|
| - DecodeTimestamp timestamp, bool is_key_frame) const {
|
| +bool SourceBufferRange::IsNextInSequence(DecodeTimestamp timestamp) const {
|
| DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp();
|
| - if (end < timestamp &&
|
| - (gap_policy_ == ALLOW_GAPS ||
|
| - timestamp <= end + GetFudgeRoom())) {
|
| - return true;
|
| - }
|
| -
|
| - return timestamp == end && AllowSameTimestamp(
|
| - buffers_.back()->is_key_frame(), is_key_frame);
|
| + return (end == timestamp ||
|
| + (end < timestamp &&
|
| + (gap_policy_ == ALLOW_GAPS || timestamp <= end + GetFudgeRoom())));
|
| }
|
|
|
| base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
|
|
|