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 "webkit/media/crypto/ppapi_decryptor.h" | 5 #include "webkit/media/crypto/ppapi_decryptor.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
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/message_loop.h" | 13 #include "base/message_loop.h" |
14 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
15 #include "media/base/audio_decoder_config.h" | |
15 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
16 #include "media/base/decryptor_client.h" | 17 #include "media/base/decryptor_client.h" |
17 #include "media/base/video_decoder_config.h" | 18 #include "media/base/video_decoder_config.h" |
18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
19 #include "webkit/media/crypto/key_systems.h" | 20 #include "webkit/media/crypto/key_systems.h" |
20 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 21 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
21 | 22 |
22 namespace webkit_media { | 23 namespace webkit_media { |
23 | 24 |
24 PpapiDecryptor::PpapiDecryptor( | 25 PpapiDecryptor::PpapiDecryptor( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 DCHECK(cdm_plugin_); | 67 DCHECK(cdm_plugin_); |
67 | 68 |
68 if (!cdm_plugin_->AddKey(session_id, | 69 if (!cdm_plugin_->AddKey(session_id, |
69 std::string(reinterpret_cast<const char*>(key), | 70 std::string(reinterpret_cast<const char*>(key), |
70 key_length), | 71 key_length), |
71 std::string(reinterpret_cast<const char*>(init_data), | 72 std::string(reinterpret_cast<const char*>(init_data), |
72 init_data_length))) { | 73 init_data_length))) { |
73 ReportFailureToCallPlugin(key_system, session_id); | 74 ReportFailureToCallPlugin(key_system, session_id); |
74 } | 75 } |
75 | 76 |
76 if (!key_added_cb_.is_null()) | 77 if (!audio_key_added_cb_.is_null()) |
77 key_added_cb_.Run(); | 78 audio_key_added_cb_.Run(); |
79 | |
80 if (!video_key_added_cb_.is_null()) | |
81 video_key_added_cb_.Run(); | |
78 } | 82 } |
79 | 83 |
80 void PpapiDecryptor::CancelKeyRequest(const std::string& key_system, | 84 void PpapiDecryptor::CancelKeyRequest(const std::string& key_system, |
81 const std::string& session_id) { | 85 const std::string& session_id) { |
82 DVLOG(2) << "CancelKeyRequest()"; | 86 DVLOG(2) << "CancelKeyRequest()"; |
83 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); | 87 DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
84 DCHECK(cdm_plugin_); | 88 DCHECK(cdm_plugin_); |
85 | 89 |
86 if (!cdm_plugin_->CancelKeyRequest(session_id)) | 90 if (!cdm_plugin_->CancelKeyRequest(session_id)) |
87 ReportFailureToCallPlugin(key_system, session_id); | 91 ReportFailureToCallPlugin(key_system, session_id); |
88 } | 92 } |
89 | 93 |
90 // TODO(xhwang): Remove Unretained in the following methods. | 94 // TODO(xhwang): Remove Unretained in the following methods. |
91 | 95 |
92 void PpapiDecryptor::Decrypt( | 96 void PpapiDecryptor::Decrypt( |
97 StreamType stream_type, | |
93 const scoped_refptr<media::DecoderBuffer>& encrypted, | 98 const scoped_refptr<media::DecoderBuffer>& encrypted, |
94 const DecryptCB& decrypt_cb) { | 99 const DecryptCB& decrypt_cb) { |
95 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 100 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
96 render_loop_proxy_->PostTask( | 101 render_loop_proxy_->PostTask( |
97 FROM_HERE, | 102 FROM_HERE, |
98 base::Bind(&PpapiDecryptor::Decrypt, base::Unretained(this), | 103 base::Bind(&PpapiDecryptor::Decrypt, base::Unretained(this), |
99 encrypted, decrypt_cb)); | 104 stream_type, encrypted, decrypt_cb)); |
100 return; | 105 return; |
101 } | 106 } |
102 | 107 |
103 DVLOG(3) << "Decrypt()"; | 108 DVLOG(3) << "Decrypt()"; |
104 if (!cdm_plugin_->Decrypt(encrypted, decrypt_cb)) | 109 if (!cdm_plugin_->Decrypt(encrypted, decrypt_cb)) |
105 decrypt_cb.Run(kError, NULL); | 110 decrypt_cb.Run(kError, NULL); |
106 } | 111 } |
107 | 112 |
108 void PpapiDecryptor::CancelDecrypt() { | 113 void PpapiDecryptor::CancelDecrypt(StreamType stream_type) { |
109 DVLOG(1) << "CancelDecrypt()"; | 114 DVLOG(1) << "CancelDecrypt()"; |
110 // TODO(xhwang): Implement CancelDecrypt() in PluginInstance and call it here. | 115 // TODO(xhwang): Implement CancelDecrypt() in PluginInstance and call it here. |
111 } | 116 } |
112 | 117 |
118 void PpapiDecryptor::InitializeAudioDecoder( | |
119 scoped_ptr<media::AudioDecoderConfig> config, | |
120 const DecoderInitCB& init_cb, | |
121 const KeyAddedCB& key_added_cb) { | |
122 if (!render_loop_proxy_->BelongsToCurrentThread()) { | |
123 render_loop_proxy_->PostTask( | |
124 FROM_HERE, | |
125 base::Bind(&PpapiDecryptor::InitializeAudioDecoder, | |
126 base::Unretained(this), base::Passed(&config), | |
127 init_cb, key_added_cb)); | |
128 return; | |
129 } | |
130 | |
131 DVLOG(2) << "InitializeAudioDecoder()"; | |
132 DCHECK(config->is_encrypted()); | |
133 DCHECK(config->IsValidConfig()); | |
134 | |
135 audio_decoder_init_cb_ = init_cb; | |
136 // TODO(xhwang): Implement InitializeAudioDecoder() in PluginInstance and call | |
137 // it here. | |
138 // if (!cdm_plugin_->InitializeAudioDecoder( | |
139 // *config, | |
140 // base::Bind(&PpapiDecryptor::OnDecoderInitialized, | |
141 // base::Unretained(this), kAudio, key_added_cb))) { | |
142 // base::ResetAndReturn(&audio_decoder_init_cb_).Run(false); | |
ddorwin
2012/10/17 02:52:33
Uncomment this instead of 146? Then move 145 up to
xhwang
2012/10/17 22:29:06
Done.
| |
143 // return; | |
144 // } | |
145 NOTIMPLEMENTED(); | |
146 base::ResetAndReturn(&audio_decoder_init_cb_).Run(false); | |
147 } | |
148 | |
113 void PpapiDecryptor::InitializeVideoDecoder( | 149 void PpapiDecryptor::InitializeVideoDecoder( |
114 scoped_ptr<media::VideoDecoderConfig> config, | 150 scoped_ptr<media::VideoDecoderConfig> config, |
115 const DecoderInitCB& init_cb, | 151 const DecoderInitCB& init_cb, |
116 const KeyAddedCB& key_added_cb) { | 152 const KeyAddedCB& key_added_cb) { |
117 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 153 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
118 render_loop_proxy_->PostTask( | 154 render_loop_proxy_->PostTask( |
119 FROM_HERE, | 155 FROM_HERE, |
120 base::Bind(&PpapiDecryptor::InitializeVideoDecoder, | 156 base::Bind(&PpapiDecryptor::InitializeVideoDecoder, |
121 base::Unretained(this), base::Passed(&config), | 157 base::Unretained(this), base::Passed(&config), |
122 init_cb, key_added_cb)); | 158 init_cb, key_added_cb)); |
123 return; | 159 return; |
124 } | 160 } |
125 | 161 |
126 DVLOG(2) << "InitializeVideoDecoder()"; | 162 DVLOG(2) << "InitializeVideoDecoder()"; |
127 DCHECK(config->is_encrypted()); | 163 DCHECK(config->is_encrypted()); |
128 DCHECK(config->IsValidConfig()); | 164 DCHECK(config->IsValidConfig()); |
129 | 165 |
130 video_decoder_init_cb_ = init_cb; | 166 video_decoder_init_cb_ = init_cb; |
131 key_added_cb_ = key_added_cb; | |
132 | |
133 if (!cdm_plugin_->InitializeVideoDecoder( | 167 if (!cdm_plugin_->InitializeVideoDecoder( |
134 *config, | 168 *config, |
135 base::Bind(&PpapiDecryptor::OnVideoDecoderInitialized, | 169 base::Bind(&PpapiDecryptor::OnDecoderInitialized, |
136 base::Unretained(this)))) { | 170 base::Unretained(this), kVideo, key_added_cb))) { |
137 key_added_cb_.Reset(); | |
138 base::ResetAndReturn(&video_decoder_init_cb_).Run(false); | 171 base::ResetAndReturn(&video_decoder_init_cb_).Run(false); |
139 return; | 172 return; |
140 } | 173 } |
141 } | 174 } |
142 | 175 |
176 void PpapiDecryptor::DecryptAndDecodeAudio( | |
177 const scoped_refptr<media::DecoderBuffer>& encrypted, | |
178 const AudioDecodeCB& audio_decode_cb) { | |
179 if (!render_loop_proxy_->BelongsToCurrentThread()) { | |
180 render_loop_proxy_->PostTask( | |
181 FROM_HERE, | |
182 base::Bind(&PpapiDecryptor::DecryptAndDecodeAudio, | |
183 base::Unretained(this), encrypted, audio_decode_cb)); | |
184 return; | |
185 } | |
186 | |
187 DVLOG(1) << "DecryptAndDecodeAudio()"; | |
188 // TODO(xhwang): Enable this once PluginInstance is updated. | |
189 // if (!cdm_plugin_->DecryptAndDecodeAudio(encrypted, audio_decode_cb)) | |
190 // audio_decode_cb.Run(kError, NULL); | |
ddorwin
2012/10/17 02:52:33
same.
And why does 192 have scoped_ptr instead of
xhwang
2012/10/17 22:29:06
It's not relevant now. But for your question, beca
| |
191 NOTIMPLEMENTED(); | |
192 audio_decode_cb.Run(kError, scoped_ptr<AudioBuffers>()); | |
193 } | |
194 | |
143 void PpapiDecryptor::DecryptAndDecodeVideo( | 195 void PpapiDecryptor::DecryptAndDecodeVideo( |
144 const scoped_refptr<media::DecoderBuffer>& encrypted, | 196 const scoped_refptr<media::DecoderBuffer>& encrypted, |
145 const VideoDecodeCB& video_decode_cb) { | 197 const VideoDecodeCB& video_decode_cb) { |
146 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 198 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
147 render_loop_proxy_->PostTask( | 199 render_loop_proxy_->PostTask( |
148 FROM_HERE, | 200 FROM_HERE, |
149 base::Bind(&PpapiDecryptor::DecryptAndDecodeVideo, | 201 base::Bind(&PpapiDecryptor::DecryptAndDecodeVideo, |
150 base::Unretained(this), encrypted, video_decode_cb)); | 202 base::Unretained(this), encrypted, video_decode_cb)); |
151 return; | 203 return; |
152 } | 204 } |
153 | 205 |
154 DVLOG(3) << "DecryptAndDecodeVideo()"; | 206 DVLOG(3) << "DecryptAndDecodeVideo()"; |
155 if (!cdm_plugin_->DecryptAndDecode(encrypted, video_decode_cb)) | 207 if (!cdm_plugin_->DecryptAndDecode(encrypted, video_decode_cb)) |
156 video_decode_cb.Run(kError, NULL); | 208 video_decode_cb.Run(kError, NULL); |
157 } | 209 } |
158 | 210 |
159 void PpapiDecryptor::CancelDecryptAndDecodeVideo() { | 211 void PpapiDecryptor::ResetDecoder(StreamType stream_type) { |
160 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 212 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
161 render_loop_proxy_->PostTask( | 213 render_loop_proxy_->PostTask( |
162 FROM_HERE, | 214 FROM_HERE, |
163 base::Bind(&PpapiDecryptor::CancelDecryptAndDecodeVideo, | 215 base::Bind(&PpapiDecryptor::ResetDecoder, |
164 base::Unretained(this))); | 216 base::Unretained(this), stream_type)); |
165 return; | 217 return; |
166 } | 218 } |
167 | 219 |
168 DVLOG(2) << "CancelDecryptAndDecodeVideo()"; | 220 DVLOG(2) << "ResetDecoder()"; |
ddorwin
2012/10/17 07:16:05
Log stream_type throughout?
xhwang
2012/10/17 22:29:06
Done.
| |
169 cdm_plugin_->ResetDecoder(); | 221 cdm_plugin_->ResetDecoder(); |
ddorwin
2012/10/17 07:16:05
TODO: Add type param?
xhwang
2012/10/17 22:29:06
Done.
| |
170 } | 222 } |
171 | 223 |
172 void PpapiDecryptor::StopVideoDecoder() { | 224 void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) { |
173 if (!render_loop_proxy_->BelongsToCurrentThread()) { | 225 if (!render_loop_proxy_->BelongsToCurrentThread()) { |
174 render_loop_proxy_->PostTask( | 226 render_loop_proxy_->PostTask( |
175 FROM_HERE, | 227 FROM_HERE, |
176 base::Bind(&PpapiDecryptor::StopVideoDecoder, base::Unretained(this))); | 228 base::Bind(&PpapiDecryptor::DeinitializeDecoder, |
229 base::Unretained(this), stream_type)); | |
177 return; | 230 return; |
178 } | 231 } |
179 | 232 |
180 DVLOG(2) << "StopVideoDecoder()"; | 233 DVLOG(2) << "DeinitializeDecoder()"; |
181 cdm_plugin_->DeinitializeDecoder(); | 234 cdm_plugin_->DeinitializeDecoder(); |
182 } | 235 } |
183 | 236 |
184 void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& key_system, | 237 void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& key_system, |
185 const std::string& session_id) { | 238 const std::string& session_id) { |
186 DVLOG(1) << "Failed to call plugin."; | 239 DVLOG(1) << "Failed to call plugin."; |
187 client_->KeyError(key_system, session_id, kUnknownError, 0); | 240 client_->KeyError(key_system, session_id, kUnknownError, 0); |
188 } | 241 } |
189 | 242 |
190 void PpapiDecryptor::OnVideoDecoderInitialized(bool success) { | 243 void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type, |
191 DCHECK(!key_added_cb_.is_null()); | 244 const KeyAddedCB& key_added_cb, |
192 DCHECK(!video_decoder_init_cb_.is_null()); | 245 bool success) { |
246 DCHECK(!key_added_cb.is_null()); | |
193 | 247 |
194 if (!success) | 248 if (stream_type == kAudio) { |
ddorwin
2012/10/17 02:52:33
Should we use a switch?
xhwang
2012/10/17 22:29:06
Done.
| |
195 key_added_cb_.Reset(); | 249 DCHECK(audio_key_added_cb_.is_null()); |
250 DCHECK(!audio_decoder_init_cb_.is_null()); | |
251 if (success) | |
252 audio_key_added_cb_ = key_added_cb; | |
253 base::ResetAndReturn(&audio_decoder_init_cb_).Run(success); | |
254 return; | |
255 } | |
196 | 256 |
197 base::ResetAndReturn(&video_decoder_init_cb_).Run(success); | 257 if (stream_type == kVideo) { |
258 DCHECK(video_key_added_cb_.is_null()); | |
259 DCHECK(!video_decoder_init_cb_.is_null()); | |
260 if (success) | |
261 video_key_added_cb_ = key_added_cb; | |
262 base::ResetAndReturn(&video_decoder_init_cb_).Run(success); | |
263 return; | |
264 } | |
265 | |
266 NOTREACHED(); | |
198 } | 267 } |
199 | 268 |
200 } // namespace webkit_media | 269 } // namespace webkit_media |
OLD | NEW |