1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <memory>
- #include <tuple>
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/notreached.h"
- #include "base/test/gmock_callback_support.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "build/build_config.h"
- #include "media/base/demuxer_stream.h"
- #include "media/base/media_switches.h"
- #include "media/base/media_util.h"
- #include "media/base/mock_filters.h"
- #include "media/base/test_helpers.h"
- #include "media/filters/decoder_selector.h"
- #include "media/filters/decrypting_demuxer_stream.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #if !BUILDFLAG(IS_ANDROID)
- #include "media/filters/decrypting_audio_decoder.h"
- #include "media/filters/decrypting_video_decoder.h"
- #endif // !BUILDFLAG(IS_ANDROID)
- using ::base::test::RunCallback;
- using ::base::test::RunOnceCallback;
- using ::testing::_;
- using ::testing::AnyNumber;
- using ::testing::IsNull;
- using ::testing::NiceMock;
- using ::testing::NotNull;
- using ::testing::Return;
- using ::testing::StrictMock;
- namespace media {
- namespace {
- enum DecryptorCapability {
- kNoDecryptor,
- kDecryptOnly,
- kDecryptAndDecode,
- };
- enum DecoderCapability {
- kAlwaysFail,
- kClearOnly,
- kEncryptedOnly,
- kAlwaysSucceed,
- };
- bool DecoderCapabilitySupportsDecryption(DecoderCapability capability) {
- switch (capability) {
- case kAlwaysFail:
- return false;
- case kClearOnly:
- return false;
- case kEncryptedOnly:
- return true;
- case kAlwaysSucceed:
- return true;
- }
- }
- DecoderStatus IsConfigSupported(DecoderCapability capability,
- bool is_encrypted) {
- switch (capability) {
- case kAlwaysFail:
- return DecoderStatus::Codes::kFailed;
- case kClearOnly:
- return is_encrypted ? DecoderStatus::Codes::kUnsupportedEncryptionMode
- : DecoderStatus::Codes::kOk;
- case kEncryptedOnly:
- return is_encrypted ? DecoderStatus::Codes::kOk
- : DecoderStatus::Codes::kUnsupportedEncryptionMode;
- case kAlwaysSucceed:
- return DecoderStatus::Codes::kOk;
- }
- }
- const int kDecoder1 = 0xabc;
- const int kDecoder2 = 0xdef;
- const int kDecoder3 = 0x123;
- const int kDecoder4 = 0x456;
- // Specializations for the AUDIO version of the test.
- class AudioDecoderSelectorTestParam {
- public:
- static constexpr DemuxerStream::Type kStreamType = DemuxerStream::AUDIO;
- using StreamTraits = DecoderStreamTraits<DemuxerStream::AUDIO>;
- using MockDecoder = MockAudioDecoder;
- using Output = AudioBuffer;
- using DecoderType = AudioDecoderType;
- #if !BUILDFLAG(IS_ANDROID)
- using DecryptingDecoder = DecryptingAudioDecoder;
- #endif // !BUILDFLAG(IS_ANDROID)
- // StreamTraits() takes different parameters depending on the type.
- static std::unique_ptr<StreamTraits> CreateStreamTraits(MediaLog* media_log) {
- return std::make_unique<StreamTraits>(media_log, CHANNEL_LAYOUT_STEREO,
- kSampleFormatPlanarF32);
- }
- static const base::Feature& ForceHardwareDecodersFeature() {
- return kForceHardwareAudioDecoders;
- }
- static media::DecoderPriority MockDecoderPriorityCB(
- const media::AudioDecoderConfig& config,
- const media::AudioDecoder& decoder) {
- const auto above_cutoff =
- config.samples_per_second() > TestAudioConfig::NormalSampleRateValue();
- return above_cutoff == decoder.IsPlatformDecoder()
- ? media::DecoderPriority::kNormal
- : media::DecoderPriority::kDeprioritized;
- }
- static media::DecoderPriority NormalDecoderPriorityCB(
- const media::AudioDecoderConfig& /*config*/,
- const media::AudioDecoder& /*decoder*/) {
- return media::DecoderPriority::kNormal;
- }
- static media::DecoderPriority SkipDecoderPriorityCB(
- const media::AudioDecoderConfig& /*config*/,
- const media::AudioDecoder& /*decoder*/) {
- return media::DecoderPriority::kSkipped;
- }
- static void UseNormalClearDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_audio_decoder_config(TestAudioConfig::Normal());
- }
- static void UseHighQualityClearDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_audio_decoder_config(TestAudioConfig::HighSampleRate());
- }
- static void UseNormalEncryptedDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_audio_decoder_config(TestAudioConfig::NormalEncrypted());
- }
- static void UseHighQualityEncryptedDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_audio_decoder_config(TestAudioConfig::HighSampleRateEncrypted());
- }
- // Decoder::Initialize() takes different parameters depending on the type.
- static void ExpectInitialize(MockDecoder* decoder,
- DecoderCapability capability) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _))
- .WillRepeatedly([capability](const AudioDecoderConfig& config,
- CdmContext*, AudioDecoder::InitCB& init_cb,
- const AudioDecoder::OutputCB&,
- const WaitingCB&) {
- std::move(init_cb).Run(
- IsConfigSupported(capability, config.is_encrypted()));
- });
- }
- static void ExpectNotInitialize(MockDecoder* decoder) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)).Times(0);
- }
- };
- // Allocate storage for the member variables.
- constexpr DemuxerStream::Type AudioDecoderSelectorTestParam::kStreamType;
- // Specializations for the VIDEO version of the test.
- class VideoDecoderSelectorTestParam {
- public:
- static constexpr DemuxerStream::Type kStreamType = DemuxerStream::VIDEO;
- using StreamTraits = DecoderStreamTraits<DemuxerStream::VIDEO>;
- using MockDecoder = MockVideoDecoder;
- using Output = VideoFrame;
- using DecoderType = VideoDecoderType;
- #if !BUILDFLAG(IS_ANDROID)
- using DecryptingDecoder = DecryptingVideoDecoder;
- #endif // !BUILDFLAG(IS_ANDROID)
- static const base::Feature& ForceHardwareDecodersFeature() {
- return kForceHardwareVideoDecoders;
- }
- static std::unique_ptr<StreamTraits> CreateStreamTraits(MediaLog* media_log) {
- return std::make_unique<StreamTraits>(media_log);
- }
- static media::DecoderPriority MockDecoderPriorityCB(
- const media::VideoDecoderConfig& config,
- const media::VideoDecoder& decoder) {
- auto const above_cutoff = config.visible_rect().height() >
- TestVideoConfig::NormalCodedSize().height();
- return decoder.IsPlatformDecoder() == above_cutoff
- ? media::DecoderPriority::kNormal
- : media::DecoderPriority::kDeprioritized;
- }
- static media::DecoderPriority NormalDecoderPriorityCB(
- const media::VideoDecoderConfig& /*config*/,
- const media::VideoDecoder& /*decoder*/) {
- return media::DecoderPriority::kNormal;
- }
- static media::DecoderPriority SkipDecoderPriorityCB(
- const media::VideoDecoderConfig& /*config*/,
- const media::VideoDecoder& /*decoder*/) {
- return media::DecoderPriority::kSkipped;
- }
- static void UseNormalClearDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_video_decoder_config(TestVideoConfig::Normal());
- }
- static void UseHighQualityClearDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_video_decoder_config(TestVideoConfig::Large());
- }
- static void UseNormalEncryptedDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_video_decoder_config(TestVideoConfig::NormalEncrypted());
- }
- static void UseHighQualityEncryptedDecoderConfig(
- StrictMock<MockDemuxerStream>& stream) {
- stream.set_video_decoder_config(TestVideoConfig::LargeEncrypted());
- }
- static void ExpectInitialize(MockDecoder* decoder,
- DecoderCapability capability) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _))
- .WillRepeatedly(
- [capability](const VideoDecoderConfig& config, bool low_delay,
- CdmContext*, VideoDecoder::InitCB& init_cb,
- const VideoDecoder::OutputCB&, const WaitingCB&) {
- std::move(init_cb).Run(
- IsConfigSupported(capability, config.is_encrypted()));
- });
- }
- static void ExpectNotInitialize(MockDecoder* decoder) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _)).Times(0);
- }
- };
- // Allocate storate for the member variables.
- constexpr DemuxerStream::Type VideoDecoderSelectorTestParam::kStreamType;
- } // namespace
- // Note: The parameter is called TypeParam in the test cases regardless of what
- // we call it here. It's been named the same for convenience.
- // Note: The test fixtures inherit from this class. Inside the test cases the
- // test fixture class is called TestFixture.
- template <typename TypeParam>
- class DecoderSelectorTest : public ::testing::Test {
- public:
- // Convenience aliases.
- using Self = DecoderSelectorTest<TypeParam>;
- using StreamTraits = typename TypeParam::StreamTraits;
- using Decoder = typename StreamTraits::DecoderType;
- using MockDecoder = typename TypeParam::MockDecoder;
- using Output = typename TypeParam::Output;
- using DecoderType = typename TypeParam::DecoderType;
- using Selector = DecoderSelector<TypeParam::kStreamType>;
- struct MockDecoderArgs {
- static MockDecoderArgs Create(int decoder_id,
- DecoderCapability capability) {
- MockDecoderArgs result;
- result.decoder_id = decoder_id;
- result.capability = capability;
- result.supports_decryption =
- DecoderCapabilitySupportsDecryption(capability);
- result.is_platform_decoder = false;
- result.expect_not_initialized = false;
- return result;
- }
- int decoder_id;
- DecoderCapability capability;
- bool supports_decryption;
- bool is_platform_decoder;
- bool expect_not_initialized;
- };
- DecoderSelectorTest()
- : traits_(TypeParam::CreateStreamTraits(&media_log_)),
- demuxer_stream_(TypeParam::kStreamType) {}
- DecoderSelectorTest(const DecoderSelectorTest&) = delete;
- DecoderSelectorTest& operator=(const DecoderSelectorTest&) = delete;
- void OnWaiting(WaitingReason reason) { NOTREACHED(); }
- void OnOutput(scoped_refptr<Output> output) { NOTREACHED(); }
- MOCK_METHOD0_T(NoDecoderSelected, void());
- MOCK_METHOD1_T(OnDecoderSelected, void(int));
- MOCK_METHOD1_T(OnDecoderSelected, void(DecoderType));
- MOCK_METHOD1_T(OnDemuxerStreamSelected,
- void(std::unique_ptr<DecryptingDemuxerStream>));
- void OnDecoderSelectedThunk(
- typename Selector::DecoderOrError decoder,
- std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
- // Report only the type or id of the decoder, since that's what the tests
- // care about. The decoder will be destructed immediately.
- if (decoder.has_value() &&
- decoder->GetDecoderType() == DecoderType::kTesting) {
- OnDecoderSelected(
- static_cast<MockDecoder*>(std::move(decoder).value().get())
- ->GetDecoderId());
- } else if (decoder.has_value()) {
- OnDecoderSelected(decoder->GetDecoderType());
- } else {
- NoDecoderSelected();
- }
- if (decrypting_demuxer_stream)
- OnDemuxerStreamSelected(std::move(decrypting_demuxer_stream));
- }
- void AddDecryptingDecoder() {
- // Require the DecryptingDecoder to be first, because that's easier to
- // implement.
- DCHECK(mock_decoders_to_create_.empty());
- DCHECK(!use_decrypting_decoder_);
- use_decrypting_decoder_ = true;
- }
- void AddMockDecoder(int decoder_id, DecoderCapability capability) {
- auto args = MockDecoderArgs::Create(decoder_id, capability);
- AddMockDecoder(std::move(args));
- }
- void AddMockPlatformDecoder(int decoder_id, DecoderCapability capability) {
- auto args = MockDecoderArgs::Create(std::move(decoder_id), capability);
- args.is_platform_decoder = true;
- AddMockDecoder(std::move(args));
- }
- void AddMockDecoder(MockDecoderArgs args) {
- // Actual decoders are created in CreateDecoders(), which may be called
- // multiple times by the DecoderSelector.
- mock_decoders_to_create_.push_back(std::move(args));
- }
- std::vector<std::unique_ptr<Decoder>> CreateDecoders() {
- std::vector<std::unique_ptr<Decoder>> decoders;
- #if !BUILDFLAG(IS_ANDROID)
- if (use_decrypting_decoder_) {
- decoders.push_back(
- std::make_unique<typename TypeParam::DecryptingDecoder>(
- task_environment_.GetMainThreadTaskRunner(), &media_log_));
- }
- #endif // !BUILDFLAG(IS_ANDROID)
- for (const auto& args : mock_decoders_to_create_) {
- std::unique_ptr<StrictMock<MockDecoder>> decoder =
- std::make_unique<StrictMock<MockDecoder>>(args.is_platform_decoder,
- args.supports_decryption,
- args.decoder_id);
- if (args.expect_not_initialized) {
- TypeParam::ExpectNotInitialize(decoder.get());
- } else {
- TypeParam::ExpectInitialize(decoder.get(), args.capability);
- }
- decoders.push_back(std::move(decoder));
- }
- return decoders;
- }
- void CreateCdmContext(DecryptorCapability capability) {
- DCHECK(!decoder_selector_);
- cdm_context_ = std::make_unique<StrictMock<MockCdmContext>>();
- EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).Times(AnyNumber());
- if (capability == kNoDecryptor) {
- EXPECT_CALL(*cdm_context_, GetDecryptor())
- .WillRepeatedly(Return(nullptr));
- return;
- }
- decryptor_ = std::make_unique<NiceMock<MockDecryptor>>();
- EXPECT_CALL(*cdm_context_, GetDecryptor())
- .WillRepeatedly(Return(decryptor_.get()));
- switch (TypeParam::kStreamType) {
- case DemuxerStream::AUDIO:
- EXPECT_CALL(*decryptor_, InitializeAudioDecoder(_, _))
- .WillRepeatedly(
- RunOnceCallback<1>(capability == kDecryptAndDecode));
- break;
- case DemuxerStream::VIDEO:
- EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
- .WillRepeatedly(
- RunOnceCallback<1>(capability == kDecryptAndDecode));
- break;
- default:
- NOTREACHED();
- }
- }
- void CreateDecoderSelector() {
- decoder_selector_ = std::make_unique<Selector>(
- task_environment_.GetMainThreadTaskRunner(),
- base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)),
- &media_log_);
- decoder_selector_->Initialize(
- traits_.get(), &demuxer_stream_, cdm_context_.get(),
- base::BindRepeating(&Self::OnWaiting, base::Unretained(this)));
- }
- void UseClearDecoderConfig() {
- TypeParam::UseNormalClearDecoderConfig(demuxer_stream_);
- }
- void UseHighQualityClearDecoderConfig() {
- TypeParam::UseHighQualityClearDecoderConfig(demuxer_stream_);
- }
- void UseEncryptedDecoderConfig() {
- TypeParam::UseNormalEncryptedDecoderConfig(demuxer_stream_);
- }
- void UseHighQualityEncryptedDecoderConfig() {
- TypeParam::UseHighQualityEncryptedDecoderConfig(demuxer_stream_);
- }
- void SelectNextDecoder() {
- if (is_selecting_) {
- decoder_selector_->ResumeDecoderSelection(
- base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)),
- base::BindRepeating(&Self::OnOutput, base::Unretained(this)),
- DecoderStatus::Codes::kFailed);
- } else {
- decoder_selector_->BeginDecoderSelection(
- base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)),
- base::BindRepeating(&Self::OnOutput, base::Unretained(this)));
- }
- is_selecting_ = true;
- RunUntilIdle();
- }
- void FinalizeDecoderSelection() {
- decoder_selector_->FinalizeDecoderSelection();
- is_selecting_ = false;
- }
- void RunUntilIdle() { task_environment_.RunUntilIdle(); }
- base::test::TaskEnvironment task_environment_;
- NullMediaLog media_log_;
- std::unique_ptr<StreamTraits> traits_;
- StrictMock<MockDemuxerStream> demuxer_stream_;
- std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;
- std::unique_ptr<NiceMock<MockDecryptor>> decryptor_;
- std::unique_ptr<Selector> decoder_selector_;
- bool use_decrypting_decoder_ = false;
- bool is_selecting_ = false;
- std::vector<MockDecoderArgs> mock_decoders_to_create_;
- };
- using VideoDecoderSelectorTest =
- DecoderSelectorTest<VideoDecoderSelectorTestParam>;
- using DecoderSelectorTestParams =
- ::testing::Types<AudioDecoderSelectorTestParam,
- VideoDecoderSelectorTestParam>;
- TYPED_TEST_SUITE(DecoderSelectorTest, DecoderSelectorTestParams);
- // Tests for clear streams. CDM will not be used for clear streams so
- // DecryptorCapability doesn't really matter.
- TYPED_TEST(DecoderSelectorTest, ClearStream_NoDecoders) {
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_NoClearDecoder) {
- this->AddDecryptingDecoder();
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_OneClearDecoder) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_InternalFallback) {
- this->AddMockDecoder(kDecoder1, kAlwaysFail);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_ExternalFallback) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_FinalizeDecoderSelection) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- this->FinalizeDecoderSelection();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- // Tests that platform decoders are prioritized for
- // high-quality configs, retaining their relative order.
- TYPED_TEST(DecoderSelectorTest, ClearStream_PrioritizePlatformDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseHighQualityClearDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::MockDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests that non-platform decoders are prioritized for
- // normal-quality configs, retaining their relative order.
- TYPED_TEST(DecoderSelectorTest, ClearStream_DeprioritizePlatformDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::MockDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests that platform and non-platform decoders remain in the order they are
- // given for a priority callback returning 'kNormal'.
- TYPED_TEST(DecoderSelectorTest,
- ClearStream_NormalPriorityCallbackRetainsGivenOrder) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_SkipAllDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::SkipDecoderPriorityCB));
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearStream_ForceHardwareDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(TypeParam::ForceHardwareDecodersFeature());
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
- TEST_F(VideoDecoderSelectorTest, ClearStream_PrioritizeSoftwareDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- // Create a clear config that will cause software decoders to be
- // prioritized on any platform.
- this->demuxer_stream_.set_video_decoder_config(
- TestVideoConfig::Custom(gfx::Size(64, 64)));
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
- TEST_F(VideoDecoderSelectorTest, ClearStream_PrioritizePlatformDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- // Create a clear config that will cause hardware decoders to be prioritized
- // on any platform.
- this->demuxer_stream_.set_video_decoder_config(
- TestVideoConfig::Custom(gfx::Size(4096, 4096)));
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests for encrypted streams.
- // Tests that non-decrypting decoders are filtered out by DecoderSelector
- // before being initialized.
- TYPED_TEST(DecoderSelectorTest,
- EncryptedStream_NoDecryptor_DecodersNotInitialized) {
- using MockDecoderArgs =
- typename DecoderSelectorTest<TypeParam>::MockDecoderArgs;
- auto args = MockDecoderArgs::Create(kDecoder1, kClearOnly);
- args.expect_not_initialized = true;
- this->AddMockDecoder(std::move(args));
- args = MockDecoderArgs::Create(kDecoder2, kClearOnly);
- args.expect_not_initialized = true;
- this->AddMockDecoder(std::move(args));
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests that for an encrypted stream, platform decoders are prioritized for
- // high-quality configs, retaining their relative order.
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_PrioritizePlatformDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseHighQualityEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::MockDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests that for an encrypted stream, non-platform decoders are prioritized for
- // normal-quality configs, retaining their relative order.
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_DeprioritizePlatformDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::MockDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests that platform and non-platform decoders remain in the order they are
- // given for a priority callback returning 'kNormal'.
- TYPED_TEST(DecoderSelectorTest,
- EncryptedStream_NormalPriorityCallbackRetainsGivenOrder) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_SkipAllDecoders) {
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
- base::BindRepeating(TypeParam::SkipDecoderPriorityCB));
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_ForceHardwareDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(TypeParam::ForceHardwareDecodersFeature());
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_OneClearDecoder) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->CreateCdmContext(kNoDecryptor);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_InternalFallback) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kEncryptedOnly);
- this->CreateCdmContext(kNoDecryptor);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_ExternalFallback) {
- this->AddMockDecoder(kDecoder1, kEncryptedOnly);
- this->AddMockDecoder(kDecoder2, kEncryptedOnly);
- this->CreateCdmContext(kNoDecryptor);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest,
- EncryptedStream_NoDecryptor_FinalizeDecoderSelection) {
- this->AddMockDecoder(kDecoder1, kEncryptedOnly);
- this->AddMockDecoder(kDecoder2, kEncryptedOnly);
- this->CreateCdmContext(kNoDecryptor);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- this->FinalizeDecoderSelection();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_NoDecoder) {
- this->CreateCdmContext(kDecryptOnly);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->CreateCdmContext(kDecryptOnly);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptOnly_InternalFallback) {
- this->AddMockDecoder(kDecoder1, kAlwaysFail);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->CreateCdmContext(kDecryptOnly);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest,
- EncryptedStream_DecryptOnly_FinalizeDecoderSelection) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->CreateCdmContext(kDecryptOnly);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- std::unique_ptr<DecryptingDemuxerStream> saved_dds;
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()))
- .WillOnce([&](std::unique_ptr<DecryptingDemuxerStream> dds) {
- saved_dds = std::move(dds);
- });
- this->SelectNextDecoder();
- this->FinalizeDecoderSelection();
- // DDS is reused.
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, EncryptedStream_DecryptAndDecode) {
- this->AddDecryptingDecoder();
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->CreateCdmContext(kDecryptAndDecode);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- #if !BUILDFLAG(IS_ANDROID)
- // A DecryptingVideoDecoder will be created and selected. The clear decoder
- // should not be touched at all. No DecryptingDemuxerStream should be
- // created.
- EXPECT_CALL(*this, OnDecoderSelected(TestFixture::DecoderType::kDecrypting));
- #else
- // A DecryptingDemuxerStream will be created. The clear decoder will be
- // initialized and returned.
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
- #endif // !BUILDFLAG(IS_ANDROID)
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest,
- EncryptedStream_DecryptAndDecode_ExternalFallback) {
- this->AddDecryptingDecoder();
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->CreateCdmContext(kDecryptAndDecode);
- this->UseEncryptedDecoderConfig();
- this->CreateDecoderSelector();
- #if !BUILDFLAG(IS_ANDROID)
- // DecryptingDecoder is selected immediately.
- EXPECT_CALL(*this, OnDecoderSelected(TestFixture::DecoderType::kDecrypting));
- this->SelectNextDecoder();
- #endif // !BUILDFLAG(IS_ANDROID)
- // On fallback, a DecryptingDemuxerStream will be created.
- std::unique_ptr<DecryptingDemuxerStream> saved_dds;
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()))
- .WillOnce([&](std::unique_ptr<DecryptingDemuxerStream> dds) {
- saved_dds = std::move(dds);
- });
- this->SelectNextDecoder();
- // The DecryptingDemuxerStream should be reused.
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- }
- TYPED_TEST(DecoderSelectorTest, ClearToEncryptedStream_DecryptOnly) {
- this->AddMockDecoder(kDecoder1, kClearOnly);
- this->CreateCdmContext(kDecryptOnly);
- this->UseClearDecoderConfig();
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- this->FinalizeDecoderSelection();
- this->UseEncryptedDecoderConfig();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- EXPECT_CALL(*this, OnDemuxerStreamSelected(NotNull()));
- this->SelectNextDecoder();
- }
- // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
- TEST_F(VideoDecoderSelectorTest, EncryptedStream_PrioritizeSoftwareDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- // Create an encrypted config that will cause software decoders to be
- // prioritized on any platform.
- this->demuxer_stream_.set_video_decoder_config(
- TestVideoConfig::CustomEncrypted(gfx::Size(64, 64)));
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests the production predicate for `DecoderSelector<DemuxerStream::VIDEO>`
- TEST_F(VideoDecoderSelectorTest, EncryptedStream_PrioritizePlatformDecoders) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(kResolutionBasedDecoderPriority);
- this->AddMockPlatformDecoder(kDecoder1, kClearOnly);
- this->AddMockDecoder(kDecoder2, kClearOnly);
- this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
- this->AddMockDecoder(kDecoder4, kAlwaysSucceed);
- // Create an encrypted config that will cause hardware decoders to be
- // prioritized on any platform.
- this->demuxer_stream_.set_video_decoder_config(
- TestVideoConfig::CustomEncrypted(gfx::Size(4096, 4096)));
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder3));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder4));
- this->SelectNextDecoder();
- EXPECT_CALL(*this, NoDecoderSelected());
- this->SelectNextDecoder();
- }
- // Tests we always use resolution-based rules for RTC.
- TEST_F(VideoDecoderSelectorTest, RTC_UseResolutionRuleWithoutSwitch) {
- // Turn off `kResolutionBasedDecoderPriority`, since rtc should override it.
- base::test::ScopedFeatureList features;
- features.InitAndDisableFeature(kResolutionBasedDecoderPriority);
- // Add the non-platform decoder earlier, but expect the platform one.
- this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
- this->AddMockPlatformDecoder(kDecoder2, kAlwaysSucceed);
- auto config = TestVideoConfig::Custom(gfx::Size(4096, 4096));
- config.set_is_rtc(true);
- this->demuxer_stream_.set_video_decoder_config(config);
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectNextDecoder();
- }
- // Non-platform decoders should be used for RTC unless enabled by a switch.
- TEST_F(VideoDecoderSelectorTest, RTC_SkipNonPlatformDecodersWithoutSwitch) {
- base::test::ScopedFeatureList features;
- features.InitAndDisableFeature(kExposeSwDecodersToWebRTC);
- // Add a non-platform decoder, which it should not use.
- this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
- auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
- config.set_is_rtc(true);
- this->demuxer_stream_.set_video_decoder_config(config);
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)).Times(0);
- this->SelectNextDecoder();
- }
- // Platform decoders should be allowed for RTC without the sw switch.
- TEST_F(VideoDecoderSelectorTest, RTC_AllowPlatformDecodersWithoutSwitch) {
- base::test::ScopedFeatureList features;
- features.InitAndDisableFeature(kExposeSwDecodersToWebRTC);
- // Add a platform decoder, which it should use.
- this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
- auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
- config.set_is_rtc(true);
- this->demuxer_stream_.set_video_decoder_config(config);
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- // Non-platform decoders should be allowed for RTC if enabled by a switch.
- TEST_F(VideoDecoderSelectorTest, RTC_AllowNonPlatformDecodersWithSwitch) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(kExposeSwDecodersToWebRTC);
- // Add a non-platform decoder, which it should use.
- this->AddMockDecoder(kDecoder1, kAlwaysSucceed);
- auto config = TestVideoConfig::Custom(gfx::Size(100, 100));
- config.set_is_rtc(true);
- this->demuxer_stream_.set_video_decoder_config(config);
- this->CreateDecoderSelector();
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectNextDecoder();
- }
- } // namespace media
|