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 = | |
1117 DecodeTimestamp::FromPresentationTime(duration); | |
1118 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" | 1166 DVLOG(1) << __func__ << " " << GetStreamTypeName() << " (" |
1119 << duration.InSecondsF() << ")"; | 1167 << duration.InSecondsF() << ")"; |
| 1168 DCHECK(!end_of_stream_); |
1120 | 1169 |
1121 RangeList::iterator itr = ranges_.end(); | 1170 if (ranges_.empty()) |
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; | 1171 return; |
1128 | 1172 |
1129 // Need to partially truncate this range. | 1173 DecodeTimestamp start = DecodeTimestamp::FromPresentationTime(duration); |
1130 if ((*itr)->GetStartTimestamp() < duration_dts) { | 1174 DecodeTimestamp end = ranges_.back()->GetBufferedEndTimestamp(); |
1131 bool delete_range = (*itr)->TruncateAt(duration_dts, NULL, false); | 1175 |
1132 if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition()) | 1176 // Trim the end if it exceeds the new duration. |
| 1177 if (start < end) { |
| 1178 BufferQueue deleted_buffers; |
| 1179 RemoveInternal(start, end, false, &deleted_buffers); |
| 1180 |
| 1181 if (!deleted_buffers.empty()) { |
| 1182 // Truncation removed current position. Clear selected range. |
1133 SetSelectedRange(NULL); | 1183 SetSelectedRange(NULL); |
1134 | |
1135 if (delete_range) { | |
1136 DeleteAndRemoveRange(&itr); | |
1137 } else { | |
1138 ++itr; | |
1139 } | 1184 } |
1140 } | 1185 } |
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 } | 1186 } |
1151 | 1187 |
1152 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1188 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1153 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1189 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1154 DVLOG(2) << __func__ << " " << GetStreamTypeName(); | 1190 DVLOG(2) << __func__ << " " << GetStreamTypeName(); |
1155 if (!pending_buffer_.get()) { | 1191 if (!pending_buffer_.get()) { |
1156 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1192 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
1157 if (status != SourceBufferStream::kSuccess || | 1193 if (status != SourceBufferStream::kSuccess || |
1158 !SetPendingBuffer(out_buffer)) { | 1194 !SetPendingBuffer(out_buffer)) { |
1159 DVLOG(2) << __func__ << " " << GetStreamTypeName() | 1195 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 | 1713 |
1678 DCHECK(*itr != ranges_.end()); | 1714 DCHECK(*itr != ranges_.end()); |
1679 if (**itr == selected_range_) { | 1715 if (**itr == selected_range_) { |
1680 DVLOG(1) << __func__ << " deleting selected range."; | 1716 DVLOG(1) << __func__ << " deleting selected range."; |
1681 SetSelectedRange(NULL); | 1717 SetSelectedRange(NULL); |
1682 } | 1718 } |
1683 | 1719 |
1684 if (*itr == range_for_next_append_) { | 1720 if (*itr == range_for_next_append_) { |
1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; | 1721 DVLOG(1) << __func__ << " deleting range_for_next_append_."; |
1686 range_for_next_append_ = ranges_.end(); | 1722 range_for_next_append_ = ranges_.end(); |
1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 1723 ResetLastAppendedState(); |
1688 last_appended_buffer_is_keyframe_ = false; | |
1689 } | 1724 } |
1690 | 1725 |
1691 delete **itr; | 1726 delete **itr; |
1692 *itr = ranges_.erase(*itr); | 1727 *itr = ranges_.erase(*itr); |
1693 } | 1728 } |
1694 | 1729 |
1695 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { | 1730 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { |
1696 DCHECK(!new_buffers.empty()); | 1731 DCHECK(!new_buffers.empty()); |
1697 | 1732 |
1698 // Splice frames are only supported for audio. | 1733 // Splice frames are only supported for audio. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 return false; | 1845 return false; |
1811 | 1846 |
1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1847 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1813 splice_buffers_index_ = 0; | 1848 splice_buffers_index_ = 0; |
1814 pending_buffer_.swap(*out_buffer); | 1849 pending_buffer_.swap(*out_buffer); |
1815 pending_buffers_complete_ = false; | 1850 pending_buffers_complete_ = false; |
1816 return true; | 1851 return true; |
1817 } | 1852 } |
1818 | 1853 |
1819 } // namespace media | 1854 } // namespace media |
OLD | NEW |