Chromium Code Reviews| 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 |