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 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 new_coded_frame_group_ = true; | 200 new_coded_frame_group_ = true; |
201 | 201 |
202 RangeList::iterator last_range = range_for_next_append_; | 202 RangeList::iterator last_range = range_for_next_append_; |
203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time); | 203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time); |
204 | 204 |
205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group | 205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group |
206 // is not adjacent to the previous coded frame group appended to the stream. | 206 // is not adjacent to the previous coded frame group appended to the stream. |
207 if (range_for_next_append_ == ranges_.end() || | 207 if (range_for_next_append_ == ranges_.end() || |
208 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 208 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
209 coded_frame_group_start_time)) { | 209 coded_frame_group_start_time)) { |
210 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 210 ResetLastAppendedState(); |
211 last_appended_buffer_duration_ = kNoTimestamp; | |
212 last_appended_buffer_is_keyframe_ = false; | |
213 DVLOG(3) << __func__ << " next appended buffers will " | 211 DVLOG(3) << __func__ << " next appended buffers will " |
214 << (range_for_next_append_ == ranges_.end() | 212 << (range_for_next_append_ == ranges_.end() |
215 ? "be in a new range" | 213 ? "be in a new range" |
216 : "overlap an existing range"); | 214 : "overlap an existing range"); |
217 } else if (last_range != ranges_.end()) { | 215 } else if (last_range != ranges_.end()) { |
218 DCHECK(last_range == range_for_next_append_); | 216 DCHECK(last_range == range_for_next_append_); |
219 DVLOG(3) << __func__ << " next appended buffers will continue range unless " | 217 DVLOG(3) << __func__ << " next appended buffers will continue range unless " |
220 << "intervening remove makes discontinuity"; | 218 << "intervening remove makes discontinuity"; |
221 } | 219 } |
222 } | 220 } |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 if (new_coded_frame_group_) | 445 if (new_coded_frame_group_) |
448 return coded_frame_group_start_time_; | 446 return coded_frame_group_start_time_; |
449 | 447 |
450 // If we still don't know a potential next append timestamp, then we have | 448 // If we still don't know a potential next append timestamp, then we have |
451 // removed the ranged to which it previously belonged and have not completed a | 449 // removed the ranged to which it previously belonged and have not completed a |
452 // subsequent append or received a subsequent OnStartOfCodedFrameGroup() | 450 // subsequent append or received a subsequent OnStartOfCodedFrameGroup() |
453 // signal. | 451 // signal. |
454 return kNoDecodeTimestamp(); | 452 return kNoDecodeTimestamp(); |
455 } | 453 } |
456 | 454 |
455 void SourceBufferStream::UpdateLastAppendStateForRemove( | |
456 DecodeTimestamp remove_start, | |
457 DecodeTimestamp remove_end, | |
458 bool exclude_start) { | |
459 // TODO(chcunningham): change exclude_start to include_start in this class and | |
460 // SourceBufferRange. Negatives are hard to reason about. | |
461 bool include_start = !exclude_start; | |
462 | |
463 // No need to check previous append's GOP if starting a new CFG. New CFG is | |
464 // already required to begin with a key frame. | |
465 if (new_coded_frame_group_) | |
466 return; | |
467 | |
468 if (range_for_next_append_ != ranges_.end()) { | |
469 if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) { | |
470 DCHECK((*range_for_next_append_) | |
471 ->BelongsToRange(last_appended_buffer_timestamp_)); | |
472 | |
473 // Note start and end of last appended GOP. | |
474 DecodeTimestamp gop_end = last_appended_buffer_timestamp_; | |
475 DecodeTimestamp gop_start = | |
476 (*range_for_next_append_)->KeyframeBeforeTimestamp(gop_end); | |
477 | |
478 // If last append is about to be disrupted, reset associated state so we | |
479 // know to create a new range for future appends and require an initial | |
480 // key frame. | |
481 if (((include_start && remove_start == gop_end) || | |
482 remove_start < gop_end) && | |
483 remove_end > gop_start) { | |
484 DVLOG(2) << __func__ << " " << GetStreamTypeName() | |
485 << " Resetting next append state for remove (" | |
486 << remove_start.InSecondsF() << ", " << remove_end.InSecondsF() | |
487 << ", " << exclude_start << ")"; | |
488 range_for_next_append_ = ranges_.end(); | |
489 ResetLastAppendedState(); | |
490 } | |
491 } else { | |
492 NOTREACHED() << __func__ << " " << GetStreamTypeName() | |
493 << " range_for_next_append_ set, but not tracking last" | |
494 << " append nor new coded frame group."; | |
495 } | |
496 } | |
497 } | |
498 | |
457 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, | 499 void SourceBufferStream::RemoveInternal(DecodeTimestamp start, |
458 DecodeTimestamp end, | 500 DecodeTimestamp end, |
459 bool exclude_start, | 501 bool exclude_start, |
460 BufferQueue* deleted_buffers) { | 502 BufferQueue* deleted_buffers) { |
461 DVLOG(2) << __func__ << " " << GetStreamTypeName() << " (" | 503 DVLOG(2) << __func__ << " " << GetStreamTypeName() << " (" |
462 << start.InSecondsF() << ", " << end.InSecondsF() << ", " | 504 << start.InSecondsF() << ", " << end.InSecondsF() << ", " |
463 << exclude_start << ")"; | 505 << exclude_start << ")"; |
464 DVLOG(3) << __func__ << " " << GetStreamTypeName() | 506 DVLOG(3) << __func__ << " " << GetStreamTypeName() |
465 << ": before remove ranges_=" << RangesToString(ranges_); | 507 << ": before remove ranges_=" << RangesToString(ranges_); |
466 | 508 |
467 DCHECK(start >= DecodeTimestamp()); | 509 DCHECK(start >= DecodeTimestamp()); |
468 DCHECK(start < end) << "start " << start.InSecondsF() | 510 DCHECK(start < end) << "start " << start.InSecondsF() |
469 << " end " << end.InSecondsF(); | 511 << " end " << end.InSecondsF(); |
470 DCHECK(deleted_buffers); | 512 DCHECK(deleted_buffers); |
471 | 513 |
514 // Doing this upfront simplifies decisions about range_for_next_append_ below. | |
515 UpdateLastAppendStateForRemove(start, end, exclude_start); | |
516 | |
472 RangeList::iterator itr = ranges_.begin(); | 517 RangeList::iterator itr = ranges_.begin(); |
473 | |
474 while (itr != ranges_.end()) { | 518 while (itr != ranges_.end()) { |
475 SourceBufferRange* range = *itr; | 519 SourceBufferRange* range = *itr; |
476 if (range->GetStartTimestamp() >= end) | 520 if (range->GetStartTimestamp() >= end) |
477 break; | 521 break; |
478 | 522 |
479 // Split off any remaining GOPs starting at or after |end| and add it to | 523 // Split off any remaining GOPs starting at or after |end| and add it to |
480 // |ranges_|. | 524 // |ranges_|. |
481 SourceBufferRange* new_range = range->SplitRange(end); | 525 SourceBufferRange* new_range = range->SplitRange(end); |
482 if (new_range) { | 526 if (new_range) { |
483 itr = ranges_.insert(++itr, new_range); | 527 itr = ranges_.insert(++itr, new_range); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 SetSelectedRange(NULL); | 601 SetSelectedRange(NULL); |
558 track_buffer_.clear(); | 602 track_buffer_.clear(); |
559 config_change_pending_ = false; | 603 config_change_pending_ = false; |
560 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); | 604 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); |
561 just_exhausted_track_buffer_ = false; | 605 just_exhausted_track_buffer_ = false; |
562 splice_buffers_index_ = 0; | 606 splice_buffers_index_ = 0; |
563 pending_buffer_ = NULL; | 607 pending_buffer_ = NULL; |
564 pending_buffers_complete_ = false; | 608 pending_buffers_complete_ = false; |
565 } | 609 } |
566 | 610 |
611 void SourceBufferStream::ResetLastAppendedState() { | |
612 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | |
613 last_appended_buffer_duration_ = kNoTimestamp; | |
614 last_appended_buffer_is_keyframe_ = false; | |
615 } | |
616 | |
567 bool SourceBufferStream::ShouldSeekToStartOfBuffered( | 617 bool SourceBufferStream::ShouldSeekToStartOfBuffered( |
568 base::TimeDelta seek_timestamp) const { | 618 base::TimeDelta seek_timestamp) const { |
569 if (ranges_.empty()) | 619 if (ranges_.empty()) |
570 return false; | 620 return false; |
571 base::TimeDelta beginning_of_buffered = | 621 base::TimeDelta beginning_of_buffered = |
572 ranges_.front()->GetStartTimestamp().ToPresentationTime(); | 622 ranges_.front()->GetStartTimestamp().ToPresentationTime(); |
573 return (seek_timestamp <= beginning_of_buffered && | 623 return (seek_timestamp <= beginning_of_buffered && |
574 beginning_of_buffered < kSeekToStartFudgeRoom()); | 624 beginning_of_buffered < kSeekToStartFudgeRoom()); |
575 } | 625 } |
576 | 626 |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1106 | 1156 |
1107 SeekAndSetSelectedRange(*itr, seek_dts); | 1157 SeekAndSetSelectedRange(*itr, seek_dts); |
1108 seek_pending_ = false; | 1158 seek_pending_ = false; |
1109 } | 1159 } |
1110 | 1160 |
1111 bool SourceBufferStream::IsSeekPending() const { | 1161 bool SourceBufferStream::IsSeekPending() const { |
1112 return seek_pending_ && !IsEndOfStreamReached(); | 1162 return seek_pending_ && !IsEndOfStreamReached(); |
1113 } | 1163 } |
1114 | 1164 |
1115 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { | 1165 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) { |
1116 DecodeTimestamp duration_dts = | 1166 if (ranges_.empty()) |
wolenetz
2016/10/05 22:41:09
nit: why remove the DVLOG? Maybe retain it but wit
chcunningham
2016/10/06 21:57:33
Added back.
| |
1117 DecodeTimestamp::FromPresentationTime(duration); | |
1118 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" | |
1119 << duration.InSecondsF() << ")"; | |
1120 | |
1121 RangeList::iterator itr = ranges_.end(); | |
1122 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { | |
1123 if ((*itr)->GetEndTimestamp() > duration_dts) | |
1124 break; | |
1125 } | |
1126 if (itr == ranges_.end()) | |
1127 return; | 1167 return; |
1128 | 1168 |
1129 // Need to partially truncate this range. | 1169 DecodeTimestamp start = DecodeTimestamp::FromPresentationTime(duration); |
1130 if ((*itr)->GetStartTimestamp() < duration_dts) { | 1170 DecodeTimestamp end = ranges_.back()->GetBufferedEndTimestamp(); |
1131 bool delete_range = (*itr)->TruncateAt(duration_dts, NULL, false); | 1171 |
1132 if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition()) | 1172 // Trim the end if it exceeds the new duration. |
1173 if (start < end) { | |
wolenetz
2016/10/05 22:41:09
aside: this truncate-on-duration-reduction behavio
chcunningham
2016/10/06 21:57:32
Acknowledged.
| |
1174 BufferQueue deleted_buffers; | |
1175 RemoveInternal(start, end, false, &deleted_buffers); | |
1176 | |
1177 if (!deleted_buffers.empty()) { | |
1178 // Truncation removed current seek position. Clear selected range. | |
wolenetz
2016/10/05 22:41:09
nit: let's be careful not to confuse seek position
chcunningham
2016/10/06 21:57:32
Done.
| |
1133 SetSelectedRange(NULL); | 1179 SetSelectedRange(NULL); |
1134 | |
1135 if (delete_range) { | |
1136 DeleteAndRemoveRange(&itr); | |
1137 } else { | |
1138 ++itr; | |
1139 } | 1180 } |
1140 } | 1181 } |
1141 | |
1142 // Delete all ranges that begin after |duration_dts|. | |
1143 while (itr != ranges_.end()) { | |
1144 // If we're about to delete the selected range, also reset the seek state. | |
1145 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); | |
1146 if (*itr == selected_range_) | |
1147 ResetSeekState(); | |
1148 DeleteAndRemoveRange(&itr); | |
1149 } | |
1150 } | 1182 } |
1151 | 1183 |
1152 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1184 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1153 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1185 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1154 DVLOG(2) << __func__ << " " << GetStreamTypeName(); | 1186 DVLOG(2) << __func__ << " " << GetStreamTypeName(); |
1155 if (!pending_buffer_.get()) { | 1187 if (!pending_buffer_.get()) { |
1156 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1188 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
1157 if (status != SourceBufferStream::kSuccess || | 1189 if (status != SourceBufferStream::kSuccess || |
1158 !SetPendingBuffer(out_buffer)) { | 1190 !SetPendingBuffer(out_buffer)) { |
1159 DVLOG(2) << __func__ << " " << GetStreamTypeName() | 1191 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1677 | 1709 |
1678 DCHECK(*itr != ranges_.end()); | 1710 DCHECK(*itr != ranges_.end()); |
1679 if (**itr == selected_range_) { | 1711 if (**itr == selected_range_) { |
1680 DVLOG(1) << __func__ << " deleting selected range."; | 1712 DVLOG(1) << __func__ << " deleting selected range."; |
1681 SetSelectedRange(NULL); | 1713 SetSelectedRange(NULL); |
1682 } | 1714 } |
1683 | 1715 |
1684 if (*itr == range_for_next_append_) { | 1716 if (*itr == range_for_next_append_) { |
1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; | 1717 DVLOG(1) << __func__ << " deleting range_for_next_append_."; |
1686 range_for_next_append_ = ranges_.end(); | 1718 range_for_next_append_ = ranges_.end(); |
1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 1719 ResetLastAppendedState(); |
1688 last_appended_buffer_is_keyframe_ = false; | |
1689 } | 1720 } |
1690 | 1721 |
1691 delete **itr; | 1722 delete **itr; |
1692 *itr = ranges_.erase(*itr); | 1723 *itr = ranges_.erase(*itr); |
1693 } | 1724 } |
1694 | 1725 |
1695 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { | 1726 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { |
1696 DCHECK(!new_buffers.empty()); | 1727 DCHECK(!new_buffers.empty()); |
1697 | 1728 |
1698 // Splice frames are only supported for audio. | 1729 // Splice frames are only supported for audio. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1810 return false; | 1841 return false; |
1811 | 1842 |
1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1843 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1813 splice_buffers_index_ = 0; | 1844 splice_buffers_index_ = 0; |
1814 pending_buffer_.swap(*out_buffer); | 1845 pending_buffer_.swap(*out_buffer); |
1815 pending_buffers_complete_ = false; | 1846 pending_buffers_complete_ = false; |
1816 return true; | 1847 return true; |
1817 } | 1848 } |
1818 | 1849 |
1819 } // namespace media | 1850 } // namespace media |
OLD | NEW |