Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / filters / decrypting_audio_decoder.cc
index 7336f21..ee50e2e 100644 (file)
@@ -45,7 +45,8 @@ DecryptingAudioDecoder::DecryptingAudioDecoder(
       weak_factory_(this) {}
 
 void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config,
-                                        const PipelineStatusCB& status_cb) {
+                                        const PipelineStatusCB& status_cb,
+                                        const OutputCB& output_cb) {
   DVLOG(2) << "Initialize()";
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(decode_cb_.is_null());
@@ -53,6 +54,7 @@ void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config,
 
   weak_this_ = weak_factory_.GetWeakPtr();
   init_cb_ = BindToCurrentLoop(status_cb);
+  output_cb_ = BindToCurrentLoop(output_cb);
 
   if (!config.IsValidConfig()) {
     DLOG(ERROR) << "Invalid audio stream config.";
@@ -92,14 +94,8 @@ void DecryptingAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
 
   // Return empty (end-of-stream) frames if decoding has finished.
   if (state_ == kDecodeFinished) {
-    base::ResetAndReturn(&decode_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer());
-    return;
-  }
-
-  if (!queued_audio_frames_.empty()) {
-    DCHECK(!buffer);
-    base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front());
-    queued_audio_frames_.pop_front();
+    output_cb_.Run(AudioBuffer::CreateEOSBuffer());
+    base::ResetAndReturn(&decode_cb_).Run(kOk);
     return;
   }
 
@@ -115,14 +111,6 @@ void DecryptingAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
   DecodePendingBuffer();
 }
 
-scoped_refptr<AudioBuffer> DecryptingAudioDecoder::GetDecodeOutput() {
-  if (queued_audio_frames_.empty())
-    return NULL;
-  scoped_refptr<AudioBuffer> out = queued_audio_frames_.front();
-  queued_audio_frames_.pop_front();
-  return out;
-}
-
 void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
   DVLOG(2) << "Reset() - state: " << state_;
   DCHECK(task_runner_->BelongsToCurrentThread());
@@ -149,20 +137,19 @@ void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
   if (state_ == kWaitingForKey) {
     DCHECK(!decode_cb_.is_null());
     pending_buffer_to_decode_ = NULL;
-    base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
+    base::ResetAndReturn(&decode_cb_).Run(kAborted);
   }
 
   DCHECK(decode_cb_.is_null());
   DoReset();
 }
 
-void DecryptingAudioDecoder::Stop(const base::Closure& closure) {
-  DVLOG(2) << "Stop() - state: " << state_;
+DecryptingAudioDecoder::~DecryptingAudioDecoder() {
+  DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
-  // Invalidate all weak pointers so that pending callbacks won't be fired into
-  // this object.
-  weak_factory_.InvalidateWeakPtrs();
+  if (state_ == kUninitialized)
+    return;
 
   if (decryptor_) {
     decryptor_->DeinitializeDecoder(Decryptor::kAudio);
@@ -174,19 +161,14 @@ void DecryptingAudioDecoder::Stop(const base::Closure& closure) {
   if (!init_cb_.is_null())
     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
   if (!decode_cb_.is_null())
-    base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
+    base::ResetAndReturn(&decode_cb_).Run(kAborted);
   if (!reset_cb_.is_null())
     base::ResetAndReturn(&reset_cb_).Run();
-
-  state_ = kStopped;
-  task_runner_->PostTask(FROM_HERE, closure);
-}
-
-DecryptingAudioDecoder::~DecryptingAudioDecoder() {
-  DCHECK(state_ == kUninitialized || state_ == kStopped) << state_;
 }
 
-void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) {
+void DecryptingAudioDecoder::SetDecryptor(
+    Decryptor* decryptor,
+    const DecryptorAttachedCB& decryptor_attached_cb) {
   DVLOG(2) << "SetDecryptor()";
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK_EQ(state_, kDecryptorRequested) << state_;
@@ -197,29 +179,18 @@ void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) {
 
   if (!decryptor) {
     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
-    // TODO(xhwang): Add kError state. See http://crbug.com/251503
-    state_ = kStopped;
+    state_ = kError;
+    decryptor_attached_cb.Run(false);
     return;
   }
 
   decryptor_ = decryptor;
 
   InitializeDecoder();
+  decryptor_attached_cb.Run(true);
 }
 
 void DecryptingAudioDecoder::InitializeDecoder() {
-  // Force to use S16 due to limitations of the CDM. See b/13548512
-  config_.Initialize(config_.codec(),
-                     kSampleFormatS16,
-                     config_.channel_layout(),
-                     config_.samples_per_second(),
-                     config_.extra_data(),
-                     config_.extra_data_size(),
-                     config_.is_encrypted(),
-                     false,
-                     base::TimeDelta(),
-                     base::TimeDelta());
-
   state_ = kPendingDecoderInit;
   decryptor_->InitializeAudioDecoder(
       config_,
@@ -237,7 +208,8 @@ void DecryptingAudioDecoder::FinishInitialization(bool success) {
 
   if (!success) {
     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
-    state_ = kStopped;
+    decryptor_ = NULL;
+    state_ = kError;
     return;
   }
 
@@ -278,7 +250,6 @@ void DecryptingAudioDecoder::DeliverFrame(
   DCHECK_EQ(state_, kPendingDecode) << state_;
   DCHECK(!decode_cb_.is_null());
   DCHECK(pending_buffer_to_decode_.get());
-  DCHECK(queued_audio_frames_.empty());
 
   bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
   key_added_while_decode_pending_ = false;
@@ -288,7 +259,7 @@ void DecryptingAudioDecoder::DeliverFrame(
   pending_buffer_to_decode_ = NULL;
 
   if (!reset_cb_.is_null()) {
-    base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
+    base::ResetAndReturn(&decode_cb_).Run(kAborted);
     DoReset();
     return;
   }
@@ -298,7 +269,7 @@ void DecryptingAudioDecoder::DeliverFrame(
   if (status == Decryptor::kError) {
     DVLOG(2) << "DeliverFrame() - kError";
     state_ = kDecodeFinished; // TODO add kError state
-    base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
+    base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
     return;
   }
 
@@ -320,25 +291,26 @@ void DecryptingAudioDecoder::DeliverFrame(
 
   if (status == Decryptor::kNeedMoreData) {
     DVLOG(2) << "DeliverFrame() - kNeedMoreData";
-    if (scoped_pending_buffer_to_decode->end_of_stream()) {
-      state_ = kDecodeFinished;
-      base::ResetAndReturn(&decode_cb_)
-          .Run(kOk, AudioBuffer::CreateEOSBuffer());
-      return;
-    }
-
-    state_ = kIdle;
-    base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
+    state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished
+                                                              : kIdle;
+    base::ResetAndReturn(&decode_cb_).Run(kOk);
     return;
   }
 
   DCHECK_EQ(status, Decryptor::kSuccess);
   DCHECK(!frames.empty());
-  EnqueueFrames(frames);
+  ProcessDecodedFrames(frames);
+
+  if (scoped_pending_buffer_to_decode->end_of_stream()) {
+    // Set |pending_buffer_to_decode_| back as we need to keep flushing the
+    // decryptor until kNeedMoreData is returned.
+    pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
+    DecodePendingBuffer();
+    return;
+  }
 
   state_ = kIdle;
-  base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front());
-  queued_audio_frames_.pop_front();
+  base::ResetAndReturn(&decode_cb_).Run(kOk);
 }
 
 void DecryptingAudioDecoder::OnKeyAdded() {
@@ -363,14 +335,12 @@ void DecryptingAudioDecoder::DoReset() {
   base::ResetAndReturn(&reset_cb_).Run();
 }
 
-void DecryptingAudioDecoder::EnqueueFrames(
+void DecryptingAudioDecoder::ProcessDecodedFrames(
     const Decryptor::AudioBuffers& frames) {
-  queued_audio_frames_ = frames;
-
-  for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin();
-       iter != queued_audio_frames_.end();
+  for (Decryptor::AudioBuffers::const_iterator iter = frames.begin();
+       iter != frames.end();
        ++iter) {
-    scoped_refptr<AudioBuffer>& frame = *iter;
+    scoped_refptr<AudioBuffer> frame = *iter;
 
     DCHECK(!frame->end_of_stream()) << "EOS frame returned.";
     DCHECK_GT(frame->frame_count(), 0) << "Empty frame returned.";
@@ -384,9 +354,9 @@ void DecryptingAudioDecoder::EnqueueFrames(
     }
 
     frame->set_timestamp(current_time);
-    frame->set_duration(
-        timestamp_helper_->GetFrameDuration(frame->frame_count()));
     timestamp_helper_->AddFrames(frame->frame_count());
+
+    output_cb_.Run(frame);
   }
 }