| 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" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
| 15 #include "media/base/bind_to_current_loop.h" | 15 #include "media/base/bind_to_current_loop.h" |
| 16 #include "media/base/cdm_context.h" |
| 16 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/limits.h" | 18 #include "media/base/limits.h" |
| 18 #include "media/base/media_log.h" | 19 #include "media/base/media_log.h" |
| 19 #include "media/base/timestamp_constants.h" | 20 #include "media/base/timestamp_constants.h" |
| 20 #include "media/base/video_decoder.h" | 21 #include "media/base/video_decoder.h" |
| 21 #include "media/base/video_frame.h" | 22 #include "media/base/video_frame.h" |
| 22 #include "media/filters/decrypting_demuxer_stream.h" | 23 #include "media/filters/decrypting_demuxer_stream.h" |
| 23 | 24 |
| 24 namespace media { | 25 namespace media { |
| 25 | 26 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 | 86 |
| 86 template <DemuxerStream::Type StreamType> | 87 template <DemuxerStream::Type StreamType> |
| 87 std::string DecoderStream<StreamType>::GetStreamTypeString() { | 88 std::string DecoderStream<StreamType>::GetStreamTypeString() { |
| 88 return DecoderStreamTraits<StreamType>::ToString(); | 89 return DecoderStreamTraits<StreamType>::ToString(); |
| 89 } | 90 } |
| 90 | 91 |
| 91 template <DemuxerStream::Type StreamType> | 92 template <DemuxerStream::Type StreamType> |
| 92 void DecoderStream<StreamType>::Initialize( | 93 void DecoderStream<StreamType>::Initialize( |
| 93 DemuxerStream* stream, | 94 DemuxerStream* stream, |
| 94 const InitCB& init_cb, | 95 const InitCB& init_cb, |
| 95 const SetCdmReadyCB& set_cdm_ready_cb, | 96 CdmContext* cdm_context, |
| 96 const StatisticsCB& statistics_cb, | 97 const StatisticsCB& statistics_cb, |
| 97 const base::Closure& waiting_for_decryption_key_cb) { | 98 const base::Closure& waiting_for_decryption_key_cb) { |
| 98 FUNCTION_DVLOG(2); | 99 FUNCTION_DVLOG(2); |
| 99 DCHECK(task_runner_->BelongsToCurrentThread()); | 100 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 100 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 101 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 101 DCHECK(init_cb_.is_null()); | 102 DCHECK(init_cb_.is_null()); |
| 102 DCHECK(!init_cb.is_null()); | 103 DCHECK(!init_cb.is_null()); |
| 103 | 104 |
| 104 statistics_cb_ = statistics_cb; | 105 statistics_cb_ = statistics_cb; |
| 105 init_cb_ = init_cb; | 106 init_cb_ = init_cb; |
| 106 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 107 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
| 107 stream_ = stream; | 108 stream_ = stream; |
| 108 | 109 |
| 109 state_ = STATE_INITIALIZING; | 110 state_ = STATE_INITIALIZING; |
| 110 SelectDecoder(set_cdm_ready_cb); | 111 SelectDecoder(cdm_context); |
| 111 } | 112 } |
| 112 | 113 |
| 113 template <DemuxerStream::Type StreamType> | 114 template <DemuxerStream::Type StreamType> |
| 114 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { | 115 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { |
| 115 FUNCTION_DVLOG(2); | 116 FUNCTION_DVLOG(2); |
| 116 DCHECK(task_runner_->BelongsToCurrentThread()); | 117 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 117 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) | 118 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) |
| 118 << state_; | 119 << state_; |
| 119 // No two reads in the flight at any time. | 120 // No two reads in the flight at any time. |
| 120 DCHECK(read_cb_.is_null()); | 121 DCHECK(read_cb_.is_null()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 218 } |
| 218 | 219 |
| 219 template <DemuxerStream::Type StreamType> | 220 template <DemuxerStream::Type StreamType> |
| 220 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { | 221 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { |
| 221 DCHECK(task_runner_->BelongsToCurrentThread()); | 222 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 222 return duration_tracker_.count() ? duration_tracker_.Average() | 223 return duration_tracker_.count() ? duration_tracker_.Average() |
| 223 : base::TimeDelta(); | 224 : base::TimeDelta(); |
| 224 } | 225 } |
| 225 | 226 |
| 226 template <DemuxerStream::Type StreamType> | 227 template <DemuxerStream::Type StreamType> |
| 227 void DecoderStream<StreamType>::SelectDecoder( | 228 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { |
| 228 const SetCdmReadyCB& set_cdm_ready_cb) { | |
| 229 decoder_selector_->SelectDecoder( | 229 decoder_selector_->SelectDecoder( |
| 230 stream_, set_cdm_ready_cb, | 230 stream_, cdm_context, |
| 231 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 231 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
| 232 weak_factory_.GetWeakPtr()), | 232 weak_factory_.GetWeakPtr()), |
| 233 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 233 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 234 weak_factory_.GetWeakPtr()), | 234 weak_factory_.GetWeakPtr()), |
| 235 waiting_for_decryption_key_cb_); | 235 waiting_for_decryption_key_cb_); |
| 236 } | 236 } |
| 237 | 237 |
| 238 template <DemuxerStream::Type StreamType> | 238 template <DemuxerStream::Type StreamType> |
| 239 void DecoderStream<StreamType>::OnDecoderSelected( | 239 void DecoderStream<StreamType>::OnDecoderSelected( |
| 240 scoped_ptr<Decoder> selected_decoder, | 240 scoped_ptr<Decoder> selected_decoder, |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 template <DemuxerStream::Type StreamType> | 523 template <DemuxerStream::Type StreamType> |
| 524 void DecoderStream<StreamType>::ReinitializeDecoder() { | 524 void DecoderStream<StreamType>::ReinitializeDecoder() { |
| 525 FUNCTION_DVLOG(2); | 525 FUNCTION_DVLOG(2); |
| 526 DCHECK(task_runner_->BelongsToCurrentThread()); | 526 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 527 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); | 527 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); |
| 528 DCHECK_EQ(pending_decode_requests_, 0); | 528 DCHECK_EQ(pending_decode_requests_, 0); |
| 529 | 529 |
| 530 state_ = STATE_REINITIALIZING_DECODER; | 530 state_ = STATE_REINITIALIZING_DECODER; |
| 531 // Decoders should not need CDMs during reinitialization. | 531 // Decoders should not need CDMs during reinitialization. |
| 532 DecoderStreamTraits<StreamType>::InitializeDecoder( | 532 DecoderStreamTraits<StreamType>::InitializeDecoder( |
| 533 decoder_.get(), stream_, SetCdmReadyCB(), | 533 decoder_.get(), stream_, nullptr, |
| 534 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, | 534 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, |
| 535 weak_factory_.GetWeakPtr()), | 535 weak_factory_.GetWeakPtr()), |
| 536 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 536 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 537 weak_factory_.GetWeakPtr())); | 537 weak_factory_.GetWeakPtr())); |
| 538 } | 538 } |
| 539 | 539 |
| 540 template <DemuxerStream::Type StreamType> | 540 template <DemuxerStream::Type StreamType> |
| 541 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { | 541 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { |
| 542 FUNCTION_DVLOG(2); | 542 FUNCTION_DVLOG(2); |
| 543 DCHECK(task_runner_->BelongsToCurrentThread()); | 543 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 544 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); | 544 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); |
| 545 | 545 |
| 546 // ReinitializeDecoder() can be called in two cases: | 546 // ReinitializeDecoder() can be called in two cases: |
| 547 // 1, Flushing decoder finished (see OnDecodeOutputReady()). | 547 // 1, Flushing decoder finished (see OnDecodeOutputReady()). |
| 548 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). | 548 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). |
| 549 // Also, Reset() can be called during pending ReinitializeDecoder(). | 549 // Also, Reset() can be called during pending ReinitializeDecoder(). |
| 550 // This function needs to handle them all! | 550 // This function needs to handle them all! |
| 551 | 551 |
| 552 if (!success) { | 552 if (!success) { |
| 553 // Reinitialization failed. Try to fall back to one of the remaining | 553 // Reinitialization failed. Try to fall back to one of the remaining |
| 554 // decoders. This will consume at least one decoder so doing it more than | 554 // decoders. This will consume at least one decoder so doing it more than |
| 555 // once is safe. | 555 // once is safe. |
| 556 // For simplicity, don't attempt to fall back to a decrypting decoder. | 556 // For simplicity, don't attempt to fall back to a decrypting decoder. |
| 557 // Calling this with a null callback ensures that one won't be selected. | 557 // Calling this with a null CdmContext ensures that one won't be selected. |
| 558 SelectDecoder(SetCdmReadyCB()); | 558 SelectDecoder(nullptr); |
| 559 } else { | 559 } else { |
| 560 CompleteDecoderReinitialization(true); | 560 CompleteDecoderReinitialization(true); |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 | 563 |
| 564 template <DemuxerStream::Type StreamType> | 564 template <DemuxerStream::Type StreamType> |
| 565 void DecoderStream<StreamType>::CompleteDecoderReinitialization(bool success) { | 565 void DecoderStream<StreamType>::CompleteDecoderReinitialization(bool success) { |
| 566 FUNCTION_DVLOG(2); | 566 FUNCTION_DVLOG(2); |
| 567 DCHECK(task_runner_->BelongsToCurrentThread()); | 567 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 568 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); | 568 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } | 618 } |
| 619 | 619 |
| 620 // The resetting process will be continued in OnDecoderReinitialized(). | 620 // The resetting process will be continued in OnDecoderReinitialized(). |
| 621 ReinitializeDecoder(); | 621 ReinitializeDecoder(); |
| 622 } | 622 } |
| 623 | 623 |
| 624 template class DecoderStream<DemuxerStream::VIDEO>; | 624 template class DecoderStream<DemuxerStream::VIDEO>; |
| 625 template class DecoderStream<DemuxerStream::AUDIO>; | 625 template class DecoderStream<DemuxerStream::AUDIO>; |
| 626 | 626 |
| 627 } // namespace media | 627 } // namespace media |
| OLD | NEW |