decrypting_audio_decoder_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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 <string>
6#include <vector>
7
8#include "base/bind.h"
9#include "base/callback_helpers.h"
10#include "base/message_loop/message_loop.h"
11#include "media/base/audio_buffer.h"
12#include "media/base/buffers.h"
13#include "media/base/decoder_buffer.h"
14#include "media/base/decrypt_config.h"
15#include "media/base/gmock_callback_support.h"
16#include "media/base/mock_filters.h"
17#include "media/base/test_helpers.h"
18#include "media/filters/decrypting_audio_decoder.h"
19#include "testing/gmock/include/gmock/gmock.h"
20
21using ::testing::_;
22using ::testing::AtMost;
23using ::testing::IsNull;
24using ::testing::SaveArg;
25using ::testing::StrictMock;
26
27namespace media {
28
29static const int kSampleRate = 44100;
30
31// Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
32// configs used in this test.
33static const int kFakeAudioFrameSize = 48;
34static const uint8 kFakeKeyId[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
35static const uint8 kFakeIv[DecryptConfig::kDecryptionKeySize] = { 0 };
36
37// Create a fake non-empty encrypted buffer.
38static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
39  const int buffer_size = 16;  // Need a non-empty buffer;
40  scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
41  buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(new DecryptConfig(
42      std::string(reinterpret_cast<const char*>(kFakeKeyId),
43                  arraysize(kFakeKeyId)),
44      std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)),
45      std::vector<SubsampleEntry>())));
46  return buffer;
47}
48
49// Use anonymous namespace here to prevent the actions to be defined multiple
50// times across multiple test files. Sadly we can't use static for them.
51namespace {
52
53ACTION_P(ReturnBuffer, buffer) {
54  return buffer;
55}
56
57ACTION_P(RunCallbackIfNotNull, param) {
58  if (!arg0.is_null())
59    arg0.Run(param);
60}
61
62// Mock action which we use to repeatedly call ReadAndExpectFrameReadyWith() if
63// we get kNotEnoughData from a Decode() call to |decoder_|.
64ACTION_P2(CallExpectFrameReadyMoreData, test, buffer) {
65  test->ReadAndExpectFrameReadyWith(
66      CreateFakeEncryptedBuffer(), AudioDecoder::kNotEnoughData, buffer);
67}
68
69MATCHER(IsEndOfStream, "end of stream") {
70  return (arg->end_of_stream());
71}
72
73}  // namespace
74
75class DecryptingAudioDecoderTest : public testing::Test {
76 public:
77  DecryptingAudioDecoderTest()
78      : decoder_(new DecryptingAudioDecoder(
79            message_loop_.message_loop_proxy(),
80            base::Bind(
81                &DecryptingAudioDecoderTest::RequestDecryptorNotification,
82                base::Unretained(this)))),
83        decryptor_(new StrictMock<MockDecryptor>()),
84        encrypted_buffer_(CreateFakeEncryptedBuffer()),
85        decoded_frame_(NULL),
86        end_of_stream_frame_(AudioBuffer::CreateEOSBuffer()),
87        decoded_frame_list_() {}
88
89  virtual ~DecryptingAudioDecoderTest() {
90    EXPECT_CALL(*this, RequestDecryptorNotification(_))
91        .Times(testing::AnyNumber());
92    Stop();
93  }
94
95  void InitializeAndExpectStatus(const AudioDecoderConfig& config,
96                                 PipelineStatus status) {
97    decoded_frame_ = AudioBuffer::CreateEmptyBuffer(config.channel_layout(),
98                                                    kSampleRate,
99                                                    kFakeAudioFrameSize,
100                                                    kNoTimestamp(),
101                                                    kNoTimestamp());
102    decoded_frame_list_.push_back(decoded_frame_);
103
104    decoder_->Initialize(config, NewExpectedStatusCB(status));
105    message_loop_.RunUntilIdle();
106  }
107
108  void Initialize() {
109    EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
110        .Times(AtMost(1))
111        .WillOnce(RunCallback<1>(true));
112    EXPECT_CALL(*this, RequestDecryptorNotification(_))
113        .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
114    EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
115        .WillOnce(SaveArg<1>(&key_added_cb_));
116
117    config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32,
118                       CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true, true,
119                       base::TimeDelta(), base::TimeDelta());
120    InitializeAndExpectStatus(config_, PIPELINE_OK);
121
122    EXPECT_EQ(DecryptingAudioDecoder::kSupportedBitsPerChannel,
123              decoder_->bits_per_channel());
124    EXPECT_EQ(config_.channel_layout(), decoder_->channel_layout());
125    EXPECT_EQ(config_.samples_per_second(), decoder_->samples_per_second());
126  }
127
128  void Reinitialize() {
129    ReinitializeConfigChange(config_);
130  }
131
132  void ReinitializeConfigChange(AudioDecoderConfig& new_config) {
133    EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
134    EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
135        .WillOnce(RunCallback<1>(true));
136    EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _))
137              .WillOnce(SaveArg<1>(&key_added_cb_));
138    decoder_->Initialize(new_config, NewExpectedStatusCB(PIPELINE_OK));
139  }
140
141  void ReadAndExpectFrameReadyWith(
142      scoped_refptr<DecoderBuffer> input,
143      AudioDecoder::Status status,
144      const scoped_refptr<AudioBuffer>& audio_frame) {
145
146    const scoped_refptr<AudioBuffer>& buffer = decoder_->GetDecodeOutput();
147
148    if (buffer) {
149      EXPECT_EQ(audio_frame, buffer);
150      EXPECT_EQ(status, AudioDecoder::kOk);
151      return;
152    }
153
154    if (status == AudioDecoder::kNotEnoughData)
155      // Keep calling again to give it more data if we get kNotEnoughData.
156      EXPECT_CALL(*this, FrameReady(status, scoped_refptr<AudioBuffer>(NULL))).
157        WillRepeatedly(CallExpectFrameReadyMoreData(this, audio_frame));
158    else if (status != AudioDecoder::kOk)
159      EXPECT_CALL(*this, FrameReady(status, IsNull()));
160    else if (audio_frame->end_of_stream())
161      EXPECT_CALL(*this, FrameReady(status, IsEndOfStream()));
162    else
163      EXPECT_CALL(*this, FrameReady(status, audio_frame));
164
165    decoder_->Decode(input,
166                     base::Bind(&DecryptingAudioDecoderTest::FrameReady,
167                                base::Unretained(this)));
168    message_loop_.RunUntilIdle();
169  }
170
171  // Sets up expectations and actions to put DecryptingAudioDecoder in an
172  // active normal decoding state.
173  void EnterNormalDecodingState() {
174    Decryptor::AudioBuffers end_of_stream_frames_(1, end_of_stream_frame_);
175
176    EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
177        .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_))
178        .WillRepeatedly(RunCallback<1>(Decryptor::kNeedMoreData,
179                                       Decryptor::AudioBuffers()));
180
181    ReadAndExpectFrameReadyWith(
182        encrypted_buffer_, AudioDecoder::kOk, decoded_frame_);
183  }
184
185  // Sets up expectations and actions to put DecryptingAudioDecoder in an end
186  // of stream state. This function must be called after
187  // EnterNormalDecodingState() to work.
188  void EnterEndOfStreamState() {
189    ReadAndExpectFrameReadyWith(DecoderBuffer::CreateEOSBuffer(),
190                                AudioDecoder::kOk,
191                                end_of_stream_frame_);
192  }
193
194  // Make the audio decode callback pending by saving and not firing it.
195  void EnterPendingDecodeState() {
196    EXPECT_TRUE(pending_audio_decode_cb_.is_null());
197    EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
198        .WillOnce(SaveArg<1>(&pending_audio_decode_cb_));
199
200    decoder_->Decode(encrypted_buffer_,
201                     base::Bind(&DecryptingAudioDecoderTest::FrameReady,
202                                base::Unretained(this)));
203    message_loop_.RunUntilIdle();
204    // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
205    // the decryptor.
206    EXPECT_FALSE(pending_audio_decode_cb_.is_null());
207  }
208
209  void EnterWaitingForKeyState() {
210    EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
211        .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey,
212                                       Decryptor::AudioBuffers()));
213    decoder_->Decode(encrypted_buffer_,
214                     base::Bind(&DecryptingAudioDecoderTest::FrameReady,
215                                base::Unretained(this)));
216    message_loop_.RunUntilIdle();
217  }
218
219  void AbortPendingAudioDecodeCB() {
220    if (!pending_audio_decode_cb_.is_null()) {
221      base::ResetAndReturn(&pending_audio_decode_cb_).Run(
222          Decryptor::kSuccess, Decryptor::AudioBuffers());
223    }
224  }
225
226  void AbortAllPendingCBs() {
227    if (!pending_init_cb_.is_null()) {
228      ASSERT_TRUE(pending_audio_decode_cb_.is_null());
229      base::ResetAndReturn(&pending_init_cb_).Run(false);
230      return;
231    }
232
233    AbortPendingAudioDecodeCB();
234  }
235
236  void Reset() {
237    EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
238        .WillRepeatedly(InvokeWithoutArgs(
239            this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
240
241    decoder_->Reset(NewExpectedClosure());
242    message_loop_.RunUntilIdle();
243  }
244
245  void Stop() {
246    EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
247        .WillRepeatedly(InvokeWithoutArgs(
248            this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
249
250    decoder_->Stop(NewExpectedClosure());
251    message_loop_.RunUntilIdle();
252  }
253
254  MOCK_METHOD1(RequestDecryptorNotification, void(const DecryptorReadyCB&));
255
256  MOCK_METHOD2(FrameReady,
257               void(AudioDecoder::Status, const scoped_refptr<AudioBuffer>&));
258
259  base::MessageLoop message_loop_;
260  scoped_ptr<DecryptingAudioDecoder> decoder_;
261  scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
262  AudioDecoderConfig config_;
263
264  Decryptor::DecoderInitCB pending_init_cb_;
265  Decryptor::NewKeyCB key_added_cb_;
266  Decryptor::AudioDecodeCB pending_audio_decode_cb_;
267
268  // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
269  scoped_refptr<DecoderBuffer> encrypted_buffer_;
270  scoped_refptr<AudioBuffer> decoded_frame_;
271  scoped_refptr<AudioBuffer> end_of_stream_frame_;
272  Decryptor::AudioBuffers decoded_frame_list_;
273
274 private:
275  DISALLOW_COPY_AND_ASSIGN(DecryptingAudioDecoderTest);
276};
277
278TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
279  Initialize();
280}
281
282// Ensure that DecryptingAudioDecoder only accepts encrypted audio.
283TEST_F(DecryptingAudioDecoderTest, Initialize_UnencryptedAudioConfig) {
284  AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
285                            CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, false);
286
287  InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
288}
289
290// Ensure decoder handles invalid audio configs without crashing.
291TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
292  AudioDecoderConfig config(kUnknownAudioCodec, kUnknownSampleFormat,
293                            CHANNEL_LAYOUT_STEREO, 0, NULL, 0, true);
294
295  InitializeAndExpectStatus(config, PIPELINE_ERROR_DECODE);
296}
297
298// Ensure decoder handles unsupported audio configs without crashing.
299TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
300  EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
301      .WillOnce(RunCallback<1>(false));
302  EXPECT_CALL(*this, RequestDecryptorNotification(_))
303      .WillOnce(RunCallbackIfNotNull(decryptor_.get()));
304
305  AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
306                            CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
307  InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
308}
309
310TEST_F(DecryptingAudioDecoderTest, Initialize_NullDecryptor) {
311  EXPECT_CALL(*this, RequestDecryptorNotification(_))
312      .WillRepeatedly(RunCallbackIfNotNull(static_cast<Decryptor*>(NULL)));
313
314  AudioDecoderConfig config(kCodecVorbis, kSampleFormatPlanarF32,
315                            CHANNEL_LAYOUT_STEREO, kSampleRate, NULL, 0, true);
316  InitializeAndExpectStatus(config, DECODER_ERROR_NOT_SUPPORTED);
317}
318
319// Test normal decrypt and decode case.
320TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
321  Initialize();
322  EnterNormalDecodingState();
323}
324
325// Test the case where the decryptor returns error when doing decrypt and
326// decode.
327TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
328  Initialize();
329
330  EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
331      .WillRepeatedly(RunCallback<1>(Decryptor::kError,
332                                     Decryptor::AudioBuffers()));
333
334  ReadAndExpectFrameReadyWith(
335      encrypted_buffer_, AudioDecoder::kDecodeError, NULL);
336}
337
338// Test the case where the decryptor returns kNeedMoreData to ask for more
339// buffers before it can produce a frame.
340TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_NeedMoreData) {
341  Initialize();
342
343  EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
344      .WillOnce(RunCallback<1>(Decryptor::kNeedMoreData,
345                               Decryptor::AudioBuffers()))
346      .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
347
348  // We expect it to eventually return kOk, with any number of returns of
349  // kNotEnoughData beforehand.
350  EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
351  ReadAndExpectFrameReadyWith(
352      encrypted_buffer_, AudioDecoder::kNotEnoughData, decoded_frame_);
353}
354
355// Test the case where the decryptor returns multiple decoded frames.
356TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
357  Initialize();
358
359  scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
360      config_.channel_layout(),
361      kSampleRate,
362      kFakeAudioFrameSize,
363      kNoTimestamp(),
364      kNoTimestamp());
365  scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
366      config_.channel_layout(),
367      kSampleRate,
368      kFakeAudioFrameSize,
369      kNoTimestamp(),
370      kNoTimestamp());
371  decoded_frame_list_.push_back(frame_a);
372  decoded_frame_list_.push_back(frame_b);
373
374  EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
375      .WillOnce(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
376
377  ReadAndExpectFrameReadyWith(
378      encrypted_buffer_, AudioDecoder::kOk, decoded_frame_);
379  ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_a);
380  ReadAndExpectFrameReadyWith(encrypted_buffer_, AudioDecoder::kOk, frame_b);
381}
382
383// Test the case where the decryptor receives end-of-stream buffer.
384TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
385  Initialize();
386  EnterNormalDecodingState();
387  EnterEndOfStreamState();
388}
389
390// Test reinitializing decode with a new config
391TEST_F(DecryptingAudioDecoderTest, Reinitialize_ConfigChange) {
392  Initialize();
393
394  EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
395      .Times(AtMost(1))
396      .WillOnce(RunCallback<1>(true));
397
398  // The new config is different from the initial config in bits-per-channel,
399  // channel layout and samples_per_second.
400  AudioDecoderConfig new_config(kCodecVorbis, kSampleFormatPlanarS16,
401                                CHANNEL_LAYOUT_5_1, 88200, NULL, 0, true);
402  EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
403  EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
404  EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
405
406  ReinitializeConfigChange(new_config);
407  message_loop_.RunUntilIdle();
408
409  EXPECT_EQ(new_config.bits_per_channel(), decoder_->bits_per_channel());
410  EXPECT_EQ(new_config.channel_layout(), decoder_->channel_layout());
411  EXPECT_EQ(new_config.samples_per_second(), decoder_->samples_per_second());
412}
413
414// Test the case where the a key is added when the decryptor is in
415// kWaitingForKey state.
416TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
417  Initialize();
418  EnterWaitingForKeyState();
419
420  EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
421      .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
422  EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
423  key_added_cb_.Run();
424  message_loop_.RunUntilIdle();
425}
426
427// Test the case where the a key is added when the decryptor is in
428// kPendingDecode state.
429TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
430  Initialize();
431  EnterPendingDecodeState();
432
433  EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
434      .WillRepeatedly(RunCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
435  EXPECT_CALL(*this, FrameReady(AudioDecoder::kOk, decoded_frame_));
436  // The audio decode callback is returned after the correct decryption key is
437  // added.
438  key_added_cb_.Run();
439  base::ResetAndReturn(&pending_audio_decode_cb_).Run(
440      Decryptor::kNoKey, Decryptor::AudioBuffers());
441  message_loop_.RunUntilIdle();
442}
443
444// Test resetting when the decoder is in kIdle state but has not decoded any
445// frame.
446TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
447  Initialize();
448  Reset();
449}
450
451// Test resetting when the decoder is in kIdle state after it has decoded one
452// frame.
453TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
454  Initialize();
455  EnterNormalDecodingState();
456  Reset();
457}
458
459// Test resetting when the decoder is in kPendingDecode state.
460TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
461  Initialize();
462  EnterPendingDecodeState();
463
464  EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
465
466  Reset();
467}
468
469// Test resetting when the decoder is in kWaitingForKey state.
470TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
471  Initialize();
472  EnterWaitingForKeyState();
473
474  EXPECT_CALL(*this, FrameReady(AudioDecoder::kAborted, IsNull()));
475
476  Reset();
477}
478
479// Test resetting when the decoder has hit end of stream and is in
480// kDecodeFinished state.
481TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
482  Initialize();
483  EnterNormalDecodingState();
484  EnterEndOfStreamState();
485  Reset();
486}
487
488// Test resetting after the decoder has been reset.
489TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
490  Initialize();
491  EnterNormalDecodingState();
492  Reset();
493  Reset();
494}
495
496}  // namespace media
497