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