Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / video_decoder_selector_unittest.cc
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/base/test_helpers.h"
12 #include "media/filters/decoder_selector.h"
13 #include "media/filters/decrypting_demuxer_stream.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using ::testing::_;
17 using ::testing::IsNull;
18 using ::testing::NiceMock;
19 using ::testing::NotNull;
20 using ::testing::Return;
21 using ::testing::StrictMock;
22
23 namespace media {
24
25 class VideoDecoderSelectorTest : public ::testing::Test {
26  public:
27   enum DecryptorCapability {
28     kNoDecryptor,
29     // Used to test Abort() during DecryptingVideoDecoder::Initialize() and
30     // DecryptingDemuxerStream::Initialize(). We don't need this for normal
31     // VideoDecoders since we use MockVideoDecoder.
32     kHoldSetDecryptor,
33     kDecryptOnly,
34     kDecryptAndDecode
35   };
36
37   VideoDecoderSelectorTest()
38       : demuxer_stream_(
39             new StrictMock<MockDemuxerStream>(DemuxerStream::VIDEO)),
40         decryptor_(new NiceMock<MockDecryptor>()),
41         decoder_1_(new StrictMock<MockVideoDecoder>()),
42         decoder_2_(new StrictMock<MockVideoDecoder>()) {
43     all_decoders_.push_back(decoder_1_);
44     all_decoders_.push_back(decoder_2_);
45   }
46
47   ~VideoDecoderSelectorTest() {
48     if (selected_decoder_)
49       selected_decoder_->Stop();
50
51     message_loop_.RunUntilIdle();
52   }
53
54   MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
55   MOCK_METHOD2(OnDecoderSelected,
56                void(VideoDecoder*, DecryptingDemuxerStream*));
57
58   void MockOnDecoderSelected(
59       scoped_ptr<VideoDecoder> decoder,
60       scoped_ptr<DecryptingDemuxerStream> stream) {
61     OnDecoderSelected(decoder.get(), stream.get());
62     selected_decoder_ = decoder.Pass();
63   }
64
65   void UseClearStream() {
66     demuxer_stream_->set_video_decoder_config(TestVideoConfig::Normal());
67   }
68
69   void UseEncryptedStream() {
70     demuxer_stream_->set_video_decoder_config(
71         TestVideoConfig::NormalEncrypted());
72   }
73
74   void InitializeDecoderSelector(DecryptorCapability decryptor_capability,
75                                  int num_decoders) {
76     SetDecryptorReadyCB set_decryptor_ready_cb;
77     if (decryptor_capability != kNoDecryptor) {
78       set_decryptor_ready_cb =
79           base::Bind(&VideoDecoderSelectorTest::SetDecryptorReadyCallback,
80                      base::Unretained(this));
81     }
82
83     if (decryptor_capability == kDecryptOnly ||
84         decryptor_capability == kDecryptAndDecode) {
85       EXPECT_CALL(*this, SetDecryptorReadyCallback(_))
86           .WillRepeatedly(RunCallback<0>(decryptor_.get()));
87
88       if (decryptor_capability == kDecryptOnly) {
89         EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
90             .WillRepeatedly(RunCallback<1>(false));
91       } else {
92         EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
93             .WillRepeatedly(RunCallback<1>(true));
94       }
95     } else if (decryptor_capability == kHoldSetDecryptor) {
96       // Set and cancel DecryptorReadyCB but the callback is never fired.
97       EXPECT_CALL(*this, SetDecryptorReadyCallback(_))
98           .Times(2);
99     }
100
101     DCHECK_GE(all_decoders_.size(), static_cast<size_t>(num_decoders));
102     all_decoders_.erase(
103         all_decoders_.begin() + num_decoders, all_decoders_.end());
104
105     decoder_selector_.reset(new VideoDecoderSelector(
106         message_loop_.message_loop_proxy(),
107         all_decoders_.Pass(),
108         set_decryptor_ready_cb));
109   }
110
111   void SelectDecoder() {
112     decoder_selector_->SelectDecoder(
113         demuxer_stream_.get(),
114         false,
115         base::Bind(&VideoDecoderSelectorTest::MockOnDecoderSelected,
116                    base::Unretained(this)));
117     message_loop_.RunUntilIdle();
118   }
119
120   void SelectDecoderAndAbort() {
121     SelectDecoder();
122
123     EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
124     decoder_selector_->Abort();
125     message_loop_.RunUntilIdle();
126   }
127
128   // Fixture members.
129   scoped_ptr<VideoDecoderSelector> decoder_selector_;
130   scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
131   // Use NiceMock since we don't care about most of calls on the decryptor, e.g.
132   // RegisterNewKeyCB().
133   scoped_ptr<NiceMock<MockDecryptor> > decryptor_;
134   StrictMock<MockVideoDecoder>* decoder_1_;
135   StrictMock<MockVideoDecoder>* decoder_2_;
136   ScopedVector<VideoDecoder> all_decoders_;
137
138   scoped_ptr<VideoDecoder> selected_decoder_;
139
140   base::MessageLoop message_loop_;
141
142  private:
143   DISALLOW_COPY_AND_ASSIGN(VideoDecoderSelectorTest);
144 };
145
146 // Note:
147 // In all the tests, Stop() is expected to be called on a decoder if a decoder:
148 // - is pending initialization and DecoderSelector::Abort() is called, or
149 // - has been successfully initialized.
150
151 // The stream is not encrypted but we have no clear decoder. No decoder can be
152 // selected.
153 TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_NoClearDecoder) {
154   UseClearStream();
155   InitializeDecoderSelector(kNoDecryptor, 0);
156
157   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
158
159   SelectDecoder();
160 }
161
162 // The stream is not encrypted and we have one clear decoder. The decoder
163 // will be selected.
164 TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_OneClearDecoder) {
165   UseClearStream();
166   InitializeDecoderSelector(kNoDecryptor, 1);
167
168   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
169       .WillOnce(RunCallback<2>(PIPELINE_OK));
170   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
171   EXPECT_CALL(*decoder_1_, Stop());
172
173   SelectDecoder();
174 }
175
176 TEST_F(VideoDecoderSelectorTest,
177        Abort_ClearStream_NoDecryptor_OneClearDecoder) {
178   UseClearStream();
179   InitializeDecoderSelector(kNoDecryptor, 1);
180
181   EXPECT_CALL(*decoder_1_, Initialize(_, _, _));
182   EXPECT_CALL(*decoder_1_, Stop());
183
184   SelectDecoderAndAbort();
185 }
186
187 // The stream is not encrypted and we have multiple clear decoders. The first
188 // decoder that can decode the input stream will be selected.
189 TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_MultipleClearDecoder) {
190   UseClearStream();
191   InitializeDecoderSelector(kNoDecryptor, 2);
192
193   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
194       .WillOnce(RunCallback<2>(DECODER_ERROR_NOT_SUPPORTED));
195   EXPECT_CALL(*decoder_2_, Initialize(_, _, _))
196       .WillOnce(RunCallback<2>(PIPELINE_OK));
197   EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, IsNull()));
198   EXPECT_CALL(*decoder_2_, Stop());
199
200   SelectDecoder();
201 }
202
203 TEST_F(VideoDecoderSelectorTest,
204        Abort_ClearStream_NoDecryptor_MultipleClearDecoder) {
205   UseClearStream();
206   InitializeDecoderSelector(kNoDecryptor, 2);
207
208   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
209       .WillOnce(RunCallback<2>(DECODER_ERROR_NOT_SUPPORTED));
210   EXPECT_CALL(*decoder_2_, Initialize(_, _, _));
211   EXPECT_CALL(*decoder_2_, Stop());
212
213   SelectDecoderAndAbort();
214 }
215
216 // There is a decryptor but the stream is not encrypted. The decoder will be
217 // selected.
218 TEST_F(VideoDecoderSelectorTest, ClearStream_HasDecryptor) {
219   UseClearStream();
220   InitializeDecoderSelector(kDecryptOnly, 1);
221
222   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
223       .WillOnce(RunCallback<2>(PIPELINE_OK));
224   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
225   EXPECT_CALL(*decoder_1_, Stop());
226
227   SelectDecoder();
228 }
229
230 TEST_F(VideoDecoderSelectorTest, Abort_ClearStream_HasDecryptor) {
231   UseClearStream();
232   InitializeDecoderSelector(kDecryptOnly, 1);
233
234   EXPECT_CALL(*decoder_1_, Initialize(_, _, _));
235   EXPECT_CALL(*decoder_1_, Stop());
236
237   SelectDecoderAndAbort();
238 }
239
240 // The stream is encrypted and there's no decryptor. No decoder can be selected.
241 TEST_F(VideoDecoderSelectorTest, EncryptedStream_NoDecryptor) {
242   UseEncryptedStream();
243   InitializeDecoderSelector(kNoDecryptor, 1);
244
245   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
246
247   SelectDecoder();
248 }
249
250 // Decryptor can only do decryption and there's no decoder available. No decoder
251 // can be selected.
252 TEST_F(VideoDecoderSelectorTest, EncryptedStream_DecryptOnly_NoClearDecoder) {
253   UseEncryptedStream();
254   InitializeDecoderSelector(kDecryptOnly, 0);
255
256   EXPECT_CALL(*this, OnDecoderSelected(IsNull(), IsNull()));
257
258   SelectDecoder();
259 }
260
261 TEST_F(VideoDecoderSelectorTest,
262        Abort_EncryptedStream_DecryptOnly_NoClearDecoder) {
263   UseEncryptedStream();
264   InitializeDecoderSelector(kHoldSetDecryptor, 0);
265
266   SelectDecoderAndAbort();
267 }
268
269 // Decryptor can do decryption-only and there's a decoder available. The decoder
270 // will be selected and a DecryptingDemuxerStream will be created.
271 TEST_F(VideoDecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
272   UseEncryptedStream();
273   InitializeDecoderSelector(kDecryptOnly, 1);
274
275   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
276       .WillOnce(RunCallback<2>(PIPELINE_OK));
277   EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, NotNull()));
278   EXPECT_CALL(*decoder_1_, Stop());
279
280   SelectDecoder();
281 }
282
283 TEST_F(VideoDecoderSelectorTest,
284        Abort_EncryptedStream_DecryptOnly_OneClearDecoder) {
285   UseEncryptedStream();
286   InitializeDecoderSelector(kDecryptOnly, 1);
287
288   EXPECT_CALL(*decoder_1_, Initialize(_, _, _));
289   EXPECT_CALL(*decoder_1_, Stop());
290
291   SelectDecoderAndAbort();
292 }
293
294 // Decryptor can only do decryption and there are multiple decoders available.
295 // The first decoder that can decode the input stream will be selected and
296 // a DecryptingDemuxerStream will be created.
297 TEST_F(VideoDecoderSelectorTest,
298        EncryptedStream_DecryptOnly_MultipleClearDecoder) {
299   UseEncryptedStream();
300   InitializeDecoderSelector(kDecryptOnly, 2);
301
302   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
303       .WillOnce(RunCallback<2>(DECODER_ERROR_NOT_SUPPORTED));
304   EXPECT_CALL(*decoder_2_, Initialize(_, _, _))
305       .WillOnce(RunCallback<2>(PIPELINE_OK));
306   EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, NotNull()));
307   EXPECT_CALL(*decoder_2_, Stop());
308
309   SelectDecoder();
310 }
311
312 TEST_F(VideoDecoderSelectorTest,
313        Abort_EncryptedStream_DecryptOnly_MultipleClearDecoder) {
314   UseEncryptedStream();
315   InitializeDecoderSelector(kDecryptOnly, 2);
316
317   EXPECT_CALL(*decoder_1_, Initialize(_, _, _))
318       .WillOnce(RunCallback<2>(DECODER_ERROR_NOT_SUPPORTED));
319   EXPECT_CALL(*decoder_2_, Initialize(_, _, _));
320   EXPECT_CALL(*decoder_2_, Stop());
321
322   SelectDecoderAndAbort();
323 }
324
325 // Decryptor can do decryption and decoding. A DecryptingVideoDecoder will be
326 // created and selected. The clear decoders should not be touched at all.
327 // No DecryptingDemuxerStream should to be created.
328 TEST_F(VideoDecoderSelectorTest, EncryptedStream_DecryptAndDecode) {
329   UseEncryptedStream();
330   InitializeDecoderSelector(kDecryptAndDecode, 1);
331
332   EXPECT_CALL(*this, OnDecoderSelected(NotNull(), IsNull()));
333
334   SelectDecoder();
335 }
336
337 TEST_F(VideoDecoderSelectorTest, Abort_EncryptedStream_DecryptAndDecode) {
338   UseEncryptedStream();
339   InitializeDecoderSelector(kHoldSetDecryptor, 1);
340
341   SelectDecoderAndAbort();
342 }
343
344 }  // namespace media