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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 MediaLog* media_log) | 49 MediaLog* media_log) |
50 : traits_(media_log), | 50 : traits_(media_log), |
51 task_runner_(task_runner), | 51 task_runner_(task_runner), |
52 media_log_(media_log), | 52 media_log_(media_log), |
53 state_(STATE_UNINITIALIZED), | 53 state_(STATE_UNINITIALIZED), |
54 stream_(NULL), | 54 stream_(NULL), |
55 cdm_context_(nullptr), | 55 cdm_context_(nullptr), |
56 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 56 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
57 std::move(decoders), | 57 std::move(decoders), |
58 media_log)), | 58 media_log)), |
59 decoded_frames_since_fallback_(0), | 59 decoder_produced_a_frame_(false), |
60 decoding_eos_(false), | 60 decoding_eos_(false), |
61 pending_decode_requests_(0), | 61 pending_decode_requests_(0), |
62 duration_tracker_(8), | 62 duration_tracker_(8), |
63 received_config_change_during_reinit_(false), | 63 received_config_change_during_reinit_(false), |
64 pending_demuxer_read_(false), | 64 pending_demuxer_read_(false), |
65 weak_factory_(this), | 65 weak_factory_(this), |
66 fallback_weak_factory_(this) { | 66 fallback_weak_factory_(this) { |
67 FUNCTION_DVLOG(1); | 67 FUNCTION_DVLOG(1); |
68 } | 68 } |
69 | 69 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) | 277 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) |
278 << state_; | 278 << state_; |
279 if (state_ == STATE_INITIALIZING) { | 279 if (state_ == STATE_INITIALIZING) { |
280 DCHECK(!init_cb_.is_null()); | 280 DCHECK(!init_cb_.is_null()); |
281 DCHECK(read_cb_.is_null()); | 281 DCHECK(read_cb_.is_null()); |
282 DCHECK(reset_cb_.is_null()); | 282 DCHECK(reset_cb_.is_null()); |
283 } else if (state_ == STATE_REINITIALIZING_DECODER) { | 283 } else if (state_ == STATE_REINITIALIZING_DECODER) { |
284 DCHECK(decoder_); | 284 DCHECK(decoder_); |
285 } | 285 } |
286 | 286 |
287 previous_decoder_ = std::move(decoder_); | |
288 decoded_frames_since_fallback_ = 0; | |
289 decoder_ = std::move(selected_decoder); | 287 decoder_ = std::move(selected_decoder); |
290 if (decrypting_demuxer_stream) { | 288 if (decrypting_demuxer_stream) { |
291 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); | 289 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); |
292 stream_ = decrypting_demuxer_stream_.get(); | 290 stream_ = decrypting_demuxer_stream_.get(); |
293 } | 291 } |
294 | 292 |
295 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. | 293 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. |
296 if (received_config_change_during_reinit_) { | 294 if (received_config_change_during_reinit_) { |
297 CompleteDecoderReinitialization(false); | 295 CompleteDecoderReinitialization(false); |
298 return; | 296 return; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 base::ResetAndReturn(&read_cb_).Run(status, output); | 337 base::ResetAndReturn(&read_cb_).Run(status, output); |
340 } | 338 } |
341 | 339 |
342 template <DemuxerStream::Type StreamType> | 340 template <DemuxerStream::Type StreamType> |
343 void DecoderStream<StreamType>::Decode( | 341 void DecoderStream<StreamType>::Decode( |
344 const scoped_refptr<DecoderBuffer>& buffer) { | 342 const scoped_refptr<DecoderBuffer>& buffer) { |
345 FUNCTION_DVLOG(3); | 343 FUNCTION_DVLOG(3); |
346 | 344 |
347 // We don't know if the decoder will error out on first decode yet. Save the | 345 // We don't know if the decoder will error out on first decode yet. Save the |
348 // buffer to feed it to the fallback decoder later if needed. | 346 // buffer to feed it to the fallback decoder later if needed. |
349 if (!decoded_frames_since_fallback_) | 347 if (!decoder_produced_a_frame_) |
350 pending_buffers_.push_back(buffer); | 348 pending_buffers_.push_back(buffer); |
351 | 349 |
352 // It's possible for a buffer to arrive from the demuxer right after the | 350 // It's possible for a buffer to arrive from the demuxer right after the |
353 // fallback decoder successfully completed its initialization. At this point | 351 // fallback decoder successfully completed its initialization. At this point |
354 // |pending_buffers_| has already been copied to |fallback_buffers_| and we | 352 // |pending_buffers_| has already been copied to |fallback_buffers_| and we |
355 // need to append it ourselves. | 353 // need to append it ourselves. |
356 if (!fallback_buffers_.empty()) { | 354 if (!fallback_buffers_.empty()) { |
357 fallback_buffers_.push_back(buffer); | 355 fallback_buffers_.push_back(buffer); |
358 | 356 |
359 scoped_refptr<DecoderBuffer> temp = fallback_buffers_.front(); | 357 scoped_refptr<DecoderBuffer> temp = fallback_buffers_.front(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 return; | 422 return; |
425 } | 423 } |
426 | 424 |
427 // Drop decoding result if Reset() was called during decoding. | 425 // Drop decoding result if Reset() was called during decoding. |
428 // The resetting process will be handled when the decoder is reset. | 426 // The resetting process will be handled when the decoder is reset. |
429 if (!reset_cb_.is_null()) | 427 if (!reset_cb_.is_null()) |
430 return; | 428 return; |
431 | 429 |
432 switch (status) { | 430 switch (status) { |
433 case DecodeStatus::DECODE_ERROR: | 431 case DecodeStatus::DECODE_ERROR: |
434 if (!decoded_frames_since_fallback_) { | 432 if (!decoder_produced_a_frame_) { |
435 pending_decode_requests_ = 0; | 433 pending_decode_requests_ = 0; |
436 | 434 |
437 // Prevent all pending decode requests and outputs form those requests | 435 // Prevent all pending decode requests and outputs from those requests |
438 // from being called back. | 436 // from being called back. |
439 fallback_weak_factory_.InvalidateWeakPtrs(); | 437 fallback_weak_factory_.InvalidateWeakPtrs(); |
440 | 438 |
441 FUNCTION_DVLOG(1) | 439 FUNCTION_DVLOG(1) |
442 << ": Falling back to new decoder after initial decode error."; | 440 << ": Falling back to new decoder after initial decode error."; |
443 state_ = STATE_REINITIALIZING_DECODER; | 441 state_ = STATE_REINITIALIZING_DECODER; |
444 SelectDecoder(); | 442 SelectDecoder(); |
445 return; | 443 return; |
446 } | 444 } |
447 FUNCTION_DVLOG(1) << ": Decode error!"; | 445 FUNCTION_DVLOG(1) << ": Decode error!"; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 if (state_ == STATE_ERROR) { | 491 if (state_ == STATE_ERROR) { |
494 DCHECK(read_cb_.is_null()); | 492 DCHECK(read_cb_.is_null()); |
495 return; | 493 return; |
496 } | 494 } |
497 | 495 |
498 // Drop decoding result if Reset() was called during decoding. | 496 // Drop decoding result if Reset() was called during decoding. |
499 // The resetting process will be handled when the decoder is reset. | 497 // The resetting process will be handled when the decoder is reset. |
500 if (!reset_cb_.is_null()) | 498 if (!reset_cb_.is_null()) |
501 return; | 499 return; |
502 | 500 |
501 decoder_produced_a_frame_ = true; | |
503 traits_.OnDecodeDone(output); | 502 traits_.OnDecodeDone(output); |
504 | 503 |
505 ++decoded_frames_since_fallback_; | |
506 | |
507 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a | 504 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a |
508 // fallback decoder. | 505 // fallback decoder. |
509 // Note: |fallback_buffers_| might still have buffers, and we will keep | 506 // Note: |fallback_buffers_| might still have buffers, and we will keep |
510 // reading from there before requesting new buffers from |stream_|. | 507 // reading from there before requesting new buffers from |stream_|. |
511 pending_buffers_.clear(); | 508 pending_buffers_.clear(); |
512 | 509 |
513 if (!read_cb_.is_null()) { | 510 if (!read_cb_.is_null()) { |
514 // If |ready_outputs_| was non-empty, the read would have already been | 511 // If |ready_outputs_| was non-empty, the read would have already been |
515 // satisifed by Read(). | 512 // satisifed by Read(). |
516 DCHECK(ready_outputs_.empty()); | 513 DCHECK(ready_outputs_.empty()); |
517 SatisfyRead(OK, output); | 514 SatisfyRead(OK, output); |
518 return; | 515 return; |
519 } | 516 } |
520 | 517 |
521 // Store decoded output. | 518 // Store decoded output. |
522 ready_outputs_.push_back(output); | 519 ready_outputs_.push_back(output); |
523 | |
524 // Destruct any previous decoder once we've decoded enough frames to ensure | |
525 // that it's no longer in use. | |
526 if (previous_decoder_ && | |
527 decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { | |
528 previous_decoder_.reset(); | |
529 } | |
530 } | 520 } |
531 | 521 |
532 template <DemuxerStream::Type StreamType> | 522 template <DemuxerStream::Type StreamType> |
533 void DecoderStream<StreamType>::ReadFromDemuxerStream() { | 523 void DecoderStream<StreamType>::ReadFromDemuxerStream() { |
534 FUNCTION_DVLOG(3); | 524 FUNCTION_DVLOG(3); |
535 DCHECK_EQ(state_, STATE_NORMAL); | 525 DCHECK_EQ(state_, STATE_NORMAL); |
536 DCHECK(CanDecodeMore()); | 526 DCHECK(CanDecodeMore()); |
537 DCHECK(reset_cb_.is_null()); | 527 DCHECK(reset_cb_.is_null()); |
538 | 528 |
539 if (!fallback_buffers_.empty()) { | 529 if (!fallback_buffers_.empty()) { |
(...skipping 17 matching lines...) Expand all Loading... | |
557 template <DemuxerStream::Type StreamType> | 547 template <DemuxerStream::Type StreamType> |
558 void DecoderStream<StreamType>::OnBufferReady( | 548 void DecoderStream<StreamType>::OnBufferReady( |
559 DemuxerStream::Status status, | 549 DemuxerStream::Status status, |
560 const scoped_refptr<DecoderBuffer>& buffer) { | 550 const scoped_refptr<DecoderBuffer>& buffer) { |
561 FUNCTION_DVLOG(3) << ": " << status << ", " | 551 FUNCTION_DVLOG(3) << ": " << status << ", " |
562 << (buffer.get() ? buffer->AsHumanReadableString() | 552 << (buffer.get() ? buffer->AsHumanReadableString() |
563 : "NULL"); | 553 : "NULL"); |
564 | 554 |
565 DCHECK(task_runner_->BelongsToCurrentThread()); | 555 DCHECK(task_runner_->BelongsToCurrentThread()); |
566 DCHECK(pending_demuxer_read_); | 556 DCHECK(pending_demuxer_read_); |
567 if (decoded_frames_since_fallback_) { | 557 if (!decoder_produced_a_frame_) { |
568 DCHECK(pending_demuxer_read_ || state_ == STATE_ERROR) << state_; | |
watk
2017/04/24 23:13:02
Two lines above we DCHECK(pending_demuxer_read_) s
| |
569 } else { | |
570 DCHECK(state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || | 558 DCHECK(state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || |
571 state_ == STATE_NORMAL) | 559 state_ == STATE_NORMAL) |
572 << state_; | 560 << state_; |
573 } | 561 } |
574 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 562 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
575 pending_demuxer_read_ = false; | 563 pending_demuxer_read_ = false; |
576 | 564 |
577 // If parallel decode requests are supported, multiple read requests might | 565 // If parallel decode requests are supported, multiple read requests might |
578 // have been sent to the demuxer. The buffers might arrive while the decoder | 566 // have been sent to the demuxer. The buffers might arrive while the decoder |
579 // is reinitializing after falling back on first decode error. | 567 // is reinitializing after falling back on first decode error. |
580 if (state_ == STATE_REINITIALIZING_DECODER && | 568 if (state_ == STATE_REINITIALIZING_DECODER && !decoder_produced_a_frame_) { |
581 !decoded_frames_since_fallback_) { | |
582 switch (status) { | 569 switch (status) { |
583 case DemuxerStream::kOk: | 570 case DemuxerStream::kOk: |
584 // Save valid buffers to be consumed by the new decoder. | 571 // Save valid buffers to be consumed by the new decoder. |
585 // |pending_buffers_| is copied to |fallback_buffers| in | 572 // |pending_buffers_| is copied to |fallback_buffers| in |
586 // OnDecoderSelected(). | 573 // OnDecoderSelected(). |
587 pending_buffers_.push_back(buffer); | 574 pending_buffers_.push_back(buffer); |
588 break; | 575 break; |
589 case DemuxerStream::kConfigChanged: | 576 case DemuxerStream::kConfigChanged: |
590 // TODO(tguilbert): crbug.com/603713 | 577 // TODO(tguilbert): crbug.com/603713 |
591 // |decoder_| might have a stale config by the time it is reinitialized. | 578 // |decoder_| might have a stale config by the time it is reinitialized. |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 } | 769 } |
783 | 770 |
784 // The resetting process will be continued in OnDecoderReinitialized(). | 771 // The resetting process will be continued in OnDecoderReinitialized(). |
785 ReinitializeDecoder(); | 772 ReinitializeDecoder(); |
786 } | 773 } |
787 | 774 |
788 template class DecoderStream<DemuxerStream::VIDEO>; | 775 template class DecoderStream<DemuxerStream::VIDEO>; |
789 template class DecoderStream<DemuxerStream::AUDIO>; | 776 template class DecoderStream<DemuxerStream::AUDIO>; |
790 | 777 |
791 } // namespace media | 778 } // namespace media |
OLD | NEW |