Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / decrypting_audio_decoder_unittest.cc
1 // Copyright 2012 The Chromium Authors
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_audio_decoder.h"
6
7 #include <stdint.h>
8
9 #include <string>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/run_loop.h"
15 #include "base/test/gmock_callback_support.h"
16 #include "base/test/gmock_move_support.h"
17 #include "base/test/task_environment.h"
18 #include "media/base/audio_buffer.h"
19 #include "media/base/decoder_buffer.h"
20 #include "media/base/decrypt_config.h"
21 #include "media/base/media_util.h"
22 #include "media/base/mock_filters.h"
23 #include "media/base/test_helpers.h"
24 #include "media/base/timestamp_constants.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26
27 using ::base::test::RunOnceCallback;
28 using ::testing::_;
29 using ::testing::AtMost;
30 using ::testing::Return;
31 using ::testing::StrictMock;
32
33 namespace media {
34
35 const int kSampleRate = 44100;
36
37 // Make sure the kFakeAudioFrameSize is a valid frame size for all audio decoder
38 // configs used in this test.
39 const int kFakeAudioFrameSize = 48;
40 const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
41 const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
42 const int kDecodingDelay = 3;
43
44 // Create a fake non-empty encrypted buffer.
45 static scoped_refptr<DecoderBuffer> CreateFakeEncryptedBuffer() {
46   const int buffer_size = 16;  // Need a non-empty buffer;
47   scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(buffer_size));
48   buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
49       std::string(reinterpret_cast<const char*>(kFakeKeyId),
50                   std::size(kFakeKeyId)),
51       std::string(reinterpret_cast<const char*>(kFakeIv), std::size(kFakeIv)),
52       std::vector<SubsampleEntry>()));
53   return buffer;
54 }
55
56 class DecryptingAudioDecoderTest : public testing::Test {
57  public:
58   DecryptingAudioDecoderTest()
59       : decoder_(new DecryptingAudioDecoder(
60             task_environment_.GetMainThreadTaskRunner(),
61             &media_log_)),
62         cdm_context_(new StrictMock<MockCdmContext>()),
63         decryptor_(new StrictMock<MockDecryptor>()),
64         num_decrypt_and_decode_calls_(0),
65         num_frames_in_decryptor_(0),
66         encrypted_buffer_(CreateFakeEncryptedBuffer()),
67         decoded_frame_(nullptr),
68         decoded_frame_list_() {}
69
70   DecryptingAudioDecoderTest(const DecryptingAudioDecoderTest&) = delete;
71   DecryptingAudioDecoderTest& operator=(const DecryptingAudioDecoderTest&) =
72       delete;
73
74   ~DecryptingAudioDecoderTest() override { Destroy(); }
75
76   void InitializeAndExpectResult(const AudioDecoderConfig& config,
77                                  bool success) {
78     // Initialize data now that the config is known. Since the code uses
79     // invalid values (that CreateEmptyBuffer() doesn't support), tweak them
80     // just for CreateEmptyBuffer().
81     int channels = ChannelLayoutToChannelCount(config.channel_layout());
82     if (channels < 0)
83       channels = 0;
84     decoded_frame_ = AudioBuffer::CreateEmptyBuffer(
85         config.channel_layout(), channels, kSampleRate, kFakeAudioFrameSize,
86         kNoTimestamp);
87     decoded_frame_list_.push_back(decoded_frame_);
88
89     decoder_->Initialize(
90         config, cdm_context_.get(),
91         base::BindOnce(
92             [](bool success, DecoderStatus status) {
93               EXPECT_EQ(status.is_ok(), success);
94             },
95             success),
96         base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
97                             base::Unretained(this)),
98         base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
99                             base::Unretained(this)));
100     base::RunLoop().RunUntilIdle();
101   }
102
103   enum CdmType { CDM_WITHOUT_DECRYPTOR, CDM_WITH_DECRYPTOR };
104
105   void SetCdmType(CdmType cdm_type) {
106     const bool has_decryptor = cdm_type == CDM_WITH_DECRYPTOR;
107     EXPECT_CALL(*cdm_context_, GetDecryptor())
108         .WillRepeatedly(Return(has_decryptor ? decryptor_.get() : nullptr));
109   }
110
111   void Initialize() {
112     SetCdmType(CDM_WITH_DECRYPTOR);
113     EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
114         .Times(AtMost(1))
115         .WillOnce(RunOnceCallback<1>(true));
116     EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
117       event_cb_ = cb;
118       return std::make_unique<CallbackRegistration>();
119     });
120
121     config_.Initialize(AudioCodec::kVorbis, kSampleFormatPlanarF32,
122                        CHANNEL_LAYOUT_STEREO, kSampleRate, EmptyExtraData(),
123                        EncryptionScheme::kCenc, base::TimeDelta(), 0);
124     InitializeAndExpectResult(config_, true);
125   }
126
127   void Reinitialize() { ReinitializeConfigChange(config_); }
128
129   void ReinitializeConfigChange(const AudioDecoderConfig& new_config) {
130     EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio));
131     EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
132         .WillOnce(RunOnceCallback<1>(true));
133     decoder_->Initialize(
134         new_config, cdm_context_.get(),
135         base::BindOnce(
136             [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }),
137         base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady,
138                             base::Unretained(this)),
139         base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting,
140                             base::Unretained(this)));
141   }
142
143   // Decode |buffer| and expect DecodeDone to get called with |status|.
144   void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer,
145                        DecoderStatus status) {
146     EXPECT_CALL(*this, DecodeDone(HasStatusCode(status)));
147     decoder_->Decode(buffer,
148                      base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
149                                     base::Unretained(this)));
150     base::RunLoop().RunUntilIdle();
151   }
152
153   // Helper function to simulate the decrypting and decoding process in the
154   // |decryptor_| with a decoding delay of kDecodingDelay buffers.
155   void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
156                              Decryptor::AudioDecodeCB audio_decode_cb) {
157     num_decrypt_and_decode_calls_++;
158     if (!encrypted->end_of_stream())
159       num_frames_in_decryptor_++;
160
161     if (num_decrypt_and_decode_calls_ <= kDecodingDelay ||
162         num_frames_in_decryptor_ == 0) {
163       std::move(audio_decode_cb)
164           .Run(Decryptor::kNeedMoreData, Decryptor::AudioFrames());
165       return;
166     }
167
168     num_frames_in_decryptor_--;
169     std::move(audio_decode_cb)
170         .Run(Decryptor::kSuccess, Decryptor::AudioFrames(1, decoded_frame_));
171   }
172
173   // Sets up expectations and actions to put DecryptingAudioDecoder in an
174   // active normal decoding state.
175   void EnterNormalDecodingState() {
176     EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
177         .WillRepeatedly(
178             Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio));
179     EXPECT_CALL(*this, FrameReady(decoded_frame_));
180     for (int i = 0; i < kDecodingDelay + 1; ++i)
181       DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
182   }
183
184   // Sets up expectations and actions to put DecryptingAudioDecoder in an end
185   // of stream state. This function must be called after
186   // EnterNormalDecodingState() to work.
187   void EnterEndOfStreamState() {
188     // The codec in the |decryptor_| will be flushed.
189     EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay);
190     DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(),
191                     DecoderStatus::Codes::kOk);
192     EXPECT_EQ(0, num_frames_in_decryptor_);
193   }
194
195   // Make the audio decode callback pending by saving and not firing it.
196   void EnterPendingDecodeState() {
197     EXPECT_TRUE(!pending_audio_decode_cb_);
198     EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
199         .WillOnce(MoveArg<1>(&pending_audio_decode_cb_));
200
201     decoder_->Decode(encrypted_buffer_,
202                      base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
203                                     base::Unretained(this)));
204     base::RunLoop().RunUntilIdle();
205     // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
206     // the decryptor.
207     EXPECT_FALSE(!pending_audio_decode_cb_);
208   }
209
210   void EnterWaitingForKeyState() {
211     EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _))
212         .WillRepeatedly(
213             RunOnceCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames()));
214     EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
215     decoder_->Decode(encrypted_buffer_,
216                      base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone,
217                                     base::Unretained(this)));
218
219     base::RunLoop().RunUntilIdle();
220   }
221
222   void AbortPendingAudioDecodeCB() {
223     if (pending_audio_decode_cb_) {
224       std::move(pending_audio_decode_cb_)
225           .Run(Decryptor::kSuccess, Decryptor::AudioFrames());
226     }
227   }
228
229   void AbortAllPendingCBs() {
230     if (pending_init_cb_) {
231       ASSERT_TRUE(!pending_audio_decode_cb_);
232       std::move(pending_init_cb_).Run(false);
233       return;
234     }
235
236     AbortPendingAudioDecodeCB();
237   }
238
239   void Reset() {
240     EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kAudio))
241         .WillRepeatedly(InvokeWithoutArgs(
242             this, &DecryptingAudioDecoderTest::AbortPendingAudioDecodeCB));
243
244     decoder_->Reset(NewExpectedClosure());
245     base::RunLoop().RunUntilIdle();
246   }
247
248   void Destroy() {
249     EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kAudio))
250         .WillRepeatedly(InvokeWithoutArgs(
251             this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
252
253     decoder_.reset();
254     base::RunLoop().RunUntilIdle();
255   }
256
257   MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>));
258   MOCK_METHOD1(DecodeDone, void(DecoderStatus));
259
260   MOCK_METHOD1(OnWaiting, void(WaitingReason));
261
262   base::test::SingleThreadTaskEnvironment task_environment_;
263   NullMediaLog media_log_;
264   std::unique_ptr<DecryptingAudioDecoder> decoder_;
265   std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
266   std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
267   AudioDecoderConfig config_;
268
269   // Variables to help the |decryptor_| to simulate decoding delay and flushing.
270   int num_decrypt_and_decode_calls_;
271   int num_frames_in_decryptor_;
272
273   Decryptor::DecoderInitCB pending_init_cb_;
274   CdmContext::EventCB event_cb_;
275   Decryptor::AudioDecodeCB pending_audio_decode_cb_;
276
277   // Constant buffer/frames, to be used/returned by |decoder_| and |decryptor_|.
278   scoped_refptr<DecoderBuffer> encrypted_buffer_;
279   scoped_refptr<AudioBuffer> decoded_frame_;
280   Decryptor::AudioFrames decoded_frame_list_;
281 };
282
283 TEST_F(DecryptingAudioDecoderTest, Initialize_Normal) {
284   Initialize();
285 }
286
287 // Ensure decoder handles invalid audio configs without crashing.
288 TEST_F(DecryptingAudioDecoderTest, Initialize_InvalidAudioConfig) {
289   AudioDecoderConfig config(AudioCodec::kUnknown, kUnknownSampleFormat,
290                             CHANNEL_LAYOUT_STEREO, 0, EmptyExtraData(),
291                             EncryptionScheme::kCenc);
292
293   InitializeAndExpectResult(config, false);
294 }
295
296 // Ensure decoder handles unsupported audio configs without crashing.
297 TEST_F(DecryptingAudioDecoderTest, Initialize_UnsupportedAudioConfig) {
298   SetCdmType(CDM_WITH_DECRYPTOR);
299   EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).WillOnce([&](auto cb) {
300     event_cb_ = cb;
301     return std::make_unique<CallbackRegistration>();
302   });
303   EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
304       .WillOnce(RunOnceCallback<1>(false));
305
306   AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
307                             CHANNEL_LAYOUT_STEREO, kSampleRate,
308                             EmptyExtraData(), EncryptionScheme::kCenc);
309   InitializeAndExpectResult(config, false);
310 }
311
312 TEST_F(DecryptingAudioDecoderTest, Initialize_CdmWithoutDecryptor) {
313   SetCdmType(CDM_WITHOUT_DECRYPTOR);
314   AudioDecoderConfig config(AudioCodec::kVorbis, kSampleFormatPlanarF32,
315                             CHANNEL_LAYOUT_STEREO, kSampleRate,
316                             EmptyExtraData(), EncryptionScheme::kCenc);
317   InitializeAndExpectResult(config, false);
318 }
319
320 // Test normal decrypt and decode case.
321 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_Normal) {
322   Initialize();
323   EnterNormalDecodingState();
324 }
325
326 // Test the case where the decryptor returns error when doing decrypt and
327 // decode.
328 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_DecodeError) {
329   Initialize();
330
331   EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
332       .WillRepeatedly(
333           RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames()));
334
335   DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed);
336 }
337
338 // Test the case where the decryptor returns multiple decoded frames.
339 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_MultipleFrames) {
340   Initialize();
341
342   scoped_refptr<AudioBuffer> frame_a = AudioBuffer::CreateEmptyBuffer(
343       config_.channel_layout(),
344       ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
345       kFakeAudioFrameSize, kNoTimestamp);
346   scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
347       config_.channel_layout(),
348       ChannelLayoutToChannelCount(config_.channel_layout()), kSampleRate,
349       kFakeAudioFrameSize, kNoTimestamp);
350   decoded_frame_list_.push_back(frame_a);
351   decoded_frame_list_.push_back(frame_b);
352
353   EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
354       .WillOnce(RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
355
356   EXPECT_CALL(*this, FrameReady(decoded_frame_));
357   EXPECT_CALL(*this, FrameReady(frame_a));
358   EXPECT_CALL(*this, FrameReady(frame_b));
359   DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk);
360 }
361
362 // Test the case where the decryptor receives end-of-stream buffer.
363 TEST_F(DecryptingAudioDecoderTest, DecryptAndDecode_EndOfStream) {
364   Initialize();
365   EnterNormalDecodingState();
366   EnterEndOfStreamState();
367 }
368
369 // Test reinitializing decode with a new encrypted config.
370 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToEncrypted) {
371   Initialize();
372
373   EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
374       .Times(AtMost(1))
375       .WillOnce(RunOnceCallback<1>(true));
376
377   // The new config is different from the initial config in bits-per-channel,
378   // channel layout and samples_per_second.
379   AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
380                                 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
381                                 EncryptionScheme::kCenc);
382   EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
383   EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
384   EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
385   ASSERT_TRUE(new_config.is_encrypted());
386
387   ReinitializeConfigChange(new_config);
388   base::RunLoop().RunUntilIdle();
389 }
390
391 // Test reinitializing decode with a new clear config.
392 TEST_F(DecryptingAudioDecoderTest, Reinitialize_EncryptedToClear) {
393   Initialize();
394
395   EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
396       .Times(AtMost(1))
397       .WillOnce(RunOnceCallback<1>(true));
398
399   // The new config is different from the initial config in bits-per-channel,
400   // channel layout and samples_per_second.
401   AudioDecoderConfig new_config(AudioCodec::kVorbis, kSampleFormatPlanarS16,
402                                 CHANNEL_LAYOUT_5_1, 88200, EmptyExtraData(),
403                                 EncryptionScheme::kUnencrypted);
404   EXPECT_NE(new_config.bits_per_channel(), config_.bits_per_channel());
405   EXPECT_NE(new_config.channel_layout(), config_.channel_layout());
406   EXPECT_NE(new_config.samples_per_second(), config_.samples_per_second());
407   ASSERT_FALSE(new_config.is_encrypted());
408
409   ReinitializeConfigChange(new_config);
410   base::RunLoop().RunUntilIdle();
411 }
412
413 // Test the case where the a key is added when the decryptor is in
414 // kWaitingForKey state.
415 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DuringWaitingForKey) {
416   Initialize();
417   EnterWaitingForKeyState();
418
419   EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
420       .WillRepeatedly(
421           RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
422   EXPECT_CALL(*this, FrameReady(decoded_frame_));
423   EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
424   event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
425   base::RunLoop().RunUntilIdle();
426 }
427
428 // Test the case where the a key is added when the decryptor is in
429 // kPendingDecode state.
430 TEST_F(DecryptingAudioDecoderTest, KeyAdded_DruingPendingDecode) {
431   Initialize();
432   EnterPendingDecodeState();
433
434   EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(_, _))
435       .WillRepeatedly(
436           RunOnceCallback<1>(Decryptor::kSuccess, decoded_frame_list_));
437   EXPECT_CALL(*this, FrameReady(decoded_frame_));
438   EXPECT_CALL(*this, DecodeDone(IsOkStatus()));
439   // The audio decode callback is returned after the correct decryption key is
440   // added.
441   event_cb_.Run(CdmContext::Event::kHasAdditionalUsableKey);
442   std::move(pending_audio_decode_cb_)
443       .Run(Decryptor::kNoKey, Decryptor::AudioFrames());
444   base::RunLoop().RunUntilIdle();
445 }
446
447 // Test resetting when the decoder is in kIdle state but has not decoded any
448 // frame.
449 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterInitialization) {
450   Initialize();
451   Reset();
452 }
453
454 // Test resetting when the decoder is in kIdle state after it has decoded one
455 // frame.
456 TEST_F(DecryptingAudioDecoderTest, Reset_DuringIdleAfterDecodedOneFrame) {
457   Initialize();
458   EnterNormalDecodingState();
459   Reset();
460 }
461
462 // Test resetting when the decoder is in kPendingDecode state.
463 TEST_F(DecryptingAudioDecoderTest, Reset_DuringPendingDecode) {
464   Initialize();
465   EnterPendingDecodeState();
466
467   EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
468
469   Reset();
470 }
471
472 // Test resetting when the decoder is in kWaitingForKey state.
473 TEST_F(DecryptingAudioDecoderTest, Reset_DuringWaitingForKey) {
474   Initialize();
475   EnterWaitingForKeyState();
476
477   EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted)));
478
479   Reset();
480 }
481
482 // Test resetting when the decoder has hit end of stream and is in
483 // kDecodeFinished state.
484 TEST_F(DecryptingAudioDecoderTest, Reset_AfterDecodeFinished) {
485   Initialize();
486   EnterNormalDecodingState();
487   EnterEndOfStreamState();
488   Reset();
489 }
490
491 // Test resetting after the decoder has been reset.
492 TEST_F(DecryptingAudioDecoderTest, Reset_AfterReset) {
493   Initialize();
494   EnterNormalDecodingState();
495   Reset();
496   Reset();
497 }
498
499 }  // namespace media