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 17 matching lines...) Expand all Loading... |
28 static bool AllowSameTimestamp( | 28 static bool AllowSameTimestamp( |
29 bool prev_is_keyframe, bool current_is_keyframe, | 29 bool prev_is_keyframe, bool current_is_keyframe, |
30 SourceBufferStream::Type type) { | 30 SourceBufferStream::Type type) { |
31 return prev_is_keyframe || !current_is_keyframe; | 31 return prev_is_keyframe || !current_is_keyframe; |
32 } | 32 } |
33 | 33 |
34 // Returns the config ID of |buffer| if |buffer| has no splice buffers or | 34 // Returns the config ID of |buffer| if |buffer| has no splice buffers or |
35 // |index| is out of range. Otherwise returns the config ID for the fade out | 35 // |index| is out of range. Otherwise returns the config ID for the fade out |
36 // preroll buffer at position |index|. | 36 // preroll buffer at position |index|. |
37 static int GetConfigId(StreamParserBuffer* buffer, size_t index) { | 37 static int GetConfigId(StreamParserBuffer* buffer, size_t index) { |
38 return index < buffer->get_splice_buffers().size() | 38 return index < buffer->splice_buffers().size() |
39 ? buffer->get_splice_buffers()[index]->GetConfigId() | 39 ? buffer->splice_buffers()[index]->GetConfigId() |
40 : buffer->GetConfigId(); | 40 : buffer->GetConfigId(); |
41 } | 41 } |
42 | 42 |
43 // Helper class representing a range of buffered data. All buffers in a | 43 // Helper class representing a range of buffered data. All buffers in a |
44 // SourceBufferRange are ordered sequentially in presentation order with no | 44 // SourceBufferRange are ordered sequentially in presentation order with no |
45 // gaps. | 45 // gaps. |
46 class SourceBufferRange { | 46 class SourceBufferRange { |
47 public: | 47 public: |
48 // Returns the maximum distance in time between any buffer seen in this | 48 // Returns the maximum distance in time between any buffer seen in this |
49 // stream. Used to estimate the duration of a buffer if its duration is not | 49 // stream. Used to estimate the duration of a buffer if its duration is not |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 // Make the delete range exclusive if we are dealing with an allowed same | 993 // Make the delete range exclusive if we are dealing with an allowed same |
994 // timestamp situation. This prevents the first buffer in the current append | 994 // timestamp situation. This prevents the first buffer in the current append |
995 // from deleting the last buffer in the previous append if both buffers | 995 // from deleting the last buffer in the previous append if both buffers |
996 // have the same timestamp. | 996 // have the same timestamp. |
997 // | 997 // |
998 // The delete range should never be exclusive if a splice frame was generated | 998 // The delete range should never be exclusive if a splice frame was generated |
999 // because we don't generate splice frames for same timestamp situations. | 999 // because we don't generate splice frames for same timestamp situations. |
1000 DCHECK(new_buffers.front()->splice_timestamp() != | 1000 DCHECK(new_buffers.front()->splice_timestamp() != |
1001 new_buffers.front()->timestamp()); | 1001 new_buffers.front()->timestamp()); |
1002 const bool is_exclusive = | 1002 const bool is_exclusive = |
1003 new_buffers.front()->get_splice_buffers().empty() && | 1003 new_buffers.front()->splice_buffers().empty() && |
1004 prev_timestamp == next_timestamp && | 1004 prev_timestamp == next_timestamp && |
1005 AllowSameTimestamp(prev_is_keyframe, next_is_keyframe, GetType()); | 1005 AllowSameTimestamp(prev_is_keyframe, next_is_keyframe, GetType()); |
1006 | 1006 |
1007 // Delete the buffers that |new_buffers| overlaps. | 1007 // Delete the buffers that |new_buffers| overlaps. |
1008 base::TimeDelta start = new_buffers.front()->GetDecodeTimestamp(); | 1008 base::TimeDelta start = new_buffers.front()->GetDecodeTimestamp(); |
1009 base::TimeDelta end = new_buffers.back()->GetDecodeTimestamp(); | 1009 base::TimeDelta end = new_buffers.back()->GetDecodeTimestamp(); |
1010 base::TimeDelta duration = new_buffers.back()->duration(); | 1010 base::TimeDelta duration = new_buffers.back()->duration(); |
1011 | 1011 |
1012 if (duration != kNoTimestamp() && duration > base::TimeDelta()) { | 1012 if (duration != kNoTimestamp() && duration > base::TimeDelta()) { |
1013 end += duration; | 1013 end += duration; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 } | 1134 } |
1135 | 1135 |
1136 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1136 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1137 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1137 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1138 if (!splice_buffer_) { | 1138 if (!splice_buffer_) { |
1139 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1139 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
1140 | 1140 |
1141 // Just return if GetNextBufferInternal() failed or there's no fade out | 1141 // Just return if GetNextBufferInternal() failed or there's no fade out |
1142 // preroll, there's nothing else to do. | 1142 // preroll, there's nothing else to do. |
1143 if (status != SourceBufferStream::kSuccess || | 1143 if (status != SourceBufferStream::kSuccess || |
1144 (*out_buffer)->get_splice_buffers().empty()) { | 1144 (*out_buffer)->splice_buffers().empty()) { |
1145 return status; | 1145 return status; |
1146 } | 1146 } |
1147 | 1147 |
1148 // Fall through into splice buffer processing. | 1148 // Fall through into splice buffer processing. |
1149 splice_buffers_index_ = 0; | 1149 splice_buffers_index_ = 0; |
1150 splice_buffer_.swap(*out_buffer); | 1150 splice_buffer_.swap(*out_buffer); |
1151 } | 1151 } |
1152 | 1152 |
1153 DCHECK(splice_buffer_); | 1153 DCHECK(splice_buffer_); |
1154 const BufferQueue& splice_buffers = splice_buffer_->get_splice_buffers(); | 1154 const BufferQueue& splice_buffers = splice_buffer_->splice_buffers(); |
1155 const size_t last_splice_buffer_index = splice_buffers.size() - 1; | 1155 const size_t last_splice_buffer_index = splice_buffers.size() - 1; |
1156 | 1156 |
1157 // Are there any splice buffers left to hand out? The last buffer should be | 1157 // Are there any splice buffers left to hand out? The last buffer should be |
1158 // handed out separately since it represents the first post-splice buffer. | 1158 // handed out separately since it represents the first post-splice buffer. |
1159 if (splice_buffers_index_ < last_splice_buffer_index) { | 1159 if (splice_buffers_index_ < last_splice_buffer_index) { |
1160 // Account for config changes which occur between fade out buffers. | 1160 // Account for config changes which occur between fade out buffers. |
1161 if (current_config_index_ != | 1161 if (current_config_index_ != |
1162 splice_buffers[splice_buffers_index_]->GetConfigId()) { | 1162 splice_buffers[splice_buffers_index_]->GetConfigId()) { |
1163 config_change_pending_ = true; | 1163 config_change_pending_ = true; |
1164 DVLOG(1) << "Config change (splice buffer config ID does not match)."; | 1164 DVLOG(1) << "Config change (splice buffer config ID does not match)."; |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 // not generate splice frames in this case. | 1633 // not generate splice frames in this case. |
1634 // | 1634 // |
1635 // We also do not want to generate splices if the first new buffer replaces an | 1635 // We also do not want to generate splices if the first new buffer replaces an |
1636 // existing buffer exactly. | 1636 // existing buffer exactly. |
1637 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) | 1637 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) |
1638 return; | 1638 return; |
1639 | 1639 |
1640 // If any |pre_splice_buffers| are already splices, do not generate a splice. | 1640 // If any |pre_splice_buffers| are already splices, do not generate a splice. |
1641 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | 1641 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { |
1642 const BufferQueue& original_splice_buffers = | 1642 const BufferQueue& original_splice_buffers = |
1643 pre_splice_buffers[i]->get_splice_buffers(); | 1643 pre_splice_buffers[i]->splice_buffers(); |
1644 if (!original_splice_buffers.empty()) { | 1644 if (!original_splice_buffers.empty()) { |
1645 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | 1645 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " |
1646 "pre-existing splice."; | 1646 "pre-existing splice."; |
1647 return; | 1647 return; |
1648 } | 1648 } |
1649 } | 1649 } |
1650 | 1650 |
1651 // Don't generate splice frames which represent less than two frames, since we | 1651 // Don't generate splice frames which represent less than two frames, since we |
1652 // need at least that much to generate a crossfade. Per the spec, make this | 1652 // need at least that much to generate a crossfade. Per the spec, make this |
1653 // check using the sample rate of the overlapping buffers. | 1653 // check using the sample rate of the overlapping buffers. |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2191 if (buffer->end_of_stream() || buffer->timestamp() >= end) | 2191 if (buffer->end_of_stream() || buffer->timestamp() >= end) |
2192 break; | 2192 break; |
2193 if (buffer->timestamp() + buffer->duration() <= start) | 2193 if (buffer->timestamp() + buffer->duration() <= start) |
2194 continue; | 2194 continue; |
2195 buffers->push_back(buffer); | 2195 buffers->push_back(buffer); |
2196 } | 2196 } |
2197 return previous_size < buffers->size(); | 2197 return previous_size < buffers->size(); |
2198 } | 2198 } |
2199 | 2199 |
2200 } // namespace media | 2200 } // namespace media |
OLD | NEW |