Commit a9ee55ac authored by Will Cassella's avatar Will Cassella Committed by Commit Bot

Modify DecoderPriorityCB so that it's called per-decoder

Currently, `DecoderSelector::decoder_priority_cb_` is called once
per-config, and can only return whether platform decoders specifically
should be prioritized, deprioritized, or left as-is.

This is somewhat inflexible, as it disallows skipping or deprioritizing
individual decoders based on other characteristics. This CL modifies
the decoder selector so that it runs the given predicate/callback once
per decoder, and modifies `DecoderPriority` to be one of
`kDeprioritized`, `kSkipped`, or `kNormal`. kNormal was chosen instead
of `kPrioritized` since it better reflects the mechanism of what's
happening. It's not being prioritized, it's just being left as-is in the
queue.

Change-Id: I9dfcecec5454201501dd1d09c23638da634fe188
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2388269Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Commit-Queue: Will Cassella <cassew@google.com>
Cr-Commit-Position: refs/heads/master@{#805994}
parent a9b3e907
......@@ -243,6 +243,19 @@ VideoDecoderConfig TestVideoConfig::ExtraLargeEncrypted(VideoCodec codec) {
VIDEO_ROTATION_0, kExtraLargeSize, true);
}
// static
VideoDecoderConfig TestVideoConfig::Custom(gfx::Size size, VideoCodec codec) {
return GetTestConfig(codec, MinProfile(codec), VideoColorSpace::JPEG(),
VIDEO_ROTATION_0, size, false);
}
// static
VideoDecoderConfig TestVideoConfig::CustomEncrypted(gfx::Size size,
VideoCodec codec) {
return GetTestConfig(codec, MinProfile(codec), VideoColorSpace::JPEG(),
VIDEO_ROTATION_0, size, true);
}
// static
gfx::Size TestVideoConfig::NormalCodedSize() {
return kNormalSize;
......
......@@ -110,6 +110,11 @@ class TestVideoConfig {
static VideoDecoderConfig ExtraLarge(VideoCodec codec = kCodecVP8);
static VideoDecoderConfig ExtraLargeEncrypted(VideoCodec codec = kCodecVP8);
static VideoDecoderConfig Custom(gfx::Size size,
VideoCodec codec = kCodecVP8);
static VideoDecoderConfig CustomEncrypted(gfx::Size size,
VideoCodec codec = kCodecVP8);
// Returns coded size for Normal and Large config.
static gfx::Size NormalCodedSize();
static gfx::Size LargeCodedSize();
......
......@@ -32,13 +32,14 @@ namespace {
const char kSelectDecoderTrace[] = "DecoderSelector::SelectDecoder";
template <typename T>
DecoderPriority UnspecifiedDecoderPriority(const T& /*config*/) {
return DecoderPriority::kUnspecified;
template <typename ConfigT, typename DecoderT>
DecoderPriority NormalDecoderPriority(const ConfigT& /*config*/,
const DecoderT& /*decoder*/) {
return DecoderPriority::kNormal;
}
DecoderPriority GetDefaultVideoDecoderPriority(
const VideoDecoderConfig& config) {
DecoderPriority ResolutionBasedDecoderPriority(const VideoDecoderConfig& config,
const VideoDecoder& decoder) {
#if defined(OS_ANDROID)
constexpr auto kSoftwareDecoderHeightCutoff = 360;
#elif defined(OS_CHROMEOS)
......@@ -47,25 +48,31 @@ DecoderPriority GetDefaultVideoDecoderPriority(
constexpr auto kSoftwareDecoderHeightCutoff = 720;
#endif
// We only do a height check to err on the side of hardware decoding
return config.visible_rect().height() < kSoftwareDecoderHeightCutoff
? DecoderPriority::kPreferSoftwareDecoders
: DecoderPriority::kPreferPlatformDecoders;
// We only do a height check to err on the side of prioritizing platform
// decoders.
const auto at_or_above_software_cutoff =
config.visible_rect().height() >= kSoftwareDecoderHeightCutoff;
// Platform decoders are deprioritized below the cutoff, and non-platform
// decoders are deprioritized above it.
return at_or_above_software_cutoff == decoder.IsPlatformDecoder()
? DecoderPriority::kNormal
: DecoderPriority::kDeprioritized;
}
void SetDefaultDecoderPriorityCB(VideoDecoderSelector::DecoderPriorityCB* out) {
if (base::FeatureList::IsEnabled(kResolutionBasedDecoderPriority)) {
*out = base::BindRepeating(GetDefaultVideoDecoderPriority);
*out = base::BindRepeating(ResolutionBasedDecoderPriority);
} else {
*out = base::BindRepeating<DecoderPriority(const VideoDecoderConfig&)>(
UnspecifiedDecoderPriority);
*out = base::BindRepeating(
NormalDecoderPriority<VideoDecoderConfig, VideoDecoder>);
}
}
void SetDefaultDecoderPriorityCB(AudioDecoderSelector::DecoderPriorityCB* out) {
// Platform audio decoders are not currently prioritized or deprioritized
*out = base::BindRepeating<DecoderPriority(const AudioDecoderConfig&)>(
UnspecifiedDecoderPriority);
*out = base::BindRepeating(
NormalDecoderPriority<AudioDecoderConfig, AudioDecoder>);
}
} // namespace
......@@ -346,31 +353,31 @@ void DecoderSelector<StreamType>::RunSelectDecoderCB() {
template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::FilterAndSortAvailableDecoders() {
// Filter out any decoders that do not support decryption
if (config_.is_encrypted()) {
auto const non_decrypting = std::remove_if(
decoders_.begin(), decoders_.end(),
[](auto& decoder) { return !decoder->SupportsDecryption(); });
decoders_.erase(non_decrypting, decoders_.end());
std::vector<std::unique_ptr<Decoder>> decoders = std::move(decoders_);
std::vector<std::unique_ptr<Decoder>> deprioritized_decoders;
for (auto& decoder : decoders) {
// Skip the decoder if this decoder doesn't support encryption for a
// decrypting config
if (config_.is_encrypted() && !decoder->SupportsDecryption())
continue;
// Run the predicate on this decoder.
switch (decoder_priority_cb_.Run(config_, *decoder)) {
case DecoderPriority::kSkipped:
continue;
case DecoderPriority::kNormal:
decoders_.push_back(std::move(decoder));
break;
case DecoderPriority::kDeprioritized:
deprioritized_decoders.push_back(std::move(decoder));
break;
}
}
// If platform decoders are prioritized for this config, shift all platform
// decoders to the front of the list (retaining their relative order).
const auto decoder_priority = decoder_priority_cb_.Run(config_);
switch (decoder_priority) {
case DecoderPriority::kUnspecified:
break;
case DecoderPriority::kPreferPlatformDecoders:
case DecoderPriority::kPreferSoftwareDecoders: {
auto prefer_platform_decoder =
decoder_priority == DecoderPriority::kPreferPlatformDecoders;
std::stable_partition(decoders_.begin(), decoders_.end(),
[prefer_platform_decoder](auto& decoder) {
return decoder->IsPlatformDecoder() ==
prefer_platform_decoder;
});
} break;
}
// Post-insert deprioritized decoders
std::move(deprioritized_decoders.begin(), deprioritized_decoders.end(),
std::inserter(decoders_, decoders_.end()));
}
// These forward declarations tell the compiler that we will use
......
......@@ -28,10 +28,19 @@ class CdmContext;
class DecryptingDemuxerStream;
class MediaLog;
// Enum returned by `DecoderSelector::DecoderPriorityCB` to indicate
// priority of the current decoder.
enum class DecoderPriority {
kUnspecified,
kPreferPlatformDecoders,
kPreferSoftwareDecoders,
// `kNormal` indicates that the current decoder should continue through with
// selection in it's current order.
kNormal,
// `kDeprioritized` indicates that the current decoder should only be selected
// if other decoders have failed.
kDeprioritized,
// `kSkipped` indicates that the current decoder should not be used at all.
kSkipped,
};
// DecoderSelector handles construction and initialization of Decoders for a
......@@ -51,10 +60,11 @@ class MEDIA_EXPORT DecoderSelector {
using CreateDecodersCB =
base::RepeatingCallback<std::vector<std::unique_ptr<Decoder>>()>;
// Evaluates what type of decoders should be prioritized for the given config.
// If |kUnspecified| is returned, nothing is prioritized.
// Prediate to evaluate whether a decoder should be prioritized,
// deprioritized, or skipped.
using DecoderPriorityCB =
base::RepeatingCallback<DecoderPriority(const DecoderConfig&)>;
base::RepeatingCallback<DecoderPriority(const DecoderConfig&,
const Decoder&)>;
// Emits the result of a single call to SelectDecoder(). Parameters are
// 1: The initialized Decoder. nullptr if selection failed.
......
......@@ -11,9 +11,11 @@
#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"
......@@ -106,15 +108,23 @@ class AudioDecoderSelectorTestParam {
}
static media::DecoderPriority MockDecoderPriorityCB(
const media::AudioDecoderConfig& config) {
return config.samples_per_second() >
TestAudioConfig::NormalSampleRateValue()
? media::DecoderPriority::kPreferPlatformDecoders
: media::DecoderPriority::kPreferSoftwareDecoders;
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 UnspecifiedDecoderPriorityCB(
const media::AudioDecoderConfig& /*config*/) {
return media::DecoderPriority::kUnspecified;
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(
......@@ -177,15 +187,23 @@ class VideoDecoderSelectorTestParam {
}
static media::DecoderPriority MockDecoderPriorityCB(
const media::VideoDecoderConfig& config) {
return config.visible_rect().height() >
TestVideoConfig::NormalCodedSize().height()
? media::DecoderPriority::kPreferPlatformDecoders
: media::DecoderPriority::kPreferSoftwareDecoders;
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 UnspecifiedDecoderPriorityCB(
const media::VideoDecoderConfig& /*config*/) {
return media::DecoderPriority::kUnspecified;
static media::DecoderPriority SkipDecoderPriorityCB(
const media::VideoDecoderConfig& /*config*/,
const media::VideoDecoder& /*decoder*/) {
return media::DecoderPriority::kSkipped;
}
static void UseNormalClearDecoderConfig(
......@@ -374,8 +392,6 @@ class DecoderSelectorTest : public ::testing::Test {
task_environment_.GetMainThreadTaskRunner(),
base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)),
&media_log_);
decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::MockDecoderPriorityCB));
decoder_selector_->Initialize(
traits_.get(), &demuxer_stream_, cdm_context_.get(),
base::BindRepeating(&Self::OnWaiting, base::Unretained(this)));
......@@ -420,6 +436,9 @@ class DecoderSelectorTest : public ::testing::Test {
DISALLOW_COPY_AND_ASSIGN(DecoderSelectorTest);
};
using VideoDecoderSelectorTest =
DecoderSelectorTest<VideoDecoderSelectorTestParam>;
using DecoderSelectorTestParams =
::testing::Types<AudioDecoderSelectorTestParam,
VideoDecoderSelectorTestParam>;
......@@ -505,6 +524,8 @@ TYPED_TEST(DecoderSelectorTest, ClearStream_PrioritizePlatformDecoders) {
this->UseHighQualityClearDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::MockDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder1, IsNull()));
this->SelectDecoder();
......@@ -529,6 +550,8 @@ TYPED_TEST(DecoderSelectorTest, ClearStream_DeprioritizePlatformDecoders) {
this->UseClearDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::MockDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder2, IsNull()));
this->SelectDecoder();
......@@ -544,9 +567,9 @@ TYPED_TEST(DecoderSelectorTest, ClearStream_DeprioritizePlatformDecoders) {
}
// Tests that platform and non-platform decoders remain in the order they are
// given for a priority callback returning 'kNop'.
// given for a priority callback returning 'kNormal'.
TYPED_TEST(DecoderSelectorTest,
ClearStream_NopPriorityCallbackRetainsGivenOrder) {
ClearStream_NormalPriorityCallbackRetainsGivenOrder) {
this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
......@@ -555,7 +578,7 @@ TYPED_TEST(DecoderSelectorTest,
this->UseClearDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::UnspecifiedDecoderPriorityCB));
base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder1, IsNull()));
this->SelectDecoder();
......@@ -570,6 +593,77 @@ TYPED_TEST(DecoderSelectorTest,
this->SelectDecoder();
}
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, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
// 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, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder4, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder1, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder3, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
// 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, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder3, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder2, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder4, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
// Tests for encrypted streams.
// Tests that non-decrypting decoders are filtered out by DecoderSelector
......@@ -604,6 +698,8 @@ TYPED_TEST(DecoderSelectorTest, EncryptedStream_PrioritizePlatformDecoders) {
this->UseHighQualityEncryptedDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::MockDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder1, IsNull()));
this->SelectDecoder();
......@@ -628,6 +724,8 @@ TYPED_TEST(DecoderSelectorTest, EncryptedStream_DeprioritizePlatformDecoders) {
this->UseEncryptedDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::MockDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder2, IsNull()));
this->SelectDecoder();
......@@ -643,9 +741,9 @@ TYPED_TEST(DecoderSelectorTest, EncryptedStream_DeprioritizePlatformDecoders) {
}
// Tests that platform and non-platform decoders remain in the order they are
// given for a priority callback returning 'kNop'.
// given for a priority callback returning 'kNormal'.
TYPED_TEST(DecoderSelectorTest,
EncryptedStream_NopPriorityCallbackRetainsGivenOrder) {
EncryptedStream_NormalPriorityCallbackRetainsGivenOrder) {
this->AddMockPlatformDecoder(kDecoder1, kAlwaysSucceed);
this->AddMockDecoder(kDecoder2, kAlwaysSucceed);
this->AddMockPlatformDecoder(kDecoder3, kAlwaysSucceed);
......@@ -654,7 +752,7 @@ TYPED_TEST(DecoderSelectorTest,
this->UseEncryptedDecoderConfig();
this->CreateDecoderSelector();
this->decoder_selector_->OverrideDecoderPriorityCBForTesting(
base::BindRepeating(TypeParam::UnspecifiedDecoderPriorityCB));
base::BindRepeating(TypeParam::NormalDecoderPriorityCB));
EXPECT_CALL(*this, OnDecoderSelected(kDecoder1, IsNull()));
this->SelectDecoder();
......@@ -669,6 +767,21 @@ TYPED_TEST(DecoderSelectorTest,
this->SelectDecoder();
}
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, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
TYPED_TEST(DecoderSelectorTest, EncryptedStream_NoDecryptor_OneClearDecoder) {
this->AddMockDecoder(kDecoder1, kClearOnly);
this->CreateCdmContext(kNoDecryptor);
......@@ -842,4 +955,52 @@ TYPED_TEST(DecoderSelectorTest, ClearToEncryptedStream_DecryptOnly) {
this->SelectDecoder();
}
// 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, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder3, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
// 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, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kDecoder4, IsNull()));
this->SelectDecoder();
EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder, IsNull()));
this->SelectDecoder();
}
} // namespace media
......@@ -51,11 +51,13 @@ static std::string GetDecoderName(int i) {
return std::string("VideoDecoder") + base::NumberToString(i);
}
DecoderPriority MockDecoderPriority(const VideoDecoderConfig& config) {
return config.visible_rect().height() >=
TestVideoConfig::LargeCodedSize().height()
? DecoderPriority::kPreferPlatformDecoders
: DecoderPriority::kPreferSoftwareDecoders;
DecoderPriority MockDecoderPriority(const VideoDecoderConfig& config,
const VideoDecoder& decoder) {
auto const at_or_above_cutoff = config.visible_rect().height() >=
TestVideoConfig::LargeCodedSize().height();
return at_or_above_cutoff == decoder.IsPlatformDecoder()
? DecoderPriority::kNormal
: DecoderPriority::kDeprioritized;
}
} // namespace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment