1 // Copyright 2018 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.
9 #include "base/check.h"
10 #include "base/memory/scoped_refptr.h"
11 #include "base/notreached.h"
12 #include "base/test/gmock_callback_support.h"
13 #include "base/test/scoped_feature_list.h"
14 #include "base/test/task_environment.h"
15 #include "build/build_config.h"
16 #include "media/base/demuxer_stream.h"
17 #include "media/base/media_switches.h"
18 #include "media/base/media_util.h"
19 #include "media/base/mock_filters.h"
20 #include "media/base/test_helpers.h"
21 #include "media/filters/decoder_selector.h"
22 #include "media/filters/decrypting_demuxer_stream.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 #if !BUILDFLAG(IS_ANDROID)
27 #include "media/filters/decrypting_audio_decoder.h"
28 #include "media/filters/decrypting_video_decoder.h"
29 #endif // !BUILDFLAG(IS_ANDROID)
31 using ::base::test::RunCallback;
32 using ::base::test::RunOnceCallback;
34 using ::testing::AnyNumber;
35 using ::testing::IsNull;
36 using ::testing::NiceMock;
37 using ::testing::NotNull;
38 using ::testing::Return;
39 using ::testing::StrictMock;
45 enum DecryptorCapability {
51 enum DecoderCapability {
58 bool DecoderCapabilitySupportsDecryption(DecoderCapability capability) {
71 DecoderStatus IsConfigSupported(DecoderCapability capability,
75 return DecoderStatus::Codes::kFailed;
77 return is_encrypted ? DecoderStatus::Codes::kUnsupportedEncryptionMode
78 : DecoderStatus::Codes::kOk;
80 return is_encrypted ? DecoderStatus::Codes::kOk
81 : DecoderStatus::Codes::kUnsupportedEncryptionMode;
83 return DecoderStatus::Codes::kOk;
87 const int kDecoder1 = 0xabc;
88 const int kDecoder2 = 0xdef;
89 const int kDecoder3 = 0x123;
90 const int kDecoder4 = 0x456;
92 // Specializations for the AUDIO version of the test.
93 class AudioDecoderSelectorTestParam {
95 static constexpr DemuxerStream::Type kStreamType = DemuxerStream::AUDIO;
97 using StreamTraits = DecoderStreamTraits<DemuxerStream::AUDIO>;
98 using MockDecoder = MockAudioDecoder;
99 using Output = AudioBuffer;
100 using DecoderType = AudioDecoderType;
102 #if !BUILDFLAG(IS_ANDROID)
103 using DecryptingDecoder = DecryptingAudioDecoder;
104 #endif // !BUILDFLAG(IS_ANDROID)
106 // StreamTraits() takes different parameters depending on the type.
107 static std::unique_ptr<StreamTraits> CreateStreamTraits(MediaLog* media_log) {
108 return std::make_unique<StreamTraits>(media_log, CHANNEL_LAYOUT_STEREO,
109 kSampleFormatPlanarF32);
112 static const base::Feature& ForceHardwareDecodersFeature() {
113 return kForceHardwareAudioDecoders;
116 static media::DecoderPriority MockDecoderPriorityCB(
117 const media::AudioDecoderConfig& config,
118 const media::AudioDecoder& decoder) {
119 const auto above_cutoff =
120 config.samples_per_second() > TestAudioConfig::NormalSampleRateValue();
121 return above_cutoff == decoder.IsPlatformDecoder()
122 ? media::DecoderPriority::kNormal
123 : media::DecoderPriority::kDeprioritized;
125 static media::DecoderPriority NormalDecoderPriorityCB(
126 const media::AudioDecoderConfig& /*config*/,
127 const media::AudioDecoder& /*decoder*/) {
128 return media::DecoderPriority::kNormal;
130 static media::DecoderPriority SkipDecoderPriorityCB(
131 const media::AudioDecoderConfig& /*config*/,
132 const media::AudioDecoder& /*decoder*/) {
133 return media::DecoderPriority::kSkipped;
136 static void UseNormalClearDecoderConfig(
137 StrictMock<MockDemuxerStream>& stream) {
138 stream.set_audio_decoder_config(TestAudioConfig::Normal());
140 static void UseHighQualityClearDecoderConfig(
141 StrictMock<MockDemuxerStream>& stream) {
142 stream.set_audio_decoder_config(TestAudioConfig::HighSampleRate());
144 static void UseNormalEncryptedDecoderConfig(
145 StrictMock<MockDemuxerStream>& stream) {
146 stream.set_audio_decoder_config(TestAudioConfig::NormalEncrypted());
148 static void UseHighQualityEncryptedDecoderConfig(
149 StrictMock<MockDemuxerStream>& stream) {
150 stream.set_audio_decoder_config(TestAudioConfig::HighSampleRateEncrypted());
153 // Decoder::Initialize() takes different parameters depending on the type.
154 static void ExpectInitialize(MockDecoder* decoder,
155 DecoderCapability capability) {
156 EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _))
157 .WillRepeatedly([capability](const AudioDecoderConfig& config,
158 CdmContext*, AudioDecoder::InitCB& init_cb,
159 const AudioDecoder::OutputCB&,
161 std::move(init_cb).Run(
162 IsConfigSupported(capability, config.is_encrypted()));
166 static void ExpectNotInitialize(MockDecoder* decoder) {
167 EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)).Times(0);
171 // Allocate storage for the member variables.
172 constexpr DemuxerStream::Type AudioDecoderSelectorTestParam::kStreamType;
174 // Specializations for the VIDEO version of the test.
175 class VideoDecoderSelectorTestParam {
177 static constexpr DemuxerStream::Type kStreamType = DemuxerStream::VIDEO;
179 using StreamTraits = DecoderStreamTraits<DemuxerStream::VIDEO>;
180 using MockDecoder = MockVideoDecoder;
181 using Output = VideoFrame;
182 using DecoderType = VideoDecoderType;
184 #if !BUILDFLAG(IS_ANDROID)
185 using DecryptingDecoder = DecryptingVideoDecoder;
186 #endif // !BUILDFLAG(IS_ANDROID)
188 static const base::Feature& ForceHardwareDecodersFeature() {
189 return kForceHardwareVideoDecoders;
192 static std::unique_ptr<StreamTraits> CreateStreamTraits(MediaLog* media_log) {
193 return std::make_unique<StreamTraits>(media_log);
196 static media::DecoderPriority MockDecoderPriorityCB(
197 const media::VideoDecoderConfig& config,
198 const media::VideoDecoder& decoder) {
199 auto const above_cutoff = config.visible_rect().height() >
200 TestVideoConfig::NormalCodedSize().height();
201 return decoder.IsPlatformDecoder() == above_cutoff
202 ? media::DecoderPriority::kNormal
203 : media::DecoderPriority::kDeprioritized;
205 static media::DecoderPriority NormalDecoderPriorityCB(
206 const media::VideoDecoderConfig& /*config*/,
207 const media::VideoDecoder& /*decoder*/) {
208 return media::DecoderPriority::kNormal;
210 static media::DecoderPriority SkipDecoderPriorityCB(
211 const media::VideoDecoderConfig& /*config*/,
212 const media::VideoDecoder& /*decoder*/) {
213 return media::DecoderPriority::kSkipped;
216 static void UseNormalClearDecoderConfig(
217 StrictMock<MockDemuxerStream>& stream) {
218 stream.set_video_decoder_config(TestVideoConfig::Normal());
220 static void UseHighQualityClearDecoderConfig(
221 StrictMock<MockDemuxerStream>& stream) {
222 stream.set_video_decoder_config(TestVideoConfig::Large());
224 static void UseNormalEncryptedDecoderConfig(
225 StrictMock<MockDemuxerStream>& stream) {
226 stream.set_video_decoder_config(TestVideoConfig::NormalEncrypted());
228 static void UseHighQualityEncryptedDecoderConfig(
229 StrictMock<MockDemuxerStream>& stream) {
230 stream.set_video_decoder_config(TestVideoConfig::LargeEncrypted());
233 static void ExpectInitialize(MockDecoder* decoder,
234 DecoderCapability capability) {
235 EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _))
237 [capability](const VideoDecoderConfig& config, bool low_delay,
238 CdmContext*, VideoDecoder::InitCB& init_cb,
239 const VideoDecoder::OutputCB&, const WaitingCB&) {
240 std::move(init_cb).Run(
241 IsConfigSupported(capability, config.is_encrypted()));
245 static void ExpectNotInitialize(MockDecoder* decoder) {
246 EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _)).Times(0);
250 // Allocate storate for the member variables.
251 constexpr DemuxerStream::Type VideoDecoderSelectorTestParam::kStreamType;
255 // Note: The parameter is called TypeParam in the test cases regardless of what
256 // we call it here. It's been named the same for convenience.
257 // Note: The test fixtures inherit from this class. Inside the test cases the
258 // test fixture class is called TestFixture.
259 template <typename TypeParam>
260 class DecoderSelectorTest : public ::testing::Test {
262 // Convenience aliases.
263 using Self = DecoderSelectorTest<TypeParam>;
264 using StreamTraits = typename TypeParam::StreamTraits;
265 using Decoder = typename StreamTraits::DecoderType;
266 using MockDecoder = typename TypeParam::MockDecoder;
267 using Output = typename TypeParam::Output;
268 using DecoderType = typename TypeParam::DecoderType;
269 using Selector = DecoderSelector<TypeParam::kStreamType>;
271 struct MockDecoderArgs {
272 static MockDecoderArgs Create(int decoder_id,
273 DecoderCapability capability) {
274 MockDecoderArgs result;
275 result.decoder_id = decoder_id;
276 result.capability = capability;
277 result.supports_decryption =
278 DecoderCapabilitySupportsDecryption(capability);
279 result.is_platform_decoder = false;
280 result.expect_not_initialized = false;
285 DecoderCapability capability;
286 bool supports_decryption;
287 bool is_platform_decoder;
288 bool expect_not_initialized;
291 DecoderSelectorTest()
292 : traits_(TypeParam::CreateStreamTraits(&media_log_)),
293 demuxer_stream_(TypeParam::kStreamType) {}
295 DecoderSelectorTest(const DecoderSelectorTest&) = delete;
296 DecoderSelectorTest& operator=(const DecoderSelectorTest&) = delete;
298 void OnWaiting(WaitingReason reason) { NOTREACHED(); }
299 void OnOutput(scoped_refptr<Output> output) { NOTREACHED(); }
301 MOCK_METHOD0_T(NoDecoderSelected, void());
302 MOCK_METHOD1_T(OnDecoderSelected, void(int));
303 MOCK_METHOD1_T(OnDecoderSelected, void(DecoderType));
304 MOCK_METHOD1_T(OnDemuxerStreamSelected,
305 void(std::unique_ptr<DecryptingDemuxerStream>));
307 void OnDecoderSelectedThunk(
308 typename Selector::DecoderOrError decoder,
309 std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
310 // Report only the type or id of the decoder, since that's what the tests
311 // care about. The decoder will be destructed immediately.
312 if (decoder.has_value() &&
313 decoder->GetDecoderType() == DecoderType::kTesting) {
315 static_cast<MockDecoder*>(std::move(decoder).value().get())
317 } else if (decoder.has_value()) {
318 OnDecoderSelected(decoder->GetDecoderType());
323 if (decrypting_demuxer_stream)
324 OnDemuxerStreamSelected(std::move(decrypting_demuxer_stream));
327 void AddDecryptingDecoder() {
328 // Require the DecryptingDecoder to be first, because that's easier to
330 DCHECK(mock_decoders_to_create_.empty());
331 DCHECK(!use_decrypting_decoder_);
332 use_decrypting_decoder_ = true;
335 void AddMockDecoder(int decoder_id, DecoderCapability capability) {
336 auto args = MockDecoderArgs::Create(decoder_id, capability);
337 AddMockDecoder(std::move(args));
340 void AddMockPlatformDecoder(int decoder_id, DecoderCapability capability) {
341 auto args = MockDecoderArgs::Create(std::move(decoder_id), capability);
342 args.is_platform_decoder = true;
343 AddMockDecoder(std::move(args));
346 void AddMockDecoder(MockDecoderArgs args) {
347 // Actual decoders are created in CreateDecoders(), which may be called
348 // multiple times by the DecoderSelector.
349 mock_decoders_to_create_.push_back(std::move(args));
352 std::vector<std::unique_ptr<Decoder>> CreateDecoders() {
353 std::vector<std::unique_ptr<Decoder>> decoders;
355 #if !BUILDFLAG(IS_ANDROID)
356 if (use_decrypting_decoder_) {
358 std::make_unique<typename TypeParam::DecryptingDecoder>(
359 task_environment_.GetMainThreadTaskRunner(), &media_log_));
361 #endif // !BUILDFLAG(IS_ANDROID)
363 for (const auto& args : mock_decoders_to_create_) {
364 std::unique_ptr<StrictMock<MockDecoder>> decoder =
365 std::make_unique<StrictMock<MockDecoder>>(args.is_platform_decoder,
366 args.supports_decryption,
368 if (args.expect_not_initialized) {
369 TypeParam::ExpectNotInitialize(decoder.get());
371 TypeParam::ExpectInitialize(decoder.get(), args.capability);
373 decoders.push_back(std::move(decoder));
379 void CreateCdmContext(DecryptorCapability capability) {
380 DCHECK(!decoder_selector_);
382 cdm_context_ = std::make_unique<StrictMock<MockCdmContext>>();
384 EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).Times(AnyNumber());
386 if (capability == kNoDecryptor) {
387 EXPECT_CALL(*cdm_context_, GetDecryptor())
388 .WillRepeatedly(Return(nullptr));
392 decryptor_ = std::make_unique<NiceMock<MockDecryptor>>();
393 EXPECT_CALL(*cdm_context_, GetDecryptor())
394 .WillRepeatedly(Return(decryptor_.get()));
395 switch (TypeParam::kStreamType) {
396 case DemuxerStream::AUDIO:
397 EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
399 RunOnceCallback<1>(capability == kDecryptAndDecode));
401 case DemuxerStream::VIDEO:
402 EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
404 RunOnceCallback<1>(capability == kDecryptAndDecode));
411 void CreateDecoderSelector() {
412 decoder_selector_ = std::make_unique<Selector>(
413 task_environment_.GetMainThreadTaskRunner(),
414 base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)),
416 decoder_selector_->Initialize(
417 traits_.get(), &demuxer_stream_, cdm_context_.get(),
418 base::BindRepeating(&Self::OnWaiting, base::Unretained(this)));
421 void UseClearDecoderConfig() {
422 TypeParam::UseNormalClearDecoderConfig(demuxer_stream_);
424 void UseHighQualityClearDecoderConfig() {
425 TypeParam::UseHighQualityClearDecoderConfig(demuxer_stream_);
427 void UseEncryptedDecoderConfig() {
428 TypeParam::UseNormalEncryptedDecoderConfig(demuxer_stream_);
430 void UseHighQualityEncryptedDecoderConfig() {
431 TypeParam::UseHighQualityEncryptedDecoderConfig(demuxer_stream_);
434 void SelectNextDecoder() {
436 decoder_selector_->ResumeDecoderSelection(
437 base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)),
438 base::BindRepeating(&Self::OnOutput, base::Unretained(this)),
439 DecoderStatus::Codes::kFailed);
441 decoder_selector_->BeginDecoderSelection(
442 base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)),
443 base::BindRepeating(&Self::OnOutput, base::Unretained(this)));
445 is_selecting_ = true;
449 void FinalizeDecoderSelection() {
450 decoder_selector_->FinalizeDecoderSelection();
451 is_selecting_ = false;
454 void RunUntilIdle() { task_environment_.RunUntilIdle(); }
456 base::test::TaskEnvironment task_environment_;
457 NullMediaLog media_log_;
459 std::unique_ptr<StreamTraits> traits_;
460 StrictMock<MockDemuxerStream> demuxer_stream_;
461 std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
462 std::unique_ptr<NiceMock<MockDecryptor>> decryptor_;
464 std::unique_ptr<Selector> decoder_selector_;
466 bool use_decrypting_decoder_ = false;
467 bool is_selecting_ = false;
468 std::vector<MockDecoderArgs> mock_decoders_to_create_;
471 using VideoDecoderSelectorTest =
472 DecoderSelectorTest<VideoDecoderSelectorTestParam>;
474 using DecoderSelectorTestParams =
475 ::testing::Types<AudioDecoderSelectorTestParam,
476 VideoDecoderSelectorTestParam>;
477 TYPED_TEST_SUITE(DecoderSelectorTest, DecoderSelectorTestParams);
479 // Tests for clear streams. CDM will not be used for clear streams so
480 // DecryptorCapability doesn't really matter.
482 TYPED_TEST(DecoderSelectorTest, ClearStream_NoDecoders) {
483 this->UseClearDecoderConfig();
484 this->CreateDecoderSelector();
486 EXPECT_CALL(*this, NoDecoderSelected());
487 this->SelectNextDecoder();
490 TYPED_TEST(DecoderSelectorTest, ClearStream_NoClearDecoder) {
491 this->AddDecryptingDecoder();
492 this->UseClearDecoderConfig();
493 this->CreateDecoderSelector();
495 EXPECT_CALL(*this, NoDecoderSelected());
496 this->SelectNextDecoder();
499 TYPED_TEST(DecoderSelectorTest, ClearStream_OneClearDecoder) {
500 this->AddMockDecoder(kDecoder1, kClearOnly);
501 this->UseClearDecoderConfig();
502 this->CreateDecoderSelector();
504 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
505 this->SelectNextDecoder();
508 TYPED_TEST(DecoderSelectorTest, ClearStream_InternalFallback) {
509 this->AddMockDecoder(kDecoder1, kAlwaysFail);
510 this->AddMockDecoder(kDecoder2, kClearOnly);
511 this->UseClearDecoderConfig();
512 this->CreateDecoderSelector();
514 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
515 this->SelectNextDecoder();
518 TYPED_TEST(DecoderSelectorTest, ClearStream_ExternalFallback) {
519 this->AddMockDecoder(kDecoder1, kClearOnly);
520 this->AddMockDecoder(kDecoder2, kClearOnly);
521 this->UseClearDecoderConfig();
522 this->CreateDecoderSelector();
524 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
525 this->SelectNextDecoder();
527 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
528 this->SelectNextDecoder();
530 EXPECT_CALL(*this, NoDecoderSelected());
531 this->SelectNextDecoder();
534 TYPED_TEST(DecoderSelectorTest, ClearStream_FinalizeDecoderSelection) {
535 this->AddMockDecoder(kDecoder1, kClearOnly);
536 this->AddMockDecoder(kDecoder2, kClearOnly);
537 this->UseClearDecoderConfig();
538 this->CreateDecoderSelector();
540 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
541 this->SelectNextDecoder();
543 this->FinalizeDecoderSelection();
545 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
546 this->SelectNextDecoder();
549 // Tests that platform decoders are prioritized for
550 // high-quality configs, retaining their relative order.
551 TYPED_TEST(DecoderSelectorTest, ClearStream_PrioritizePlatformDecoders) {
552 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
553 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
554 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
555 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
557 this->UseHighQualityClearDecoderConfig();
558 this->CreateDecoderSelector();
559 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
560 base::BindRepeating(TypeParam::MockDecoderPriorityCB));
562 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
563 this->SelectNextDecoder();
564 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
565 this->SelectNextDecoder();
566 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
567 this->SelectNextDecoder();
568 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
569 this->SelectNextDecoder();
571 EXPECT_CALL(*this, NoDecoderSelected());
572 this->SelectNextDecoder();
575 // Tests that non-platform decoders are prioritized for
576 // normal-quality configs, retaining their relative order.
577 TYPED_TEST(DecoderSelectorTest, ClearStream_DeprioritizePlatformDecoders) {
578 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
579 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
580 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
581 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
583 this->UseClearDecoderConfig();
584 this->CreateDecoderSelector();
585 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
586 base::BindRepeating(TypeParam::MockDecoderPriorityCB));
588 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
589 this->SelectNextDecoder();
590 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
591 this->SelectNextDecoder();
592 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
593 this->SelectNextDecoder();
594 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
595 this->SelectNextDecoder();
597 EXPECT_CALL(*this, NoDecoderSelected());
598 this->SelectNextDecoder();
601 // Tests that platform and non-platform decoders remain in the order they are
602 // given for a priority callback returning 'kNormal'.
603 TYPED_TEST(DecoderSelectorTest,
604 ClearStream_NormalPriorityCallbackRetainsGivenOrder) {
605 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
606 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
607 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
608 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
610 this->UseClearDecoderConfig();
611 this->CreateDecoderSelector();
612 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
613 base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
615 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
616 this->SelectNextDecoder();
617 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
618 this->SelectNextDecoder();
619 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
620 this->SelectNextDecoder();
621 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
622 this->SelectNextDecoder();
624 EXPECT_CALL(*this, NoDecoderSelected());
625 this->SelectNextDecoder();
628 TYPED_TEST(DecoderSelectorTest, ClearStream_SkipAllDecoders) {
629 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
630 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
631 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
632 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
634 this->UseClearDecoderConfig();
635 this->CreateDecoderSelector();
636 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
637 base::BindRepeating(TypeParam::SkipDecoderPriorityCB));
639 EXPECT_CALL(*this, NoDecoderSelected());
640 this->SelectNextDecoder();
643 TYPED_TEST(DecoderSelectorTest, ClearStream_ForceHardwareDecoders) {
644 base::test::ScopedFeatureList features;
645 features.InitAndEnableFeature(TypeParam::ForceHardwareDecodersFeature());
647 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
648 this->AddMockDecoder(kDecoder2, kClearOnly);
649 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
650 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
652 this->UseClearDecoderConfig();
653 this->CreateDecoderSelector();
655 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
656 this->SelectNextDecoder();
657 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
658 this->SelectNextDecoder();
659 EXPECT_CALL(*this, NoDecoderSelected());
660 this->SelectNextDecoder();
663 // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
664 TEST_F(VideoDecoderSelectorTest, ClearStream_PrioritizeSoftwareDecoders) {
665 base::test::ScopedFeatureList features;
666 features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
668 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
669 this->AddMockDecoder(kDecoder2, kClearOnly);
670 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
671 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
673 // Create a clear config that will cause software decoders to be
674 // prioritized on any platform.
675 this->demuxer_stream_.set_video_decoder_config(
676 TestVideoConfig::Custom(gfx::Size(64, 64)));
677 this->CreateDecoderSelector();
679 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
680 this->SelectNextDecoder();
681 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
682 this->SelectNextDecoder();
683 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
684 this->SelectNextDecoder();
685 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
686 this->SelectNextDecoder();
687 EXPECT_CALL(*this, NoDecoderSelected());
688 this->SelectNextDecoder();
691 // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
692 TEST_F(VideoDecoderSelectorTest, ClearStream_PrioritizePlatformDecoders) {
693 base::test::ScopedFeatureList features;
694 features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
696 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
697 this->AddMockDecoder(kDecoder2, kClearOnly);
698 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
699 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
701 // Create a clear config that will cause hardware decoders to be prioritized
703 this->demuxer_stream_.set_video_decoder_config(
704 TestVideoConfig::Custom(gfx::Size(4096, 4096)));
705 this->CreateDecoderSelector();
707 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
708 this->SelectNextDecoder();
709 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
710 this->SelectNextDecoder();
711 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
712 this->SelectNextDecoder();
713 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
714 this->SelectNextDecoder();
715 EXPECT_CALL(*this, NoDecoderSelected());
716 this->SelectNextDecoder();
719 // Tests for encrypted streams.
721 // Tests that non-decrypting decoders are filtered out by DecoderSelector
722 // before being initialized.
723 TYPED_TEST(DecoderSelectorTest,
724 EncryptedStream_NoDecryptor_DecodersNotInitialized) {
725 using MockDecoderArgs =
726 typename DecoderSelectorTest<TypeParam>::MockDecoderArgs;
728 auto args = MockDecoderArgs::Create(kDecoder1, kClearOnly);
729 args.expect_not_initialized = true;
730 this->AddMockDecoder(std::move(args));
732 args = MockDecoderArgs::Create(kDecoder2, kClearOnly);
733 args.expect_not_initialized = true;
734 this->AddMockDecoder(std::move(args));
736 this->UseEncryptedDecoderConfig();
737 this->CreateDecoderSelector();
739 EXPECT_CALL(*this, NoDecoderSelected());
740 this->SelectNextDecoder();
743 // Tests that for an encrypted stream, platform decoders are prioritized for
744 // high-quality configs, retaining their relative order.
745 TYPED_TEST(DecoderSelectorTest, EncryptedStream_PrioritizePlatformDecoders) {
746 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
747 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
748 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
749 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
751 this->UseHighQualityEncryptedDecoderConfig();
752 this->CreateDecoderSelector();
753 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
754 base::BindRepeating(TypeParam::MockDecoderPriorityCB));
756 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
757 this->SelectNextDecoder();
758 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
759 this->SelectNextDecoder();
760 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
761 this->SelectNextDecoder();
762 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
763 this->SelectNextDecoder();
765 EXPECT_CALL(*this, NoDecoderSelected());
766 this->SelectNextDecoder();
769 // Tests that for an encrypted stream, non-platform decoders are prioritized for
770 // normal-quality configs, retaining their relative order.
771 TYPED_TEST(DecoderSelectorTest, EncryptedStream_DeprioritizePlatformDecoders) {
772 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
773 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
774 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
775 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
777 this->UseEncryptedDecoderConfig();
778 this->CreateDecoderSelector();
779 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
780 base::BindRepeating(TypeParam::MockDecoderPriorityCB));
782 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
783 this->SelectNextDecoder();
784 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
785 this->SelectNextDecoder();
786 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
787 this->SelectNextDecoder();
788 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
789 this->SelectNextDecoder();
791 EXPECT_CALL(*this, NoDecoderSelected());
792 this->SelectNextDecoder();
795 // Tests that platform and non-platform decoders remain in the order they are
796 // given for a priority callback returning 'kNormal'.
797 TYPED_TEST(DecoderSelectorTest,
798 EncryptedStream_NormalPriorityCallbackRetainsGivenOrder) {
799 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
800 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
801 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
802 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
804 this->UseEncryptedDecoderConfig();
805 this->CreateDecoderSelector();
806 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
807 base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
809 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
810 this->SelectNextDecoder();
811 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
812 this->SelectNextDecoder();
813 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
814 this->SelectNextDecoder();
815 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
816 this->SelectNextDecoder();
818 EXPECT_CALL(*this, NoDecoderSelected());
819 this->SelectNextDecoder();
822 TYPED_TEST(DecoderSelectorTest, EncryptedStream_SkipAllDecoders) {
823 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
824 this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
825 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
826 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
828 this->UseEncryptedDecoderConfig();
829 this->CreateDecoderSelector();
830 this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
831 base::BindRepeating(TypeParam::SkipDecoderPriorityCB));
833 EXPECT_CALL(*this, NoDecoderSelected());
834 this->SelectNextDecoder();
837 TYPED_TEST(DecoderSelectorTest, EncryptedStream_ForceHardwareDecoders) {
838 base::test::ScopedFeatureList features;
839 features.InitAndEnableFeature(TypeParam::ForceHardwareDecodersFeature());
841 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
842 this->AddMockDecoder(kDecoder2, kClearOnly);
843 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
844 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
846 this->UseEncryptedDecoderConfig();
847 this->CreateDecoderSelector();
849 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
850 this->SelectNextDecoder();
851 EXPECT_CALL(*this, NoDecoderSelected());
852 this->SelectNextDecoder();
855 TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_OneClearDecoder) {
856 this->AddMockDecoder(kDecoder1, kClearOnly);
857 this->CreateCdmContext(kNoDecryptor);
858 this->UseEncryptedDecoderConfig();
859 this->CreateDecoderSelector();
861 EXPECT_CALL(*this, NoDecoderSelected());
862 this->SelectNextDecoder();
865 TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_InternalFallback) {
866 this->AddMockDecoder(kDecoder1, kClearOnly);
867 this->AddMockDecoder(kDecoder2, kEncryptedOnly);
868 this->CreateCdmContext(kNoDecryptor);
869 this->UseEncryptedDecoderConfig();
870 this->CreateDecoderSelector();
872 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
873 this->SelectNextDecoder();
876 TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_ExternalFallback) {
877 this->AddMockDecoder(kDecoder1, kEncryptedOnly);
878 this->AddMockDecoder(kDecoder2, kEncryptedOnly);
879 this->CreateCdmContext(kNoDecryptor);
880 this->UseEncryptedDecoderConfig();
881 this->CreateDecoderSelector();
883 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
884 this->SelectNextDecoder();
886 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
887 this->SelectNextDecoder();
890 TYPED_TEST(DecoderSelectorTest,
891 EncryptedStream_NoDecryptor_FinalizeDecoderSelection) {
892 this->AddMockDecoder(kDecoder1, kEncryptedOnly);
893 this->AddMockDecoder(kDecoder2, kEncryptedOnly);
894 this->CreateCdmContext(kNoDecryptor);
895 this->UseEncryptedDecoderConfig();
896 this->CreateDecoderSelector();
898 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
899 this->SelectNextDecoder();
901 this->FinalizeDecoderSelection();
903 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
904 this->SelectNextDecoder();
907 TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_NoDecoder) {
908 this->CreateCdmContext(kDecryptOnly);
909 this->UseEncryptedDecoderConfig();
910 this->CreateDecoderSelector();
912 EXPECT_CALL(*this, NoDecoderSelected());
913 this->SelectNextDecoder();
916 TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
917 this->AddMockDecoder(kDecoder1, kClearOnly);
918 this->CreateCdmContext(kDecryptOnly);
919 this->UseEncryptedDecoderConfig();
920 this->CreateDecoderSelector();
922 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
923 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
924 this->SelectNextDecoder();
927 TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_InternalFallback) {
928 this->AddMockDecoder(kDecoder1, kAlwaysFail);
929 this->AddMockDecoder(kDecoder2, kClearOnly);
930 this->CreateCdmContext(kDecryptOnly);
931 this->UseEncryptedDecoderConfig();
932 this->CreateDecoderSelector();
934 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
935 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
937 this->SelectNextDecoder();
940 TYPED_TEST(DecoderSelectorTest,
941 EncryptedStream_DecryptOnly_FinalizeDecoderSelection) {
942 this->AddMockDecoder(kDecoder1, kClearOnly);
943 this->AddMockDecoder(kDecoder2, kClearOnly);
944 this->CreateCdmContext(kDecryptOnly);
945 this->UseEncryptedDecoderConfig();
946 this->CreateDecoderSelector();
948 std::unique_ptr<DecryptingDemuxerStream> saved_dds;
949 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
950 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()))
951 .WillOnce([&](std::unique_ptr<DecryptingDemuxerStream> dds) {
952 saved_dds = std::move(dds);
955 this->SelectNextDecoder();
957 this->FinalizeDecoderSelection();
960 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
961 this->SelectNextDecoder();
964 TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptAndDecode) {
965 this->AddDecryptingDecoder();
966 this->AddMockDecoder(kDecoder1, kClearOnly);
967 this->CreateCdmContext(kDecryptAndDecode);
968 this->UseEncryptedDecoderConfig();
969 this->CreateDecoderSelector();
971 #if !BUILDFLAG(IS_ANDROID)
972 // A DecryptingVideoDecoder will be created and selected. The clear decoder
973 // should not be touched at all. No DecryptingDemuxerStream should be
975 EXPECT_CALL(*this, OnDecoderSelected(TestFixture::DecoderType::kDecrypting));
977 // A DecryptingDemuxerStream will be created. The clear decoder will be
978 // initialized and returned.
979 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
980 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
981 #endif // !BUILDFLAG(IS_ANDROID)
983 this->SelectNextDecoder();
986 TYPED_TEST(DecoderSelectorTest,
987 EncryptedStream_DecryptAndDecode_ExternalFallback) {
988 this->AddDecryptingDecoder();
989 this->AddMockDecoder(kDecoder1, kClearOnly);
990 this->AddMockDecoder(kDecoder2, kClearOnly);
991 this->CreateCdmContext(kDecryptAndDecode);
992 this->UseEncryptedDecoderConfig();
993 this->CreateDecoderSelector();
995 #if !BUILDFLAG(IS_ANDROID)
996 // DecryptingDecoder is selected immediately.
997 EXPECT_CALL(*this, OnDecoderSelected(TestFixture::DecoderType::kDecrypting));
998 this->SelectNextDecoder();
999 #endif // !BUILDFLAG(IS_ANDROID)
1001 // On fallback, a DecryptingDemuxerStream will be created.
1002 std::unique_ptr<DecryptingDemuxerStream> saved_dds;
1003 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
1004 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()))
1005 .WillOnce([&](std::unique_ptr<DecryptingDemuxerStream> dds) {
1006 saved_dds = std::move(dds);
1008 this->SelectNextDecoder();
1010 // The DecryptingDemuxerStream should be reused.
1011 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
1012 this->SelectNextDecoder();
1015 TYPED_TEST(DecoderSelectorTest, ClearToEncryptedStream_DecryptOnly) {
1016 this->AddMockDecoder(kDecoder1, kClearOnly);
1017 this->CreateCdmContext(kDecryptOnly);
1018 this->UseClearDecoderConfig();
1019 this->CreateDecoderSelector();
1021 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
1022 this->SelectNextDecoder();
1024 this->FinalizeDecoderSelection();
1025 this->UseEncryptedDecoderConfig();
1027 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
1028 EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
1029 this->SelectNextDecoder();
1032 // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
1033 TEST_F(VideoDecoderSelectorTest, EncryptedStream_PrioritizeSoftwareDecoders) {
1034 base::test::ScopedFeatureList features;
1035 features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
1037 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
1038 this->AddMockDecoder(kDecoder2, kClearOnly);
1039 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
1040 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
1042 // Create an encrypted config that will cause software decoders to be
1043 // prioritized on any platform.
1044 this->demuxer_stream_.set_video_decoder_config(
1045 TestVideoConfig::CustomEncrypted(gfx::Size(64, 64)));
1046 this->CreateDecoderSelector();
1048 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
1049 this->SelectNextDecoder();
1050 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
1051 this->SelectNextDecoder();
1052 EXPECT_CALL(*this, NoDecoderSelected());
1053 this->SelectNextDecoder();
1056 // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
1057 TEST_F(VideoDecoderSelectorTest, EncryptedStream_PrioritizePlatformDecoders) {
1058 base::test::ScopedFeatureList features;
1059 features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
1061 this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
1062 this->AddMockDecoder(kDecoder2, kClearOnly);
1063 this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
1064 this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
1066 // Create an encrypted config that will cause hardware decoders to be
1067 // prioritized on any platform.
1068 this->demuxer_stream_.set_video_decoder_config(
1069 TestVideoConfig::CustomEncrypted(gfx::Size(4096, 4096)));
1070 this->CreateDecoderSelector();
1072 EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
1073 this->SelectNextDecoder();
1074 EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
1075 this->SelectNextDecoder();
1076 EXPECT_CALL(*this, NoDecoderSelected());
1077 this->SelectNextDecoder();
1080 // Tests we always use resolution-based rules for RTC.
1081 TEST_F(VideoDecoderSelectorTest, RTC_UseResolutionRuleWithoutSwitch) {
1082 // Turn off `kResolutionBasedDecoderPriority`, since rtc should override it.
1083 base::test::ScopedFeatureList features;
1084 features.InitAndDisableFeature(kResolutionBasedDecoderPriority);
1086 // Add the non-platform decoder earlier, but expect the platform one.
1087 this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
1088 this->AddMockPlatformDecoder(kDecoder2, kAlwaysSucceed);
1090 auto config = TestVideoConfig::Custom(gfx::Size(4096, 4096));
1091 config.set_is_rtc(true);
1092 this->demuxer_stream_.set_video_decoder_config(config);
1093 this->CreateDecoderSelector();
1095 EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
1096 this->SelectNextDecoder();
1099 // Non-platform decoders should be used for RTC unless enabled by a switch.
1100 TEST_F(VideoDecoderSelectorTest, RTC_SkipNonPlatformDecodersWithoutSwitch) {
1101 base::test::ScopedFeatureList features;
1102 features.InitAndDisableFeature(kExposeSwDecodersToWebRTC);
1104 // Add a non-platform decoder, which it should not use.
1105 this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
1107 auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
1108 config.set_is_rtc(true);
1109 this->demuxer_stream_.set_video_decoder_config(config);
1110 this->CreateDecoderSelector();
1112 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)).Times(0);
1113 this->SelectNextDecoder();
1116 // Platform decoders should be allowed for RTC without the sw switch.
1117 TEST_F(VideoDecoderSelectorTest, RTC_AllowPlatformDecodersWithoutSwitch) {
1118 base::test::ScopedFeatureList features;
1119 features.InitAndDisableFeature(kExposeSwDecodersToWebRTC);
1121 // Add a platform decoder, which it should use.
1122 this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
1124 auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
1125 config.set_is_rtc(true);
1126 this->demuxer_stream_.set_video_decoder_config(config);
1127 this->CreateDecoderSelector();
1129 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
1130 this->SelectNextDecoder();
1133 // Non-platform decoders should be allowed for RTC if enabled by a switch.
1134 TEST_F(VideoDecoderSelectorTest, RTC_AllowNonPlatformDecodersWithSwitch) {
1135 base::test::ScopedFeatureList features;
1136 features.InitAndEnableFeature(kExposeSwDecodersToWebRTC);
1138 // Add a non-platform decoder, which it should use.
1139 this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
1141 auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
1142 config.set_is_rtc(true);
1143 this->demuxer_stream_.set_video_decoder_config(config);
1144 this->CreateDecoderSelector();
1146 EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
1147 this->SelectNextDecoder();
1150 } // namespace media