Commit 8d1cffce authored by Mounir Lamouri's avatar Mounir Lamouri Committed by Commit Bot

Media Capabilities: make the smooth threshold configurable via Finch.

Bug: 817136
Change-Id: I225591b1c6fdcaf50475a1a81cc2f2d5445b9eb3
Reviewed-on: https://chromium-review.googlesource.com/c/1351908
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611426}
parent d6552013
......@@ -224,6 +224,10 @@ const base::Feature kResumeBackgroundVideo {
#endif
};
// Enable Media Capabilities with finch-parameters.
const base::Feature kMediaCapabilitiesWithParameters{
"MediaCapabilitiesWithParameters", base::FEATURE_ENABLED_BY_DEFAULT};
// Display the Cast overlay button on the media controls.
const base::Feature kMediaCastOverlayButton{"MediaCastOverlayButton",
base::FEATURE_ENABLED_BY_DEFAULT};
......
......@@ -112,6 +112,7 @@ MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling;
MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryption;
MEDIA_EXPORT extern const base::Feature kLimitParallelMediaPreloading;
MEDIA_EXPORT extern const base::Feature kLowDelayVideoRenderingOnLiveStream;
MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesWithParameters;
MEDIA_EXPORT extern const base::Feature kMediaCastOverlayButton;
MEDIA_EXPORT extern const base::Feature kMediaEngagementBypassAutoplayPolicies;
MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC;
......
......@@ -8,8 +8,10 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/stringprintf.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/metrics/public/cpp/ukm_builders.h"
......@@ -17,6 +19,22 @@
namespace media {
namespace {
const double kMaxSmoothDroppedFramesPercentParamDefault = .10;
} // namespace
const char VideoDecodePerfHistory::kMaxSmoothDroppedFramesPercentParamName[] =
"smooth_threshold";
// static
double VideoDecodePerfHistory::GetMaxSmoothDroppedFramesPercent() {
return base::GetFieldTrialParamByFeatureAsDouble(
kMediaCapabilitiesWithParameters, kMaxSmoothDroppedFramesPercentParamName,
kMaxSmoothDroppedFramesPercentParamDefault);
}
VideoDecodePerfHistory::VideoDecodePerfHistory(
std::unique_ptr<VideoDecodeStatsDB> db)
: db_(std::move(db)),
......@@ -129,7 +147,7 @@ void VideoDecodePerfHistory::AssessStats(
*is_power_efficient =
percent_power_efficient >= kMinPowerEfficientDecodedFramePercent;
*is_smooth = percent_dropped <= kMaxSmoothDroppedFramesPercent;
*is_smooth = percent_dropped <= GetMaxSmoothDroppedFramesPercent();
}
void VideoDecodePerfHistory::OnGotStatsForRequest(
......
......@@ -49,6 +49,8 @@ class MEDIA_MOJO_EXPORT VideoDecodePerfHistory
public VideoDecodeStatsDBProvider,
public base::SupportsUserData::Data {
public:
static const char kMaxSmoothDroppedFramesPercentParamName[];
explicit VideoDecodePerfHistory(std::unique_ptr<VideoDecodeStatsDB> db);
~VideoDecodePerfHistory() override;
......@@ -84,6 +86,10 @@ class MEDIA_MOJO_EXPORT VideoDecodePerfHistory
private:
friend class VideoDecodePerfHistoryTest;
// Decode capabilities will be described as "smooth" whenever the percentage
// of dropped frames is less-than-or-equal-to this value.
static double GetMaxSmoothDroppedFramesPercent();
// Track the status of database lazy initialization.
enum InitStatus {
UNINITIALIZED,
......@@ -92,11 +98,6 @@ class MEDIA_MOJO_EXPORT VideoDecodePerfHistory
FAILED,
};
// Decode capabilities will be described as "smooth" whenever the percentage
// of dropped frames is less-than-or-equal-to this value. 10% chosen as a
// lenient value after manual testing.
static constexpr double kMaxSmoothDroppedFramesPercent = .10;
// Decode capabilities will be described as "power efficient" whenever the
// percentage of power efficient decoded frames is higher-than-or-equal-to
// this value.
......
......@@ -6,12 +6,16 @@
#include <string>
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "components/ukm/test_ukm_recorder.h"
#include "media/base/media_switches.h"
#include "media/capabilities/video_decode_stats_db.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "services/metrics/public/cpp/ukm_builders.h"
......@@ -142,6 +146,10 @@ class VideoDecodePerfHistoryTest : public testing::Test {
GetFakeDB()->CompleteInitialize(initialize_success);
}
double GetMaxSmoothDroppedFramesPercent() {
return VideoDecodePerfHistory::GetMaxSmoothDroppedFramesPercent();
}
// Tests may set this as the callback for VideoDecodePerfHistory::GetPerfInfo
// to check the results of the call.
MOCK_METHOD2(MockGetPerfInfoCB,
......@@ -202,8 +210,6 @@ class VideoDecodePerfHistoryTest : public testing::Test {
using VideoDescKey = VideoDecodeStatsDB::VideoDescKey;
using DecodeStatsEntry = VideoDecodeStatsDB::DecodeStatsEntry;
static constexpr double kMaxSmoothDroppedFramesPercent =
VideoDecodePerfHistory::kMaxSmoothDroppedFramesPercent;
static constexpr double kMinPowerEfficientDecodedFramePercent =
VideoDecodePerfHistory::kMinPowerEfficientDecodedFramePercent;
......@@ -243,10 +249,10 @@ TEST_P(VideoDecodePerfHistoryParamTest, GetPerfInfo_Smooth) {
const int kNotPowerEfficientFramesDecoded = 0;
// Sets the ratio of dropped frames to barely qualify as smooth.
const int kSmoothFramesDropped =
kFramesDecoded * kMaxSmoothDroppedFramesPercent;
kFramesDecoded * GetMaxSmoothDroppedFramesPercent();
// Set the ratio of dropped frames to barely qualify as NOT smooth.
const int kNotSmoothFramesDropped =
kFramesDecoded * kMaxSmoothDroppedFramesPercent + 1;
kFramesDecoded * GetMaxSmoothDroppedFramesPercent() + 1;
// Add the entries.
SavePerfRecord(kOrigin, kIsTopFrame,
......@@ -319,10 +325,10 @@ TEST_P(VideoDecodePerfHistoryParamTest, GetPerfInfo_PowerEfficient) {
kFramesDecoded * kMinPowerEfficientDecodedFramePercent - 1;
// Sets the ratio of dropped frames to barely qualify as smooth.
const int kSmoothFramesDropped =
kFramesDecoded * kMaxSmoothDroppedFramesPercent;
kFramesDecoded * GetMaxSmoothDroppedFramesPercent();
// Set the ratio of dropped frames to barely qualify as NOT smooth.
const int kNotSmoothFramesDropped =
kFramesDecoded * kMaxSmoothDroppedFramesPercent + 1;
kFramesDecoded * GetMaxSmoothDroppedFramesPercent() + 1;
// Add the entries.
SavePerfRecord(
......@@ -569,7 +575,7 @@ TEST_P(VideoDecodePerfHistoryParamTest, FailedDatabaseAppend) {
const int kFrameRate = 30;
const int kFramesDecoded = 1000;
const int kFramesDropped =
kFramesDecoded * kMaxSmoothDroppedFramesPercent + 1;
kFramesDecoded * GetMaxSmoothDroppedFramesPercent() + 1;
const int kFramesPowerEfficient = 0;
// Attempt (and fail) the save.
......@@ -613,6 +619,121 @@ TEST_P(VideoDecodePerfHistoryParamTest, FailedDatabaseAppend) {
}
}
// Tests that the feature parameters are used to override constants for the
// Media Capabilities feature.
// To avoid race conditions when setting the parameter, the test sets it when
// starting and make sure the values recorded to the DB wouldn't be smooth per
// the default value.
TEST_P(VideoDecodePerfHistoryParamTest, SmoothThresholdFinchOverride) {
base::test::ScopedFeatureList scoped_feature_list;
std::unique_ptr<base::FieldTrialList> field_trial_list;
double previous_smooth_dropped_frames_threshold =
GetMaxSmoothDroppedFramesPercent();
double new_smooth_dropped_frames_threshold =
previous_smooth_dropped_frames_threshold / 2;
ASSERT_LT(new_smooth_dropped_frames_threshold,
previous_smooth_dropped_frames_threshold);
// Override field trial.
std::map<std::string, std::string> params;
params[VideoDecodePerfHistory::kMaxSmoothDroppedFramesPercentParamName] =
std::to_string(new_smooth_dropped_frames_threshold);
field_trial_list.reset();
field_trial_list.reset(new base::FieldTrialList(nullptr));
base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
const std::string kTrialName = "TrialName";
const std::string kGroupName = "GroupName";
base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
base::FieldTrial* field_trial =
base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
feature_list->RegisterFieldTrialOverride(
media::kMediaCapabilitiesWithParameters.name,
base::FeatureList::OVERRIDE_ENABLE_FEATURE, field_trial);
base::FeatureList::ClearInstanceForTesting();
scoped_feature_list.InitWithFeatureList(std::move(feature_list));
std::map<std::string, std::string> actual_params;
EXPECT_TRUE(base::GetFieldTrialParamsByFeature(
media::kMediaCapabilitiesWithParameters, &actual_params));
EXPECT_EQ(params, actual_params);
EXPECT_EQ(new_smooth_dropped_frames_threshold,
GetMaxSmoothDroppedFramesPercent());
// NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
// delayed until we db_->CompleteInitialize(). testing::InSequence enforces
// that EXPECT_CALLs arrive in top-to-bottom order.
bool defer_initialize = GetParam();
testing::InSequence dummy;
// Complete initialization in advance of API calls when not asked to defer.
if (!defer_initialize)
PreInitializeDB(/* success */ true);
// First add 2 records to the history. The second record has a higher frame
// rate and a higher number of dropped frames such that it is "not smooth".
const VideoCodecProfile kKnownProfile = VP9PROFILE_PROFILE0;
const gfx::Size kKownSize(100, 200);
const int kSmoothFrameRatePrevious = 30;
const int kSmoothFrameRateNew = 90;
const int kFramesDecoded = 1000;
const int kNotPowerEfficientFramesDecoded = 0;
// Sets the ratio of dropped frames to qualify as smooth per the default
// threshold.
const int kSmoothFramesDroppedPrevious =
kFramesDecoded * previous_smooth_dropped_frames_threshold;
// Sets the ratio of dropped frames to quality as smooth per the new
// threshold.
const int kSmoothFramesDroppedNew =
kFramesDecoded * new_smooth_dropped_frames_threshold;
// Add the entry.
SavePerfRecord(
kOrigin, kIsTopFrame,
MakeFeatures(kKnownProfile, kKownSize, kSmoothFrameRatePrevious),
MakeTargets(kFramesDecoded, kSmoothFramesDroppedPrevious,
kNotPowerEfficientFramesDecoded),
kPlayerId);
SavePerfRecord(kOrigin, kIsTopFrame,
MakeFeatures(kKnownProfile, kKownSize, kSmoothFrameRateNew),
MakeTargets(kFramesDecoded, kSmoothFramesDroppedNew,
kNotPowerEfficientFramesDecoded),
kPlayerId);
// Verify perf history returns is_smooth = false for entry that would be
// smooth per previous smooth threshold.
EXPECT_CALL(*this, MockGetPerfInfoCB(kIsNotSmooth, kIsNotPowerEfficient));
perf_history_->GetPerfInfo(
MakeFeaturesPtr(kKnownProfile, kKownSize, kSmoothFrameRatePrevious),
base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
base::Unretained(this)));
// Verify perf history returns is_smooth = true for entry that would be
// smooth per new smooth theshold.
EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsNotPowerEfficient));
perf_history_->GetPerfInfo(
MakeFeaturesPtr(kKnownProfile, kKownSize, kSmoothFrameRateNew),
base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
base::Unretained(this)));
// Complete successful deferred DB initialization (see comment at top of test)
if (defer_initialize) {
GetFakeDB()->CompleteInitialize(true);
// Allow initialize-deferred API calls to complete.
scoped_task_environment_.RunUntilIdle();
}
}
INSTANTIATE_TEST_CASE_P(VaryDBInitTiming,
VideoDecodePerfHistoryParamTest,
::testing::Values(true, false));
......
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