Home | History | Annotate | Download | only in filters
      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_demuxer_stream.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback_helpers.h"
      9 #include "base/location.h"
     10 #include "base/logging.h"
     11 #include "base/single_thread_task_runner.h"
     12 #include "media/base/audio_decoder_config.h"
     13 #include "media/base/bind_to_current_loop.h"
     14 #include "media/base/decoder_buffer.h"
     15 #include "media/base/decryptor.h"
     16 #include "media/base/demuxer_stream.h"
     17 #include "media/base/pipeline.h"
     18 #include "media/base/video_decoder_config.h"
     19 
     20 namespace media {
     21 
     22 static bool IsStreamValidAndEncrypted(DemuxerStream* stream) {
     23   return ((stream->type() == DemuxerStream::AUDIO &&
     24            stream->audio_decoder_config().IsValidConfig() &&
     25            stream->audio_decoder_config().is_encrypted()) ||
     26           (stream->type() == DemuxerStream::VIDEO &&
     27            stream->video_decoder_config().IsValidConfig() &&
     28            stream->video_decoder_config().is_encrypted()));
     29 }
     30 
     31 DecryptingDemuxerStream::DecryptingDemuxerStream(
     32     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     33     const SetDecryptorReadyCB& set_decryptor_ready_cb)
     34     : task_runner_(task_runner),
     35       state_(kUninitialized),
     36       demuxer_stream_(NULL),
     37       set_decryptor_ready_cb_(set_decryptor_ready_cb),
     38       decryptor_(NULL),
     39       key_added_while_decrypt_pending_(false),
     40       weak_factory_(this) {}
     41 
     42 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream,
     43                                          const PipelineStatusCB& status_cb) {
     44   DVLOG(2) << __FUNCTION__;
     45   DCHECK(task_runner_->BelongsToCurrentThread());
     46   DCHECK_EQ(state_, kUninitialized) << state_;
     47 
     48   DCHECK(!demuxer_stream_);
     49   weak_this_ = weak_factory_.GetWeakPtr();
     50   demuxer_stream_ = stream;
     51   init_cb_ = BindToCurrentLoop(status_cb);
     52 
     53   InitializeDecoderConfig();
     54 
     55   state_ = kDecryptorRequested;
     56   set_decryptor_ready_cb_.Run(BindToCurrentLoop(
     57       base::Bind(&DecryptingDemuxerStream::SetDecryptor, weak_this_)));
     58 }
     59 
     60 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) {
     61   DVLOG(3) << __FUNCTION__;
     62   DCHECK(task_runner_->BelongsToCurrentThread());
     63   DCHECK_EQ(state_, kIdle) << state_;
     64   DCHECK(!read_cb.is_null());
     65   CHECK(read_cb_.is_null()) << "Overlapping reads are not supported.";
     66 
     67   read_cb_ = BindToCurrentLoop(read_cb);
     68   state_ = kPendingDemuxerRead;
     69   demuxer_stream_->Read(
     70       base::Bind(&DecryptingDemuxerStream::DecryptBuffer, weak_this_));
     71 }
     72 
     73 void DecryptingDemuxerStream::Reset(const base::Closure& closure) {
     74   DVLOG(2) << __FUNCTION__ << " - state: " << state_;
     75   DCHECK(task_runner_->BelongsToCurrentThread());
     76   DCHECK(state_ != kUninitialized) << state_;
     77   DCHECK(reset_cb_.is_null());
     78 
     79   reset_cb_ = BindToCurrentLoop(closure);
     80 
     81   // TODO(xhwang): This should not happen. Remove it, DCHECK against the
     82   // condition and clean up related tests.
     83   if (state_ == kDecryptorRequested) {
     84     DCHECK(!init_cb_.is_null());
     85     set_decryptor_ready_cb_.Run(DecryptorReadyCB());
     86     base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
     87     DoReset();
     88     return;
     89   }
     90 
     91   decryptor_->CancelDecrypt(GetDecryptorStreamType());
     92 
     93   // 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   // after the read callback is fired - see DoDecryptBuffer() and
     96   // DoDeliverBuffer().
     97   if (state_ == kPendingDemuxerRead || state_ == kPendingDecrypt) {
     98     DCHECK(!read_cb_.is_null());
     99     return;
    100   }
    101 
    102   if (state_ == kWaitingForKey) {
    103     DCHECK(!read_cb_.is_null());
    104     pending_buffer_to_decrypt_ = NULL;
    105     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    106   }
    107 
    108   DCHECK(read_cb_.is_null());
    109   DoReset();
    110 }
    111 
    112 AudioDecoderConfig DecryptingDemuxerStream::audio_decoder_config() {
    113   DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_;
    114   CHECK_EQ(demuxer_stream_->type(), AUDIO);
    115   return audio_config_;
    116 }
    117 
    118 VideoDecoderConfig DecryptingDemuxerStream::video_decoder_config() {
    119   DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_;
    120   CHECK_EQ(demuxer_stream_->type(), VIDEO);
    121   return video_config_;
    122 }
    123 
    124 DemuxerStream::Type DecryptingDemuxerStream::type() {
    125   DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_;
    126   return demuxer_stream_->type();
    127 }
    128 
    129 void DecryptingDemuxerStream::EnableBitstreamConverter() {
    130   demuxer_stream_->EnableBitstreamConverter();
    131 }
    132 
    133 bool DecryptingDemuxerStream::SupportsConfigChanges() {
    134   return demuxer_stream_->SupportsConfigChanges();
    135 }
    136 
    137 VideoRotation DecryptingDemuxerStream::video_rotation() {
    138   return VIDEO_ROTATION_0;
    139 }
    140 
    141 DecryptingDemuxerStream::~DecryptingDemuxerStream() {
    142   DVLOG(2) << __FUNCTION__ << " : state_ = " << state_;
    143   DCHECK(task_runner_->BelongsToCurrentThread());
    144 
    145   if (state_ == kUninitialized)
    146     return;
    147 
    148   if (decryptor_) {
    149     decryptor_->CancelDecrypt(GetDecryptorStreamType());
    150     decryptor_ = NULL;
    151   }
    152   if (!set_decryptor_ready_cb_.is_null())
    153     base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB());
    154   if (!init_cb_.is_null())
    155     base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
    156   if (!read_cb_.is_null())
    157     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    158   if (!reset_cb_.is_null())
    159     base::ResetAndReturn(&reset_cb_).Run();
    160   pending_buffer_to_decrypt_ = NULL;
    161 }
    162 
    163 void DecryptingDemuxerStream::SetDecryptor(
    164     Decryptor* decryptor,
    165     const DecryptorAttachedCB& decryptor_attached_cb) {
    166   DVLOG(2) << __FUNCTION__;
    167   DCHECK(task_runner_->BelongsToCurrentThread());
    168   DCHECK_EQ(state_, kDecryptorRequested) << state_;
    169   DCHECK(!init_cb_.is_null());
    170   DCHECK(!set_decryptor_ready_cb_.is_null());
    171 
    172   set_decryptor_ready_cb_.Reset();
    173 
    174   if (!decryptor) {
    175     state_ = kUninitialized;
    176     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
    177     decryptor_attached_cb.Run(false);
    178     return;
    179   }
    180 
    181   decryptor_ = decryptor;
    182 
    183   decryptor_->RegisterNewKeyCB(
    184       GetDecryptorStreamType(),
    185       BindToCurrentLoop(
    186           base::Bind(&DecryptingDemuxerStream::OnKeyAdded, weak_this_)));
    187 
    188   state_ = kIdle;
    189   base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
    190   decryptor_attached_cb.Run(true);
    191 }
    192 
    193 void DecryptingDemuxerStream::DecryptBuffer(
    194     DemuxerStream::Status status,
    195     const scoped_refptr<DecoderBuffer>& buffer) {
    196   DVLOG(3) << __FUNCTION__;
    197   DCHECK(task_runner_->BelongsToCurrentThread());
    198   DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
    199   DCHECK(!read_cb_.is_null());
    200   DCHECK_EQ(buffer.get() != NULL, status == kOk) << status;
    201 
    202   // Even when |!reset_cb_.is_null()|, we need to pass |kConfigChanged| back to
    203   // the caller so that the downstream decoder can be properly reinitialized.
    204   if (status == kConfigChanged) {
    205     DVLOG(2) << "DoDecryptBuffer() - kConfigChanged.";
    206     DCHECK_EQ(demuxer_stream_->type() == AUDIO, audio_config_.IsValidConfig());
    207     DCHECK_EQ(demuxer_stream_->type() == VIDEO, video_config_.IsValidConfig());
    208 
    209     // Update the decoder config, which the decoder will use when it is notified
    210     // of kConfigChanged.
    211     InitializeDecoderConfig();
    212     state_ = kIdle;
    213     base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
    214     if (!reset_cb_.is_null())
    215       DoReset();
    216     return;
    217   }
    218 
    219   if (!reset_cb_.is_null()) {
    220     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    221     DoReset();
    222     return;
    223   }
    224 
    225   if (status == kAborted) {
    226     DVLOG(2) << "DoDecryptBuffer() - kAborted.";
    227     state_ = kIdle;
    228     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    229     return;
    230   }
    231 
    232   if (buffer->end_of_stream()) {
    233     DVLOG(2) << "DoDecryptBuffer() - EOS buffer.";
    234     state_ = kIdle;
    235     base::ResetAndReturn(&read_cb_).Run(status, buffer);
    236     return;
    237   }
    238 
    239   DCHECK(buffer->decrypt_config());
    240   // An empty iv string signals that the frame is unencrypted.
    241   if (buffer->decrypt_config()->iv().empty()) {
    242     DVLOG(2) << "DoDecryptBuffer() - clear buffer.";
    243     scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom(
    244         buffer->data(), buffer->data_size());
    245     decrypted->set_timestamp(buffer->timestamp());
    246     decrypted->set_duration(buffer->duration());
    247     state_ = kIdle;
    248     base::ResetAndReturn(&read_cb_).Run(kOk, decrypted);
    249     return;
    250   }
    251 
    252   pending_buffer_to_decrypt_ = buffer;
    253   state_ = kPendingDecrypt;
    254   DecryptPendingBuffer();
    255 }
    256 
    257 void DecryptingDemuxerStream::DecryptPendingBuffer() {
    258   DCHECK(task_runner_->BelongsToCurrentThread());
    259   DCHECK_EQ(state_, kPendingDecrypt) << state_;
    260   decryptor_->Decrypt(
    261       GetDecryptorStreamType(),
    262       pending_buffer_to_decrypt_,
    263       BindToCurrentLoop(
    264           base::Bind(&DecryptingDemuxerStream::DeliverBuffer, weak_this_)));
    265 }
    266 
    267 void DecryptingDemuxerStream::DeliverBuffer(
    268     Decryptor::Status status,
    269     const scoped_refptr<DecoderBuffer>& decrypted_buffer) {
    270   DVLOG(3) << __FUNCTION__ << " - status: " << status;
    271   DCHECK(task_runner_->BelongsToCurrentThread());
    272   DCHECK_EQ(state_, kPendingDecrypt) << state_;
    273   DCHECK_NE(status, Decryptor::kNeedMoreData);
    274   DCHECK(!read_cb_.is_null());
    275   DCHECK(pending_buffer_to_decrypt_.get());
    276 
    277   bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_;
    278   key_added_while_decrypt_pending_ = false;
    279 
    280   if (!reset_cb_.is_null()) {
    281     pending_buffer_to_decrypt_ = NULL;
    282     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    283     DoReset();
    284     return;
    285   }
    286 
    287   DCHECK_EQ(status == Decryptor::kSuccess, decrypted_buffer.get() != NULL);
    288 
    289   if (status == Decryptor::kError) {
    290     DVLOG(2) << "DoDeliverBuffer() - kError";
    291     pending_buffer_to_decrypt_ = NULL;
    292     state_ = kIdle;
    293     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
    294     return;
    295   }
    296 
    297   if (status == Decryptor::kNoKey) {
    298     DVLOG(2) << "DoDeliverBuffer() - kNoKey";
    299     if (need_to_try_again_if_nokey) {
    300       // The |state_| is still kPendingDecrypt.
    301       DecryptPendingBuffer();
    302       return;
    303     }
    304 
    305     state_ = kWaitingForKey;
    306     return;
    307   }
    308 
    309   DCHECK_EQ(status, Decryptor::kSuccess);
    310   pending_buffer_to_decrypt_ = NULL;
    311   state_ = kIdle;
    312   base::ResetAndReturn(&read_cb_).Run(kOk, decrypted_buffer);
    313 }
    314 
    315 void DecryptingDemuxerStream::OnKeyAdded() {
    316   DCHECK(task_runner_->BelongsToCurrentThread());
    317 
    318   if (state_ == kPendingDecrypt) {
    319     key_added_while_decrypt_pending_ = true;
    320     return;
    321   }
    322 
    323   if (state_ == kWaitingForKey) {
    324     state_ = kPendingDecrypt;
    325     DecryptPendingBuffer();
    326   }
    327 }
    328 
    329 void DecryptingDemuxerStream::DoReset() {
    330   DCHECK(state_ != kUninitialized);
    331   DCHECK(init_cb_.is_null());
    332   DCHECK(read_cb_.is_null());
    333 
    334   if (state_ == kDecryptorRequested)
    335     state_ = kUninitialized;
    336   else
    337     state_ = kIdle;
    338 
    339   base::ResetAndReturn(&reset_cb_).Run();
    340 }
    341 
    342 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const {
    343   if (demuxer_stream_->type() == AUDIO)
    344     return Decryptor::kAudio;
    345 
    346   DCHECK_EQ(demuxer_stream_->type(), VIDEO);
    347   return Decryptor::kVideo;
    348 }
    349 
    350 void DecryptingDemuxerStream::InitializeDecoderConfig() {
    351   // The decoder selector or upstream demuxer make sure the stream is valid and
    352   // potentially encrypted.
    353   DCHECK(IsStreamValidAndEncrypted(demuxer_stream_));
    354 
    355   switch (demuxer_stream_->type()) {
    356     case AUDIO: {
    357       AudioDecoderConfig input_audio_config =
    358           demuxer_stream_->audio_decoder_config();
    359       audio_config_.Initialize(input_audio_config.codec(),
    360                                input_audio_config.sample_format(),
    361                                input_audio_config.channel_layout(),
    362                                input_audio_config.samples_per_second(),
    363                                input_audio_config.extra_data(),
    364                                input_audio_config.extra_data_size(),
    365                                false,  // Output audio is not encrypted.
    366                                false,
    367                                input_audio_config.seek_preroll(),
    368                                input_audio_config.codec_delay());
    369       break;
    370     }
    371 
    372     case VIDEO: {
    373       VideoDecoderConfig input_video_config =
    374           demuxer_stream_->video_decoder_config();
    375       video_config_.Initialize(input_video_config.codec(),
    376                                input_video_config.profile(),
    377                                input_video_config.format(),
    378                                input_video_config.coded_size(),
    379                                input_video_config.visible_rect(),
    380                                input_video_config.natural_size(),
    381                                input_video_config.extra_data(),
    382                                input_video_config.extra_data_size(),
    383                                false,  // Output video is not encrypted.
    384                                false);
    385       break;
    386     }
    387 
    388     default:
    389       NOTREACHED();
    390       return;
    391   }
    392 }
    393 
    394 }  // namespace media
    395