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 3// found in the LICENSE file. 4 5#include "media/filters/decrypting_audio_decoder.h" 6 7#include <cstdlib> 8 9#include "base/bind.h" 10#include "base/callback_helpers.h" 11#include "base/location.h" 12#include "base/logging.h" 13#include "base/single_thread_task_runner.h" 14#include "media/base/audio_buffer.h" 15#include "media/base/audio_decoder_config.h" 16#include "media/base/audio_timestamp_helper.h" 17#include "media/base/bind_to_current_loop.h" 18#include "media/base/buffers.h" 19#include "media/base/decoder_buffer.h" 20#include "media/base/decryptor.h" 21#include "media/base/demuxer_stream.h" 22#include "media/base/pipeline.h" 23 24namespace media { 25 26const int DecryptingAudioDecoder::kSupportedBitsPerChannel = 16; 27 28static inline bool IsOutOfSync(const base::TimeDelta& timestamp_1, 29 const base::TimeDelta& timestamp_2) { 30 // Out of sync of 100ms would be pretty noticeable and we should keep any 31 // drift below that. 32 const int64 kOutOfSyncThresholdInMilliseconds = 100; 33 return std::abs(timestamp_1.InMilliseconds() - timestamp_2.InMilliseconds()) > 34 kOutOfSyncThresholdInMilliseconds; 35} 36 37DecryptingAudioDecoder::DecryptingAudioDecoder( 38 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 39 const SetDecryptorReadyCB& set_decryptor_ready_cb) 40 : task_runner_(task_runner), 41 state_(kUninitialized), 42 set_decryptor_ready_cb_(set_decryptor_ready_cb), 43 decryptor_(NULL), 44 key_added_while_decode_pending_(false), 45 weak_factory_(this) {} 46 47std::string DecryptingAudioDecoder::GetDisplayName() const { 48 return "DecryptingAudioDecoder"; 49} 50 51void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config, 52 const PipelineStatusCB& status_cb, 53 const OutputCB& output_cb) { 54 DVLOG(2) << "Initialize()"; 55 DCHECK(task_runner_->BelongsToCurrentThread()); 56 DCHECK(decode_cb_.is_null()); 57 DCHECK(reset_cb_.is_null()); 58 59 weak_this_ = weak_factory_.GetWeakPtr(); 60 init_cb_ = BindToCurrentLoop(status_cb); 61 output_cb_ = BindToCurrentLoop(output_cb); 62 63 if (!config.IsValidConfig()) { 64 DLOG(ERROR) << "Invalid audio stream config."; 65 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_DECODE); 66 return; 67 } 68 69 // DecryptingAudioDecoder only accepts potentially encrypted stream. 70 if (!config.is_encrypted()) { 71 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 72 return; 73 } 74 75 config_ = config; 76 77 if (state_ == kUninitialized) { 78 state_ = kDecryptorRequested; 79 set_decryptor_ready_cb_.Run(BindToCurrentLoop( 80 base::Bind(&DecryptingAudioDecoder::SetDecryptor, weak_this_))); 81 return; 82 } 83 84 // Reinitialization (i.e. upon a config change) 85 decryptor_->DeinitializeDecoder(Decryptor::kAudio); 86 InitializeDecoder(); 87} 88 89void DecryptingAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 90 const DecodeCB& decode_cb) { 91 DVLOG(3) << "Decode()"; 92 DCHECK(task_runner_->BelongsToCurrentThread()); 93 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; 94 DCHECK(!decode_cb.is_null()); 95 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; 96 97 decode_cb_ = BindToCurrentLoop(decode_cb); 98 99 // Return empty (end-of-stream) frames if decoding has finished. 100 if (state_ == kDecodeFinished) { 101 output_cb_.Run(AudioBuffer::CreateEOSBuffer()); 102 base::ResetAndReturn(&decode_cb_).Run(kOk); 103 return; 104 } 105 106 // Initialize the |next_output_timestamp_| to be the timestamp of the first 107 // non-EOS buffer. 108 if (timestamp_helper_->base_timestamp() == kNoTimestamp() && 109 !buffer->end_of_stream()) { 110 timestamp_helper_->SetBaseTimestamp(buffer->timestamp()); 111 } 112 113 pending_buffer_to_decode_ = buffer; 114 state_ = kPendingDecode; 115 DecodePendingBuffer(); 116} 117 118void DecryptingAudioDecoder::Reset(const base::Closure& closure) { 119 DVLOG(2) << "Reset() - state: " << state_; 120 DCHECK(task_runner_->BelongsToCurrentThread()); 121 DCHECK(state_ == kIdle || 122 state_ == kPendingDecode || 123 state_ == kWaitingForKey || 124 state_ == kDecodeFinished) << state_; 125 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 126 DCHECK(reset_cb_.is_null()); 127 128 reset_cb_ = BindToCurrentLoop(closure); 129 130 decryptor_->ResetDecoder(Decryptor::kAudio); 131 132 // Reset() cannot complete if the read callback is still pending. 133 // Defer the resetting process in this case. The |reset_cb_| will be fired 134 // after the read callback is fired - see DecryptAndDecodeBuffer() and 135 // DeliverFrame(). 136 if (state_ == kPendingDecode) { 137 DCHECK(!decode_cb_.is_null()); 138 return; 139 } 140 141 if (state_ == kWaitingForKey) { 142 DCHECK(!decode_cb_.is_null()); 143 pending_buffer_to_decode_ = NULL; 144 base::ResetAndReturn(&decode_cb_).Run(kAborted); 145 } 146 147 DCHECK(decode_cb_.is_null()); 148 DoReset(); 149} 150 151DecryptingAudioDecoder::~DecryptingAudioDecoder() { 152 DVLOG(2) << __FUNCTION__; 153 DCHECK(task_runner_->BelongsToCurrentThread()); 154 155 if (state_ == kUninitialized) 156 return; 157 158 if (decryptor_) { 159 decryptor_->DeinitializeDecoder(Decryptor::kAudio); 160 decryptor_ = NULL; 161 } 162 if (!set_decryptor_ready_cb_.is_null()) 163 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); 164 pending_buffer_to_decode_ = NULL; 165 if (!init_cb_.is_null()) 166 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 167 if (!decode_cb_.is_null()) 168 base::ResetAndReturn(&decode_cb_).Run(kAborted); 169 if (!reset_cb_.is_null()) 170 base::ResetAndReturn(&reset_cb_).Run(); 171} 172 173void DecryptingAudioDecoder::SetDecryptor( 174 Decryptor* decryptor, 175 const DecryptorAttachedCB& decryptor_attached_cb) { 176 DVLOG(2) << "SetDecryptor()"; 177 DCHECK(task_runner_->BelongsToCurrentThread()); 178 DCHECK_EQ(state_, kDecryptorRequested) << state_; 179 DCHECK(!init_cb_.is_null()); 180 DCHECK(!set_decryptor_ready_cb_.is_null()); 181 182 set_decryptor_ready_cb_.Reset(); 183 184 if (!decryptor) { 185 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 186 state_ = kError; 187 decryptor_attached_cb.Run(false); 188 return; 189 } 190 191 decryptor_ = decryptor; 192 193 InitializeDecoder(); 194 decryptor_attached_cb.Run(true); 195} 196 197void DecryptingAudioDecoder::InitializeDecoder() { 198 state_ = kPendingDecoderInit; 199 decryptor_->InitializeAudioDecoder( 200 config_, 201 BindToCurrentLoop(base::Bind( 202 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); 203} 204 205void DecryptingAudioDecoder::FinishInitialization(bool success) { 206 DVLOG(2) << "FinishInitialization()"; 207 DCHECK(task_runner_->BelongsToCurrentThread()); 208 DCHECK(state_ == kPendingDecoderInit) << state_; 209 DCHECK(!init_cb_.is_null()); 210 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 211 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. 212 213 if (!success) { 214 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 215 decryptor_ = NULL; 216 state_ = kError; 217 return; 218 } 219 220 // Success! 221 timestamp_helper_.reset( 222 new AudioTimestampHelper(config_.samples_per_second())); 223 224 decryptor_->RegisterNewKeyCB( 225 Decryptor::kAudio, 226 BindToCurrentLoop( 227 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_))); 228 229 state_ = kIdle; 230 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 231} 232 233void DecryptingAudioDecoder::DecodePendingBuffer() { 234 DCHECK(task_runner_->BelongsToCurrentThread()); 235 DCHECK_EQ(state_, kPendingDecode) << state_; 236 237 int buffer_size = 0; 238 if (!pending_buffer_to_decode_->end_of_stream()) { 239 buffer_size = pending_buffer_to_decode_->data_size(); 240 } 241 242 decryptor_->DecryptAndDecodeAudio( 243 pending_buffer_to_decode_, 244 BindToCurrentLoop(base::Bind( 245 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); 246} 247 248void DecryptingAudioDecoder::DeliverFrame( 249 int buffer_size, 250 Decryptor::Status status, 251 const Decryptor::AudioBuffers& frames) { 252 DVLOG(3) << "DeliverFrame() - status: " << status; 253 DCHECK(task_runner_->BelongsToCurrentThread()); 254 DCHECK_EQ(state_, kPendingDecode) << state_; 255 DCHECK(!decode_cb_.is_null()); 256 DCHECK(pending_buffer_to_decode_.get()); 257 258 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; 259 key_added_while_decode_pending_ = false; 260 261 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = 262 pending_buffer_to_decode_; 263 pending_buffer_to_decode_ = NULL; 264 265 if (!reset_cb_.is_null()) { 266 base::ResetAndReturn(&decode_cb_).Run(kAborted); 267 DoReset(); 268 return; 269 } 270 271 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); 272 273 if (status == Decryptor::kError) { 274 DVLOG(2) << "DeliverFrame() - kError"; 275 state_ = kDecodeFinished; // TODO add kError state 276 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); 277 return; 278 } 279 280 if (status == Decryptor::kNoKey) { 281 DVLOG(2) << "DeliverFrame() - kNoKey"; 282 // Set |pending_buffer_to_decode_| back as we need to try decoding the 283 // pending buffer again when new key is added to the decryptor. 284 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 285 286 if (need_to_try_again_if_nokey_is_returned) { 287 // The |state_| is still kPendingDecode. 288 DecodePendingBuffer(); 289 return; 290 } 291 292 state_ = kWaitingForKey; 293 return; 294 } 295 296 if (status == Decryptor::kNeedMoreData) { 297 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 298 state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished 299 : kIdle; 300 base::ResetAndReturn(&decode_cb_).Run(kOk); 301 return; 302 } 303 304 DCHECK_EQ(status, Decryptor::kSuccess); 305 DCHECK(!frames.empty()); 306 ProcessDecodedFrames(frames); 307 308 if (scoped_pending_buffer_to_decode->end_of_stream()) { 309 // Set |pending_buffer_to_decode_| back as we need to keep flushing the 310 // decryptor until kNeedMoreData is returned. 311 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 312 DecodePendingBuffer(); 313 return; 314 } 315 316 state_ = kIdle; 317 base::ResetAndReturn(&decode_cb_).Run(kOk); 318} 319 320void DecryptingAudioDecoder::OnKeyAdded() { 321 DCHECK(task_runner_->BelongsToCurrentThread()); 322 323 if (state_ == kPendingDecode) { 324 key_added_while_decode_pending_ = true; 325 return; 326 } 327 328 if (state_ == kWaitingForKey) { 329 state_ = kPendingDecode; 330 DecodePendingBuffer(); 331 } 332} 333 334void DecryptingAudioDecoder::DoReset() { 335 DCHECK(init_cb_.is_null()); 336 DCHECK(decode_cb_.is_null()); 337 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); 338 state_ = kIdle; 339 base::ResetAndReturn(&reset_cb_).Run(); 340} 341 342void DecryptingAudioDecoder::ProcessDecodedFrames( 343 const Decryptor::AudioBuffers& frames) { 344 for (Decryptor::AudioBuffers::const_iterator iter = frames.begin(); 345 iter != frames.end(); 346 ++iter) { 347 scoped_refptr<AudioBuffer> frame = *iter; 348 349 DCHECK(!frame->end_of_stream()) << "EOS frame returned."; 350 DCHECK_GT(frame->frame_count(), 0) << "Empty frame returned."; 351 352 base::TimeDelta current_time = timestamp_helper_->GetTimestamp(); 353 if (IsOutOfSync(current_time, frame->timestamp())) { 354 DVLOG(1) << "Timestamp returned by the decoder (" 355 << frame->timestamp().InMilliseconds() << " ms)" 356 << " does not match the input timestamp and number of samples" 357 << " decoded (" << current_time.InMilliseconds() << " ms)."; 358 } 359 360 frame->set_timestamp(current_time); 361 timestamp_helper_->AddFrames(frame->frame_count()); 362 363 output_cb_.Run(frame); 364 } 365} 366 367} // namespace media 368