| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 | 72 |
| 73 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { | 73 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { |
| 74 if (!message_loop_->BelongsToCurrentThread()) { | 74 if (!message_loop_->BelongsToCurrentThread()) { |
| 75 message_loop_->PostTask(FROM_HERE, base::Bind( | 75 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 76 &DecryptingAudioDecoder::Reset, this, closure)); | 76 &DecryptingAudioDecoder::Reset, this, closure)); |
| 77 return; | 77 return; |
| 78 } | 78 } |
| 79 | 79 |
| 80 DVLOG(2) << "Reset() - state: " << state_; | 80 DVLOG(2) << "Reset() - state: " << state_; |
| 81 DCHECK(state_ == kIdle || | 81 DCHECK(state_ == kIdle || |
| 82 state_ == kPendingConfigChange || |
| 82 state_ == kPendingDemuxerRead || | 83 state_ == kPendingDemuxerRead || |
| 83 state_ == kPendingDecode || | 84 state_ == kPendingDecode || |
| 84 state_ == kWaitingForKey || | 85 state_ == kWaitingForKey || |
| 85 state_ == kDecodeFinished) << state_; | 86 state_ == kDecodeFinished) << state_; |
| 86 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 87 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
| 87 DCHECK(reset_cb_.is_null()); | 88 DCHECK(reset_cb_.is_null()); |
| 88 | 89 |
| 89 reset_cb_ = closure; | 90 reset_cb_ = closure; |
| 90 | 91 |
| 91 decryptor_->ResetDecoder(Decryptor::kAudio); | 92 decryptor_->ResetDecoder(Decryptor::kAudio); |
| 92 | 93 |
| 93 // Reset() cannot complete if the read callback is still pending. | 94 // Reset() cannot complete if the read callback is still pending. |
| 94 // Defer the resetting process in this case. The |reset_cb_| will be fired | 95 // Defer the resetting process in this case. The |reset_cb_| will be fired |
| 95 // after the read callback is fired - see DoDecryptAndDecodeBuffer() and | 96 // after the read callback is fired - see DoDecryptAndDecodeBuffer() and |
| 96 // DoDeliverFrame(). | 97 // DoDeliverFrame(). |
| 97 if (state_ == kPendingDemuxerRead || state_ == kPendingDecode) { | 98 if (state_ == kPendingConfigChange || |
| 99 state_ == kPendingDemuxerRead || |
| 100 state_ == kPendingDecode) { |
| 98 DCHECK(!read_cb_.is_null()); | 101 DCHECK(!read_cb_.is_null()); |
| 99 return; | 102 return; |
| 100 } | 103 } |
| 101 | 104 |
| 102 if (state_ == kWaitingForKey) { | 105 if (state_ == kWaitingForKey) { |
| 103 DCHECK(!read_cb_.is_null()); | 106 DCHECK(!read_cb_.is_null()); |
| 104 pending_buffer_to_decode_ = NULL; | 107 pending_buffer_to_decode_ = NULL; |
| 105 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 108 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 106 } | 109 } |
| 107 | 110 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) * | 202 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) * |
| 200 bits_per_channel_ / kBitsPerByte; | 203 bits_per_channel_ / kBitsPerByte; |
| 201 | 204 |
| 202 decryptor_->RegisterNewKeyCB( | 205 decryptor_->RegisterNewKeyCB( |
| 203 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded)); | 206 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded)); |
| 204 | 207 |
| 205 state_ = kIdle; | 208 state_ = kIdle; |
| 206 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 209 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 207 } | 210 } |
| 208 | 211 |
| 212 void DecryptingAudioDecoder::FinishConfigChange(bool success) { |
| 213 DVLOG(2) << "FinishConfigChange()"; |
| 214 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 215 DCHECK_EQ(state_, kPendingConfigChange) << state_; |
| 216 DCHECK(!read_cb_.is_null()); |
| 217 |
| 218 if (!success) { |
| 219 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
| 220 state_ = kDecodeFinished; |
| 221 if (!reset_cb_.is_null()) |
| 222 base::ResetAndReturn(&reset_cb_).Run(); |
| 223 return; |
| 224 } |
| 225 |
| 226 // Config change succeeded. |
| 227 if (!reset_cb_.is_null()) { |
| 228 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 229 DoReset(); |
| 230 return; |
| 231 } |
| 232 |
| 233 state_ = kPendingDemuxerRead; |
| 234 ReadFromDemuxerStream(); |
| 235 } |
| 236 |
| 209 void DecryptingAudioDecoder::DoRead(const ReadCB& read_cb) { | 237 void DecryptingAudioDecoder::DoRead(const ReadCB& read_cb) { |
| 210 DVLOG(3) << "DoRead()"; | 238 DVLOG(3) << "DoRead()"; |
| 211 DCHECK(message_loop_->BelongsToCurrentThread()); | 239 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 212 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; | 240 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; |
| 213 DCHECK(!read_cb.is_null()); | 241 DCHECK(!read_cb.is_null()); |
| 214 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; | 242 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; |
| 215 | 243 |
| 216 // Return empty (end-of-stream) frames if decoding has finished. | 244 // Return empty (end-of-stream) frames if decoding has finished. |
| 217 if (state_ == kDecodeFinished) { | 245 if (state_ == kDecodeFinished) { |
| 218 read_cb.Run(kOk, scoped_refptr<Buffer>(new DataBuffer(0))); | 246 read_cb.Run(kOk, scoped_refptr<Buffer>(new DataBuffer(0))); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 247 &DecryptingAudioDecoder::DoDecryptAndDecodeBuffer, this, | 275 &DecryptingAudioDecoder::DoDecryptAndDecodeBuffer, this, |
| 248 status, buffer)); | 276 status, buffer)); |
| 249 return; | 277 return; |
| 250 } | 278 } |
| 251 | 279 |
| 252 DVLOG(3) << "DoDecryptAndDecodeBuffer()"; | 280 DVLOG(3) << "DoDecryptAndDecodeBuffer()"; |
| 253 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | 281 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; |
| 254 DCHECK(!read_cb_.is_null()); | 282 DCHECK(!read_cb_.is_null()); |
| 255 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; | 283 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; |
| 256 | 284 |
| 285 if (status == DemuxerStream::kConfigChanged) { |
| 286 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged"; |
| 287 |
| 288 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig()); |
| 289 scoped_config->CopyFrom(demuxer_stream_->audio_decoder_config()); |
| 290 |
| 291 state_ = kPendingConfigChange; |
| 292 decryptor_->DeinitializeDecoder(Decryptor::kAudio); |
| 293 decryptor_->InitializeAudioDecoder( |
| 294 scoped_config.Pass(), BindToCurrentLoop(base::Bind( |
| 295 &DecryptingAudioDecoder::FinishConfigChange, this))); |
| 296 return; |
| 297 } |
| 298 |
| 257 if (!reset_cb_.is_null()) { | 299 if (!reset_cb_.is_null()) { |
| 258 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 300 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 259 DoReset(); | 301 DoReset(); |
| 260 return; | 302 return; |
| 261 } | 303 } |
| 262 | 304 |
| 263 if (status == DemuxerStream::kAborted) { | 305 if (status == DemuxerStream::kAborted) { |
| 264 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kAborted"; | 306 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kAborted"; |
| 265 state_ = kIdle; | 307 state_ = kIdle; |
| 266 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 308 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 267 return; | 309 return; |
| 268 } | 310 } |
| 269 | 311 |
| 270 if (status == DemuxerStream::kConfigChanged) { | |
| 271 // TODO(xhwang): Add config change support. | |
| 272 // The |state_| is chosen to be kDecodeFinished here to be consistent with | |
| 273 // the implementation of FFmpegVideoDecoder. | |
| 274 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged"; | |
| 275 state_ = kDecodeFinished; | |
| 276 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | |
| 277 return; | |
| 278 } | |
| 279 | |
| 280 DCHECK_EQ(status, DemuxerStream::kOk); | 312 DCHECK_EQ(status, DemuxerStream::kOk); |
| 281 | 313 |
| 282 // Initialize the |next_output_timestamp_| to be the timestamp of the first | 314 // Initialize the |next_output_timestamp_| to be the timestamp of the first |
| 283 // non-EOS buffer. | 315 // non-EOS buffer. |
| 284 if (output_timestamp_base_ == kNoTimestamp() && !buffer->IsEndOfStream()) { | 316 if (output_timestamp_base_ == kNoTimestamp() && !buffer->IsEndOfStream()) { |
| 285 DCHECK_EQ(total_samples_decoded_, 0); | 317 DCHECK_EQ(total_samples_decoded_, 0); |
| 286 output_timestamp_base_ = buffer->GetTimestamp(); | 318 output_timestamp_base_ = buffer->GetTimestamp(); |
| 287 } | 319 } |
| 288 | 320 |
| 289 pending_buffer_to_decode_ = buffer; | 321 pending_buffer_to_decode_ = buffer; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 | 484 |
| 453 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration( | 485 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration( |
| 454 int number_of_samples) const { | 486 int number_of_samples) const { |
| 455 DCHECK(samples_per_second_); | 487 DCHECK(samples_per_second_); |
| 456 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond * | 488 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond * |
| 457 number_of_samples / | 489 number_of_samples / |
| 458 samples_per_second_); | 490 samples_per_second_); |
| 459 } | 491 } |
| 460 | 492 |
| 461 } // namespace media | 493 } // namespace media |
| OLD | NEW |