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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 // Returns the timestamp of the last buffer in the range. | 161 // Returns the timestamp of the last buffer in the range. |
162 base::TimeDelta GetEndTimestamp() const; | 162 base::TimeDelta GetEndTimestamp() const; |
163 | 163 |
164 // Returns the timestamp for the end of the buffered region in this range. | 164 // Returns the timestamp for the end of the buffered region in this range. |
165 // This is an approximation if the duration for the last buffer in the range | 165 // This is an approximation if the duration for the last buffer in the range |
166 // is unset. | 166 // is unset. |
167 base::TimeDelta GetBufferedEndTimestamp() const; | 167 base::TimeDelta GetBufferedEndTimestamp() const; |
168 | 168 |
169 // Gets the timestamp for the keyframe that is after |timestamp|. If | 169 // Gets the timestamp for the keyframe that is after |timestamp|. If |
170 // there isn't a keyframe in the range after |timestamp| then kNoTimestamp() | 170 // there isn't a keyframe in the range after |timestamp| then kNoTimestamp() |
171 // is returned. | 171 // is returned. If |timestamp| is in the "gap" between the value returned by |
| 172 // GetStartTimestamp() and the timestamp on the first buffer in |buffers_|, |
| 173 // then |timestamp| is returned. |
172 base::TimeDelta NextKeyframeTimestamp(base::TimeDelta timestamp); | 174 base::TimeDelta NextKeyframeTimestamp(base::TimeDelta timestamp); |
173 | 175 |
174 // Gets the timestamp for the closest keyframe that is <= |timestamp|. If | 176 // Gets the timestamp for the closest keyframe that is <= |timestamp|. If |
175 // there isn't a keyframe before |timestamp| or |timestamp| is outside | 177 // there isn't a keyframe before |timestamp| or |timestamp| is outside |
176 // this range, then kNoTimestamp() is returned. | 178 // this range, then kNoTimestamp() is returned. |
177 base::TimeDelta KeyframeBeforeTimestamp(base::TimeDelta timestamp); | 179 base::TimeDelta KeyframeBeforeTimestamp(base::TimeDelta timestamp); |
178 | 180 |
179 // Returns whether a buffer with a starting timestamp of |timestamp| would | 181 // Returns whether a buffer with a starting timestamp of |timestamp| would |
180 // belong in this range. This includes a buffer that would be appended to | 182 // belong in this range. This includes a buffer that would be appended to |
181 // the end of the range. | 183 // the end of the range. |
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 SourceBufferRange::SourceBufferRange( | 1702 SourceBufferRange::SourceBufferRange( |
1701 SourceBufferStream::Type type, const BufferQueue& new_buffers, | 1703 SourceBufferStream::Type type, const BufferQueue& new_buffers, |
1702 base::TimeDelta media_segment_start_time, | 1704 base::TimeDelta media_segment_start_time, |
1703 const InterbufferDistanceCB& interbuffer_distance_cb) | 1705 const InterbufferDistanceCB& interbuffer_distance_cb) |
1704 : type_(type), | 1706 : type_(type), |
1705 keyframe_map_index_base_(0), | 1707 keyframe_map_index_base_(0), |
1706 next_buffer_index_(-1), | 1708 next_buffer_index_(-1), |
1707 media_segment_start_time_(media_segment_start_time), | 1709 media_segment_start_time_(media_segment_start_time), |
1708 interbuffer_distance_cb_(interbuffer_distance_cb), | 1710 interbuffer_distance_cb_(interbuffer_distance_cb), |
1709 size_in_bytes_(0) { | 1711 size_in_bytes_(0) { |
1710 DCHECK(!new_buffers.empty()); | 1712 CHECK(!new_buffers.empty()); |
1711 DCHECK(new_buffers.front()->IsKeyframe()); | 1713 DCHECK(new_buffers.front()->IsKeyframe()); |
1712 DCHECK(!interbuffer_distance_cb.is_null()); | 1714 DCHECK(!interbuffer_distance_cb.is_null()); |
1713 AppendBuffersToEnd(new_buffers); | 1715 AppendBuffersToEnd(new_buffers); |
1714 } | 1716 } |
1715 | 1717 |
1716 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { | 1718 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { |
1717 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); | 1719 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); |
1718 DCHECK(media_segment_start_time_ == kNoTimestamp() || | 1720 DCHECK(media_segment_start_time_ == kNoTimestamp() || |
1719 media_segment_start_time_ <= | 1721 media_segment_start_time_ <= |
1720 new_buffers.front()->GetDecodeTimestamp()); | 1722 new_buffers.front()->GetDecodeTimestamp()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 1769 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
1768 } | 1770 } |
1769 | 1771 |
1770 void SourceBufferRange::SeekToStart() { | 1772 void SourceBufferRange::SeekToStart() { |
1771 DCHECK(!buffers_.empty()); | 1773 DCHECK(!buffers_.empty()); |
1772 next_buffer_index_ = 0; | 1774 next_buffer_index_ = 0; |
1773 } | 1775 } |
1774 | 1776 |
1775 SourceBufferRange* SourceBufferRange::SplitRange( | 1777 SourceBufferRange* SourceBufferRange::SplitRange( |
1776 base::TimeDelta timestamp, bool is_exclusive) { | 1778 base::TimeDelta timestamp, bool is_exclusive) { |
| 1779 CHECK(!buffers_.empty()); |
| 1780 |
1777 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not | 1781 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not |
1778 // include keyframes at |timestamp|. | 1782 // include keyframes at |timestamp|. |
1779 KeyframeMap::iterator new_beginning_keyframe = | 1783 KeyframeMap::iterator new_beginning_keyframe = |
1780 GetFirstKeyframeAt(timestamp, is_exclusive); | 1784 GetFirstKeyframeAt(timestamp, is_exclusive); |
1781 | 1785 |
1782 // If there is no keyframe after |timestamp|, we can't split the range. | 1786 // If there is no keyframe after |timestamp|, we can't split the range. |
1783 if (new_beginning_keyframe == keyframe_map_.end()) | 1787 if (new_beginning_keyframe == keyframe_map_.end()) |
1784 return NULL; | 1788 return NULL; |
1785 | 1789 |
1786 // Remove the data beginning at |keyframe_index| from |buffers_| and save it | 1790 // Remove the data beginning at |keyframe_index| from |buffers_| and save it |
1787 // into |removed_buffers|. | 1791 // into |removed_buffers|. |
1788 int keyframe_index = | 1792 int keyframe_index = |
1789 new_beginning_keyframe->second - keyframe_map_index_base_; | 1793 new_beginning_keyframe->second - keyframe_map_index_base_; |
1790 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); | 1794 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
1791 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; | 1795 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; |
1792 BufferQueue removed_buffers(starting_point, buffers_.end()); | 1796 BufferQueue removed_buffers(starting_point, buffers_.end()); |
| 1797 |
| 1798 base::TimeDelta new_range_start_timestamp = kNoTimestamp(); |
| 1799 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() && |
| 1800 timestamp < removed_buffers.front()->GetDecodeTimestamp()) { |
| 1801 // The split is in the gap between |media_segment_start_time_| and |
| 1802 // the first buffer of the new range so we should set the start |
| 1803 // time of the new range to |timestamp| so we preserve part of the |
| 1804 // gap in the new range. |
| 1805 new_range_start_timestamp = timestamp; |
| 1806 } |
| 1807 |
1793 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); | 1808 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); |
1794 FreeBufferRange(starting_point, buffers_.end()); | 1809 FreeBufferRange(starting_point, buffers_.end()); |
1795 | 1810 |
1796 // Create a new range with |removed_buffers|. | 1811 // Create a new range with |removed_buffers|. |
1797 SourceBufferRange* split_range = | 1812 SourceBufferRange* split_range = |
1798 new SourceBufferRange( | 1813 new SourceBufferRange( |
1799 type_, removed_buffers, kNoTimestamp(), interbuffer_distance_cb_); | 1814 type_, removed_buffers, new_range_start_timestamp, |
| 1815 interbuffer_distance_cb_); |
1800 | 1816 |
1801 // If the next buffer position is now in |split_range|, update the state of | 1817 // If the next buffer position is now in |split_range|, update the state of |
1802 // this range and |split_range| accordingly. | 1818 // this range and |split_range| accordingly. |
1803 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 1819 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
1804 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; | 1820 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; |
1805 ResetNextBufferPosition(); | 1821 ResetNextBufferPosition(); |
1806 } | 1822 } |
1807 | 1823 |
1808 return split_range; | 1824 return split_range; |
1809 } | 1825 } |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 } | 2024 } |
2009 buffers_.erase(starting_point, ending_point); | 2025 buffers_.erase(starting_point, ending_point); |
2010 } | 2026 } |
2011 | 2027 |
2012 bool SourceBufferRange::TruncateAt( | 2028 bool SourceBufferRange::TruncateAt( |
2013 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { | 2029 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { |
2014 DCHECK(!removed_buffers || removed_buffers->empty()); | 2030 DCHECK(!removed_buffers || removed_buffers->empty()); |
2015 | 2031 |
2016 // Return if we're not deleting anything. | 2032 // Return if we're not deleting anything. |
2017 if (starting_point == buffers_.end()) | 2033 if (starting_point == buffers_.end()) |
2018 return false; | 2034 return buffers_.empty(); |
2019 | 2035 |
2020 // Reset the next buffer index if we will be deleting the buffer that's next | 2036 // Reset the next buffer index if we will be deleting the buffer that's next |
2021 // in sequence. | 2037 // in sequence. |
2022 if (HasNextBufferPosition()) { | 2038 if (HasNextBufferPosition()) { |
2023 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); | 2039 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); |
2024 if (next_buffer_timestamp == kNoTimestamp() || | 2040 if (next_buffer_timestamp == kNoTimestamp() || |
2025 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { | 2041 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { |
2026 if (HasNextBuffer() && removed_buffers) { | 2042 if (HasNextBuffer() && removed_buffers) { |
2027 int starting_offset = starting_point - buffers_.begin(); | 2043 int starting_offset = starting_point - buffers_.begin(); |
2028 int next_buffer_offset = next_buffer_index_ - starting_offset; | 2044 int next_buffer_offset = next_buffer_index_ - starting_offset; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 base::TimeDelta SourceBufferRange::NextKeyframeTimestamp( | 2173 base::TimeDelta SourceBufferRange::NextKeyframeTimestamp( |
2158 base::TimeDelta timestamp) { | 2174 base::TimeDelta timestamp) { |
2159 DCHECK(!keyframe_map_.empty()); | 2175 DCHECK(!keyframe_map_.empty()); |
2160 | 2176 |
2161 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 2177 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
2162 return kNoTimestamp(); | 2178 return kNoTimestamp(); |
2163 | 2179 |
2164 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); | 2180 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); |
2165 if (itr == keyframe_map_.end()) | 2181 if (itr == keyframe_map_.end()) |
2166 return kNoTimestamp(); | 2182 return kNoTimestamp(); |
| 2183 |
| 2184 // If the timestamp is inside the gap between the start of the media |
| 2185 // segment and the first buffer, then just pretend there is a |
| 2186 // keyframe at the specified timestamp. |
| 2187 if (itr == keyframe_map_.begin() && |
| 2188 timestamp > media_segment_start_time_ && |
| 2189 timestamp < itr->first) { |
| 2190 return timestamp; |
| 2191 } |
| 2192 |
2167 return itr->first; | 2193 return itr->first; |
2168 } | 2194 } |
2169 | 2195 |
2170 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp( | 2196 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp( |
2171 base::TimeDelta timestamp) { | 2197 base::TimeDelta timestamp) { |
2172 DCHECK(!keyframe_map_.empty()); | 2198 DCHECK(!keyframe_map_.empty()); |
2173 | 2199 |
2174 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 2200 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
2175 return kNoTimestamp(); | 2201 return kNoTimestamp(); |
2176 | 2202 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 return false; | 2266 return false; |
2241 | 2267 |
2242 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 2268 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
2243 splice_buffers_index_ = 0; | 2269 splice_buffers_index_ = 0; |
2244 pending_buffer_.swap(*out_buffer); | 2270 pending_buffer_.swap(*out_buffer); |
2245 pending_buffers_complete_ = false; | 2271 pending_buffers_complete_ = false; |
2246 return true; | 2272 return true; |
2247 } | 2273 } |
2248 | 2274 |
2249 } // namespace media | 2275 } // namespace media |
OLD | NEW |