Commit 2dc7f1dc authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

[getUserMedia] Enforce explicitly requested frame rates

This CL ensures that if an ideal or max frame rate is requested
via constraints in getUserMedia(), the requested rate will be
enforced using frame-rate adjustment, if necessary. Even if the
requested rate equals the reported native frame rate being used
by the device.

In practice, it has been reported that actual frame rates sometimes
exceed the rate reported by the device, so this ensures that
explicitly requested rates are produced in practice.

Prior to this CL, if the requested rate matched the rate reported
by the device, no attempts to adjust the frame rate were made.

Fixed: 1133796
Change-Id: If0699f97292b3bccc69205f861f059660355cc11
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2440758
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarMarina Ciocea <marinaciocea@chromium.org>
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812684}
parent 849ef444
...@@ -249,10 +249,6 @@ VideoTrackAdapterSettings SelectVideoTrackAdapterSettings( ...@@ -249,10 +249,6 @@ VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
if (frame_rate_set.Max() && track_max_frame_rate > *frame_rate_set.Max()) if (frame_rate_set.Max() && track_max_frame_rate > *frame_rate_set.Max())
track_max_frame_rate = *frame_rate_set.Max(); track_max_frame_rate = *frame_rate_set.Max();
} }
// Disable frame-rate adjustment if the requested rate is greater than the
// source rate.
if (track_max_frame_rate >= source_format.frame_rate)
track_max_frame_rate = 0.0;
return VideoTrackAdapterSettings(target_resolution, track_min_aspect_ratio, return VideoTrackAdapterSettings(target_resolution, track_min_aspect_ratio,
track_max_aspect_ratio, track_max_aspect_ratio,
......
...@@ -544,9 +544,7 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) { ...@@ -544,9 +544,7 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
EXPECT_EQ(kSourceWidth, result.target_width()); EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio()); EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio()); EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio());
// No frame-rate adjustment because the track will use the same frame rate EXPECT_EQ(kSourceFrameRate, result.max_frame_rate());
// as the source.
EXPECT_EQ(0.0, result.max_frame_rate());
} }
// High frame rate. // High frame rate.
...@@ -563,9 +561,7 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) { ...@@ -563,9 +561,7 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
EXPECT_EQ(kSourceWidth, result.target_width()); EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio()); EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio()); EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio());
// No frame-rate adjustment because the track will use a frame rate that is EXPECT_EQ(kHighFrameRate, result.max_frame_rate());
// greater than the source's.
EXPECT_EQ(0.0, result.max_frame_rate());
} }
} }
......
...@@ -299,9 +299,12 @@ class CandidateFormat { ...@@ -299,9 +299,12 @@ class CandidateFormat {
static_cast<double>(track_settings_with_rescale.target_width()) / static_cast<double>(track_settings_with_rescale.target_width()) /
track_settings_with_rescale.target_height(); track_settings_with_rescale.target_height();
DCHECK(!std::isnan(target_aspect_ratio)); DCHECK(!std::isnan(target_aspect_ratio));
double target_frame_rate = track_settings_with_rescale.max_frame_rate(); double best_supported_frame_rate =
if (target_frame_rate == 0.0) track_settings_with_rescale.max_frame_rate();
target_frame_rate = NativeFrameRate(); if (best_supported_frame_rate == 0.0 ||
best_supported_frame_rate > NativeFrameRate()) {
best_supported_frame_rate = NativeFrameRate();
}
track_fitness_with_rescale = track_fitness_with_rescale =
NumericValueFitness(basic_constraint_set.aspect_ratio, NumericValueFitness(basic_constraint_set.aspect_ratio,
...@@ -311,7 +314,7 @@ class CandidateFormat { ...@@ -311,7 +314,7 @@ class CandidateFormat {
NumericValueFitness(basic_constraint_set.width, NumericValueFitness(basic_constraint_set.width,
track_settings_with_rescale.target_width()) + track_settings_with_rescale.target_width()) +
NumericValueFitness(basic_constraint_set.frame_rate, NumericValueFitness(basic_constraint_set.frame_rate,
target_frame_rate); best_supported_frame_rate);
} }
double track_fitness_without_rescale = HUGE_VAL; double track_fitness_without_rescale = HUGE_VAL;
...@@ -326,17 +329,19 @@ class CandidateFormat { ...@@ -326,17 +329,19 @@ class CandidateFormat {
basic_constraint_set, resolution_set(), constrained_frame_rate(), basic_constraint_set, resolution_set(), constrained_frame_rate(),
format(), false /* enable_rescale */); format(), false /* enable_rescale */);
DCHECK(!track_settings_without_rescale.target_size().has_value()); DCHECK(!track_settings_without_rescale.target_size().has_value());
double target_frame_rate = double best_supported_frame_rate =
track_settings_without_rescale.max_frame_rate(); track_settings_without_rescale.max_frame_rate();
if (target_frame_rate == 0.0) if (best_supported_frame_rate == 0.0 ||
target_frame_rate = NativeFrameRate(); best_supported_frame_rate > NativeFrameRate()) {
best_supported_frame_rate = NativeFrameRate();
}
track_fitness_without_rescale = track_fitness_without_rescale =
NumericValueFitness(basic_constraint_set.aspect_ratio, NumericValueFitness(basic_constraint_set.aspect_ratio,
NativeAspectRatio()) + NativeAspectRatio()) +
NumericValueFitness(basic_constraint_set.height, NativeHeight()) + NumericValueFitness(basic_constraint_set.height, NativeHeight()) +
NumericValueFitness(basic_constraint_set.width, NativeWidth()) + NumericValueFitness(basic_constraint_set.width, NativeWidth()) +
NumericValueFitness(basic_constraint_set.frame_rate, NumericValueFitness(basic_constraint_set.frame_rate,
target_frame_rate); best_supported_frame_rate);
} }
} }
......
...@@ -50,8 +50,6 @@ void CheckTrackAdapterSettingsEqualsResolution( ...@@ -50,8 +50,6 @@ void CheckTrackAdapterSettingsEqualsResolution(
void CheckTrackAdapterSettingsEqualsFrameRate( void CheckTrackAdapterSettingsEqualsFrameRate(
const VideoCaptureSettings& settings, const VideoCaptureSettings& settings,
double value = 0.0) { double value = 0.0) {
if (value >= settings.FrameRate())
value = 0.0;
EXPECT_EQ(value, settings.track_adapter_settings().max_frame_rate()); EXPECT_EQ(value, settings.track_adapter_settings().max_frame_rate());
} }
...@@ -1184,7 +1182,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) { ...@@ -1184,7 +1182,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) {
// format has a frame rate included in the requested range. // format has a frame rate included in the requested range.
EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format()); EXPECT_EQ(*default_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate);
} }
{ {
...@@ -1201,7 +1200,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) { ...@@ -1201,7 +1200,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) {
// range. The default resolution should be preferred as secondary criterion. // range. The default resolution should be preferred as secondary criterion.
EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*low_res_closest_format_, result.Format()); EXPECT_EQ(*low_res_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate);
} }
{ {
...@@ -1220,7 +1220,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) { ...@@ -1220,7 +1220,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFrameRateRange) {
EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(1280, result.Width()); EXPECT_EQ(1280, result.Width());
EXPECT_EQ(720, result.Height()); EXPECT_EQ(720, result.Height());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate);
} }
} }
...@@ -1284,7 +1285,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealFrameRate) { ...@@ -1284,7 +1285,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealFrameRate) {
EXPECT_EQ(1280, result.Width()); EXPECT_EQ(1280, result.Width());
EXPECT_EQ(720, result.Height()); EXPECT_EQ(720, result.Height());
EXPECT_EQ(60, result.FrameRate()); EXPECT_EQ(60, result.FrameRate());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, kIdealFrameRate);
} }
} }
...@@ -2383,7 +2385,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, ...@@ -2383,7 +2385,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
// set. // set.
EXPECT_EQ(40.0, result.FrameRate()); EXPECT_EQ(40.0, result.FrameRate());
CheckTrackAdapterSettingsEqualsResolution(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result); CheckTrackAdapterSettingsEqualsFrameRate(result, 40.0);
} }
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
...@@ -2425,7 +2427,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, ...@@ -2425,7 +2427,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(30.0, result.FrameRate()); EXPECT_EQ(30.0, result.FrameRate());
EXPECT_GE(1920, result.Width()); EXPECT_GE(1920, result.Width());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, 30.0);
} }
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
...@@ -2450,7 +2453,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, ...@@ -2450,7 +2453,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(60.0, result.FrameRate()); EXPECT_EQ(60.0, result.FrameRate());
EXPECT_GE(1080, result.Height()); EXPECT_GE(1080, result.Height());
CheckTrackAdapterSettingsEqualsFormat(result); CheckTrackAdapterSettingsEqualsResolution(result);
CheckTrackAdapterSettingsEqualsFrameRate(result, 60.0);
} }
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedDeviceID) { TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedDeviceID) {
......
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