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 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 // If we're about to delete the selected range, also reset the seek state. | 1142 // If we're about to delete the selected range, also reset the seek state. |
1143 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); | 1143 DCHECK((*itr)->GetStartTimestamp() >= duration_dts); |
1144 if (*itr == selected_range_) | 1144 if (*itr == selected_range_) |
1145 ResetSeekState(); | 1145 ResetSeekState(); |
1146 DeleteAndRemoveRange(&itr); | 1146 DeleteAndRemoveRange(&itr); |
1147 } | 1147 } |
1148 } | 1148 } |
1149 | 1149 |
1150 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( | 1150 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( |
1151 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1151 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1152 if (!pending_buffer_) { | 1152 if (!pending_buffer_.get()) { |
1153 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1153 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
1154 if (status != SourceBufferStream::kSuccess || !SetPendingBuffer(out_buffer)) | 1154 if (status != SourceBufferStream::kSuccess || !SetPendingBuffer(out_buffer)) |
1155 return status; | 1155 return status; |
1156 } | 1156 } |
1157 | 1157 |
1158 if (!pending_buffer_->splice_buffers().empty()) | 1158 if (!pending_buffer_->splice_buffers().empty()) |
1159 return HandleNextBufferWithSplice(out_buffer); | 1159 return HandleNextBufferWithSplice(out_buffer); |
1160 | 1160 |
1161 DCHECK(pending_buffer_->preroll_buffer()); | 1161 DCHECK(pending_buffer_->preroll_buffer().get()); |
1162 return HandleNextBufferWithPreroll(out_buffer); | 1162 return HandleNextBufferWithPreroll(out_buffer); |
1163 } | 1163 } |
1164 | 1164 |
1165 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( | 1165 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( |
1166 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1166 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1167 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); | 1167 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); |
1168 const size_t last_splice_buffer_index = splice_buffers.size() - 1; | 1168 const size_t last_splice_buffer_index = splice_buffers.size() - 1; |
1169 | 1169 |
1170 // Are there any splice buffers left to hand out? The last buffer should be | 1170 // Are there any splice buffers left to hand out? The last buffer should be |
1171 // handed out separately since it represents the first post-splice buffer. | 1171 // handed out separately since it represents the first post-splice buffer. |
1172 if (splice_buffers_index_ < last_splice_buffer_index) { | 1172 if (splice_buffers_index_ < last_splice_buffer_index) { |
1173 // Account for config changes which occur between fade out buffers. | 1173 // Account for config changes which occur between fade out buffers. |
1174 if (current_config_index_ != | 1174 if (current_config_index_ != |
1175 splice_buffers[splice_buffers_index_]->GetConfigId()) { | 1175 splice_buffers[splice_buffers_index_]->GetConfigId()) { |
1176 config_change_pending_ = true; | 1176 config_change_pending_ = true; |
1177 DVLOG(1) << "Config change (splice buffer config ID does not match)."; | 1177 DVLOG(1) << "Config change (splice buffer config ID does not match)."; |
1178 return SourceBufferStream::kConfigChange; | 1178 return SourceBufferStream::kConfigChange; |
1179 } | 1179 } |
1180 | 1180 |
1181 // Every pre splice buffer must have the same splice_timestamp(). | 1181 // Every pre splice buffer must have the same splice_timestamp(). |
1182 DCHECK(pending_buffer_->splice_timestamp() == | 1182 DCHECK(pending_buffer_->splice_timestamp() == |
1183 splice_buffers[splice_buffers_index_]->splice_timestamp()); | 1183 splice_buffers[splice_buffers_index_]->splice_timestamp()); |
1184 | 1184 |
1185 // No pre splice buffers should have preroll. | 1185 // No pre splice buffers should have preroll. |
1186 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer()); | 1186 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get()); |
1187 | 1187 |
1188 *out_buffer = splice_buffers[splice_buffers_index_++]; | 1188 *out_buffer = splice_buffers[splice_buffers_index_++]; |
1189 return SourceBufferStream::kSuccess; | 1189 return SourceBufferStream::kSuccess; |
1190 } | 1190 } |
1191 | 1191 |
1192 // Did we hand out the last pre-splice buffer on the previous call? | 1192 // Did we hand out the last pre-splice buffer on the previous call? |
1193 if (!pending_buffers_complete_) { | 1193 if (!pending_buffers_complete_) { |
1194 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); | 1194 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); |
1195 pending_buffers_complete_ = true; | 1195 pending_buffers_complete_ = true; |
1196 config_change_pending_ = true; | 1196 config_change_pending_ = true; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( | 1234 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( |
1235 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1235 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1236 CHECK(!config_change_pending_); | 1236 CHECK(!config_change_pending_); |
1237 | 1237 |
1238 if (!track_buffer_.empty()) { | 1238 if (!track_buffer_.empty()) { |
1239 DCHECK(!selected_range_); | 1239 DCHECK(!selected_range_); |
1240 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); | 1240 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); |
1241 | 1241 |
1242 // If the next buffer is an audio splice frame, the next effective config id | 1242 // If the next buffer is an audio splice frame, the next effective config id |
1243 // comes from the first splice buffer. | 1243 // comes from the first splice buffer. |
1244 if (GetConfigId(next_buffer, 0) != current_config_index_) { | 1244 if (GetConfigId(next_buffer.get(), 0) != current_config_index_) { |
1245 config_change_pending_ = true; | 1245 config_change_pending_ = true; |
1246 DVLOG(1) << "Config change (track buffer config ID does not match)."; | 1246 DVLOG(1) << "Config change (track buffer config ID does not match)."; |
1247 return kConfigChange; | 1247 return kConfigChange; |
1248 } | 1248 } |
1249 | 1249 |
1250 *out_buffer = next_buffer; | 1250 *out_buffer = next_buffer; |
1251 track_buffer_.pop_front(); | 1251 track_buffer_.pop_front(); |
1252 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); | 1252 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); |
1253 | 1253 |
1254 // If the track buffer becomes empty, then try to set the selected range | 1254 // If the track buffer becomes empty, then try to set the selected range |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 append_config_index_ = video_configs_.size(); | 1454 append_config_index_ = video_configs_.size(); |
1455 DVLOG(2) << "New video config - index: " << append_config_index_; | 1455 DVLOG(2) << "New video config - index: " << append_config_index_; |
1456 video_configs_.resize(video_configs_.size() + 1); | 1456 video_configs_.resize(video_configs_.size() + 1); |
1457 video_configs_[append_config_index_] = config; | 1457 video_configs_[append_config_index_] = config; |
1458 return true; | 1458 return true; |
1459 } | 1459 } |
1460 | 1460 |
1461 void SourceBufferStream::CompleteConfigChange() { | 1461 void SourceBufferStream::CompleteConfigChange() { |
1462 config_change_pending_ = false; | 1462 config_change_pending_ = false; |
1463 | 1463 |
1464 if (pending_buffer_) { | 1464 if (pending_buffer_.get()) { |
1465 current_config_index_ = | 1465 current_config_index_ = |
1466 GetConfigId(pending_buffer_, splice_buffers_index_); | 1466 GetConfigId(pending_buffer_.get(), splice_buffers_index_); |
1467 return; | 1467 return; |
1468 } | 1468 } |
1469 | 1469 |
1470 if (!track_buffer_.empty()) { | 1470 if (!track_buffer_.empty()) { |
1471 current_config_index_ = GetConfigId(track_buffer_.front(), 0); | 1471 current_config_index_ = GetConfigId(track_buffer_.front().get(), 0); |
1472 return; | 1472 return; |
1473 } | 1473 } |
1474 | 1474 |
1475 if (selected_range_ && selected_range_->HasNextBuffer()) | 1475 if (selected_range_ && selected_range_->HasNextBuffer()) |
1476 current_config_index_ = selected_range_->GetNextConfigId(); | 1476 current_config_index_ = selected_range_->GetNextConfigId(); |
1477 } | 1477 } |
1478 | 1478 |
1479 void SourceBufferStream::SetSelectedRangeIfNeeded( | 1479 void SourceBufferStream::SetSelectedRangeIfNeeded( |
1480 const DecodeTimestamp timestamp) { | 1480 const DecodeTimestamp timestamp) { |
1481 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; | 1481 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")"; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1678 // a splice. | 1678 // a splice. |
1679 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | 1679 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { |
1680 const BufferQueue& original_splice_buffers = | 1680 const BufferQueue& original_splice_buffers = |
1681 pre_splice_buffers[i]->splice_buffers(); | 1681 pre_splice_buffers[i]->splice_buffers(); |
1682 if (!original_splice_buffers.empty()) { | 1682 if (!original_splice_buffers.empty()) { |
1683 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | 1683 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " |
1684 "pre-existing splice."; | 1684 "pre-existing splice."; |
1685 return; | 1685 return; |
1686 } | 1686 } |
1687 | 1687 |
1688 if (pre_splice_buffers[i]->preroll_buffer()) { | 1688 if (pre_splice_buffers[i]->preroll_buffer().get()) { |
1689 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; | 1689 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; |
1690 return; | 1690 return; |
1691 } | 1691 } |
1692 } | 1692 } |
1693 | 1693 |
1694 // Don't generate splice frames which represent less than two frames, since we | 1694 // Don't generate splice frames which represent less than two frames, since we |
1695 // need at least that much to generate a crossfade. Per the spec, make this | 1695 // need at least that much to generate a crossfade. Per the spec, make this |
1696 // check using the sample rate of the overlapping buffers. | 1696 // check using the sample rate of the overlapping buffers. |
1697 const base::TimeDelta splice_duration = | 1697 const base::TimeDelta splice_duration = |
1698 pre_splice_buffers.back()->timestamp() + | 1698 pre_splice_buffers.back()->timestamp() + |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2082 | 2082 |
2083 bool SourceBufferRange::HasNextBuffer() const { | 2083 bool SourceBufferRange::HasNextBuffer() const { |
2084 return next_buffer_index_ >= 0 && | 2084 return next_buffer_index_ >= 0 && |
2085 next_buffer_index_ < static_cast<int>(buffers_.size()); | 2085 next_buffer_index_ < static_cast<int>(buffers_.size()); |
2086 } | 2086 } |
2087 | 2087 |
2088 int SourceBufferRange::GetNextConfigId() const { | 2088 int SourceBufferRange::GetNextConfigId() const { |
2089 DCHECK(HasNextBuffer()); | 2089 DCHECK(HasNextBuffer()); |
2090 // If the next buffer is an audio splice frame, the next effective config id | 2090 // If the next buffer is an audio splice frame, the next effective config id |
2091 // comes from the first fade out preroll buffer. | 2091 // comes from the first fade out preroll buffer. |
2092 return GetConfigId(buffers_[next_buffer_index_], 0); | 2092 return GetConfigId(buffers_[next_buffer_index_].get(), 0); |
2093 } | 2093 } |
2094 | 2094 |
2095 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const { | 2095 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const { |
2096 DCHECK(!buffers_.empty()); | 2096 DCHECK(!buffers_.empty()); |
2097 DCHECK(HasNextBufferPosition()); | 2097 DCHECK(HasNextBufferPosition()); |
2098 | 2098 |
2099 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 2099 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
2100 return kNoDecodeTimestamp(); | 2100 return kNoDecodeTimestamp(); |
2101 } | 2101 } |
2102 | 2102 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2262 | 2262 |
2263 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) | 2263 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) |
2264 continue; | 2264 continue; |
2265 buffers->push_back(buffer); | 2265 buffers->push_back(buffer); |
2266 } | 2266 } |
2267 return previous_size < buffers->size(); | 2267 return previous_size < buffers->size(); |
2268 } | 2268 } |
2269 | 2269 |
2270 bool SourceBufferStream::SetPendingBuffer( | 2270 bool SourceBufferStream::SetPendingBuffer( |
2271 scoped_refptr<StreamParserBuffer>* out_buffer) { | 2271 scoped_refptr<StreamParserBuffer>* out_buffer) { |
2272 DCHECK(*out_buffer); | 2272 DCHECK(out_buffer->get()); |
2273 DCHECK(!pending_buffer_); | 2273 DCHECK(!pending_buffer_.get()); |
2274 | 2274 |
2275 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); | 2275 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); |
2276 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer(); | 2276 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); |
2277 | 2277 |
2278 if (!have_splice_buffers && !have_preroll_buffer) | 2278 if (!have_splice_buffers && !have_preroll_buffer) |
2279 return false; | 2279 return false; |
2280 | 2280 |
2281 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 2281 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
2282 splice_buffers_index_ = 0; | 2282 splice_buffers_index_ = 0; |
2283 pending_buffer_.swap(*out_buffer); | 2283 pending_buffer_.swap(*out_buffer); |
2284 pending_buffers_complete_ = false; | 2284 pending_buffers_complete_ = false; |
2285 return true; | 2285 return true; |
2286 } | 2286 } |
2287 | 2287 |
2288 } // namespace media | 2288 } // namespace media |
OLD | NEW |