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 namespace media { | 9 namespace media { |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 AppendBuffersToEnd(new_buffers); | 41 AppendBuffersToEnd(new_buffers); |
42 } | 42 } |
43 | 43 |
44 SourceBufferRange::~SourceBufferRange() {} | 44 SourceBufferRange::~SourceBufferRange() {} |
45 | 45 |
46 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { | 46 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { |
47 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); | 47 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); |
48 DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() || | 48 DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() || |
49 media_segment_start_time_ <= | 49 media_segment_start_time_ <= |
50 new_buffers.front()->GetDecodeTimestamp()); | 50 new_buffers.front()->GetDecodeTimestamp()); |
| 51 |
| 52 AdjustEstimatedDurationForNewAppend(new_buffers); |
| 53 |
51 for (BufferQueue::const_iterator itr = new_buffers.begin(); | 54 for (BufferQueue::const_iterator itr = new_buffers.begin(); |
52 itr != new_buffers.end(); | 55 itr != new_buffers.end(); |
53 ++itr) { | 56 ++itr) { |
54 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); | 57 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); |
55 buffers_.push_back(*itr); | 58 buffers_.push_back(*itr); |
56 size_in_bytes_ += (*itr)->data_size(); | 59 size_in_bytes_ += (*itr)->data_size(); |
57 | 60 |
58 if ((*itr)->is_key_frame()) { | 61 if ((*itr)->is_key_frame()) { |
59 keyframe_map_.insert( | 62 keyframe_map_.insert( |
60 std::make_pair((*itr)->GetDecodeTimestamp(), | 63 std::make_pair((*itr)->GetDecodeTimestamp(), |
61 buffers_.size() - 1 + keyframe_map_index_base_)); | 64 buffers_.size() - 1 + keyframe_map_index_base_)); |
62 } | 65 } |
63 } | 66 } |
64 } | 67 } |
65 | 68 |
| 69 void SourceBufferRange::AdjustEstimatedDurationForNewAppend( |
| 70 const BufferQueue& new_buffers) { |
| 71 if (buffers_.empty() || new_buffers.empty()) { |
| 72 return; |
| 73 } |
| 74 |
| 75 // If the last of the previously appended buffers contains estimated duration, |
| 76 // we now refine that estimate by taking the PTS delta from the first new |
| 77 // buffer being appended. |
| 78 const auto& last_appended_buffer = buffers_.back(); |
| 79 if (last_appended_buffer->is_duration_estimated()) { |
| 80 base::TimeDelta timestamp_delta = |
| 81 new_buffers.front()->timestamp() - last_appended_buffer->timestamp(); |
| 82 DCHECK(timestamp_delta > base::TimeDelta()); |
| 83 if (last_appended_buffer->duration() != timestamp_delta) { |
| 84 DVLOG(1) << "Replacing estimated duration (" |
| 85 << last_appended_buffer->duration() |
| 86 << ") from previous range-end with derived duration (" |
| 87 << timestamp_delta << ")."; |
| 88 last_appended_buffer->set_duration(timestamp_delta); |
| 89 } |
| 90 } |
| 91 } |
| 92 |
66 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { | 93 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { |
67 DCHECK(CanSeekTo(timestamp)); | 94 DCHECK(CanSeekTo(timestamp)); |
68 DCHECK(!keyframe_map_.empty()); | 95 DCHECK(!keyframe_map_.empty()); |
69 | 96 |
70 KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp); | 97 KeyframeMap::iterator result = GetFirstKeyframeAtOrBefore(timestamp); |
71 next_buffer_index_ = result->second - keyframe_map_index_base_; | 98 next_buffer_index_ = result->second - keyframe_map_index_base_; |
72 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 99 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
73 } | 100 } |
74 | 101 |
75 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { | 102 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { |
76 SeekAhead(timestamp, false); | 103 SeekAhead(timestamp, false); |
77 } | 104 } |
78 | 105 |
79 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { | 106 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { |
80 SeekAhead(timestamp, true); | 107 SeekAhead(timestamp, true); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 | 193 |
167 SourceBufferRange::KeyframeMap::iterator | 194 SourceBufferRange::KeyframeMap::iterator |
168 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp, | 195 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp, |
169 bool skip_given_timestamp) { | 196 bool skip_given_timestamp) { |
170 return skip_given_timestamp ? | 197 return skip_given_timestamp ? |
171 keyframe_map_.upper_bound(timestamp) : | 198 keyframe_map_.upper_bound(timestamp) : |
172 keyframe_map_.lower_bound(timestamp); | 199 keyframe_map_.lower_bound(timestamp); |
173 } | 200 } |
174 | 201 |
175 SourceBufferRange::KeyframeMap::iterator | 202 SourceBufferRange::KeyframeMap::iterator |
176 SourceBufferRange::GetFirstKeyframeBefore(DecodeTimestamp timestamp) { | 203 SourceBufferRange::GetFirstKeyframeAtOrBefore(DecodeTimestamp timestamp) { |
177 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 204 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
178 // lower_bound() returns the first element >= |timestamp|, so we want the | 205 // lower_bound() returns the first element >= |timestamp|, so we want the |
179 // previous element if it did not return the element exactly equal to | 206 // previous element if it did not return the element exactly equal to |
180 // |timestamp|. | 207 // |timestamp|. |
181 if (result != keyframe_map_.begin() && | 208 if (result != keyframe_map_.begin() && |
182 (result == keyframe_map_.end() || result->first != timestamp)) { | 209 (result == keyframe_map_.end() || result->first != timestamp)) { |
183 --result; | 210 --result; |
184 } | 211 } |
185 return result; | 212 return result; |
186 } | 213 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 int bytes_to_free = total_bytes_to_free; | 306 int bytes_to_free = total_bytes_to_free; |
280 int bytes_removed = 0; | 307 int bytes_removed = 0; |
281 | 308 |
282 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); | 309 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); |
283 if (gop_itr == keyframe_map_.end()) | 310 if (gop_itr == keyframe_map_.end()) |
284 return 0; | 311 return 0; |
285 int keyframe_index = gop_itr->second - keyframe_map_index_base_; | 312 int keyframe_index = gop_itr->second - keyframe_map_index_base_; |
286 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; | 313 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; |
287 KeyframeMap::iterator gop_end = keyframe_map_.end(); | 314 KeyframeMap::iterator gop_end = keyframe_map_.end(); |
288 if (end_timestamp < GetBufferedEndTimestamp()) | 315 if (end_timestamp < GetBufferedEndTimestamp()) |
289 gop_end = GetFirstKeyframeBefore(end_timestamp); | 316 gop_end = GetFirstKeyframeAtOrBefore(end_timestamp); |
290 | 317 |
291 // Check if the removal range is within a GOP and skip the loop if so. | 318 // Check if the removal range is within a GOP and skip the loop if so. |
292 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] | 319 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] |
293 KeyframeMap::iterator gop_itr_prev = gop_itr; | 320 KeyframeMap::iterator gop_itr_prev = gop_itr; |
294 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) | 321 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) |
295 gop_end = gop_itr; | 322 gop_end = gop_itr; |
296 | 323 |
297 while (gop_itr != gop_end && bytes_to_free > 0) { | 324 while (gop_itr != gop_end && bytes_to_free > 0) { |
298 ++gop_itr; | 325 ++gop_itr; |
299 | 326 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 return itr->first; | 546 return itr->first; |
520 } | 547 } |
521 | 548 |
522 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( | 549 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( |
523 DecodeTimestamp timestamp) { | 550 DecodeTimestamp timestamp) { |
524 DCHECK(!keyframe_map_.empty()); | 551 DCHECK(!keyframe_map_.empty()); |
525 | 552 |
526 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 553 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
527 return kNoDecodeTimestamp(); | 554 return kNoDecodeTimestamp(); |
528 | 555 |
529 return GetFirstKeyframeBefore(timestamp)->first; | 556 return GetFirstKeyframeAtOrBefore(timestamp)->first; |
530 } | 557 } |
531 | 558 |
532 bool SourceBufferRange::IsNextInSequence( | 559 bool SourceBufferRange::IsNextInSequence( |
533 DecodeTimestamp timestamp, bool is_key_frame) const { | 560 DecodeTimestamp timestamp, bool is_key_frame) const { |
534 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); | 561 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); |
535 if (end < timestamp && | 562 if (end < timestamp && |
536 (gap_policy_ == ALLOW_GAPS || | 563 (gap_policy_ == ALLOW_GAPS || |
537 timestamp <= end + GetFudgeRoom())) { | 564 timestamp <= end + GetFudgeRoom())) { |
538 return true; | 565 return true; |
539 } | 566 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 } | 607 } |
581 | 608 |
582 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) | 609 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) |
583 continue; | 610 continue; |
584 buffers->push_back(buffer); | 611 buffers->push_back(buffer); |
585 } | 612 } |
586 return previous_size < buffers->size(); | 613 return previous_size < buffers->size(); |
587 } | 614 } |
588 | 615 |
589 } // namespace media | 616 } // namespace media |
OLD | NEW |