| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 state_(STATE_UNINITIALIZED), | 52 state_(STATE_UNINITIALIZED), |
| 53 stream_(NULL), | 53 stream_(NULL), |
| 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
| 55 std::move(decoders), | 55 std::move(decoders), |
| 56 media_log)), | 56 media_log)), |
| 57 decoded_frames_since_fallback_(0), | 57 decoded_frames_since_fallback_(0), |
| 58 active_splice_(false), | 58 active_splice_(false), |
| 59 decoding_eos_(false), | 59 decoding_eos_(false), |
| 60 pending_decode_requests_(0), | 60 pending_decode_requests_(0), |
| 61 duration_tracker_(8), | 61 duration_tracker_(8), |
| 62 received_config_change_during_reinit_(false), |
| 63 pending_demuxer_read_(false), |
| 62 weak_factory_(this), | 64 weak_factory_(this), |
| 63 fallback_weak_factory_(this) {} | 65 fallback_weak_factory_(this) {} |
| 64 | 66 |
| 65 template <DemuxerStream::Type StreamType> | 67 template <DemuxerStream::Type StreamType> |
| 66 DecoderStream<StreamType>::~DecoderStream() { | 68 DecoderStream<StreamType>::~DecoderStream() { |
| 67 FUNCTION_DVLOG(2); | 69 FUNCTION_DVLOG(2); |
| 68 DCHECK(task_runner_->BelongsToCurrentThread()); | 70 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 69 | 71 |
| 70 decoder_selector_.reset(); | 72 decoder_selector_.reset(); |
| 71 | 73 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 template <DemuxerStream::Type StreamType> | 152 template <DemuxerStream::Type StreamType> |
| 151 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { | 153 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { |
| 152 FUNCTION_DVLOG(2); | 154 FUNCTION_DVLOG(2); |
| 153 DCHECK(task_runner_->BelongsToCurrentThread()); | 155 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 154 DCHECK_NE(state_, STATE_UNINITIALIZED); | 156 DCHECK_NE(state_, STATE_UNINITIALIZED); |
| 155 DCHECK(reset_cb_.is_null()); | 157 DCHECK(reset_cb_.is_null()); |
| 156 | 158 |
| 157 reset_cb_ = closure; | 159 reset_cb_ = closure; |
| 158 | 160 |
| 159 if (!read_cb_.is_null()) { | 161 if (!read_cb_.is_null()) { |
| 160 task_runner_->PostTask(FROM_HERE, base::Bind( | 162 task_runner_->PostTask(FROM_HERE, |
| 161 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); | 163 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, |
| 164 scoped_refptr<Output>())); |
| 162 } | 165 } |
| 163 | 166 |
| 164 ready_outputs_.clear(); | 167 ready_outputs_.clear(); |
| 165 | 168 |
| 169 // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right |
| 170 // before a Reset() is executed. If we are still waiting for a demuxer read, |
| 171 // OnBufferReady() will handle the reset callback. |
| 172 // See crbug.com/597605 and crbug.com/607454. |
| 173 if (state_ == STATE_ERROR && !pending_demuxer_read_) { |
| 174 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 175 return; |
| 176 } |
| 177 |
| 166 // During decoder reinitialization, the Decoder does not need to be and | 178 // During decoder reinitialization, the Decoder does not need to be and |
| 167 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder | 179 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder |
| 168 // reinitialization. | 180 // reinitialization. |
| 169 if (state_ == STATE_REINITIALIZING_DECODER) | 181 if (state_ == STATE_REINITIALIZING_DECODER) |
| 170 return; | 182 return; |
| 171 | 183 |
| 172 // During pending demuxer read and when not using DecryptingDemuxerStream, | 184 // |decrypting_demuxer_stream_| will fire all of its read requests when |
| 173 // the Decoder will be reset after demuxer read is returned | 185 // it resets. |reset_cb_| will be fired in OnDecoderReset(), after the |
| 174 // (in OnBufferReady()). | 186 // decrypting demuxer stream finishes its reset. |
| 175 if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_) | |
| 176 return; | |
| 177 | |
| 178 if (decrypting_demuxer_stream_) { | 187 if (decrypting_demuxer_stream_) { |
| 179 decrypting_demuxer_stream_->Reset(base::Bind( | 188 decrypting_demuxer_stream_->Reset(base::Bind( |
| 180 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); | 189 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); |
| 181 return; | 190 return; |
| 182 } | 191 } |
| 183 | 192 |
| 193 // During pending demuxer read and when not using DecryptingDemuxerStream, |
| 194 // the Decoder will be reset after demuxer read is returned |
| 195 // (in OnBufferReady()). |
| 196 if (pending_demuxer_read_) |
| 197 return; |
| 198 |
| 184 ResetDecoder(); | 199 ResetDecoder(); |
| 185 } | 200 } |
| 186 | 201 |
| 187 template <DemuxerStream::Type StreamType> | 202 template <DemuxerStream::Type StreamType> |
| 188 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { | 203 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { |
| 189 DCHECK(task_runner_->BelongsToCurrentThread()); | 204 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 190 return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); | 205 return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); |
| 191 } | 206 } |
| 192 | 207 |
| 193 template <> | 208 template <> |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 } | 254 } |
| 240 | 255 |
| 241 template <DemuxerStream::Type StreamType> | 256 template <DemuxerStream::Type StreamType> |
| 242 void DecoderStream<StreamType>::OnDecoderSelected( | 257 void DecoderStream<StreamType>::OnDecoderSelected( |
| 243 std::unique_ptr<Decoder> selected_decoder, | 258 std::unique_ptr<Decoder> selected_decoder, |
| 244 std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 259 std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
| 245 FUNCTION_DVLOG(2) << ": " | 260 FUNCTION_DVLOG(2) << ": " |
| 246 << (selected_decoder ? selected_decoder->GetDisplayName() | 261 << (selected_decoder ? selected_decoder->GetDisplayName() |
| 247 : "No decoder selected."); | 262 : "No decoder selected."); |
| 248 DCHECK(task_runner_->BelongsToCurrentThread()); | 263 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 249 DCHECK(state_ == STATE_INITIALIZING || | 264 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) |
| 250 state_ == STATE_REINITIALIZING_DECODER || | |
| 251 state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) | |
| 252 << state_; | 265 << state_; |
| 253 if (state_ == STATE_INITIALIZING) { | 266 if (state_ == STATE_INITIALIZING) { |
| 254 DCHECK(!init_cb_.is_null()); | 267 DCHECK(!init_cb_.is_null()); |
| 255 DCHECK(read_cb_.is_null()); | 268 DCHECK(read_cb_.is_null()); |
| 256 DCHECK(reset_cb_.is_null()); | 269 DCHECK(reset_cb_.is_null()); |
| 257 } else if (state_ == STATE_REINITIALIZING_DECODER) { | 270 } else if (state_ == STATE_REINITIALIZING_DECODER) { |
| 258 DCHECK(decoder_); | 271 DCHECK(decoder_); |
| 259 } | 272 } |
| 260 | 273 |
| 261 previous_decoder_ = std::move(decoder_); | 274 previous_decoder_ = std::move(decoder_); |
| 262 decoded_frames_since_fallback_ = 0; | 275 decoded_frames_since_fallback_ = 0; |
| 263 decoder_ = std::move(selected_decoder); | 276 decoder_ = std::move(selected_decoder); |
| 264 if (decrypting_demuxer_stream) { | 277 if (decrypting_demuxer_stream) { |
| 265 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); | 278 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); |
| 266 stream_ = decrypting_demuxer_stream_.get(); | 279 stream_ = decrypting_demuxer_stream_.get(); |
| 267 } | 280 } |
| 268 | 281 |
| 269 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. | 282 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. |
| 270 if (state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) { | 283 if (received_config_change_during_reinit_) { |
| 271 CompleteDecoderReinitialization(false); | 284 CompleteDecoderReinitialization(false); |
| 272 return; | 285 return; |
| 273 } | 286 } |
| 274 | 287 |
| 275 // Attempt to decode buffers from previous decoders (when those decoders have | 288 // Attempt to decode buffers from previous decoders (when those decoders have |
| 276 // never successfully outputed a frame). | 289 // never successfully outputed a frame). |
| 277 fallback_buffers_ = pending_buffers_; | 290 fallback_buffers_ = pending_buffers_; |
| 278 | 291 |
| 279 if (!decoder_) { | 292 if (!decoder_) { |
| 280 if (state_ == STATE_INITIALIZING) { | 293 if (state_ == STATE_INITIALIZING) { |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 | 512 |
| 500 if (!fallback_buffers_.empty()) { | 513 if (!fallback_buffers_.empty()) { |
| 501 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); | 514 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); |
| 502 fallback_buffers_.pop_front(); | 515 fallback_buffers_.pop_front(); |
| 503 | 516 |
| 504 // Decode the buffer without re-appending it to |pending_buffers_|. | 517 // Decode the buffer without re-appending it to |pending_buffers_|. |
| 505 DecodeInternal(buffer); | 518 DecodeInternal(buffer); |
| 506 return; | 519 return; |
| 507 } | 520 } |
| 508 | 521 |
| 522 // Set a flag in addition to the state, because the state can be overwritten |
| 523 // when encountering an error. See crbug.com/597605. |
| 524 DCHECK(!pending_demuxer_read_); |
| 525 pending_demuxer_read_ = true; |
| 526 |
| 509 state_ = STATE_PENDING_DEMUXER_READ; | 527 state_ = STATE_PENDING_DEMUXER_READ; |
| 510 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 528 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
| 511 weak_factory_.GetWeakPtr())); | 529 weak_factory_.GetWeakPtr())); |
| 512 } | 530 } |
| 513 | 531 |
| 514 template <DemuxerStream::Type StreamType> | 532 template <DemuxerStream::Type StreamType> |
| 515 void DecoderStream<StreamType>::OnBufferReady( | 533 void DecoderStream<StreamType>::OnBufferReady( |
| 516 DemuxerStream::Status status, | 534 DemuxerStream::Status status, |
| 517 const scoped_refptr<DecoderBuffer>& buffer) { | 535 const scoped_refptr<DecoderBuffer>& buffer) { |
| 518 FUNCTION_DVLOG(2) << ": " << status << ", " | 536 FUNCTION_DVLOG(2) << ": " << status << ", " |
| 519 << (buffer.get() ? buffer->AsHumanReadableString() | 537 << (buffer.get() ? buffer->AsHumanReadableString() |
| 520 : "NULL"); | 538 : "NULL"); |
| 521 | 539 |
| 522 DCHECK(task_runner_->BelongsToCurrentThread()); | 540 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 523 if (decoded_frames_since_fallback_) { | 541 if (decoded_frames_since_fallback_) { |
| 524 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 542 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
| 525 << state_; | 543 << state_; |
| 526 } else { | 544 } else { |
| 527 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || | 545 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || |
| 528 STATE_REINITIALIZING_DECODER) | 546 STATE_REINITIALIZING_DECODER) |
| 529 << state_; | 547 << state_; |
| 530 } | 548 } |
| 531 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 549 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
| 532 | 550 |
| 551 // Unset the flag. STATE_PENDING_DEMUXER_READ might have been overwritten. |
| 552 // See crbug.com/597605. |
| 553 pending_demuxer_read_ = false; |
| 554 |
| 533 // If parallel decode requests are supported, multiple read requests might | 555 // If parallel decode requests are supported, multiple read requests might |
| 534 // have been sent to the demuxer. The buffers might arrive while the decoder | 556 // have been sent to the demuxer. The buffers might arrive while the decoder |
| 535 // is reinitializing after falling back on first decode error. | 557 // is reinitializing after falling back on first decode error. |
| 536 if (state_ == STATE_REINITIALIZING_DECODER && | 558 if (state_ == STATE_REINITIALIZING_DECODER && |
| 537 !decoded_frames_since_fallback_) { | 559 !decoded_frames_since_fallback_) { |
| 538 switch (status) { | 560 switch (status) { |
| 539 case DemuxerStream::kOk: | 561 case DemuxerStream::kOk: |
| 540 // Save valid buffers to be consumed by the new decoder. | 562 // Save valid buffers to be consumed by the new decoder. |
| 541 // |pending_buffers_| is copied to |fallback_buffers| in | 563 // |pending_buffers_| is copied to |fallback_buffers| in |
| 542 // OnDecoderSelected(). | 564 // OnDecoderSelected(). |
| 543 pending_buffers_.push_back(buffer); | 565 pending_buffers_.push_back(buffer); |
| 544 break; | 566 break; |
| 545 case DemuxerStream::kConfigChanged: | 567 case DemuxerStream::kConfigChanged: |
| 546 // TODO(tguilbert): crbug.com/603713 | 568 // TODO(tguilbert): crbug.com/603713 |
| 547 // |decoder_| might have a stale config by the time it is reinitialized. | 569 // |decoder_| might have a stale config by the time it is reinitialized. |
| 548 // Ideally, we would save the config from |stream_| and reinitialize the | 570 // Ideally, we would save the config from |stream_| and reinitialize the |
| 549 // decoder by playing back the sequence of buffers and config changes. | 571 // decoder by playing back the sequence of buffers and config changes. |
| 550 state_ = STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER; | 572 received_config_change_during_reinit_ = true; |
| 551 pending_buffers_.clear(); | 573 pending_buffers_.clear(); |
| 552 break; | 574 break; |
| 553 case DemuxerStream::kAborted: | 575 case DemuxerStream::kAborted: |
| 554 // |this| will read from the demuxer stream again in OnDecoderSelected() | 576 // |this| will read from the demuxer stream again in OnDecoderSelected() |
| 555 // and receive a kAborted then. | 577 // and receive a kAborted then. |
| 556 pending_buffers_.clear(); | 578 pending_buffers_.clear(); |
| 557 break; | 579 break; |
| 558 } | 580 } |
| 559 return; | 581 return; |
| 560 } | 582 } |
| 561 | 583 |
| 562 // Decoding has been stopped (e.g due to an error). | 584 // Decoding has been stopped (e.g due to an error). |
| 563 if (state_ != STATE_PENDING_DEMUXER_READ) { | 585 if (state_ != STATE_PENDING_DEMUXER_READ) { |
| 564 DCHECK(state_ == STATE_ERROR); | 586 DCHECK(state_ == STATE_ERROR); |
| 565 DCHECK(read_cb_.is_null()); | 587 DCHECK(read_cb_.is_null()); |
| 588 |
| 589 if (!reset_cb_.is_null()) { |
| 590 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() |
| 591 // which will continue the resetting process in its callback. |
| 592 if (!decrypting_demuxer_stream_) |
| 593 Reset(base::ResetAndReturn(&reset_cb_)); |
| 594 } |
| 566 return; | 595 return; |
| 567 } | 596 } |
| 568 | 597 |
| 569 state_ = STATE_NORMAL; | 598 state_ = STATE_NORMAL; |
| 570 | 599 |
| 571 if (status == DemuxerStream::kConfigChanged) { | 600 if (status == DemuxerStream::kConfigChanged) { |
| 572 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; | 601 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; |
| 573 DCHECK(stream_->SupportsConfigChanges()); | 602 DCHECK(stream_->SupportsConfigChanges()); |
| 574 | 603 |
| 575 // Pending buffers might not match the reinitialized decoder's new config. | 604 // Pending buffers might not match the reinitialized decoder's new config. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 591 // happened, and read straight from the demuxer, which could lead to some | 620 // happened, and read straight from the demuxer, which could lead to some |
| 592 // lost frames if we were to fallback then). | 621 // lost frames if we were to fallback then). |
| 593 pending_buffers_.clear(); | 622 pending_buffers_.clear(); |
| 594 | 623 |
| 595 if (!config_change_observer_cb_.is_null()) | 624 if (!config_change_observer_cb_.is_null()) |
| 596 config_change_observer_cb_.Run(); | 625 config_change_observer_cb_.Run(); |
| 597 | 626 |
| 598 state_ = STATE_FLUSHING_DECODER; | 627 state_ = STATE_FLUSHING_DECODER; |
| 599 if (!reset_cb_.is_null()) { | 628 if (!reset_cb_.is_null()) { |
| 600 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() | 629 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() |
| 601 // which will continue the resetting process in it's callback. | 630 // which will continue the resetting process in its callback. |
| 602 if (!decrypting_demuxer_stream_) | 631 if (!decrypting_demuxer_stream_) |
| 603 Reset(base::ResetAndReturn(&reset_cb_)); | 632 Reset(base::ResetAndReturn(&reset_cb_)); |
| 604 // Reinitialization will continue after Reset() is done. | 633 // Reinitialization will continue after Reset() is done. |
| 605 } else { | 634 } else { |
| 606 FlushDecoder(); | 635 FlushDecoder(); |
| 607 } | 636 } |
| 608 return; | 637 return; |
| 609 } | 638 } |
| 610 | 639 |
| 611 if (!reset_cb_.is_null()) { | 640 if (!reset_cb_.is_null()) { |
| 612 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() | 641 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() |
| 613 // which will continue the resetting process in it's callback. | 642 // which will continue the resetting process in its callback. |
| 614 if (!decrypting_demuxer_stream_) | 643 if (!decrypting_demuxer_stream_) |
| 615 Reset(base::ResetAndReturn(&reset_cb_)); | 644 Reset(base::ResetAndReturn(&reset_cb_)); |
| 616 return; | 645 return; |
| 617 } | 646 } |
| 618 | 647 |
| 619 if (status == DemuxerStream::kAborted) { | 648 if (status == DemuxerStream::kAborted) { |
| 620 if (!read_cb_.is_null()) | 649 if (!read_cb_.is_null()) |
| 621 SatisfyRead(DEMUXER_READ_ABORTED, NULL); | 650 SatisfyRead(DEMUXER_READ_ABORTED, NULL); |
| 622 return; | 651 return; |
| 623 } | 652 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 } | 769 } |
| 741 | 770 |
| 742 // The resetting process will be continued in OnDecoderReinitialized(). | 771 // The resetting process will be continued in OnDecoderReinitialized(). |
| 743 ReinitializeDecoder(); | 772 ReinitializeDecoder(); |
| 744 } | 773 } |
| 745 | 774 |
| 746 template class DecoderStream<DemuxerStream::VIDEO>; | 775 template class DecoderStream<DemuxerStream::VIDEO>; |
| 747 template class DecoderStream<DemuxerStream::AUDIO>; | 776 template class DecoderStream<DemuxerStream::AUDIO>; |
| 748 | 777 |
| 749 } // namespace media | 778 } // namespace media |
| OLD | NEW |