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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 } | 521 } |
522 | 522 |
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 a new CDM 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 |