OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/decoder_stream.h" | 5 #include "media/filters/decoder_stream.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 45 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
46 : task_runner_(task_runner), | 46 : task_runner_(task_runner), |
47 state_(STATE_UNINITIALIZED), | 47 state_(STATE_UNINITIALIZED), |
48 stream_(NULL), | 48 stream_(NULL), |
49 low_delay_(false), | 49 low_delay_(false), |
50 decoder_selector_( | 50 decoder_selector_( |
51 new DecoderSelector<StreamType>(task_runner, | 51 new DecoderSelector<StreamType>(task_runner, |
52 decoders.Pass(), | 52 decoders.Pass(), |
53 set_decryptor_ready_cb)), | 53 set_decryptor_ready_cb)), |
54 active_splice_(false), | 54 active_splice_(false), |
| 55 decoding_eos_(false), |
55 pending_decode_requests_(0), | 56 pending_decode_requests_(0), |
56 weak_factory_(this) {} | 57 weak_factory_(this) {} |
57 | 58 |
58 template <DemuxerStream::Type StreamType> | 59 template <DemuxerStream::Type StreamType> |
59 DecoderStream<StreamType>::~DecoderStream() { | 60 DecoderStream<StreamType>::~DecoderStream() { |
60 FUNCTION_DVLOG(2); | 61 FUNCTION_DVLOG(2); |
61 DCHECK(task_runner_->BelongsToCurrentThread()); | 62 DCHECK(task_runner_->BelongsToCurrentThread()); |
62 | 63 |
63 decoder_selector_.reset(); | 64 decoder_selector_.reset(); |
64 | 65 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 201 |
201 template <DemuxerStream::Type StreamType> | 202 template <DemuxerStream::Type StreamType> |
202 bool DecoderStream<StreamType>::CanDecodeMore() const { | 203 bool DecoderStream<StreamType>::CanDecodeMore() const { |
203 DCHECK(task_runner_->BelongsToCurrentThread()); | 204 DCHECK(task_runner_->BelongsToCurrentThread()); |
204 | 205 |
205 // Limit total number of outputs stored in |ready_outputs_| and being decoded. | 206 // Limit total number of outputs stored in |ready_outputs_| and being decoded. |
206 // It only makes sense to saturate decoder completely when output queue is | 207 // It only makes sense to saturate decoder completely when output queue is |
207 // empty. | 208 // empty. |
208 int num_decodes = | 209 int num_decodes = |
209 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_; | 210 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_; |
210 return num_decodes < GetMaxDecodeRequests(); | 211 return !decoding_eos_ && num_decodes < GetMaxDecodeRequests(); |
211 } | 212 } |
212 | 213 |
213 template <DemuxerStream::Type StreamType> | 214 template <DemuxerStream::Type StreamType> |
214 void DecoderStream<StreamType>::OnDecoderSelected( | 215 void DecoderStream<StreamType>::OnDecoderSelected( |
215 scoped_ptr<Decoder> selected_decoder, | 216 scoped_ptr<Decoder> selected_decoder, |
216 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 217 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
217 FUNCTION_DVLOG(2); | 218 FUNCTION_DVLOG(2); |
218 DCHECK(task_runner_->BelongsToCurrentThread()); | 219 DCHECK(task_runner_->BelongsToCurrentThread()); |
219 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; | 220 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; |
220 DCHECK(!init_cb_.is_null()); | 221 DCHECK(!init_cb_.is_null()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 const scoped_refptr<DecoderBuffer>& buffer) { | 253 const scoped_refptr<DecoderBuffer>& buffer) { |
253 FUNCTION_DVLOG(2); | 254 FUNCTION_DVLOG(2); |
254 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 255 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
255 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 256 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
256 DCHECK(reset_cb_.is_null()); | 257 DCHECK(reset_cb_.is_null()); |
257 DCHECK(buffer); | 258 DCHECK(buffer); |
258 | 259 |
259 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 260 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
260 | 261 |
261 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); | 262 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); |
| 263 |
| 264 if (buffer->end_of_stream()) |
| 265 decoding_eos_ = true; |
| 266 |
262 ++pending_decode_requests_; | 267 ++pending_decode_requests_; |
263 decoder_->Decode(buffer, | 268 decoder_->Decode(buffer, |
264 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, | 269 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, |
265 weak_factory_.GetWeakPtr(), | 270 weak_factory_.GetWeakPtr(), |
266 buffer_size, | 271 buffer_size, |
267 buffer->end_of_stream())); | 272 buffer->end_of_stream())); |
268 } | 273 } |
269 | 274 |
270 template <DemuxerStream::Type StreamType> | 275 template <DemuxerStream::Type StreamType> |
271 void DecoderStream<StreamType>::FlushDecoder() { | 276 void DecoderStream<StreamType>::FlushDecoder() { |
272 Decode(DecoderBuffer::CreateEOSBuffer()); | 277 Decode(DecoderBuffer::CreateEOSBuffer()); |
273 } | 278 } |
274 | 279 |
275 template <DemuxerStream::Type StreamType> | 280 template <DemuxerStream::Type StreamType> |
276 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 281 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, |
277 bool end_of_stream, | 282 bool end_of_stream, |
278 typename Decoder::Status status) { | 283 typename Decoder::Status status) { |
279 FUNCTION_DVLOG(2) << status; | 284 FUNCTION_DVLOG(2) << status; |
280 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 285 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
281 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 286 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
282 << state_; | 287 << state_; |
283 DCHECK_GT(pending_decode_requests_, 0); | 288 DCHECK_GT(pending_decode_requests_, 0); |
284 | 289 |
285 --pending_decode_requests_; | 290 --pending_decode_requests_; |
286 | 291 |
287 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); | 292 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); |
288 | 293 |
| 294 if (end_of_stream) |
| 295 decoding_eos_ = false; |
| 296 |
289 if (state_ == STATE_ERROR) { | 297 if (state_ == STATE_ERROR) { |
290 DCHECK(read_cb_.is_null()); | 298 DCHECK(read_cb_.is_null()); |
291 return; | 299 return; |
292 } | 300 } |
293 | 301 |
294 // Drop decoding result if Reset() was called during decoding. | 302 // Drop decoding result if Reset() was called during decoding. |
295 // The resetting process will be handled when the decoder is reset. | 303 // The resetting process will be handled when the decoder is reset. |
296 if (!reset_cb_.is_null()) | 304 if (!reset_cb_.is_null()) |
297 return; | 305 return; |
298 | 306 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 if (active_splice_ || has_splice_ts) { | 448 if (active_splice_ || has_splice_ts) { |
441 splice_observer_cb_.Run(buffer->splice_timestamp()); | 449 splice_observer_cb_.Run(buffer->splice_timestamp()); |
442 active_splice_ = has_splice_ts; | 450 active_splice_ = has_splice_ts; |
443 } | 451 } |
444 } | 452 } |
445 | 453 |
446 DCHECK(status == DemuxerStream::kOk) << status; | 454 DCHECK(status == DemuxerStream::kOk) << status; |
447 Decode(buffer); | 455 Decode(buffer); |
448 | 456 |
449 // Read more data if the decoder supports multiple parallel decoding requests. | 457 // Read more data if the decoder supports multiple parallel decoding requests. |
450 if (CanDecodeMore() && !buffer->end_of_stream()) | 458 if (CanDecodeMore()) |
451 ReadFromDemuxerStream(); | 459 ReadFromDemuxerStream(); |
452 } | 460 } |
453 | 461 |
454 template <DemuxerStream::Type StreamType> | 462 template <DemuxerStream::Type StreamType> |
455 void DecoderStream<StreamType>::ReinitializeDecoder() { | 463 void DecoderStream<StreamType>::ReinitializeDecoder() { |
456 FUNCTION_DVLOG(2); | 464 FUNCTION_DVLOG(2); |
457 DCHECK(task_runner_->BelongsToCurrentThread()); | 465 DCHECK(task_runner_->BelongsToCurrentThread()); |
458 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; | 466 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; |
459 DCHECK_EQ(pending_decode_requests_, 0); | 467 DCHECK_EQ(pending_decode_requests_, 0); |
460 | 468 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 } | 539 } |
532 | 540 |
533 // The resetting process will be continued in OnDecoderReinitialized(). | 541 // The resetting process will be continued in OnDecoderReinitialized(). |
534 ReinitializeDecoder(); | 542 ReinitializeDecoder(); |
535 } | 543 } |
536 | 544 |
537 template class DecoderStream<DemuxerStream::VIDEO>; | 545 template class DecoderStream<DemuxerStream::VIDEO>; |
538 template class DecoderStream<DemuxerStream::AUDIO>; | 546 template class DecoderStream<DemuxerStream::AUDIO>; |
539 | 547 |
540 } // namespace media | 548 } // namespace media |
OLD | NEW |