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_audio_decoder.h" | 5 #include "media/filters/decrypting_audio_decoder.h" |
6 | 6 |
7 #include <cstdlib> | 7 #include <cstdlib> |
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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 DCHECK(task_runner_->BelongsToCurrentThread()); | 113 DCHECK(task_runner_->BelongsToCurrentThread()); |
114 DCHECK(state_ == kIdle || | 114 DCHECK(state_ == kIdle || |
115 state_ == kPendingConfigChange || | 115 state_ == kPendingConfigChange || |
116 state_ == kPendingDemuxerRead || | 116 state_ == kPendingDemuxerRead || |
117 state_ == kPendingDecode || | 117 state_ == kPendingDecode || |
118 state_ == kWaitingForKey || | 118 state_ == kWaitingForKey || |
119 state_ == kDecodeFinished) << state_; | 119 state_ == kDecodeFinished) << state_; |
120 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 120 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
121 DCHECK(reset_cb_.is_null()); | 121 DCHECK(reset_cb_.is_null()); |
122 | 122 |
123 reset_cb_ = BindToCurrentLoop(closure); | 123 reset_cb_ = closure; |
124 | 124 |
125 decryptor_->ResetDecoder(Decryptor::kAudio); | 125 decryptor_->ResetDecoder(Decryptor::kAudio); |
126 | 126 |
127 // Reset() cannot complete if the read callback is still pending. | 127 // Reset() cannot complete if the read callback is still pending. |
128 // Defer the resetting process in this case. The |reset_cb_| will be fired | 128 // Defer the resetting process in this case. The |reset_cb_| will be fired |
129 // after the read callback is fired - see DecryptAndDecodeBuffer() and | 129 // after the read callback is fired - see DecryptAndDecodeBuffer() and |
130 // DeliverFrame(). | 130 // DeliverFrame(). |
131 if (state_ == kPendingConfigChange || | 131 if (state_ == kPendingConfigChange || |
132 state_ == kPendingDemuxerRead || | 132 state_ == kPendingDemuxerRead || |
133 state_ == kPendingDecode) { | 133 state_ == kPendingDecode) { |
134 DCHECK(!read_cb_.is_null()); | 134 DCHECK(!read_cb_.is_null()); |
135 return; | 135 return; |
136 } | 136 } |
137 | 137 |
138 if (state_ == kWaitingForKey) { | 138 if (state_ == kWaitingForKey) { |
139 DCHECK(!read_cb_.is_null()); | 139 DCHECK(!read_cb_.is_null()); |
140 pending_buffer_to_decode_ = NULL; | 140 pending_buffer_to_decode_ = NULL; |
141 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 141 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
142 } | 142 } |
143 | 143 |
144 DCHECK(read_cb_.is_null()); | 144 DCHECK(read_cb_.is_null()); |
145 DoReset(); | 145 DoReset(); |
146 } | 146 } |
147 | 147 |
148 void DecryptingAudioDecoder::Stop(const base::Closure& closure) { | |
149 DVLOG(2) << "Stop() - state: " << state_; | |
150 DCHECK(task_runner_->BelongsToCurrentThread()); | |
151 | |
152 if (decryptor_) { | |
153 decryptor_->RegisterNewKeyCB(Decryptor::kAudio, Decryptor::NewKeyCB()); | |
154 decryptor_->DeinitializeDecoder(Decryptor::kAudio); | |
155 decryptor_ = NULL; | |
156 } | |
157 if (!set_decryptor_ready_cb_.is_null()) | |
158 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); | |
159 pending_buffer_to_decode_ = NULL; | |
160 if (!init_cb_.is_null()) | |
161 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | |
162 if (!read_cb_.is_null()) | |
163 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
164 if (!reset_cb_.is_null()) | |
165 base::ResetAndReturn(&reset_cb_).Run(); | |
166 state_ = kStopped; | |
167 task_runner_->PostTask(FROM_HERE, closure); | |
168 } | |
169 | |
170 int DecryptingAudioDecoder::bits_per_channel() { | 148 int DecryptingAudioDecoder::bits_per_channel() { |
171 DCHECK(task_runner_->BelongsToCurrentThread()); | 149 DCHECK(task_runner_->BelongsToCurrentThread()); |
172 return bits_per_channel_; | 150 return bits_per_channel_; |
173 } | 151 } |
174 | 152 |
175 ChannelLayout DecryptingAudioDecoder::channel_layout() { | 153 ChannelLayout DecryptingAudioDecoder::channel_layout() { |
176 DCHECK(task_runner_->BelongsToCurrentThread()); | 154 DCHECK(task_runner_->BelongsToCurrentThread()); |
177 return channel_layout_; | 155 return channel_layout_; |
178 } | 156 } |
179 | 157 |
180 int DecryptingAudioDecoder::samples_per_second() { | 158 int DecryptingAudioDecoder::samples_per_second() { |
181 DCHECK(task_runner_->BelongsToCurrentThread()); | 159 DCHECK(task_runner_->BelongsToCurrentThread()); |
182 return samples_per_second_; | 160 return samples_per_second_; |
183 } | 161 } |
184 | 162 |
185 DecryptingAudioDecoder::~DecryptingAudioDecoder() { | 163 DecryptingAudioDecoder::~DecryptingAudioDecoder() { |
186 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; | |
187 } | 164 } |
188 | 165 |
189 void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) { | 166 void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) { |
190 DVLOG(2) << "SetDecryptor()"; | 167 DVLOG(2) << "SetDecryptor()"; |
191 DCHECK(task_runner_->BelongsToCurrentThread()); | 168 DCHECK(task_runner_->BelongsToCurrentThread()); |
192 | |
193 if (state_ == kStopped) | |
194 return; | |
195 | |
196 DCHECK_EQ(state_, kDecryptorRequested) << state_; | 169 DCHECK_EQ(state_, kDecryptorRequested) << state_; |
197 DCHECK(!init_cb_.is_null()); | 170 DCHECK(!init_cb_.is_null()); |
198 DCHECK(!set_decryptor_ready_cb_.is_null()); | 171 DCHECK(!set_decryptor_ready_cb_.is_null()); |
199 | 172 |
200 set_decryptor_ready_cb_.Reset(); | 173 set_decryptor_ready_cb_.Reset(); |
201 | 174 |
202 if (!decryptor) { | 175 if (!decryptor) { |
203 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 176 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
204 // TODO(xhwang): Add kError state. See http://crbug.com/251503 | 177 // TODO(xhwang): Add kError state. See http://crbug.com/251503 |
205 state_ = kStopped; | 178 state_ = kDecodeFinished; |
206 return; | 179 return; |
207 } | 180 } |
208 | 181 |
209 decryptor_ = decryptor; | 182 decryptor_ = decryptor; |
210 | 183 |
211 const AudioDecoderConfig& input_config = | 184 const AudioDecoderConfig& input_config = |
212 demuxer_stream_->audio_decoder_config(); | 185 demuxer_stream_->audio_decoder_config(); |
213 AudioDecoderConfig config; | 186 AudioDecoderConfig config; |
214 config.Initialize(input_config.codec(), | 187 config.Initialize(input_config.codec(), |
215 kSampleFormatS16, | 188 kSampleFormatS16, |
216 input_config.channel_layout(), | 189 input_config.channel_layout(), |
217 input_config.samples_per_second(), | 190 input_config.samples_per_second(), |
218 input_config.extra_data(), | 191 input_config.extra_data(), |
219 input_config.extra_data_size(), | 192 input_config.extra_data_size(), |
220 input_config.is_encrypted(), | 193 input_config.is_encrypted(), |
221 false, | 194 false, |
222 base::TimeDelta(), | 195 base::TimeDelta(), |
223 base::TimeDelta()); | 196 base::TimeDelta()); |
224 | 197 |
225 state_ = kPendingDecoderInit; | 198 state_ = kPendingDecoderInit; |
226 decryptor_->InitializeAudioDecoder( | 199 decryptor_->InitializeAudioDecoder( |
227 config, | 200 config, |
228 BindToCurrentLoop(base::Bind( | 201 BindToCurrentLoop(base::Bind( |
229 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); | 202 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); |
230 } | 203 } |
231 | 204 |
232 void DecryptingAudioDecoder::FinishInitialization(bool success) { | 205 void DecryptingAudioDecoder::FinishInitialization(bool success) { |
233 DVLOG(2) << "FinishInitialization()"; | 206 DVLOG(2) << "FinishInitialization()"; |
234 DCHECK(task_runner_->BelongsToCurrentThread()); | 207 DCHECK(task_runner_->BelongsToCurrentThread()); |
235 | |
236 if (state_ == kStopped) | |
237 return; | |
238 | |
239 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 208 DCHECK_EQ(state_, kPendingDecoderInit) << state_; |
240 DCHECK(!init_cb_.is_null()); | 209 DCHECK(!init_cb_.is_null()); |
241 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 210 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
242 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. | 211 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. |
243 | 212 |
244 if (!success) { | 213 if (!success) { |
245 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 214 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
246 state_ = kStopped; | 215 state_ = kDecodeFinished; |
247 return; | 216 return; |
248 } | 217 } |
249 | 218 |
250 // Success! | 219 // Success! |
251 UpdateDecoderConfig(); | 220 UpdateDecoderConfig(); |
252 | 221 |
253 decryptor_->RegisterNewKeyCB( | 222 decryptor_->RegisterNewKeyCB( |
254 Decryptor::kAudio, BindToCurrentLoop(base::Bind( | 223 Decryptor::kAudio, BindToCurrentLoop(base::Bind( |
255 &DecryptingAudioDecoder::OnKeyAdded, weak_this_))); | 224 &DecryptingAudioDecoder::OnKeyAdded, weak_this_))); |
256 | 225 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 BindToCurrentLoop(base::Bind( | 337 BindToCurrentLoop(base::Bind( |
369 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); | 338 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); |
370 } | 339 } |
371 | 340 |
372 void DecryptingAudioDecoder::DeliverFrame( | 341 void DecryptingAudioDecoder::DeliverFrame( |
373 int buffer_size, | 342 int buffer_size, |
374 Decryptor::Status status, | 343 Decryptor::Status status, |
375 const Decryptor::AudioBuffers& frames) { | 344 const Decryptor::AudioBuffers& frames) { |
376 DVLOG(3) << "DeliverFrame() - status: " << status; | 345 DVLOG(3) << "DeliverFrame() - status: " << status; |
377 DCHECK(task_runner_->BelongsToCurrentThread()); | 346 DCHECK(task_runner_->BelongsToCurrentThread()); |
378 | |
379 if (state_ == kStopped) | |
380 return; | |
381 | |
382 DCHECK_EQ(state_, kPendingDecode) << state_; | 347 DCHECK_EQ(state_, kPendingDecode) << state_; |
383 DCHECK(!read_cb_.is_null()); | 348 DCHECK(!read_cb_.is_null()); |
384 DCHECK(pending_buffer_to_decode_.get()); | 349 DCHECK(pending_buffer_to_decode_.get()); |
385 DCHECK(queued_audio_frames_.empty()); | 350 DCHECK(queued_audio_frames_.empty()); |
386 | 351 |
387 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; | 352 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; |
388 key_added_while_decode_pending_ = false; | 353 key_added_while_decode_pending_ = false; |
389 | 354 |
390 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = | 355 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = |
391 pending_buffer_to_decode_; | 356 pending_buffer_to_decode_; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 } | 467 } |
503 | 468 |
504 frame->set_timestamp(current_time); | 469 frame->set_timestamp(current_time); |
505 frame->set_duration( | 470 frame->set_duration( |
506 timestamp_helper_->GetFrameDuration(frame->frame_count())); | 471 timestamp_helper_->GetFrameDuration(frame->frame_count())); |
507 timestamp_helper_->AddFrames(frame->frame_count()); | 472 timestamp_helper_->AddFrames(frame->frame_count()); |
508 } | 473 } |
509 } | 474 } |
510 | 475 |
511 } // namespace media | 476 } // namespace media |
OLD | NEW |