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.
9 #include "base/callback_helpers.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/base/decoder_buffer.h"
12 #include "media/base/decrypt_config.h"
13 #include "media/base/gmock_callback_support.h"
14 #include "media/base/mock_filters.h"
15 #include "media/base/test_helpers.h"
16 #include "media/base/video_frame.h"
17 #include "media/filters/decrypting_video_decoder.h"
18 #include "testing/gmock/include/gmock/gmock.h"
21 using ::testing::Invoke
;
22 using ::testing::SaveArg
;
23 using ::testing::StrictMock
;
27 const uint8 kFakeKeyId
[] = { 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44 };
28 const uint8 kFakeIv
[DecryptConfig::kDecryptionKeySize
] = { 0 };
29 const int kDecodingDelay
= 3;
31 // Create a fake non-empty encrypted buffer.
32 static scoped_refptr
<DecoderBuffer
> CreateFakeEncryptedBuffer() {
33 const int buffer_size
= 16; // Need a non-empty buffer;
34 scoped_refptr
<DecoderBuffer
> buffer(new DecoderBuffer(buffer_size
));
35 buffer
->set_decrypt_config(scoped_ptr
<DecryptConfig
>(new DecryptConfig(
36 std::string(reinterpret_cast<const char*>(kFakeKeyId
),
37 arraysize(kFakeKeyId
)),
38 std::string(reinterpret_cast<const char*>(kFakeIv
), arraysize(kFakeIv
)),
39 std::vector
<SubsampleEntry
>())));
43 // Use anonymous namespace here to prevent the actions to be defined multiple
44 // times across multiple test files. Sadly we can't use static for them.
47 ACTION_P3(ResetAndRunCallback
, callback
, p1
, p2
) {
48 base::ResetAndReturn(callback
).Run(p1
, p2
);
53 class DecryptingVideoDecoderTest
: public testing::Test
{
55 DecryptingVideoDecoderTest()
56 : decoder_(new DecryptingVideoDecoder(
57 message_loop_
.task_runner(),
60 &DecryptingVideoDecoderTest::RequestDecryptorNotification
,
61 base::Unretained(this)),
62 base::Bind(&DecryptingVideoDecoderTest::OnWaitingForDecryptionKey
,
63 base::Unretained(this)))),
64 decryptor_(new StrictMock
<MockDecryptor
>()),
65 num_decrypt_and_decode_calls_(0),
66 num_frames_in_decryptor_(0),
67 encrypted_buffer_(CreateFakeEncryptedBuffer()),
69 VideoFrame::CreateBlackFrame(TestVideoConfig::NormalCodedSize())),
70 null_video_frame_(scoped_refptr
<VideoFrame
>()) {}
72 virtual ~DecryptingVideoDecoderTest() {
76 void ExpectDecryptorNotification(Decryptor
* decryptor
, bool expected_result
) {
77 EXPECT_CALL(*this, RequestDecryptorNotification(_
)).WillOnce(
78 RunCallback
<0>(decryptor
,
79 base::Bind(&DecryptingVideoDecoderTest::DecryptorSet
,
80 base::Unretained(this))));
81 EXPECT_CALL(*this, DecryptorSet(expected_result
));
84 // Initializes the |decoder_| and expects |success|. Note the initialization
85 // can succeed or fail.
86 void InitializeAndExpectResult(const VideoDecoderConfig
& config
,
88 decoder_
->Initialize(config
, false, NewExpectedBoolCB(success
),
89 base::Bind(&DecryptingVideoDecoderTest::FrameReady
,
90 base::Unretained(this)));
91 message_loop_
.RunUntilIdle();
94 // Initialize the |decoder_| and expects it to succeed.
96 ExpectDecryptorNotification(decryptor_
.get(), true);
97 EXPECT_CALL(*decryptor_
, InitializeVideoDecoder(_
, _
))
98 .WillOnce(RunCallback
<1>(true));
99 EXPECT_CALL(*decryptor_
, RegisterNewKeyCB(Decryptor::kVideo
, _
))
100 .WillOnce(SaveArg
<1>(&key_added_cb_
));
102 InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), true);
105 // Reinitialize the |decoder_| and expects it to succeed.
106 void Reinitialize() {
107 EXPECT_CALL(*decryptor_
, DeinitializeDecoder(Decryptor::kVideo
));
108 EXPECT_CALL(*decryptor_
, InitializeVideoDecoder(_
, _
))
109 .WillOnce(RunCallback
<1>(true));
110 EXPECT_CALL(*decryptor_
, RegisterNewKeyCB(Decryptor::kVideo
, _
))
111 .WillOnce(SaveArg
<1>(&key_added_cb_
));
113 InitializeAndExpectResult(TestVideoConfig::LargeEncrypted(), true);
116 // Decode |buffer| and expect DecodeDone to get called with |status|.
117 void DecodeAndExpect(const scoped_refptr
<DecoderBuffer
>& buffer
,
118 VideoDecoder::Status status
) {
119 EXPECT_CALL(*this, DecodeDone(status
));
120 decoder_
->Decode(buffer
,
121 base::Bind(&DecryptingVideoDecoderTest::DecodeDone
,
122 base::Unretained(this)));
123 message_loop_
.RunUntilIdle();
126 // Helper function to simulate the decrypting and decoding process in the
127 // |decryptor_| with a decoding delay of kDecodingDelay buffers.
128 void DecryptAndDecodeVideo(const scoped_refptr
<DecoderBuffer
>& encrypted
,
129 const Decryptor::VideoDecodeCB
& video_decode_cb
) {
130 num_decrypt_and_decode_calls_
++;
131 if (!encrypted
->end_of_stream())
132 num_frames_in_decryptor_
++;
134 if (num_decrypt_and_decode_calls_
<= kDecodingDelay
||
135 num_frames_in_decryptor_
== 0) {
136 video_decode_cb
.Run(Decryptor::kNeedMoreData
,
137 scoped_refptr
<VideoFrame
>());
141 num_frames_in_decryptor_
--;
142 video_decode_cb
.Run(Decryptor::kSuccess
, decoded_video_frame_
);
145 // Sets up expectations and actions to put DecryptingVideoDecoder in an
146 // active normal decoding state.
147 void EnterNormalDecodingState() {
148 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(_
, _
)).WillRepeatedly(
149 Invoke(this, &DecryptingVideoDecoderTest::DecryptAndDecodeVideo
));
150 EXPECT_CALL(*this, FrameReady(decoded_video_frame_
));
151 for (int i
= 0; i
< kDecodingDelay
+ 1; ++i
)
152 DecodeAndExpect(encrypted_buffer_
, VideoDecoder::kOk
);
155 // Sets up expectations and actions to put DecryptingVideoDecoder in an end
156 // of stream state. This function must be called after
157 // EnterNormalDecodingState() to work.
158 void EnterEndOfStreamState() {
159 // The codec in the |decryptor_| will be flushed.
160 EXPECT_CALL(*this, FrameReady(decoded_video_frame_
))
161 .Times(kDecodingDelay
);
162 DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), VideoDecoder::kOk
);
163 EXPECT_EQ(0, num_frames_in_decryptor_
);
166 // Make the video decode callback pending by saving and not firing it.
167 void EnterPendingDecodeState() {
168 EXPECT_TRUE(pending_video_decode_cb_
.is_null());
169 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(encrypted_buffer_
, _
))
170 .WillOnce(SaveArg
<1>(&pending_video_decode_cb_
));
172 decoder_
->Decode(encrypted_buffer_
,
173 base::Bind(&DecryptingVideoDecoderTest::DecodeDone
,
174 base::Unretained(this)));
175 message_loop_
.RunUntilIdle();
176 // Make sure the Decode() on the decoder triggers a DecryptAndDecode() on
178 EXPECT_FALSE(pending_video_decode_cb_
.is_null());
181 void EnterWaitingForKeyState() {
182 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(_
, _
))
183 .WillRepeatedly(RunCallback
<1>(Decryptor::kNoKey
, null_video_frame_
));
184 EXPECT_CALL(*this, OnWaitingForDecryptionKey());
185 decoder_
->Decode(encrypted_buffer_
,
186 base::Bind(&DecryptingVideoDecoderTest::DecodeDone
,
187 base::Unretained(this)));
188 message_loop_
.RunUntilIdle();
191 void AbortPendingVideoDecodeCB() {
192 if (!pending_video_decode_cb_
.is_null()) {
193 base::ResetAndReturn(&pending_video_decode_cb_
).Run(
194 Decryptor::kSuccess
, scoped_refptr
<VideoFrame
>(NULL
));
198 void AbortAllPendingCBs() {
199 if (!pending_init_cb_
.is_null()) {
200 ASSERT_TRUE(pending_video_decode_cb_
.is_null());
201 base::ResetAndReturn(&pending_init_cb_
).Run(false);
205 AbortPendingVideoDecodeCB();
209 EXPECT_CALL(*decryptor_
, ResetDecoder(Decryptor::kVideo
))
210 .WillRepeatedly(InvokeWithoutArgs(
211 this, &DecryptingVideoDecoderTest::AbortPendingVideoDecodeCB
));
213 decoder_
->Reset(NewExpectedClosure());
214 message_loop_
.RunUntilIdle();
218 EXPECT_CALL(*decryptor_
, DeinitializeDecoder(Decryptor::kVideo
))
219 .WillRepeatedly(InvokeWithoutArgs(
220 this, &DecryptingVideoDecoderTest::AbortAllPendingCBs
));
223 message_loop_
.RunUntilIdle();
226 MOCK_METHOD1(RequestDecryptorNotification
, void(const DecryptorReadyCB
&));
228 MOCK_METHOD1(FrameReady
, void(const scoped_refptr
<VideoFrame
>&));
229 MOCK_METHOD1(DecodeDone
, void(VideoDecoder::Status
));
231 MOCK_METHOD1(DecryptorSet
, void(bool));
233 MOCK_METHOD0(OnWaitingForDecryptionKey
, void(void));
235 base::MessageLoop message_loop_
;
236 scoped_ptr
<DecryptingVideoDecoder
> decoder_
;
237 scoped_ptr
<StrictMock
<MockDecryptor
> > decryptor_
;
239 // Variables to help the |decryptor_| to simulate decoding delay and flushing.
240 int num_decrypt_and_decode_calls_
;
241 int num_frames_in_decryptor_
;
243 Decryptor::DecoderInitCB pending_init_cb_
;
244 Decryptor::NewKeyCB key_added_cb_
;
245 Decryptor::VideoDecodeCB pending_video_decode_cb_
;
247 // Constant buffer/frames.
248 scoped_refptr
<DecoderBuffer
> encrypted_buffer_
;
249 scoped_refptr
<VideoFrame
> decoded_video_frame_
;
250 scoped_refptr
<VideoFrame
> null_video_frame_
;
253 DISALLOW_COPY_AND_ASSIGN(DecryptingVideoDecoderTest
);
256 TEST_F(DecryptingVideoDecoderTest
, Initialize_Normal
) {
260 TEST_F(DecryptingVideoDecoderTest
, Initialize_NullDecryptor
) {
261 ExpectDecryptorNotification(NULL
, false);
262 InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false);
265 TEST_F(DecryptingVideoDecoderTest
, Initialize_Failure
) {
266 EXPECT_CALL(*decryptor_
, InitializeVideoDecoder(_
, _
))
267 .WillRepeatedly(RunCallback
<1>(false));
268 EXPECT_CALL(*decryptor_
, RegisterNewKeyCB(Decryptor::kVideo
, _
))
269 .WillRepeatedly(SaveArg
<1>(&key_added_cb_
));
270 EXPECT_CALL(*this, RequestDecryptorNotification(_
)).Times(2);
272 InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false);
275 TEST_F(DecryptingVideoDecoderTest
, Reinitialize_Normal
) {
277 EnterNormalDecodingState();
281 TEST_F(DecryptingVideoDecoderTest
, Reinitialize_Failure
) {
283 EnterNormalDecodingState();
285 EXPECT_CALL(*decryptor_
, DeinitializeDecoder(Decryptor::kVideo
));
286 EXPECT_CALL(*decryptor_
, InitializeVideoDecoder(_
, _
))
287 .WillOnce(RunCallback
<1>(false));
289 // Reinitialize() expects the reinitialization to succeed. Call
290 // InitializeAndExpectResult() directly to test the reinitialization failure.
291 InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false);
294 // Test normal decrypt and decode case.
295 TEST_F(DecryptingVideoDecoderTest
, DecryptAndDecode_Normal
) {
297 EnterNormalDecodingState();
300 // Test the case where the decryptor returns error when doing decrypt and
302 TEST_F(DecryptingVideoDecoderTest
, DecryptAndDecode_DecodeError
) {
305 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(_
, _
))
306 .WillRepeatedly(RunCallback
<1>(Decryptor::kError
,
307 scoped_refptr
<VideoFrame
>(NULL
)));
309 DecodeAndExpect(encrypted_buffer_
, VideoDecoder::kDecodeError
);
311 // After a decode error occurred, all following decode returns kDecodeError.
312 DecodeAndExpect(encrypted_buffer_
, VideoDecoder::kDecodeError
);
315 // Test the case where the decryptor receives end-of-stream buffer.
316 TEST_F(DecryptingVideoDecoderTest
, DecryptAndDecode_EndOfStream
) {
318 EnterNormalDecodingState();
319 EnterEndOfStreamState();
322 // Test the case where the a key is added when the decryptor is in
323 // kWaitingForKey state.
324 TEST_F(DecryptingVideoDecoderTest
, KeyAdded_DuringWaitingForKey
) {
326 EnterWaitingForKeyState();
328 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(_
, _
))
329 .WillRepeatedly(RunCallback
<1>(Decryptor::kSuccess
,
330 decoded_video_frame_
));
331 EXPECT_CALL(*this, FrameReady(decoded_video_frame_
));
332 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kOk
));
334 message_loop_
.RunUntilIdle();
337 // Test the case where the a key is added when the decryptor is in
338 // kPendingDecode state.
339 TEST_F(DecryptingVideoDecoderTest
, KeyAdded_DuringPendingDecode
) {
341 EnterPendingDecodeState();
343 EXPECT_CALL(*decryptor_
, DecryptAndDecodeVideo(_
, _
))
344 .WillRepeatedly(RunCallback
<1>(Decryptor::kSuccess
,
345 decoded_video_frame_
));
346 EXPECT_CALL(*this, FrameReady(decoded_video_frame_
));
347 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kOk
));
348 // The video decode callback is returned after the correct decryption key is
351 base::ResetAndReturn(&pending_video_decode_cb_
).Run(Decryptor::kNoKey
,
353 message_loop_
.RunUntilIdle();
356 // Test resetting when the decoder is in kIdle state but has not decoded any
358 TEST_F(DecryptingVideoDecoderTest
, Reset_DuringIdleAfterInitialization
) {
363 // Test resetting when the decoder is in kIdle state after it has decoded one
365 TEST_F(DecryptingVideoDecoderTest
, Reset_DuringIdleAfterDecodedOneFrame
) {
367 EnterNormalDecodingState();
371 // Test resetting when the decoder is in kPendingDecode state.
372 TEST_F(DecryptingVideoDecoderTest
, Reset_DuringPendingDecode
) {
374 EnterPendingDecodeState();
376 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted
));
381 // Test resetting when the decoder is in kWaitingForKey state.
382 TEST_F(DecryptingVideoDecoderTest
, Reset_DuringWaitingForKey
) {
384 EnterWaitingForKeyState();
386 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted
));
391 // Test resetting when the decoder has hit end of stream and is in
392 // kDecodeFinished state.
393 TEST_F(DecryptingVideoDecoderTest
, Reset_AfterDecodeFinished
) {
395 EnterNormalDecodingState();
396 EnterEndOfStreamState();
400 // Test resetting after the decoder has been reset.
401 TEST_F(DecryptingVideoDecoderTest
, Reset_AfterReset
) {
403 EnterNormalDecodingState();
408 // Test destruction when the decoder is in kDecryptorRequested state.
409 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringDecryptorRequested
) {
410 DecryptorReadyCB decryptor_ready_cb
;
411 EXPECT_CALL(*this, RequestDecryptorNotification(_
))
412 .WillOnce(SaveArg
<0>(&decryptor_ready_cb
));
413 decoder_
->Initialize(TestVideoConfig::NormalEncrypted(), false,
414 NewExpectedBoolCB(false),
415 base::Bind(&DecryptingVideoDecoderTest::FrameReady
,
416 base::Unretained(this)));
417 message_loop_
.RunUntilIdle();
418 // |decryptor_ready_cb| is saved but not called here.
419 EXPECT_FALSE(decryptor_ready_cb
.is_null());
421 // During destruction, RequestDecryptorNotification() should be called with a
422 // NULL callback to cancel the |decryptor_ready_cb|.
423 EXPECT_CALL(*this, RequestDecryptorNotification(IsNullCallback())).WillOnce(
424 ResetAndRunCallback(&decryptor_ready_cb
,
425 reinterpret_cast<Decryptor
*>(NULL
),
426 base::Bind(&DecryptingVideoDecoderTest::DecryptorSet
,
427 base::Unretained(this))));
428 EXPECT_CALL(*this, DecryptorSet(_
)).Times(0);
432 // Test destruction when the decoder is in kPendingDecoderInit state.
433 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringPendingDecoderInit
) {
434 ExpectDecryptorNotification(decryptor_
.get(), true);
435 EXPECT_CALL(*decryptor_
, InitializeVideoDecoder(_
, _
))
436 .WillOnce(SaveArg
<1>(&pending_init_cb_
));
438 InitializeAndExpectResult(TestVideoConfig::NormalEncrypted(), false);
439 EXPECT_FALSE(pending_init_cb_
.is_null());
444 // Test destruction when the decoder is in kIdle state but has not decoded any
446 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringIdleAfterInitialization
) {
451 // Test destruction when the decoder is in kIdle state after it has decoded one
453 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringIdleAfterDecodedOneFrame
) {
455 EnterNormalDecodingState();
459 // Test destruction when the decoder is in kPendingDecode state.
460 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringPendingDecode
) {
462 EnterPendingDecodeState();
464 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted
));
469 // Test destruction when the decoder is in kWaitingForKey state.
470 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringWaitingForKey
) {
472 EnterWaitingForKeyState();
474 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted
));
479 // Test destruction when the decoder has hit end of stream and is in
480 // kDecodeFinished state.
481 TEST_F(DecryptingVideoDecoderTest
, Destroy_AfterDecodeFinished
) {
483 EnterNormalDecodingState();
484 EnterEndOfStreamState();
488 // Test destruction when there is a pending reset on the decoder.
489 // Reset is pending because it cannot complete when the video decode callback
491 TEST_F(DecryptingVideoDecoderTest
, Destroy_DuringPendingReset
) {
493 EnterPendingDecodeState();
495 EXPECT_CALL(*decryptor_
, ResetDecoder(Decryptor::kVideo
));
496 EXPECT_CALL(*this, DecodeDone(VideoDecoder::kAborted
));
498 decoder_
->Reset(NewExpectedClosure());
502 // Test destruction after the decoder has been reset.
503 TEST_F(DecryptingVideoDecoderTest
, Destroy_AfterReset
) {
505 EnterNormalDecodingState();