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 <vector>
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "media/base/gmock_callback_support.h"
     10 #include "media/base/mock_filters.h"
     11 #include "media/filters/audio_decoder_selector.h"
     12 #include "media/filters/decrypting_demuxer_stream.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using ::testing::_;
     16 using ::testing::IsNull;
     17 using ::testing::NiceMock;
     18 using ::testing::NotNull;
     19 using ::testing::Return;
     20 using ::testing::StrictMock;
     21 
     22 namespace media {
     23 
     24 class AudioDecoderSelectorTest : public ::testing::Test {
     25  public:
     26   enum DecryptorCapability {
     27     kNoDecryptor,
     28     kDecryptOnly,
     29     kDecryptAndDecode
     30   };
     31 
     32   AudioDecoderSelectorTest()
     33       : demuxer_stream_(
     34             new StrictMock<MockDemuxerStream>(DemuxerStream::AUDIO)),
     35         decryptor_(new NiceMock<MockDecryptor>()),
     36         decoder_1_(new StrictMock<MockAudioDecoder>()),
     37         decoder_2_(new StrictMock<MockAudioDecoder>()) {
     38     all_decoders_.push_back(decoder_1_);
     39     all_decoders_.push_back(decoder_2_);
     40   }
     41 
     42   MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&));
     43   MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
     44   MOCK_METHOD2(OnDecoderSelected,
     45                void(AudioDecoder*, DecryptingDemuxerStream*));
     46 
     47   void MockOnDecoderSelected(
     48       scoped_ptr<AudioDecoder> decoder,
     49       scoped_ptr<DecryptingDemuxerStream> stream) {
     50     OnDecoderSelected(decoder.get(), stream.get());
     51   }
     52 
     53   void UseClearStream() {
     54     AudioDecoderConfig clear_audio_config(
     55         kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
     56         NULL, 0, false);
     57     demuxer_stream_->set_audio_decoder_config(clear_audio_config);
     58   }
     59 
     60   void UseEncryptedStream() {
     61     AudioDecoderConfig encrypted_audio_config(
     62         kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100,
     63         NULL, 0, true);
     64     demuxer_stream_->set_audio_decoder_config(encrypted_audio_config);
     65   }
     66 
     67   void InitializeDecoderSelector(DecryptorCapability decryptor_capability,
     68                                  int num_decoders) {
     69     SetDecryptorReadyCB set_decryptor_ready_cb;
     70     if (decryptor_capability == kDecryptOnly ||
     71         decryptor_capability == kDecryptAndDecode) {
     72       set_decryptor_ready_cb = base::Bind(
     73           &AudioDecoderSelectorTest::SetDecryptorReadyCallback,
     74           base::Unretained(this));
     75 
     76       EXPECT_CALL(*this, SetDecryptorReadyCallback(_))
     77           .WillRepeatedly(RunCallback<0>(decryptor_.get()));
     78 
     79       if (decryptor_capability == kDecryptOnly) {
     80         EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
     81             .WillRepeatedly(RunCallback<1>(false));
     82       } else {
     83         EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
     84             .WillRepeatedly(RunCallback<1>(true));
     85       }
     86     }
     87 
     88     DCHECK_GE(all_decoders_.size(), static_cast<size_t>(num_decoders));
     89     all_decoders_.erase(
     90         all_decoders_.begin() + num_decoders, all_decoders_.end());
     91 
     92     decoder_selector_.reset(new AudioDecoderSelector(
     93         message_loop_.message_loop_proxy(),
     94         all_decoders_.Pass(),
     95         set_decryptor_ready_cb));
     96   }
     97 
     98   void SelectDecoder() {
     99     decoder_selector_->SelectAudioDecoder(
    100         demuxer_stream_.get(),
    101         base::Bind(&AudioDecoderSelectorTest::OnStatistics,
    102                    base::Unretained(this)),
    103         base::Bind(&AudioDecoderSelectorTest::MockOnDecoderSelected,
    104                    base::Unretained(this)));
    105     message_loop_.RunUntilIdle();
    106   }
    107 
    108   // Fixture members.
    109   scoped_ptr<AudioDecoderSelector> decoder_selector_;
    110   scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
    111   // Use NiceMock since we don't care about most of calls on the decryptor, e.g.
    112   // RegisterNewKeyCB().
    113   scoped_ptr<NiceMock<MockDecryptor> > decryptor_;
    114   StrictMock<MockAudioDecoder>* decoder_1_;
    115   StrictMock<MockAudioDecoder>* decoder_2_;
    116   ScopedVector<AudioDecoder> all_decoders_;
    117   base::MessageLoop message_loop_;
    118 
    119  private:
    120   DISALLOW_COPY_AND_ASSIGN(AudioDecoderSelectorTest);
    121 };
    122 
    123 // The stream is not encrypted but we have no clear decoder. No decoder can be
    124 // selected.
    125 TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_NoClearDecoder) {
    126   UseClearStream();
    127   InitializeDecoderSelector(kNoDecryptor, 0);
    128 
    129   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
    130 
    131   SelectDecoder();
    132 }
    133 
    134 // The stream is not encrypted and we have one clear decoder. The decoder
    135 // will be selected.
    136 TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_OneClearDecoder) {
    137   UseClearStream();
    138   InitializeDecoderSelector(kNoDecryptor, 1);
    139 
    140   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
    141       .WillOnce(RunCallback<1>(PIPELINE_OK));
    142   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
    143 
    144   SelectDecoder();
    145 }
    146 
    147 // The stream is not encrypted and we have multiple clear decoders. The first
    148 // decoder that can decode the input stream will be selected.
    149 TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_MultipleClearDecoder) {
    150   UseClearStream();
    151   InitializeDecoderSelector(kNoDecryptor, 2);
    152 
    153   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
    154       .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
    155   EXPECT_CALL(*decoder_2_, Initialize(_, _, _))
    156       .WillOnce(RunCallback<1>(PIPELINE_OK));
    157   EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, IsNull()));
    158 
    159   SelectDecoder();
    160 }
    161 
    162 // There is a decryptor but the stream is not encrypted. The decoder will be
    163 // selected.
    164 TEST_F(AudioDecoderSelectorTest, ClearStream_HasDecryptor) {
    165   UseClearStream();
    166   InitializeDecoderSelector(kDecryptOnly, 1);
    167 
    168   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
    169       .WillOnce(RunCallback<1>(PIPELINE_OK));
    170   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
    171 
    172   SelectDecoder();
    173 }
    174 
    175 // The stream is encrypted and there's no decryptor. No decoder can be selected.
    176 TEST_F(AudioDecoderSelectorTest, EncryptedStream_NoDecryptor) {
    177   UseEncryptedStream();
    178   InitializeDecoderSelector(kNoDecryptor, 1);
    179 
    180   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
    181 
    182   SelectDecoder();
    183 }
    184 
    185 // Decryptor can only do decryption and there's no decoder available. No decoder
    186 // can be selected.
    187 TEST_F(AudioDecoderSelectorTest, EncryptedStream_DecryptOnly_NoClearDecoder) {
    188   UseEncryptedStream();
    189   InitializeDecoderSelector(kDecryptOnly, 0);
    190 
    191   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
    192 
    193   SelectDecoder();
    194 }
    195 
    196 // Decryptor can do decryption-only and there's a decoder available. The decoder
    197 // will be selected and a DecryptingDemuxerStream will be created.
    198 TEST_F(AudioDecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
    199   UseEncryptedStream();
    200   InitializeDecoderSelector(kDecryptOnly, 1);
    201 
    202   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
    203       .WillOnce(RunCallback<1>(PIPELINE_OK));
    204   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, NotNull()));
    205 
    206   SelectDecoder();
    207 }
    208 
    209 // Decryptor can only do decryption and there are multiple decoders available.
    210 // The first decoder that can decode the input stream will be selected and
    211 // a DecryptingDemuxerStream will be created.
    212 TEST_F(AudioDecoderSelectorTest,
    213        EncryptedStream_DecryptOnly_MultipleClearDecoder) {
    214   UseEncryptedStream();
    215   InitializeDecoderSelector(kDecryptOnly, 2);
    216 
    217   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
    218       .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
    219   EXPECT_CALL(*decoder_2_, Initialize(_, _, _))
    220       .WillOnce(RunCallback<1>(PIPELINE_OK));
    221   EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, NotNull()));
    222 
    223   SelectDecoder();
    224 }
    225 
    226 // Decryptor can do decryption and decoding. A DecryptingAudioDecoder will be
    227 // created and selected. The clear decoders should not be touched at all.
    228 // No DecryptingDemuxerStream should to be created.
    229 TEST_F(AudioDecoderSelectorTest, EncryptedStream_DecryptAndDecode) {
    230   UseEncryptedStream();
    231   InitializeDecoderSelector(kDecryptAndDecode, 1);
    232 
    233   EXPECT_CALL(*this, OnDecoderSelected(NotNull(), IsNull()));
    234 
    235   SelectDecoder();
    236 }
    237 
    238 }  // namespace media
    239