OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) | 26 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
27 return false; | 27 return false; |
28 prev = (*itr)->GetEndTimestamp(); | 28 prev = (*itr)->GetEndTimestamp(); |
29 } | 29 } |
30 return true; | 30 return true; |
31 } | 31 } |
32 | 32 |
33 // Returns an estimate of how far from the beginning or end of a range a buffer | 33 // Returns an estimate of how far from the beginning or end of a range a buffer |
34 // can be to still be considered in the range, given the |approximate_duration| | 34 // can be to still be considered in the range, given the |approximate_duration| |
35 // of a buffer in the stream. | 35 // of a buffer in the stream. |
| 36 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use |
| 37 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) |
| 38 // instead of an overall maximum interbuffer delta for range discontinuity |
| 39 // detection, and adjust similarly for splice frame discontinuity detection. |
| 40 // See http://crbug.com/351489 and http://crbug.com/351166. |
36 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { | 41 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { |
37 // Because we do not know exactly when is the next timestamp, any buffer | 42 // Because we do not know exactly when is the next timestamp, any buffer |
38 // that starts within 2x the approximate duration of a buffer is considered | 43 // that starts within 2x the approximate duration of a buffer is considered |
39 // within this range. | 44 // within this range. |
40 return 2 * approximate_duration; | 45 return 2 * approximate_duration; |
41 } | 46 } |
42 | 47 |
43 // An arbitrarily-chosen number to estimate the duration of a buffer if none | 48 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
44 // is set and there's not enough information to get a better estimate. | 49 // is set and there's not enough information to get a better estimate. |
45 static int kDefaultBufferDurationInMs = 125; | 50 static int kDefaultBufferDurationInMs = 125; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 147 |
143 SourceBufferStream::~SourceBufferStream() { | 148 SourceBufferStream::~SourceBufferStream() { |
144 while (!ranges_.empty()) { | 149 while (!ranges_.empty()) { |
145 delete ranges_.front(); | 150 delete ranges_.front(); |
146 ranges_.pop_front(); | 151 ranges_.pop_front(); |
147 } | 152 } |
148 } | 153 } |
149 | 154 |
150 void SourceBufferStream::OnNewMediaSegment( | 155 void SourceBufferStream::OnNewMediaSegment( |
151 DecodeTimestamp media_segment_start_time) { | 156 DecodeTimestamp media_segment_start_time) { |
| 157 DVLOG(1) << __FUNCTION__ << "(" << media_segment_start_time.InSecondsF() |
| 158 << ")"; |
152 DCHECK(!end_of_stream_); | 159 DCHECK(!end_of_stream_); |
153 media_segment_start_time_ = media_segment_start_time; | 160 media_segment_start_time_ = media_segment_start_time; |
154 new_media_segment_ = true; | 161 new_media_segment_ = true; |
155 | 162 |
156 RangeList::iterator last_range = range_for_next_append_; | 163 RangeList::iterator last_range = range_for_next_append_; |
157 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 164 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
158 | 165 |
159 // Only reset |last_appended_buffer_timestamp_| if this new media segment is | 166 // Only reset |last_appended_buffer_timestamp_| if this new media segment is |
160 // not adjacent to the previous media segment appended to the stream. | 167 // not adjacent to the previous media segment appended to the stream. |
161 if (range_for_next_append_ == ranges_.end() || | 168 if (range_for_next_append_ == ranges_.end() || |
162 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 169 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
163 media_segment_start_time)) { | 170 media_segment_start_time)) { |
164 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 171 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); |
165 last_appended_buffer_is_keyframe_ = false; | 172 last_appended_buffer_is_keyframe_ = false; |
| 173 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range"; |
166 } else if (last_range != ranges_.end()) { | 174 } else if (last_range != ranges_.end()) { |
167 DCHECK(last_range == range_for_next_append_); | 175 DCHECK(last_range == range_for_next_append_); |
| 176 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " |
| 177 << "unless intervening remove makes discontinuity"; |
168 } | 178 } |
169 } | 179 } |
170 | 180 |
171 bool SourceBufferStream::Append(const BufferQueue& buffers) { | 181 bool SourceBufferStream::Append(const BufferQueue& buffers) { |
172 TRACE_EVENT2("media", "SourceBufferStream::Append", | 182 TRACE_EVENT2("media", "SourceBufferStream::Append", |
173 "stream type", GetStreamTypeName(), | 183 "stream type", GetStreamTypeName(), |
174 "buffers to append", buffers.size()); | 184 "buffers to append", buffers.size()); |
175 | 185 |
176 DCHECK(!buffers.empty()); | 186 DCHECK(!buffers.empty()); |
177 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); | 187 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 | 506 |
497 void SourceBufferStream::UpdateMaxInterbufferDistance( | 507 void SourceBufferStream::UpdateMaxInterbufferDistance( |
498 const BufferQueue& buffers) { | 508 const BufferQueue& buffers) { |
499 DCHECK(!buffers.empty()); | 509 DCHECK(!buffers.empty()); |
500 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 510 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
501 for (BufferQueue::const_iterator itr = buffers.begin(); | 511 for (BufferQueue::const_iterator itr = buffers.begin(); |
502 itr != buffers.end(); ++itr) { | 512 itr != buffers.end(); ++itr) { |
503 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); | 513 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); |
504 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 514 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
505 | 515 |
| 516 base::TimeDelta interbuffer_distance = (*itr)->duration(); |
| 517 DCHECK(interbuffer_distance >= base::TimeDelta()); |
| 518 |
506 if (prev_timestamp != kNoDecodeTimestamp()) { | 519 if (prev_timestamp != kNoDecodeTimestamp()) { |
507 base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp; | 520 interbuffer_distance = |
| 521 std::max(current_timestamp - prev_timestamp, interbuffer_distance); |
| 522 } |
| 523 |
| 524 if (interbuffer_distance > base::TimeDelta()) { |
508 if (max_interbuffer_distance_ == kNoTimestamp()) { | 525 if (max_interbuffer_distance_ == kNoTimestamp()) { |
509 max_interbuffer_distance_ = interbuffer_distance; | 526 max_interbuffer_distance_ = interbuffer_distance; |
510 } else { | 527 } else { |
511 max_interbuffer_distance_ = | 528 max_interbuffer_distance_ = |
512 std::max(max_interbuffer_distance_, interbuffer_distance); | 529 std::max(max_interbuffer_distance_, interbuffer_distance); |
513 } | 530 } |
514 } | 531 } |
515 prev_timestamp = current_timestamp; | 532 prev_timestamp = current_timestamp; |
516 } | 533 } |
517 } | 534 } |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 return false; | 1471 return false; |
1455 | 1472 |
1456 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1473 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1457 splice_buffers_index_ = 0; | 1474 splice_buffers_index_ = 0; |
1458 pending_buffer_.swap(*out_buffer); | 1475 pending_buffer_.swap(*out_buffer); |
1459 pending_buffers_complete_ = false; | 1476 pending_buffers_complete_ = false; |
1460 return true; | 1477 return true; |
1461 } | 1478 } |
1462 | 1479 |
1463 } // namespace media | 1480 } // namespace media |
OLD | NEW |