| 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 |