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( | |
wolenetz
2015/03/28 00:26:06
Does adjustment to duration correctly include when
chcunningham
2015/04/13 23:25:17
This is a great question and I've given it a lot o
wolenetz
2015/04/15 02:55:23
I agree.
| |
70 const BufferQueue& new_buffers) { | |
71 if (buffers_.empty() || new_buffers.empty()) { | |
wolenetz
2015/03/28 00:26:06
nit: Change call to only occur when buffers_ is no
chcunningham
2015/04/13 23:25:18
Let me push back a little here (or at least argue
wolenetz
2015/04/15 02:55:23
That's fine. If this method really needed to requi
| |
72 return; | |
73 } | |
74 | |
75 // Only adjust the last of the previously appended buffers. The last buffer | |
wolenetz
2015/03/28 00:26:05
nit: s/buffers./buffers if its duration was previo
chcunningham
2015/04/13 23:25:17
Done.
| |
76 // in a given append is an edge case where the parsers (upstream) cannot know | |
77 // the implicit PTS-delta duration because the do not know the PTS of the | |
wolenetz
2015/03/28 00:26:05
nit: s/because the/because they/.. Actually, is th
chcunningham
2015/04/13 23:25:17
Done. Changed a little from what you wrote, but di
| |
78 // frame that may follow the last for that append. The PTS of this new append | |
79 // supplies the missing information for a better duration estimate. | |
80 scoped_refptr<StreamParserBuffer> last_appended_buffer = buffers_.back(); | |
wolenetz
2015/03/28 00:26:05
nit: const& the smart pointer to reduce unnecessar
chcunningham
2015/04/13 23:25:18
Done. Made auto too.
| |
81 if (last_appended_buffer->is_duration_estimated()) { | |
82 base::TimeDelta timestamp_delta = | |
83 new_buffers.front()->timestamp() - last_appended_buffer->timestamp(); | |
84 if (last_appended_buffer->duration() != timestamp_delta) { | |
85 DVLOG(1) << "Replacing estimated duration (" | |
86 << last_appended_buffer->duration() | |
87 << ") from last append with derived duration (" | |
wolenetz
2015/03/28 00:26:06
nit: may not have been from "last" append.
chcunningham
2015/04/13 23:25:17
Done. Now reads "Replacing estimated duration (X)
| |
88 << timestamp_delta << ")."; | |
89 last_appended_buffer->set_duration(timestamp_delta); | |
90 } | |
91 } | |
92 } | |
93 | |
66 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { | 94 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { |
67 DCHECK(CanSeekTo(timestamp)); | 95 DCHECK(CanSeekTo(timestamp)); |
68 DCHECK(!keyframe_map_.empty()); | 96 DCHECK(!keyframe_map_.empty()); |
69 | 97 |
70 KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp); | 98 KeyframeMap::iterator result = GetFirstKeyframeAtOrBefore(timestamp); |
71 next_buffer_index_ = result->second - keyframe_map_index_base_; | 99 next_buffer_index_ = result->second - keyframe_map_index_base_; |
72 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 100 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
73 } | 101 } |
74 | 102 |
75 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { | 103 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { |
76 SeekAhead(timestamp, false); | 104 SeekAhead(timestamp, false); |
77 } | 105 } |
78 | 106 |
79 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { | 107 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { |
80 SeekAhead(timestamp, true); | 108 SeekAhead(timestamp, true); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 | 196 |
169 SourceBufferRange::KeyframeMap::iterator | 197 SourceBufferRange::KeyframeMap::iterator |
170 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp, | 198 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp, |
171 bool skip_given_timestamp) { | 199 bool skip_given_timestamp) { |
172 return skip_given_timestamp ? | 200 return skip_given_timestamp ? |
173 keyframe_map_.upper_bound(timestamp) : | 201 keyframe_map_.upper_bound(timestamp) : |
174 keyframe_map_.lower_bound(timestamp); | 202 keyframe_map_.lower_bound(timestamp); |
175 } | 203 } |
176 | 204 |
177 SourceBufferRange::KeyframeMap::iterator | 205 SourceBufferRange::KeyframeMap::iterator |
178 SourceBufferRange::GetFirstKeyframeBefore(DecodeTimestamp timestamp) { | 206 SourceBufferRange::GetFirstKeyframeAtOrBefore(DecodeTimestamp timestamp) { |
179 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 207 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
180 // lower_bound() returns the first element >= |timestamp|, so we want the | 208 // lower_bound() returns the first element >= |timestamp|, so we want the |
181 // previous element if it did not return the element exactly equal to | 209 // previous element if it did not return the element exactly equal to |
182 // |timestamp|. | 210 // |timestamp|. |
183 if (result != keyframe_map_.begin() && | 211 if (result != keyframe_map_.begin() && |
184 (result == keyframe_map_.end() || result->first != timestamp)) { | 212 (result == keyframe_map_.end() || result->first != timestamp)) { |
185 --result; | 213 --result; |
186 } | 214 } |
187 return result; | 215 return result; |
188 } | 216 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 int bytes_to_free = total_bytes_to_free; | 309 int bytes_to_free = total_bytes_to_free; |
282 int bytes_removed = 0; | 310 int bytes_removed = 0; |
283 | 311 |
284 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); | 312 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); |
285 if (gop_itr == keyframe_map_.end()) | 313 if (gop_itr == keyframe_map_.end()) |
286 return 0; | 314 return 0; |
287 int keyframe_index = gop_itr->second - keyframe_map_index_base_; | 315 int keyframe_index = gop_itr->second - keyframe_map_index_base_; |
288 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; | 316 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; |
289 KeyframeMap::iterator gop_end = keyframe_map_.end(); | 317 KeyframeMap::iterator gop_end = keyframe_map_.end(); |
290 if (end_timestamp < GetBufferedEndTimestamp()) | 318 if (end_timestamp < GetBufferedEndTimestamp()) |
291 gop_end = GetFirstKeyframeBefore(end_timestamp); | 319 gop_end = GetFirstKeyframeAtOrBefore(end_timestamp); |
292 | 320 |
293 // Check if the removal range is within a GOP and skip the loop if so. | 321 // Check if the removal range is within a GOP and skip the loop if so. |
294 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] | 322 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] |
295 KeyframeMap::iterator gop_itr_prev = gop_itr; | 323 KeyframeMap::iterator gop_itr_prev = gop_itr; |
296 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) | 324 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) |
297 gop_end = gop_itr; | 325 gop_end = gop_itr; |
298 | 326 |
299 while (gop_itr != gop_end && bytes_to_free > 0) { | 327 while (gop_itr != gop_end && bytes_to_free > 0) { |
300 ++gop_itr; | 328 ++gop_itr; |
301 | 329 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 return itr->first; | 549 return itr->first; |
522 } | 550 } |
523 | 551 |
524 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( | 552 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( |
525 DecodeTimestamp timestamp) { | 553 DecodeTimestamp timestamp) { |
526 DCHECK(!keyframe_map_.empty()); | 554 DCHECK(!keyframe_map_.empty()); |
527 | 555 |
528 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 556 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
529 return kNoDecodeTimestamp(); | 557 return kNoDecodeTimestamp(); |
530 | 558 |
531 return GetFirstKeyframeBefore(timestamp)->first; | 559 return GetFirstKeyframeAtOrBefore(timestamp)->first; |
532 } | 560 } |
533 | 561 |
534 bool SourceBufferRange::IsNextInSequence( | 562 bool SourceBufferRange::IsNextInSequence( |
535 DecodeTimestamp timestamp, bool is_key_frame) const { | 563 DecodeTimestamp timestamp, bool is_key_frame) const { |
536 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); | 564 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); |
537 if (end < timestamp && | 565 if (end < timestamp && |
538 (gap_policy_ == ALLOW_GAPS || | 566 (gap_policy_ == ALLOW_GAPS || |
539 timestamp <= end + GetFudgeRoom())) { | 567 timestamp <= end + GetFudgeRoom())) { |
540 return true; | 568 return true; |
541 } | 569 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
582 } | 610 } |
583 | 611 |
584 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) | 612 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) |
585 continue; | 613 continue; |
586 buffers->push_back(buffer); | 614 buffers->push_back(buffer); |
587 } | 615 } |
588 return previous_size < buffers->size(); | 616 return previous_size < buffers->size(); |
589 } | 617 } |
590 | 618 |
591 } // namespace media | 619 } // namespace media |
OLD | NEW |