Chromium Code Reviews| 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 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1767 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 1767 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
| 1768 } | 1768 } |
| 1769 | 1769 |
| 1770 void SourceBufferRange::SeekToStart() { | 1770 void SourceBufferRange::SeekToStart() { |
| 1771 DCHECK(!buffers_.empty()); | 1771 DCHECK(!buffers_.empty()); |
| 1772 next_buffer_index_ = 0; | 1772 next_buffer_index_ = 0; |
| 1773 } | 1773 } |
| 1774 | 1774 |
| 1775 SourceBufferRange* SourceBufferRange::SplitRange( | 1775 SourceBufferRange* SourceBufferRange::SplitRange( |
| 1776 base::TimeDelta timestamp, bool is_exclusive) { | 1776 base::TimeDelta timestamp, bool is_exclusive) { |
| 1777 CHECK(!buffers_.empty()); | |
| 1778 | |
| 1777 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not | 1779 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not |
| 1778 // include keyframes at |timestamp|. | 1780 // include keyframes at |timestamp|. |
| 1779 KeyframeMap::iterator new_beginning_keyframe = | 1781 KeyframeMap::iterator new_beginning_keyframe = |
| 1780 GetFirstKeyframeAt(timestamp, is_exclusive); | 1782 GetFirstKeyframeAt(timestamp, is_exclusive); |
| 1781 | 1783 |
| 1782 // If there is no keyframe after |timestamp|, we can't split the range. | 1784 // If there is no keyframe after |timestamp|, we can't split the range. |
| 1783 if (new_beginning_keyframe == keyframe_map_.end()) | 1785 if (new_beginning_keyframe == keyframe_map_.end()) |
| 1784 return NULL; | 1786 return NULL; |
| 1785 | 1787 |
| 1786 // Remove the data beginning at |keyframe_index| from |buffers_| and save it | 1788 // Remove the data beginning at |keyframe_index| from |buffers_| and save it |
| 1787 // into |removed_buffers|. | 1789 // into |removed_buffers|. |
| 1788 int keyframe_index = | 1790 int keyframe_index = |
| 1789 new_beginning_keyframe->second - keyframe_map_index_base_; | 1791 new_beginning_keyframe->second - keyframe_map_index_base_; |
| 1790 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); | 1792 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
| 1791 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; | 1793 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; |
| 1792 BufferQueue removed_buffers(starting_point, buffers_.end()); | 1794 BufferQueue removed_buffers(starting_point, buffers_.end()); |
| 1795 | |
| 1796 base::TimeDelta new_range_start_timestamp = kNoTimestamp(); | |
| 1797 if (!removed_buffers.empty() && | |
| 1798 media_segment_start_time_ < buffers_.front()->GetDecodeTimestamp() && | |
|
wolenetz
2014/06/12 00:00:16
Can |media_segment_start_time_| be kNoTimestamp()
acolwell GONE FROM CHROMIUM
2014/06/12 01:19:27
Oops. Changed code to use GetStartTimestamp() so t
| |
| 1799 timestamp < removed_buffers.front()->GetDecodeTimestamp()) { | |
| 1800 // The split is in the gap between |media_segment_start_time_| and | |
| 1801 // the first buffer of the new range so we should set the start | |
| 1802 // time of the new range to |timestamp| so we preserve part of the | |
| 1803 // gap in the new range. | |
| 1804 new_range_start_timestamp = timestamp; | |
| 1805 } | |
| 1806 | |
| 1793 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); | 1807 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); |
| 1794 FreeBufferRange(starting_point, buffers_.end()); | 1808 FreeBufferRange(starting_point, buffers_.end()); |
| 1795 | 1809 |
| 1796 // Create a new range with |removed_buffers|. | 1810 // Create a new range with |removed_buffers|. |
|
wolenetz
2014/06/12 00:00:16
If |removed_buffers| is empty(), why create an emp
acolwell GONE FROM CHROMIUM
2014/06/12 01:19:27
Removed the check above. There is a DCHECK() in th
| |
| 1797 SourceBufferRange* split_range = | 1811 SourceBufferRange* split_range = |
| 1798 new SourceBufferRange( | 1812 new SourceBufferRange( |
| 1799 type_, removed_buffers, kNoTimestamp(), interbuffer_distance_cb_); | 1813 type_, removed_buffers, new_range_start_timestamp, |
| 1814 interbuffer_distance_cb_); | |
| 1800 | 1815 |
| 1801 // If the next buffer position is now in |split_range|, update the state of | 1816 // If the next buffer position is now in |split_range|, update the state of |
| 1802 // this range and |split_range| accordingly. | 1817 // this range and |split_range| accordingly. |
| 1803 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 1818 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
| 1804 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; | 1819 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; |
| 1805 ResetNextBufferPosition(); | 1820 ResetNextBufferPosition(); |
| 1806 } | 1821 } |
| 1807 | 1822 |
| 1808 return split_range; | 1823 return split_range; |
| 1809 } | 1824 } |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2008 } | 2023 } |
| 2009 buffers_.erase(starting_point, ending_point); | 2024 buffers_.erase(starting_point, ending_point); |
| 2010 } | 2025 } |
| 2011 | 2026 |
| 2012 bool SourceBufferRange::TruncateAt( | 2027 bool SourceBufferRange::TruncateAt( |
| 2013 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { | 2028 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { |
| 2014 DCHECK(!removed_buffers || removed_buffers->empty()); | 2029 DCHECK(!removed_buffers || removed_buffers->empty()); |
| 2015 | 2030 |
| 2016 // Return if we're not deleting anything. | 2031 // Return if we're not deleting anything. |
| 2017 if (starting_point == buffers_.end()) | 2032 if (starting_point == buffers_.end()) |
| 2018 return false; | 2033 return buffers_.empty(); |
| 2019 | 2034 |
| 2020 // Reset the next buffer index if we will be deleting the buffer that's next | 2035 // Reset the next buffer index if we will be deleting the buffer that's next |
| 2021 // in sequence. | 2036 // in sequence. |
| 2022 if (HasNextBufferPosition()) { | 2037 if (HasNextBufferPosition()) { |
| 2023 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); | 2038 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); |
| 2024 if (next_buffer_timestamp == kNoTimestamp() || | 2039 if (next_buffer_timestamp == kNoTimestamp() || |
| 2025 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { | 2040 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { |
| 2026 if (HasNextBuffer() && removed_buffers) { | 2041 if (HasNextBuffer() && removed_buffers) { |
| 2027 int starting_offset = starting_point - buffers_.begin(); | 2042 int starting_offset = starting_point - buffers_.begin(); |
| 2028 int next_buffer_offset = next_buffer_index_ - starting_offset; | 2043 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( | 2172 base::TimeDelta SourceBufferRange::NextKeyframeTimestamp( |
| 2158 base::TimeDelta timestamp) { | 2173 base::TimeDelta timestamp) { |
| 2159 DCHECK(!keyframe_map_.empty()); | 2174 DCHECK(!keyframe_map_.empty()); |
| 2160 | 2175 |
| 2161 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 2176 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
| 2162 return kNoTimestamp(); | 2177 return kNoTimestamp(); |
| 2163 | 2178 |
| 2164 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); | 2179 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); |
| 2165 if (itr == keyframe_map_.end()) | 2180 if (itr == keyframe_map_.end()) |
| 2166 return kNoTimestamp(); | 2181 return kNoTimestamp(); |
| 2182 | |
| 2183 // If the timestamp is inside the gap between the start of the media | |
|
wolenetz
2014/06/12 00:00:16
nit: Update the method declaration's comment, too?
acolwell GONE FROM CHROMIUM
2014/06/12 01:19:27
Done.
| |
| 2184 // segment and the first buffer, then just pretend there is a | |
| 2185 // keyframe at the specified timestamp. | |
|
wolenetz
2014/06/12 00:00:16
I'm not totally clear why this pretending is neces
acolwell GONE FROM CHROMIUM
2014/06/12 01:19:27
It makes the buffered ranges behave in a way that
| |
| 2186 if (itr == keyframe_map_.begin() && | |
| 2187 timestamp >= media_segment_start_time_ && | |
|
wolenetz
2014/06/12 19:20:49
nit: If timestamp == media_segment_start_time_, do
acolwell GONE FROM CHROMIUM
2014/06/12 20:17:58
Probably not. Made this >.
| |
| 2188 timestamp < itr->first) { | |
| 2189 return timestamp; | |
| 2190 } | |
| 2191 | |
| 2167 return itr->first; | 2192 return itr->first; |
| 2168 } | 2193 } |
| 2169 | 2194 |
| 2170 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp( | 2195 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp( |
| 2171 base::TimeDelta timestamp) { | 2196 base::TimeDelta timestamp) { |
| 2172 DCHECK(!keyframe_map_.empty()); | 2197 DCHECK(!keyframe_map_.empty()); |
| 2173 | 2198 |
| 2174 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) | 2199 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) |
| 2175 return kNoTimestamp(); | 2200 return kNoTimestamp(); |
| 2176 | 2201 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2240 return false; | 2265 return false; |
| 2241 | 2266 |
| 2242 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 2267 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 2243 splice_buffers_index_ = 0; | 2268 splice_buffers_index_ = 0; |
| 2244 pending_buffer_.swap(*out_buffer); | 2269 pending_buffer_.swap(*out_buffer); |
| 2245 pending_buffers_complete_ = false; | 2270 pending_buffers_complete_ = false; |
| 2246 return true; | 2271 return true; |
| 2247 } | 2272 } |
| 2248 | 2273 |
| 2249 } // namespace media | 2274 } // namespace media |
| OLD | NEW |