OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/decrypting_video_decoder.h" | 5 #include "media/filters/decrypting_video_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
13 #include "media/base/bind_to_current_loop.h" | 13 #include "media/base/bind_to_current_loop.h" |
| 14 #include "media/base/cdm_context.h" |
14 #include "media/base/decoder_buffer.h" | 15 #include "media/base/decoder_buffer.h" |
15 #include "media/base/media_log.h" | 16 #include "media/base/media_log.h" |
16 #include "media/base/pipeline.h" | 17 #include "media/base/pipeline.h" |
17 #include "media/base/video_frame.h" | 18 #include "media/base/video_frame.h" |
18 | 19 |
19 namespace media { | 20 namespace media { |
20 | 21 |
21 const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder"; | 22 const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder"; |
22 | 23 |
23 DecryptingVideoDecoder::DecryptingVideoDecoder( | 24 DecryptingVideoDecoder::DecryptingVideoDecoder( |
24 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 25 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
25 const scoped_refptr<MediaLog>& media_log, | 26 const scoped_refptr<MediaLog>& media_log, |
26 const base::Closure& waiting_for_decryption_key_cb) | 27 const base::Closure& waiting_for_decryption_key_cb) |
27 : task_runner_(task_runner), | 28 : task_runner_(task_runner), |
28 media_log_(media_log), | 29 media_log_(media_log), |
29 state_(kUninitialized), | 30 state_(kUninitialized), |
30 waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), | 31 waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), |
31 decryptor_(NULL), | 32 decryptor_(NULL), |
32 key_added_while_decode_pending_(false), | 33 key_added_while_decode_pending_(false), |
33 trace_id_(0), | 34 trace_id_(0), |
34 weak_factory_(this) {} | 35 weak_factory_(this) {} |
35 | 36 |
36 std::string DecryptingVideoDecoder::GetDisplayName() const { | 37 std::string DecryptingVideoDecoder::GetDisplayName() const { |
37 return kDecoderName; | 38 return kDecoderName; |
38 } | 39 } |
39 | 40 |
40 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, | 41 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, |
41 bool /* low_delay */, | 42 bool /* low_delay */, |
42 const SetCdmReadyCB& set_cdm_ready_cb, | 43 CdmContext* cdm_context, |
43 const InitCB& init_cb, | 44 const InitCB& init_cb, |
44 const OutputCB& output_cb) { | 45 const OutputCB& output_cb) { |
45 DVLOG(2) << __FUNCTION__ << ": " << config.AsHumanReadableString(); | 46 DVLOG(2) << __FUNCTION__ << ": " << config.AsHumanReadableString(); |
46 | 47 |
47 DCHECK(task_runner_->BelongsToCurrentThread()); | 48 DCHECK(task_runner_->BelongsToCurrentThread()); |
48 DCHECK(state_ == kUninitialized || | 49 DCHECK(state_ == kUninitialized || |
49 state_ == kIdle || | 50 state_ == kIdle || |
50 state_ == kDecodeFinished) << state_; | 51 state_ == kDecodeFinished) << state_; |
51 DCHECK(decode_cb_.is_null()); | 52 DCHECK(decode_cb_.is_null()); |
52 DCHECK(reset_cb_.is_null()); | 53 DCHECK(reset_cb_.is_null()); |
53 DCHECK(config.IsValidConfig()); | 54 DCHECK(config.IsValidConfig()); |
54 DCHECK(config.is_encrypted()); | 55 DCHECK(config.is_encrypted()); |
55 | 56 |
56 init_cb_ = BindToCurrentLoop(init_cb); | 57 init_cb_ = BindToCurrentLoop(init_cb); |
57 output_cb_ = BindToCurrentLoop(output_cb); | 58 output_cb_ = BindToCurrentLoop(output_cb); |
58 weak_this_ = weak_factory_.GetWeakPtr(); | 59 weak_this_ = weak_factory_.GetWeakPtr(); |
59 config_ = config; | 60 config_ = config; |
60 | 61 |
61 if (state_ == kUninitialized) { | 62 if (state_ == kUninitialized) { |
62 DCHECK(!set_cdm_ready_cb.is_null()); | 63 DCHECK(cdm_context); |
63 state_ = kDecryptorRequested; | 64 if (!cdm_context->GetDecryptor()) { |
64 set_cdm_ready_cb_ = set_cdm_ready_cb; | 65 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor"; |
65 set_cdm_ready_cb_.Run(BindToCurrentLoop( | 66 base::ResetAndReturn(&init_cb_).Run(false); |
66 base::Bind(&DecryptingVideoDecoder::SetCdm, weak_this_))); | 67 return; |
67 return; | 68 } |
| 69 |
| 70 decryptor_ = cdm_context->GetDecryptor(); |
| 71 } else { |
| 72 // Reinitialization. |
| 73 decryptor_->DeinitializeDecoder(Decryptor::kVideo); |
68 } | 74 } |
69 | 75 |
70 // Reinitialization. | |
71 decryptor_->DeinitializeDecoder(Decryptor::kVideo); | |
72 state_ = kPendingDecoderInit; | 76 state_ = kPendingDecoderInit; |
73 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind( | 77 decryptor_->InitializeVideoDecoder( |
74 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); | 78 config_, BindToCurrentLoop(base::Bind( |
| 79 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); |
75 } | 80 } |
76 | 81 |
77 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 82 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
78 const DecodeCB& decode_cb) { | 83 const DecodeCB& decode_cb) { |
79 DVLOG(3) << "Decode()"; | 84 DVLOG(3) << "Decode()"; |
80 DCHECK(task_runner_->BelongsToCurrentThread()); | 85 DCHECK(task_runner_->BelongsToCurrentThread()); |
81 DCHECK(state_ == kIdle || | 86 DCHECK(state_ == kIdle || |
82 state_ == kDecodeFinished || | 87 state_ == kDecodeFinished || |
83 state_ == kError) << state_; | 88 state_ == kError) << state_; |
84 DCHECK(!decode_cb.is_null()); | 89 DCHECK(!decode_cb.is_null()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 DecryptingVideoDecoder::~DecryptingVideoDecoder() { | 144 DecryptingVideoDecoder::~DecryptingVideoDecoder() { |
140 DCHECK(task_runner_->BelongsToCurrentThread()); | 145 DCHECK(task_runner_->BelongsToCurrentThread()); |
141 | 146 |
142 if (state_ == kUninitialized) | 147 if (state_ == kUninitialized) |
143 return; | 148 return; |
144 | 149 |
145 if (decryptor_) { | 150 if (decryptor_) { |
146 decryptor_->DeinitializeDecoder(Decryptor::kVideo); | 151 decryptor_->DeinitializeDecoder(Decryptor::kVideo); |
147 decryptor_ = NULL; | 152 decryptor_ = NULL; |
148 } | 153 } |
149 if (!set_cdm_ready_cb_.is_null()) | |
150 base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); | |
151 pending_buffer_to_decode_ = NULL; | 154 pending_buffer_to_decode_ = NULL; |
152 if (!init_cb_.is_null()) | 155 if (!init_cb_.is_null()) |
153 base::ResetAndReturn(&init_cb_).Run(false); | 156 base::ResetAndReturn(&init_cb_).Run(false); |
154 if (!decode_cb_.is_null()) | 157 if (!decode_cb_.is_null()) |
155 base::ResetAndReturn(&decode_cb_).Run(kAborted); | 158 base::ResetAndReturn(&decode_cb_).Run(kAborted); |
156 if (!reset_cb_.is_null()) | 159 if (!reset_cb_.is_null()) |
157 base::ResetAndReturn(&reset_cb_).Run(); | 160 base::ResetAndReturn(&reset_cb_).Run(); |
158 } | 161 } |
159 | 162 |
160 void DecryptingVideoDecoder::SetCdm(CdmContext* cdm_context, | |
161 const CdmAttachedCB& cdm_attached_cb) { | |
162 DVLOG(2) << __FUNCTION__; | |
163 DCHECK(task_runner_->BelongsToCurrentThread()); | |
164 DCHECK_EQ(state_, kDecryptorRequested) << state_; | |
165 DCHECK(!init_cb_.is_null()); | |
166 DCHECK(!set_cdm_ready_cb_.is_null()); | |
167 set_cdm_ready_cb_.Reset(); | |
168 | |
169 if (!cdm_context || !cdm_context->GetDecryptor()) { | |
170 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor set"; | |
171 base::ResetAndReturn(&init_cb_).Run(false); | |
172 state_ = kError; | |
173 cdm_attached_cb.Run(false); | |
174 return; | |
175 } | |
176 | |
177 decryptor_ = cdm_context->GetDecryptor(); | |
178 | |
179 state_ = kPendingDecoderInit; | |
180 decryptor_->InitializeVideoDecoder( | |
181 config_, | |
182 BindToCurrentLoop(base::Bind( | |
183 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); | |
184 cdm_attached_cb.Run(true); | |
185 } | |
186 | |
187 void DecryptingVideoDecoder::FinishInitialization(bool success) { | 163 void DecryptingVideoDecoder::FinishInitialization(bool success) { |
188 DVLOG(2) << "FinishInitialization()"; | 164 DVLOG(2) << "FinishInitialization()"; |
189 DCHECK(task_runner_->BelongsToCurrentThread()); | 165 DCHECK(task_runner_->BelongsToCurrentThread()); |
190 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 166 DCHECK_EQ(state_, kPendingDecoderInit) << state_; |
191 DCHECK(!init_cb_.is_null()); | 167 DCHECK(!init_cb_.is_null()); |
192 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 168 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
193 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. | 169 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. |
194 | 170 |
195 if (!success) { | 171 if (!success) { |
196 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() | 172 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 301 } |
326 | 302 |
327 void DecryptingVideoDecoder::DoReset() { | 303 void DecryptingVideoDecoder::DoReset() { |
328 DCHECK(init_cb_.is_null()); | 304 DCHECK(init_cb_.is_null()); |
329 DCHECK(decode_cb_.is_null()); | 305 DCHECK(decode_cb_.is_null()); |
330 state_ = kIdle; | 306 state_ = kIdle; |
331 base::ResetAndReturn(&reset_cb_).Run(); | 307 base::ResetAndReturn(&reset_cb_).Run(); |
332 } | 308 } |
333 | 309 |
334 } // namespace media | 310 } // namespace media |
OLD | NEW |