Reland "Rename requested_resolution to scale_resolution_down_to."

This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd

The reason for the revert was a downstream use of
`rtc::VideoSinkWants::requested_resolution`, so in this reland we don't
rename this field, it's fine just to rename the one in
RtpEncodingParameters for now.

Original change's description:
> Rename `requested_resolution` to `scale_resolution_down_to`.
>
> This is a pure refactor/rename CL without any changes in behavior.
>
> This field is called scaleResolutionDownTo in the spec and JavaScript.
> Let's make C++ match to avoid confusion.
>
> In order not to break downstream during the transition a variable with
> the old name being a pure reference to the renamed attribute is added.
> This means we have to add custom constructors, but we can change this
> back to "= default" when the transition is completed, which should only
> be a couple of CLs away.
>
> Bug: webrtc:375048799
> Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560
> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#43300}

NOTRY=True

Bug: webrtc:375048799
Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43304}
This commit is contained in:
Henrik Boström 2024-10-25 09:51:44 +02:00 committed by WebRTC LUCI CQ
parent 115aea4774
commit e8c97c0d09
22 changed files with 369 additions and 292 deletions

View File

@ -106,9 +106,27 @@ RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
RtpRtxParameters::~RtpRtxParameters() = default;
RtpEncodingParameters::RtpEncodingParameters() = default;
RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
default;
// TODO(https://crbug.com/webrtc/375048799): Use "= default" when
// `requested_resolution` has been deleted
RtpEncodingParameters::RtpEncodingParameters()
: requested_resolution(scale_resolution_down_to) {}
RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs)
: ssrc(rhs.ssrc),
bitrate_priority(rhs.bitrate_priority),
network_priority(rhs.network_priority),
max_bitrate_bps(rhs.max_bitrate_bps),
min_bitrate_bps(rhs.min_bitrate_bps),
max_framerate(rhs.max_framerate),
num_temporal_layers(rhs.num_temporal_layers),
scale_resolution_down_by(rhs.scale_resolution_down_by),
scalability_mode(rhs.scalability_mode),
scale_resolution_down_to(rhs.scale_resolution_down_to),
requested_resolution(scale_resolution_down_to),
active(rhs.active),
rid(rhs.rid),
request_key_frame(rhs.request_key_frame),
adaptive_ptime(rhs.adaptive_ptime),
codec(rhs.codec) {}
RtpEncodingParameters::~RtpEncodingParameters() = default;
RtpCodecParameters::RtpCodecParameters() = default;

View File

@ -497,23 +497,22 @@ struct RTC_EXPORT RtpEncodingParameters {
// https://w3c.github.io/webrtc-svc/#rtcrtpencodingparameters
std::optional<std::string> scalability_mode;
// Requested encode resolution.
// This is an alternative API to `scale_resolution_down_by` but expressed in
// absolute terms (max width and max height) as opposed to relative terms (a
// scaling factor that is relative to the input frame size).
//
// This field provides an alternative to `scale_resolution_down_by`
// that is not dependent on the video source.
// If both `scale_resolution_down_by` and `scale_resolution_down_to` are
// specified, the "scale by" value is ignored.
//
// When setting requested_resolution it is not necessary to adapt the
// video source using OnOutputFormatRequest, since the VideoStreamEncoder
// will apply downscaling if necessary. requested_resolution will also be
// propagated to the video source, this allows downscaling earlier in the
// pipeline which can be beneficial if the source is consumed by multiple
// encoders, but is not strictly necessary.
// See spec:
// https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-scaleresolutiondownto
//
// The `requested_resolution` is subject to resource adaptation.
//
// It is an error to set both `requested_resolution` and
// `scale_resolution_down_by`.
std::optional<Resolution> requested_resolution;
// This was previously known as "requested_resolution" in C++.
std::optional<Resolution> scale_resolution_down_to;
// Alternative name for `scale_resolution_down_to`.
// TODO(https://crbug.com/webrtc/375048799): Delete when downstream projects
// have migrated from `requested_resolution` to `scale_resolution_down_to`.
std::optional<Resolution>& requested_resolution;
// For an RtpSender, set to true to cause this encoding to be encoded and
// sent, and false for it not to be encoded and sent. This allows control
@ -545,11 +544,31 @@ struct RTC_EXPORT RtpEncodingParameters {
scale_resolution_down_by == o.scale_resolution_down_by &&
active == o.active && rid == o.rid &&
adaptive_ptime == o.adaptive_ptime &&
requested_resolution == o.requested_resolution && codec == o.codec;
scale_resolution_down_to == o.scale_resolution_down_to &&
codec == o.codec;
}
bool operator!=(const RtpEncodingParameters& o) const {
return !(*this == o);
}
// TODO(https://crbug.com/webrtc/375048799): Delete this operator overload
// when `requested_resolution` has been deleted in favor of auto generated op.
void operator=(const RtpEncodingParameters& o) {
ssrc = o.ssrc;
bitrate_priority = o.bitrate_priority;
network_priority = o.network_priority;
max_bitrate_bps = o.max_bitrate_bps;
min_bitrate_bps = o.min_bitrate_bps;
max_framerate = o.max_framerate;
num_temporal_layers = o.num_temporal_layers;
scale_resolution_down_by = o.scale_resolution_down_by;
scalability_mode = o.scalability_mode;
scale_resolution_down_to = o.scale_resolution_down_to;
active = o.active;
rid = o.rid;
request_key_frame = o.request_key_frame;
adaptive_ptime = o.adaptive_ptime;
codec = o.codec;
}
};
struct RTC_EXPORT RtpCodecParameters : public RtpCodec {

View File

@ -82,7 +82,8 @@ struct RTC_EXPORT VideoSinkWants {
// should only be used as a hint when constructing the webrtc::VideoFrame.
std::vector<FrameSize> resolutions;
// This is the resolution requested by the user using RtpEncodingParameters.
// This is the resolution requested by the user using RtpEncodingParameters,
// which is the maximum `scale_resolution_down_by` value of any encoding.
std::optional<FrameSize> requested_resolution;
// `is_active` : Is this VideoSinkWants from an encoder that is encoding any
@ -96,7 +97,7 @@ struct RTC_EXPORT VideoSinkWants {
// that aggregates several VideoSinkWants (and sends them to
// AdaptedVideoTrackSource).
struct Aggregates {
// `active_without_requested_resolution` is set by VideoBroadcaster
// `any_active_without_requested_resolution` is set by VideoBroadcaster
// when aggregating sink wants if there exists any sink (encoder) that is
// active but has not set the `requested_resolution`, i.e is relying on
// OnOutputFormatRequest to handle encode resolution.

View File

@ -160,7 +160,7 @@ webrtc::RTCError CheckRtpParametersValues(
const webrtc::FieldTrialsView& field_trials) {
using webrtc::RTCErrorType;
bool has_requested_resolution = false;
bool has_scale_resolution_down_to = false;
for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) {
if (rtp_parameters.encodings[i].bitrate_priority <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
@ -199,10 +199,10 @@ webrtc::RTCError CheckRtpParametersValues(
}
}
if (rtp_parameters.encodings[i].requested_resolution.has_value()) {
has_requested_resolution = true;
if (rtp_parameters.encodings[i].requested_resolution->width <= 0 ||
rtp_parameters.encodings[i].requested_resolution->height <= 0) {
if (rtp_parameters.encodings[i].scale_resolution_down_to.has_value()) {
has_scale_resolution_down_to = true;
if (rtp_parameters.encodings[i].scale_resolution_down_to->width <= 0 ||
rtp_parameters.encodings[i].scale_resolution_down_to->height <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
"The resolution dimensions must be positive.");
}
@ -218,11 +218,11 @@ webrtc::RTCError CheckRtpParametersValues(
}
}
if (has_requested_resolution &&
if (has_scale_resolution_down_to &&
absl::c_any_of(rtp_parameters.encodings,
[](const webrtc::RtpEncodingParameters& encoding) {
return encoding.active &&
!encoding.requested_resolution.has_value();
!encoding.scale_resolution_down_to.has_value();
})) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
"If a resolution is specified on any encoding then "

View File

@ -244,27 +244,30 @@ bool VideoAdapter::AdaptFrameResolution(int in_width,
RTC_DCHECK_EQ(0, *out_height % resolution_alignment_);
// Lastly, make the output size fit within the resolution restrictions as
// specified by `requested_resolution_`. This does not modify aspect ratio or
// cropping, only `out_width` and `out_height`.
if (requested_resolution_.has_value()) {
// Make frame and requested resolution have matching orientation.
webrtc::Resolution requested_resolution = requested_resolution_.value();
if ((*out_width < *out_height) !=
(requested_resolution_->width < requested_resolution_->height)) {
requested_resolution = {.width = requested_resolution_->height,
.height = requested_resolution_->width};
// specified by `scale_resolution_down_to_`. This does not modify aspect ratio
// or cropping, only `out_width` and `out_height`.
if (scale_resolution_down_to_.has_value()) {
// Make frame and "scale to" have matching orientation.
webrtc::Resolution scale_resolution_down_to =
scale_resolution_down_to_.value();
if ((*out_width < *out_height) != (scale_resolution_down_to_->width <
scale_resolution_down_to_->height)) {
scale_resolution_down_to = {.width = scale_resolution_down_to_->height,
.height = scale_resolution_down_to_->width};
}
// Downscale by smallest scaling factor, if necessary.
if (*out_width > 0 && *out_height > 0 &&
(requested_resolution.width < *out_width ||
requested_resolution.height < *out_height)) {
(scale_resolution_down_to.width < *out_width ||
scale_resolution_down_to.height < *out_height)) {
double scale_factor = std::min(
requested_resolution.width / static_cast<double>(*out_width),
requested_resolution.height / static_cast<double>(*out_height));
*out_width = roundUp(std::round(*out_width * scale_factor),
resolution_alignment_, requested_resolution.width);
*out_height = roundUp(std::round(*out_height * scale_factor),
resolution_alignment_, requested_resolution.height);
scale_resolution_down_to.width / static_cast<double>(*out_width),
scale_resolution_down_to.height / static_cast<double>(*out_height));
*out_width =
roundUp(std::round(*out_width * scale_factor), resolution_alignment_,
scale_resolution_down_to.width);
*out_height =
roundUp(std::round(*out_height * scale_factor), resolution_alignment_,
scale_resolution_down_to.height);
RTC_DCHECK_EQ(0, *out_width % resolution_alignment_);
RTC_DCHECK_EQ(0, *out_height % resolution_alignment_);
}
@ -346,7 +349,7 @@ void VideoAdapter::OnOutputFormatRequest(
if (stashed_output_format_request_) {
// Save the output format request for later use in case the encoder making
// this call would become active, because currently all active encoders use
// requested_resolution instead.
// scale_resolution_down_to instead.
stashed_output_format_request_ = request;
RTC_LOG(LS_INFO) << "Stashing OnOutputFormatRequest: "
<< stashed_output_format_request_->ToString();
@ -370,21 +373,22 @@ void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) {
source_resolution_alignment_, sink_wants.resolution_alignment);
// Convert from std::optional<rtc::VideoSinkWants::FrameSize> to
// std::optional<webrtc::Resolution>. Both are {int,int}.
requested_resolution_ = std::nullopt;
scale_resolution_down_to_ = std::nullopt;
if (sink_wants.requested_resolution.has_value()) {
requested_resolution_ = {.width = sink_wants.requested_resolution->width,
.height = sink_wants.requested_resolution->height};
scale_resolution_down_to_ = {
.width = sink_wants.requested_resolution->width,
.height = sink_wants.requested_resolution->height};
}
// If requested_resolution is used, and there are no active encoders
// that are NOT using requested_resolution (aka newapi), then override
// calls to OnOutputFormatRequest and use values from requested_resolution
// If scale_resolution_down_to is used, and there are no active encoders
// that are NOT using scale_resolution_down_to (aka newapi), then override
// calls to OnOutputFormatRequest and use values from scale_resolution_down_to
// instead (combined with qualityscaling based on pixel counts above).
if (!sink_wants.requested_resolution) {
if (stashed_output_format_request_) {
// because current active_output_format_request is based on
// requested_resolution logic, while current encoder(s) doesn't want that,
// we have to restore the stashed request.
// scale_resolution_down_to logic, while current encoder(s) doesn't want
// that, we have to restore the stashed request.
RTC_LOG(LS_INFO) << "Unstashing OnOutputFormatRequest: "
<< stashed_output_format_request_->ToString();
output_format_request_ = *stashed_output_format_request_;
@ -393,9 +397,10 @@ void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) {
return;
}
// The code below is only needed when `requested_resolution` is signalled back
// to the video source which only happens if
// `VideoStreamEncoderSettings::use_standard_requested_resolution` is false.
// The code below is only needed when `scale_resolution_down_to` is signalled
// back to the video source which only happens if
// `VideoStreamEncoderSettings::use_standard_scale_resolution_down_to` is
// false.
// TODO(https://crbug.com/webrtc/366284861): Delete the code below as part of
// deleting this flag and only supporting the standard behavior.
@ -413,8 +418,8 @@ void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) {
<< stashed_output_format_request_->ToString();
}
// Clear the output format request. Requested resolution will be applied
// instead which happens inside AdaptFrameResolution().
// Clear the output format request, `scale_resolution_down_to_` will be
// applied instead which happens inside AdaptFrameResolution().
output_format_request_ = {};
}

View File

@ -149,14 +149,14 @@ class RTC_EXPORT VideoAdapter {
int resolution_request_target_pixel_count_ RTC_GUARDED_BY(mutex_);
int resolution_request_max_pixel_count_ RTC_GUARDED_BY(mutex_);
int max_framerate_request_ RTC_GUARDED_BY(mutex_);
std::optional<webrtc::Resolution> requested_resolution_
std::optional<webrtc::Resolution> scale_resolution_down_to_
RTC_GUARDED_BY(mutex_);
// Stashed OutputFormatRequest that is used to save value of
// OnOutputFormatRequest in case all active encoders are using
// requested_resolution. I.e when all active encoders are using
// requested_resolution, the call to OnOutputFormatRequest is ignored
// and the value from requested_resolution is used instead (to scale/crop
// scale_resolution_down_to. I.e when all active encoders are using
// scale_resolution_down_to, the call to OnOutputFormatRequest is ignored
// and the value from scale_resolution_down_to is used instead (to scale/crop
// frame). This allows for an application to only use
// RtpEncodingParameters::request_resolution and get the same behavior as if
// it had used VideoAdapter::OnOutputFormatRequest.

View File

@ -52,15 +52,15 @@ rtc::VideoSinkWants BuildSinkWants(std::optional<int> target_pixel_count,
}
rtc::VideoSinkWants BuildSinkWants(
std::optional<webrtc::Resolution> requested_resolution,
std::optional<webrtc::Resolution> scale_resolution_down_to,
bool any_active_without_requested_resolution) {
rtc::VideoSinkWants wants;
wants.max_framerate_fps = kDefaultFps;
wants.resolution_alignment = 1;
wants.is_active = true;
if (requested_resolution) {
if (scale_resolution_down_to) {
wants.requested_resolution.emplace(rtc::VideoSinkWants::FrameSize(
requested_resolution->width, requested_resolution->height));
scale_resolution_down_to->width, scale_resolution_down_to->height));
}
wants.aggregates.emplace(rtc::VideoSinkWants::Aggregates());
wants.aggregates->any_active_without_requested_resolution =
@ -1202,8 +1202,9 @@ TEST_P(VideoAdapterTest, AdaptResolutionWithSinkAlignment) {
}
// Verify the cases the OnOutputFormatRequest is ignored and
// requested_resolution is used instead.
TEST_P(VideoAdapterTest, UseRequestedResolutionInsteadOfOnOutputFormatRequest) {
// scale_resolution_down_to is used instead.
TEST_P(VideoAdapterTest,
UseScaleResolutionDownToInsteadOfOnOutputFormatRequest) {
{
// Both new and old API active => Use OnOutputFormatRequest
OnOutputFormatRequest(640, 360, kDefaultFps);
@ -1218,7 +1219,7 @@ TEST_P(VideoAdapterTest, UseRequestedResolutionInsteadOfOnOutputFormatRequest) {
}
{
// New API active, old API inactive, ignore OnOutputFormatRequest and use
// requested_resolution.
// scale_resolution_down_to.
OnOutputFormatRequest(640, 360, kDefaultFps);
adapter_.OnSinkWants(
BuildSinkWants(Resolution{.width = 960, .height = 540},
@ -1256,7 +1257,7 @@ TEST_P(VideoAdapterTest, UseRequestedResolutionInsteadOfOnOutputFormatRequest) {
Eq(Resolution{.width = 960, .height = 540}));
// This is ignored since there is not any active NOT using
// requested_resolution.
// scale_resolution_down_to.
OnOutputFormatRequest(320, 180, kDefaultFps);
EXPECT_THAT(
@ -1276,7 +1277,7 @@ TEST_P(VideoAdapterTest, UseRequestedResolutionInsteadOfOnOutputFormatRequest) {
}
}
TEST_P(VideoAdapterTest, RequestedResolutionIsOrientationAgnostic) {
TEST_P(VideoAdapterTest, ScaleResolutionDownToIsOrientationAgnostic) {
// Request 1280x720 when frame is 720x1280.
{
adapter_.OnSinkWants(
@ -1301,7 +1302,7 @@ TEST_P(VideoAdapterTest, RequestedResolutionIsOrientationAgnostic) {
}
}
TEST_P(VideoAdapterTest, RequestedResolutionMaintainsAspectRatio) {
TEST_P(VideoAdapterTest, ScaleResolutionDownToMaintainsAspectRatio) {
// Request 720x720.
adapter_.OnSinkWants(
BuildSinkWants(Resolution{.width = 720, .height = 720},
@ -1366,7 +1367,7 @@ TEST_P(VideoAdapterWithSourceAlignmentTest, AdaptResolutionWithSinkAlignment) {
}
TEST_P(VideoAdapterWithSourceAlignmentTest,
RequestedResolutionMaintainsAspectRatioWithAlignment) {
ScaleResolutionDownToMaintainsAspectRatioWithAlignment) {
// Request 720x720.
adapter_.OnSinkWants(
BuildSinkWants(Resolution{.width = 720, .height = 720},

View File

@ -131,7 +131,7 @@ void VideoBroadcaster::UpdateWants() {
// "ignore" encoders that are not active. But that would
// probably require a controlled roll out with a field trials?
// To play it safe, only ignore inactive encoders is there is an
// active encoder using the new api (requested_resolution),
// active encoder using the new api (scale_resolution_down_to),
// this means that there is only a behavioural change when using new
// api.
bool ignore_inactive_encoders_old_api = false;
@ -171,8 +171,8 @@ void VideoBroadcaster::UpdateWants() {
wants.resolution_alignment = cricket::LeastCommonMultiple(
wants.resolution_alignment, sink.wants.resolution_alignment);
// Pick MAX(requested_resolution) since the actual can be downscaled
// in encoder instead.
// Pick MAX(requested_resolution) since the actual can be downscaled in
// encoder instead.
if (sink.wants.requested_resolution) {
if (!wants.requested_resolution) {
wants.requested_resolution = sink.wants.requested_resolution;

View File

@ -332,7 +332,7 @@ TEST(VideoBroadcasterTest, ForwardsConstraintsToSink) {
broadcaster.ProcessConstraints(webrtc::VideoTrackSourceConstraints{2, 3});
}
TEST(VideoBroadcasterTest, AppliesMaxOfSinkWantsRequestedResolution) {
TEST(VideoBroadcasterTest, AppliesMaxOfSinkWantsScaleResolutionDownTo) {
VideoBroadcaster broadcaster;
FakeVideoRenderer sink1;
@ -374,7 +374,7 @@ TEST(VideoBroadcasterTest, AnyActive) {
EXPECT_EQ(false, broadcaster.wants().is_active);
}
TEST(VideoBroadcasterTest, AnyActiveWithoutRequestedResolution) {
TEST(VideoBroadcasterTest, AnyActiveWithoutScaleResolutionDownTo) {
VideoBroadcaster broadcaster;
FakeVideoRenderer sink1;
@ -402,8 +402,9 @@ TEST(VideoBroadcasterTest, AnyActiveWithoutRequestedResolution) {
}
// This verifies that the VideoSinkWants from a Sink that is_active = false
// is ignored IF there is an active sink using new api (Requested_Resolution).
// The uses resolution_alignment for verification.
// is ignored IF there is an active sink using requested_resolution (controlled
// via new API scale_resolution_down_to). The uses resolution_alignment for
// verification.
TEST(VideoBroadcasterTest, IgnoreInactiveSinkIfNewApiUsed) {
VideoBroadcaster broadcaster;

View File

@ -2087,8 +2087,8 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::SetRtpParameters(
rtp_parameters_.encodings[i].scale_resolution_down_by) ||
(new_parameters.encodings[i].num_temporal_layers !=
rtp_parameters_.encodings[i].num_temporal_layers) ||
(new_parameters.encodings[i].requested_resolution !=
rtp_parameters_.encodings[i].requested_resolution) ||
(new_parameters.encodings[i].scale_resolution_down_to !=
rtp_parameters_.encodings[i].scale_resolution_down_to) ||
(new_parameters.encodings[i].scalability_mode !=
rtp_parameters_.encodings[i].scalability_mode) ||
(new_parameters.encodings[i].codec !=
@ -2228,7 +2228,7 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig(
rtp_parameters_.encodings) {
if (encoding.scalability_mode.has_value() &&
(encoding.scale_resolution_down_by.has_value() ||
encoding.requested_resolution.has_value())) {
encoding.scale_resolution_down_to.has_value())) {
legacy_scalability_mode = false;
break;
}
@ -2309,8 +2309,8 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig(
encoder_config.simulcast_layers[i].num_temporal_layers =
*rtp_parameters_.encodings[i].num_temporal_layers;
}
encoder_config.simulcast_layers[i].requested_resolution =
rtp_parameters_.encodings[i].requested_resolution;
encoder_config.simulcast_layers[i].scale_resolution_down_to =
rtp_parameters_.encodings[i].scale_resolution_down_to;
}
encoder_config.legacy_conference_mode = parameters_.conference_mode;

View File

@ -9750,7 +9750,7 @@ TEST_F(WebRtcVideoChannelBaseTest, EncoderSelectorSwitchCodec) {
send_channel_->SetEncoderSelector(kSsrc, nullptr);
}
TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecast) {
TEST_F(WebRtcVideoChannelTest, ScaleResolutionDownToSinglecast) {
cricket::VideoSenderParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8"));
ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
@ -9762,12 +9762,12 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecast) {
EXPECT_TRUE(
send_channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
{ // TEST requested_resolution < frame size
{ // TEST scale_resolution_down_to < frame size
webrtc::RtpParameters rtp_parameters =
send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 640,
.height = 360};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 640,
.height = 360};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9778,11 +9778,11 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecast) {
EXPECT_EQ(rtc::checked_cast<size_t>(360), streams[0].height);
}
{ // TEST requested_resolution == frame size
{ // TEST scale_resolution_down_to == frame size
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 1280,
.height = 720};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 720};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9792,11 +9792,11 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecast) {
EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
}
{ // TEST requested_resolution > frame size
{ // TEST scale_resolution_down_to > frame size
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 2 * 1280,
.height = 2 * 720};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 2 * 1280,
.height = 2 * 720};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9809,7 +9809,7 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecast) {
EXPECT_TRUE(send_channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}
TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
TEST_F(WebRtcVideoChannelTest, ScaleResolutionDownToSinglecastScaling) {
cricket::VideoSenderParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8"));
ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
@ -9824,8 +9824,8 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
{
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 720,
.height = 720};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 720,
.height = 720};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9841,8 +9841,8 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
{
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 1280,
.height = 1280};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 1280};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9857,8 +9857,8 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
{
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 650,
.height = 650};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 650,
.height = 650};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
auto streams = stream->GetVideoStreams();
@ -9872,8 +9872,8 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
{
auto rtp_parameters = send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 2560,
.height = 1440};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 2560,
.height = 1440};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
auto streams = stream->GetVideoStreams();
@ -9886,7 +9886,7 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSinglecastScaling) {
EXPECT_TRUE(send_channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}
TEST_F(WebRtcVideoChannelTest, RequestedResolutionSimulcast) {
TEST_F(WebRtcVideoChannelTest, ScaleResolutionDownToSimulcast) {
cricket::VideoSenderParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8"));
ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
@ -9902,12 +9902,12 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSimulcast) {
webrtc::RtpParameters rtp_parameters =
send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(3UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 320,
.height = 180};
rtp_parameters.encodings[1].requested_resolution = {.width = 640,
.height = 360};
rtp_parameters.encodings[2].requested_resolution = {.width = 1280,
.height = 720};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
rtp_parameters.encodings[1].scale_resolution_down_to = {.width = 640,
.height = 360};
rtp_parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9924,12 +9924,12 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSimulcast) {
webrtc::RtpParameters rtp_parameters =
send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(3UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 320,
.height = 180};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
rtp_parameters.encodings[1].active = false;
rtp_parameters.encodings[2].requested_resolution = {.width = 1280,
.height = 720};
rtp_parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
@ -9945,13 +9945,13 @@ TEST_F(WebRtcVideoChannelTest, RequestedResolutionSimulcast) {
webrtc::RtpParameters rtp_parameters =
send_channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(3UL, rtp_parameters.encodings.size());
rtp_parameters.encodings[0].requested_resolution = {.width = 320,
.height = 180};
rtp_parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
rtp_parameters.encodings[1].active = true;
rtp_parameters.encodings[1].requested_resolution = {.width = 640,
.height = 360};
rtp_parameters.encodings[2].requested_resolution = {.width = 960,
.height = 540};
rtp_parameters.encodings[1].scale_resolution_down_to = {.width = 640,
.height = 360};
rtp_parameters.encodings[2].scale_resolution_down_to = {.width = 960,
.height = 540};
send_channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

View File

@ -2115,17 +2115,16 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
ASSERT_TRUE(transceiver_or_error.ok());
}
TEST_F(PeerConnectionEncodingsIntegrationTest,
RequestedResolutionParameterChecking) {
TEST_F(PeerConnectionEncodingsIntegrationTest, ScaleToParameterChecking) {
rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper = CreatePc();
// AddTransceiver: If `requested_resolution` is specified on any encoding it
// must be specified on all encodings.
// AddTransceiver: If `scale_resolution_down_to` is specified on any encoding
// it must be specified on all encodings.
RtpTransceiverInit init;
RtpEncodingParameters encoding;
encoding.requested_resolution = std::nullopt;
encoding.scale_resolution_down_to = std::nullopt;
init.send_encodings.push_back(encoding);
encoding.requested_resolution = {.width = 1280, .height = 720};
encoding.scale_resolution_down_to = {.width = 1280, .height = 720};
init.send_encodings.push_back(encoding);
auto transceiver_or_error =
pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
@ -2134,64 +2133,74 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
RTCErrorType::UNSUPPORTED_OPERATION);
// AddTransceiver: Width and height must not be zero.
init.send_encodings[0].requested_resolution = {.width = 1280, .height = 0};
init.send_encodings[1].requested_resolution = {.width = 0, .height = 720};
init.send_encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 0};
init.send_encodings[1].scale_resolution_down_to = {.width = 0, .height = 720};
transceiver_or_error =
pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
EXPECT_FALSE(transceiver_or_error.ok());
EXPECT_EQ(transceiver_or_error.error().type(),
RTCErrorType::UNSUPPORTED_OPERATION);
// AddTransceiver: Specifying both `requested_resolution` and
// AddTransceiver: Specifying both `scale_resolution_down_to` and
// `scale_resolution_down_by` is allowed (the latter is ignored).
init.send_encodings[0].requested_resolution = {.width = 640, .height = 480};
init.send_encodings[0].scale_resolution_down_to = {.width = 640,
.height = 480};
init.send_encodings[0].scale_resolution_down_by = 1.0;
init.send_encodings[1].requested_resolution = {.width = 1280, .height = 720};
init.send_encodings[1].scale_resolution_down_to = {.width = 1280,
.height = 720};
init.send_encodings[1].scale_resolution_down_by = 2.0;
transceiver_or_error =
pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
ASSERT_TRUE(transceiver_or_error.ok());
// SetParameters: If `requested_resolution` is specified on any active
// SetParameters: If `scale_resolution_down_to` is specified on any active
// encoding it must be specified on all active encodings.
auto sender = transceiver_or_error.value()->sender();
auto parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 640, .height = 480};
parameters.encodings[1].requested_resolution = std::nullopt;
parameters.encodings[0].scale_resolution_down_to = {.width = 640,
.height = 480};
parameters.encodings[1].scale_resolution_down_to = std::nullopt;
auto error = sender->SetParameters(parameters);
EXPECT_FALSE(error.ok());
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
// But it's OK not to specify `requested_resolution` on an inactive encoding.
// But it's OK not to specify `scale_resolution_down_to` on an inactive
// encoding.
parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 640, .height = 480};
parameters.encodings[0].scale_resolution_down_to = {.width = 640,
.height = 480};
parameters.encodings[1].active = false;
parameters.encodings[1].requested_resolution = std::nullopt;
parameters.encodings[1].scale_resolution_down_to = std::nullopt;
error = sender->SetParameters(parameters);
EXPECT_TRUE(error.ok());
// SetParameters: Width and height must not be zero.
sender = transceiver_or_error.value()->sender();
parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 1280, .height = 0};
parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 0};
parameters.encodings[1].active = true;
parameters.encodings[1].requested_resolution = {.width = 0, .height = 720};
parameters.encodings[1].scale_resolution_down_to = {.width = 0,
.height = 720};
error = sender->SetParameters(parameters);
EXPECT_FALSE(error.ok());
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
// SetParameters: Specifying both `requested_resolution` and
// SetParameters: Specifying both `scale_resolution_down_to` and
// `scale_resolution_down_by` is allowed (the latter is ignored).
parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 640, .height = 480};
parameters.encodings[0].scale_resolution_down_to = {.width = 640,
.height = 480};
parameters.encodings[0].scale_resolution_down_by = 2.0;
parameters.encodings[1].requested_resolution = {.width = 1280, .height = 720};
parameters.encodings[1].scale_resolution_down_to = {.width = 1280,
.height = 720};
parameters.encodings[1].scale_resolution_down_by = 1.0;
error = sender->SetParameters(parameters);
EXPECT_TRUE(error.ok());
}
TEST_F(PeerConnectionEncodingsIntegrationTest,
ScaleResolutionDownByIsIgnoredWhenRequestedResolutionIsSpecified) {
ScaleResolutionDownByIsIgnoredWhenScaleToIsSpecified) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
@ -2204,7 +2213,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
RtpTransceiverInit init;
RtpEncodingParameters encoding;
encoding.scale_resolution_down_by = 2.0;
encoding.requested_resolution = {.width = 640, .height = 360};
encoding.scale_resolution_down_to = {.width = 640, .height = 360};
init.send_encodings.push_back(encoding);
auto transceiver_or_error =
local_pc_wrapper->pc()->AddTransceiver(track, init);
@ -2222,7 +2231,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
}
// Tests that use the standard path (specifying both `scalability_mode` and
// `scale_resolution_down_by` or `requested_resolution`) should pass for all
// `scale_resolution_down_by` or `scale_resolution_down_to`) should pass for all
// codecs.
class PeerConnectionEncodingsIntegrationParameterizedTest
: public PeerConnectionEncodingsIntegrationTest,
@ -2358,9 +2367,9 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) {
EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3"));
}
// Configure 4:2:1 using `requested_resolution`.
// Configure 4:2:1 using `scale_resolution_down_to`.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
SimulcastWithRequestedResolution) {
SimulcastWithScaleTo) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2381,11 +2390,14 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RtpParameters parameters = sender->GetParameters();
ASSERT_THAT(parameters.encodings, SizeIs(3));
parameters.encodings[0].scalability_mode = "L1T3";
parameters.encodings[0].requested_resolution = {.width = 320, .height = 180};
parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
parameters.encodings[1].scalability_mode = "L1T3";
parameters.encodings[1].requested_resolution = {.width = 640, .height = 360};
parameters.encodings[1].scale_resolution_down_to = {.width = 640,
.height = 360};
parameters.encodings[2].scalability_mode = "L1T3";
parameters.encodings[2].requested_resolution = {.width = 1280, .height = 720};
parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
sender->SetParameters(parameters);
NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
@ -2501,9 +2513,9 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
}
// Simulcast starting in 720p 4:2:1 then changing to {180p, 360p, 540p} using
// the `requested_resolution` API.
// the `scale_resolution_down_to` API.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
SimulcastRequestedResolutionNoLongerPowerOfTwo) {
SimulcastScaleToNoLongerPowerOfTwo) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2525,11 +2537,14 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RtpParameters parameters = sender->GetParameters();
ASSERT_THAT(parameters.encodings, SizeIs(3));
parameters.encodings[0].scalability_mode = "L1T1";
parameters.encodings[0].requested_resolution = {.width = 320, .height = 180};
parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
parameters.encodings[1].scalability_mode = "L1T1";
parameters.encodings[1].requested_resolution = {.width = 640, .height = 360};
parameters.encodings[1].scale_resolution_down_to = {.width = 640,
.height = 360};
parameters.encodings[2].scalability_mode = "L1T1";
parameters.encodings[2].requested_resolution = {.width = 1280, .height = 720};
parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
sender->SetParameters(parameters);
NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
@ -2548,9 +2563,12 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
// Configure {180p, 360p, 540p}.
parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 320, .height = 180};
parameters.encodings[1].requested_resolution = {.width = 640, .height = 360};
parameters.encodings[2].requested_resolution = {.width = 960, .height = 540};
parameters.encodings[0].scale_resolution_down_to = {.width = 320,
.height = 180};
parameters.encodings[1].scale_resolution_down_to = {.width = 640,
.height = 360};
parameters.encodings[2].scale_resolution_down_to = {.width = 960,
.height = 540};
sender->SetParameters(parameters);
// Wait for the new resolutions to be produced.
@ -2577,11 +2595,11 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
}
// The code path that disables layers based on resolution size should NOT run
// when `requested_resolution` is specified. (It shouldn't run in any case but
// that is an existing legacy code and non-compliance problem that we don't have
// to repeat here.)
// when `scale_resolution_down_to` is specified. (It shouldn't run in any case
// but that is an existing legacy code and non-compliance problem that we don't
// have to repeat here.)
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
LowResolutionSimulcastWithRequestedResolution) {
LowResolutionSimulcastWithScaleTo) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2597,13 +2615,13 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RtpEncodingParameters encoding;
encoding.scalability_mode = "L1T3";
encoding.rid = "q";
encoding.requested_resolution = {.width = 40, .height = 20};
encoding.scale_resolution_down_to = {.width = 40, .height = 20};
init.send_encodings.push_back(encoding);
encoding.rid = "h";
encoding.requested_resolution = {.width = 80, .height = 40};
encoding.scale_resolution_down_to = {.width = 80, .height = 40};
init.send_encodings.push_back(encoding);
encoding.rid = "f";
encoding.requested_resolution = {.width = 160, .height = 80};
encoding.scale_resolution_down_to = {.width = 160, .height = 80};
init.send_encodings.push_back(encoding);
rtc::scoped_refptr<MediaStreamInterface> stream =
local_pc_wrapper->GetUserMedia(
@ -2698,7 +2716,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
}
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RequestedResolutionDownscaleAndThenUpscale) {
ScaleToDownscaleAndThenUpscale) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2726,7 +2744,8 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RtpParameters parameters = sender->GetParameters();
ASSERT_THAT(parameters.encodings, SizeIs(1));
parameters.encodings[0].scalability_mode = "L1T3";
parameters.encodings[0].requested_resolution = {.width = 640, .height = 360};
parameters.encodings[0].scale_resolution_down_to = {.width = 640,
.height = 360};
sender->SetParameters(parameters);
// Confirm 640x360 is sent.
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper) ==
@ -2744,7 +2763,8 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
// Request the full 1280x720 resolution.
parameters = sender->GetParameters();
parameters.encodings[0].requested_resolution = {.width = 1280, .height = 720};
parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 720};
sender->SetParameters(parameters);
// Confirm 1280x720 is sent.
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper) ==
@ -2753,7 +2773,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
}
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RequestedResolutionIsOrientationAgnostic) {
ScaleToIsOrientationAgnostic) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2781,7 +2801,8 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
rtc::scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
RtpParameters parameters = sender->GetParameters();
ASSERT_THAT(parameters.encodings, SizeIs(1));
parameters.encodings[0].requested_resolution = {.width = 360, .height = 640};
parameters.encodings[0].scale_resolution_down_to = {.width = 360,
.height = 640};
sender->SetParameters(parameters);
// Confirm 640x360 is sent.
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper) ==
@ -2790,7 +2811,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
}
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
RequestedResolutionMaintainsAspectRatio) {
ScaleToMaintainsAspectRatio) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
return;
@ -2818,7 +2839,8 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
rtc::scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
RtpParameters parameters = sender->GetParameters();
ASSERT_THAT(parameters.encodings, SizeIs(1));
parameters.encodings[0].requested_resolution = {.width = 1280, .height = 360};
parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
.height = 360};
sender->SetParameters(parameters);
// Confirm 640x360 is sent.
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper) ==

View File

@ -150,7 +150,7 @@ void OverrideStreamSettings(
webrtc::VideoStream& layer = layers[i];
layer.active = overrides.active;
layer.scalability_mode = overrides.scalability_mode;
layer.requested_resolution = overrides.requested_resolution;
layer.scale_resolution_down_to = overrides.scale_resolution_down_to;
// Update with configured num temporal layers if supported by codec.
if (overrides.num_temporal_layers > 0 && temporal_layers_supported) {
layer.num_temporal_layers = *overrides.num_temporal_layers;
@ -352,18 +352,18 @@ EncoderStreamFactory::CreateDefaultVideoStreams(
layer.width = width;
layer.height = height;
layer.max_framerate = max_framerate;
layer.requested_resolution =
encoder_config.simulcast_layers[0].requested_resolution;
layer.scale_resolution_down_to =
encoder_config.simulcast_layers[0].scale_resolution_down_to;
// Note: VP9 seems to have be sending if any layer is active,
// (see `UpdateSendState`) and still use parameters only from
// encoder_config.simulcast_layers[0].
layer.active = absl::c_any_of(encoder_config.simulcast_layers,
[](const auto& layer) { return layer.active; });
if (encoder_config.simulcast_layers[0].requested_resolution) {
auto res = GetLayerResolutionFromRequestedResolution(
if (encoder_config.simulcast_layers[0].scale_resolution_down_to) {
auto res = GetLayerResolutionFromScaleResolutionDownTo(
width, height,
*encoder_config.simulcast_layers[0].requested_resolution);
*encoder_config.simulcast_layers[0].scale_resolution_down_to);
layer.width = res.width;
layer.height = res.height;
} else if (encoder_config.simulcast_layers[0].scale_resolution_down_by > 1.) {
@ -468,23 +468,23 @@ EncoderStreamFactory::CreateSimulcastOrConferenceModeScreenshareStreams(
}
webrtc::Resolution
EncoderStreamFactory::GetLayerResolutionFromRequestedResolution(
EncoderStreamFactory::GetLayerResolutionFromScaleResolutionDownTo(
int frame_width,
int frame_height,
webrtc::Resolution requested_resolution) const {
// Make frame and requested resolution have matching orientation.
webrtc::Resolution scale_resolution_down_to) const {
// Make frame and `scale_resolution_down_to` have matching orientation.
if ((frame_width < frame_height) !=
(requested_resolution.width < requested_resolution.height)) {
requested_resolution = {.width = requested_resolution.height,
.height = requested_resolution.width};
(scale_resolution_down_to.width < scale_resolution_down_to.height)) {
scale_resolution_down_to = {.width = scale_resolution_down_to.height,
.height = scale_resolution_down_to.width};
}
// Downscale by smallest scaling factor, if necessary.
if (frame_width > 0 && frame_height > 0 &&
(requested_resolution.width < frame_width ||
requested_resolution.height < frame_height)) {
(scale_resolution_down_to.width < frame_width ||
scale_resolution_down_to.height < frame_height)) {
double scale_factor = std::min(
requested_resolution.width / static_cast<double>(frame_width),
requested_resolution.height / static_cast<double>(frame_height));
scale_resolution_down_to.width / static_cast<double>(frame_width),
scale_resolution_down_to.height / static_cast<double>(frame_height));
frame_width = std::round(frame_width * scale_factor);
frame_height = std::round(frame_height * scale_factor);
}
@ -528,33 +528,34 @@ std::vector<webrtc::Resolution> EncoderStreamFactory::GetStreamResolutions(
} else {
size_t min_num_layers = FindRequiredActiveLayers(encoder_config);
size_t max_num_layers =
!encoder_config.HasRequestedResolution()
!encoder_config.HasScaleResolutionDownTo()
? LimitSimulcastLayerCount(
min_num_layers, encoder_config.number_of_streams, width,
height, trials, encoder_config.codec_type)
: encoder_config.number_of_streams;
RTC_DCHECK_LE(max_num_layers, encoder_config.number_of_streams);
// When the `requested_resolution` API is used, disable upper layers that
// are bigger than what adaptation restrictions allow. For example if
// When the `scale_resolution_down_to` API is used, disable upper layers
// that are bigger than what adaptation restrictions allow. For example if
// restrictions are 540p, simulcast 180p:360p:720p becomes 180p:360p:- as
// opposed to 180p:360p:540p. This makes CPU adaptation consistent with BW
// adaptation (bitrate allocator disabling layers rather than downscaling)
// and means we don't have to break power of two optimization paths (i.e.
// S-modes based simulcast). Note that the lowest layer is never disabled.
if (encoder_config.HasRequestedResolution() && restrictions_.has_value() &&
if (encoder_config.HasScaleResolutionDownTo() &&
restrictions_.has_value() &&
restrictions_->max_pixels_per_frame().has_value()) {
int max_pixels = rtc::dchecked_cast<int>(
restrictions_->max_pixels_per_frame().value());
int prev_pixel_count =
encoder_config.simulcast_layers[0]
.requested_resolution.value_or(webrtc::Resolution())
.scale_resolution_down_to.value_or(webrtc::Resolution())
.PixelCount();
std::optional<size_t> restricted_num_layers;
for (size_t i = 1; i < max_num_layers; ++i) {
int pixel_count =
encoder_config.simulcast_layers[i]
.requested_resolution.value_or(webrtc::Resolution())
.scale_resolution_down_to.value_or(webrtc::Resolution())
.PixelCount();
if (!restricted_num_layers.has_value() && max_pixels < pixel_count) {
// Current layer is the highest layer allowed by restrictions.
@ -596,10 +597,11 @@ std::vector<webrtc::Resolution> EncoderStreamFactory::GetStreamResolutions(
resolutions.resize(max_num_layers);
for (size_t i = 0; i < max_num_layers; i++) {
if (encoder_config.simulcast_layers[i].requested_resolution.has_value()) {
resolutions[i] = GetLayerResolutionFromRequestedResolution(
if (encoder_config.simulcast_layers[i]
.scale_resolution_down_to.has_value()) {
resolutions[i] = GetLayerResolutionFromScaleResolutionDownTo(
normalized_width, normalized_height,
*encoder_config.simulcast_layers[i].requested_resolution);
*encoder_config.simulcast_layers[i].scale_resolution_down_to);
} else if (has_scale_resolution_down_by) {
const double scale_resolution_down_by = std::max(
encoder_config.simulcast_layers[i].scale_resolution_down_by, 1.0);

View File

@ -49,10 +49,10 @@ class EncoderStreamFactory
const webrtc::VideoEncoderConfig& encoder_config,
const std::optional<webrtc::DataRate>& experimental_min_bitrate) const;
webrtc::Resolution GetLayerResolutionFromRequestedResolution(
webrtc::Resolution GetLayerResolutionFromScaleResolutionDownTo(
int in_frame_width,
int in_frame_height,
webrtc::Resolution requested_resolution) const;
webrtc::Resolution scale_resolution_down_to) const;
std::vector<webrtc::Resolution> GetStreamResolutions(
const webrtc::FieldTrialsView& trials,

View File

@ -79,23 +79,23 @@ std::vector<VideoStream> CreateEncoderStreams(
} // namespace
TEST(EncoderStreamFactory, SinglecastRequestedResolution) {
TEST(EncoderStreamFactory, SinglecastScaleResolutionDownTo) {
ExplicitKeyValueConfig field_trials("");
VideoEncoderConfig encoder_config;
encoder_config.number_of_streams = 1;
encoder_config.simulcast_layers.resize(1);
encoder_config.simulcast_layers[0].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 640,
.height = 360};
auto streams = CreateEncoderStreams(
field_trials, {.width = 1280, .height = 720}, encoder_config);
EXPECT_EQ(streams[0].requested_resolution,
EXPECT_EQ(streams[0].scale_resolution_down_to,
(Resolution{.width = 640, .height = 360}));
EXPECT_EQ(GetStreamResolutions(streams), (std::vector<Resolution>{
{.width = 640, .height = 360},
}));
}
TEST(EncoderStreamFactory, SinglecastRequestedResolutionWithAdaptation) {
TEST(EncoderStreamFactory, SinglecastScaleResolutionDownToWithAdaptation) {
ExplicitKeyValueConfig field_trials("");
VideoSourceRestrictions restrictions(
/* max_pixels_per_frame= */ (320 * 320),
@ -104,29 +104,29 @@ TEST(EncoderStreamFactory, SinglecastRequestedResolutionWithAdaptation) {
VideoEncoderConfig encoder_config;
encoder_config.number_of_streams = 1;
encoder_config.simulcast_layers.resize(1);
encoder_config.simulcast_layers[0].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 640,
.height = 360};
auto streams =
CreateEncoderStreams(field_trials, {.width = 1280, .height = 720},
encoder_config, restrictions);
EXPECT_EQ(streams[0].requested_resolution,
EXPECT_EQ(streams[0].scale_resolution_down_to,
(Resolution{.width = 640, .height = 360}));
EXPECT_EQ(GetStreamResolutions(streams), (std::vector<Resolution>{
{.width = 320, .height = 180},
}));
}
TEST(EncoderStreamFactory, SimulcastRequestedResolutionUnrestricted) {
TEST(EncoderStreamFactory, SimulcastScaleResolutionDownToUnrestricted) {
ExplicitKeyValueConfig field_trials("");
VideoEncoderConfig encoder_config;
encoder_config.number_of_streams = 3;
encoder_config.simulcast_layers.resize(3);
encoder_config.simulcast_layers[0].requested_resolution = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].requested_resolution = {.width = 1280,
.height = 720};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].scale_resolution_down_to = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
auto streams = CreateEncoderStreams(
field_trials, {.width = 1280, .height = 720}, encoder_config);
std::vector<Resolution> stream_resolutions = GetStreamResolutions(streams);
@ -136,7 +136,7 @@ TEST(EncoderStreamFactory, SimulcastRequestedResolutionUnrestricted) {
EXPECT_EQ(stream_resolutions[2], (Resolution{.width = 1280, .height = 720}));
}
TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith360pRestriction) {
TEST(EncoderStreamFactory, SimulcastScaleResolutionDownToWith360pRestriction) {
ExplicitKeyValueConfig field_trials("");
VideoSourceRestrictions restrictions(
/* max_pixels_per_frame= */ (640 * 360),
@ -145,12 +145,12 @@ TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith360pRestriction) {
VideoEncoderConfig encoder_config;
encoder_config.number_of_streams = 3;
encoder_config.simulcast_layers.resize(3);
encoder_config.simulcast_layers[0].requested_resolution = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].requested_resolution = {.width = 1280,
.height = 720};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].scale_resolution_down_to = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
auto streams =
CreateEncoderStreams(field_trials, {.width = 1280, .height = 720},
encoder_config, restrictions);
@ -161,7 +161,7 @@ TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith360pRestriction) {
EXPECT_EQ(stream_resolutions[1], (Resolution{.width = 640, .height = 360}));
}
TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith90pRestriction) {
TEST(EncoderStreamFactory, SimulcastScaleResolutionDownToWith90pRestriction) {
ExplicitKeyValueConfig field_trials("");
VideoSourceRestrictions restrictions(
/* max_pixels_per_frame= */ (160 * 90),
@ -170,12 +170,12 @@ TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith90pRestriction) {
VideoEncoderConfig encoder_config;
encoder_config.number_of_streams = 3;
encoder_config.simulcast_layers.resize(3);
encoder_config.simulcast_layers[0].requested_resolution = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].requested_resolution = {.width = 1280,
.height = 720};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[1].scale_resolution_down_to = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].scale_resolution_down_to = {.width = 1280,
.height = 720};
auto streams =
CreateEncoderStreams(field_trials, {.width = 1280, .height = 720},
encoder_config, restrictions);
@ -186,7 +186,8 @@ TEST(EncoderStreamFactory, SimulcastRequestedResolutionWith90pRestriction) {
EXPECT_EQ(stream_resolutions[0], (Resolution{.width = 160, .height = 90}));
}
TEST(EncoderStreamFactory, ReverseSimulcastRequestedResolutionWithRestriction) {
TEST(EncoderStreamFactory,
ReverseSimulcastScaleResolutionDownToWithRestriction) {
ExplicitKeyValueConfig field_trials("");
VideoSourceRestrictions restrictions(
/* max_pixels_per_frame= */ (640 * 360),
@ -196,12 +197,12 @@ TEST(EncoderStreamFactory, ReverseSimulcastRequestedResolutionWithRestriction) {
encoder_config.number_of_streams = 3;
encoder_config.simulcast_layers.resize(3);
// 720p, 360p, 180p (instead of the usual 180p, 360p, 720p).
encoder_config.simulcast_layers[0].requested_resolution = {.width = 1280,
.height = 720};
encoder_config.simulcast_layers[1].requested_resolution = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].requested_resolution = {.width = 320,
.height = 180};
encoder_config.simulcast_layers[0].scale_resolution_down_to = {.width = 1280,
.height = 720};
encoder_config.simulcast_layers[1].scale_resolution_down_to = {.width = 640,
.height = 360};
encoder_config.simulcast_layers[2].scale_resolution_down_to = {.width = 320,
.height = 180};
auto streams =
CreateEncoderStreams(field_trials, {.width = 1280, .height = 720},
encoder_config, restrictions);

View File

@ -88,9 +88,9 @@ std::string VideoEncoderConfig::ToString() const {
return ss.str();
}
bool VideoEncoderConfig::HasRequestedResolution() const {
bool VideoEncoderConfig::HasScaleResolutionDownTo() const {
for (const VideoStream& simulcast_layer : simulcast_layers) {
if (simulcast_layer.requested_resolution.has_value()) {
if (simulcast_layer.scale_resolution_down_to.has_value()) {
return true;
}
}

View File

@ -36,7 +36,7 @@ struct VideoStream {
// Width/Height in pixels.
// This is the actual width and height used to configure encoder,
// which might be less than `requested_resolution` due to adaptation
// which might be less than `scale_resolution_down_to` due to adaptation
// or due to the source providing smaller frames than requested.
size_t width;
size_t height;
@ -75,14 +75,14 @@ struct VideoStream {
// An optional user supplied max_frame_resolution
// than can be set independently of (adapted) VideoSource.
// This value is set from RtpEncodingParameters::requested_resolution
// This value is set from RtpEncodingParameters::scale_resolution_down_to
// (i.e. used for signaling app-level settings).
//
// The actual encode resolution is in `width` and `height`,
// which can be lower than requested_resolution,
// which can be lower than scale_resolution_down_to,
// e.g. if source only provides lower resolution or
// if resource adaptation is active.
std::optional<Resolution> requested_resolution;
std::optional<Resolution> scale_resolution_down_to;
};
class VideoEncoderConfig {
@ -166,7 +166,7 @@ class VideoEncoderConfig {
~VideoEncoderConfig();
std::string ToString() const;
bool HasRequestedResolution() const;
bool HasScaleResolutionDownTo() const;
// TODO(bugs.webrtc.org/6883): Consolidate on one of these.
VideoCodecType codec_type;

View File

@ -105,9 +105,9 @@ bool VideoSourceSinkController::active() const {
}
std::optional<rtc::VideoSinkWants::FrameSize>
VideoSourceSinkController::requested_resolution() const {
VideoSourceSinkController::scale_resolution_down_to() const {
RTC_DCHECK_RUN_ON(&sequence_checker_);
return requested_resolution_;
return scale_resolution_down_to_;
}
void VideoSourceSinkController::SetRestrictions(
@ -150,10 +150,10 @@ void VideoSourceSinkController::SetActive(bool active) {
active_ = active;
}
void VideoSourceSinkController::SetRequestedResolution(
std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) {
void VideoSourceSinkController::SetScaleResolutionDownTo(
std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
requested_resolution_ = std::move(requested_resolution);
scale_resolution_down_to_ = std::move(scale_resolution_down_to);
}
// RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_)
@ -186,7 +186,7 @@ rtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants()
: std::numeric_limits<int>::max());
wants.resolutions = resolutions_;
wants.is_active = active_;
wants.requested_resolution = requested_resolution_;
wants.requested_resolution = scale_resolution_down_to_;
return wants;
}

View File

@ -52,7 +52,8 @@ class VideoSourceSinkController {
int resolution_alignment() const;
const std::vector<rtc::VideoSinkWants::FrameSize>& resolutions() const;
bool active() const;
std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution() const;
std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to()
const;
// Updates the settings stored internally. In order for these settings to be
// applied to the sink, PushSourceSinkSettings() must subsequently be called.
@ -64,8 +65,8 @@ class VideoSourceSinkController {
void SetResolutionAlignment(int resolution_alignment);
void SetResolutions(std::vector<rtc::VideoSinkWants::FrameSize> resolutions);
void SetActive(bool active);
void SetRequestedResolution(
std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution);
void SetScaleResolutionDownTo(
std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to);
private:
rtc::VideoSinkWants CurrentSettingsToSinkWants() const
@ -93,7 +94,7 @@ class VideoSourceSinkController {
std::vector<rtc::VideoSinkWants::FrameSize> resolutions_
RTC_GUARDED_BY(&sequence_checker_);
bool active_ RTC_GUARDED_BY(&sequence_checker_) = true;
std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution_
std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to_
RTC_GUARDED_BY(&sequence_checker_);
};

View File

@ -62,7 +62,7 @@ TEST(VideoSourceSinkControllerTest, UnconstrainedByDefault) {
EXPECT_FALSE(controller.pixels_per_frame_upper_limit().has_value());
EXPECT_FALSE(controller.frame_rate_upper_limit().has_value());
EXPECT_FALSE(controller.rotation_applied());
EXPECT_FALSE(controller.requested_resolution().has_value());
EXPECT_FALSE(controller.scale_resolution_down_to().has_value());
EXPECT_EQ(controller.resolution_alignment(), 1);
EXPECT_CALL(source, AddOrUpdateSink(_, _))
@ -166,12 +166,12 @@ TEST(VideoSourceSinkControllerTest,
controller.RequestRefreshFrame();
}
TEST(VideoSourceSinkControllerTest, RequestedResolutionPropagatesToWants) {
TEST(VideoSourceSinkControllerTest, ScaleResolutionDownToPropagatesToWants) {
MockVideoSinkWithVideoFrame sink;
MockVideoSourceWithVideoFrame source;
VideoSourceSinkController controller(&sink, &source);
controller.SetRequestedResolution(FrameSize(640, 360));
EXPECT_TRUE(controller.requested_resolution().has_value());
controller.SetScaleResolutionDownTo(FrameSize(640, 360));
EXPECT_TRUE(controller.scale_resolution_down_to().has_value());
EXPECT_CALL(source, AddOrUpdateSink(_, _))
.WillOnce([](rtc::VideoSinkInterface<VideoFrame>* sink,

View File

@ -872,38 +872,40 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
RTC_DCHECK_RUN_ON(worker_queue_);
// Inform source about max configured framerate,
// requested_resolution and which layers are active.
// scale_resolution_down_to and which layers are active.
int max_framerate = -1;
// Is any layer active.
bool active = false;
// The max requested_resolution.
std::optional<rtc::VideoSinkWants::FrameSize> requested_resolution;
// The max scale_resolution_down_to.
std::optional<rtc::VideoSinkWants::FrameSize> scale_resolution_down_to;
for (const auto& stream : config.simulcast_layers) {
active |= stream.active;
if (stream.active) {
max_framerate = std::max(stream.max_framerate, max_framerate);
}
// Note: we propagate the highest requested_resolution regardless
// Note: we propagate the highest scale_resolution_down_to regardless
// if layer is active or not.
if (stream.requested_resolution) {
if (!requested_resolution) {
requested_resolution.emplace(stream.requested_resolution->width,
stream.requested_resolution->height);
if (stream.scale_resolution_down_to) {
if (!scale_resolution_down_to) {
scale_resolution_down_to.emplace(
stream.scale_resolution_down_to->width,
stream.scale_resolution_down_to->height);
} else {
requested_resolution.emplace(
std::max(stream.requested_resolution->width,
requested_resolution->width),
std::max(stream.requested_resolution->height,
requested_resolution->height));
scale_resolution_down_to.emplace(
std::max(stream.scale_resolution_down_to->width,
scale_resolution_down_to->width),
std::max(stream.scale_resolution_down_to->height,
scale_resolution_down_to->height));
}
}
}
if (requested_resolution !=
video_source_sink_controller_.requested_resolution() ||
if (scale_resolution_down_to !=
video_source_sink_controller_.scale_resolution_down_to() ||
active != video_source_sink_controller_.active() ||
max_framerate !=
video_source_sink_controller_.frame_rate_upper_limit().value_or(-1)) {
video_source_sink_controller_.SetRequestedResolution(requested_resolution);
video_source_sink_controller_.SetScaleResolutionDownTo(
scale_resolution_down_to);
if (max_framerate >= 0) {
video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate);
} else {
@ -2412,12 +2414,12 @@ void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
// so that ownership on restrictions/wants is kept on &encoder_queue_
latest_restrictions_ = restrictions;
// When the `requested_resolution` API is used, we need to reconfigure any
// When the `scale_resolution_down_to` API is used, we need to reconfigure any
// time the restricted resolution is updated. When that API isn't used, the
// encoder settings are relative to the frame size and reconfiguration happens
// automatically on new frame size and we don't need to reconfigure here.
if (encoder_ && max_pixels_updated &&
encoder_config_.HasRequestedResolution()) {
encoder_config_.HasScaleResolutionDownTo()) {
// The encoder will be reconfigured on the next frame.
pending_encoder_reconfiguration_ = true;
}

View File

@ -2588,7 +2588,7 @@ TEST_F(VideoStreamEncoderTest, FrameRateLimitCanBeReset) {
}
TEST_F(VideoStreamEncoderTest, RequestInSinkWantsBeforeFirstFrame) {
// Use a real video stream factory or else `requested_resolution` is not
// Use a real video stream factory or else `scale_resolution_down_to` is not
// applied correctly.
video_encoder_config_.video_stream_factory = nullptr;
ConfigureEncoder(video_encoder_config_.Copy());
@ -2596,7 +2596,7 @@ TEST_F(VideoStreamEncoderTest, RequestInSinkWantsBeforeFirstFrame) {
kTargetBitrate, kTargetBitrate, kTargetBitrate, 0, 0, 0);
ASSERT_THAT(video_encoder_config_.simulcast_layers, SizeIs(1));
video_encoder_config_.simulcast_layers[0].requested_resolution.emplace(
video_encoder_config_.simulcast_layers[0].scale_resolution_down_to.emplace(
Resolution({.width = 320, .height = 160}));
video_stream_encoder_->ConfigureEncoder(video_encoder_config_.Copy(),
@ -2605,8 +2605,10 @@ TEST_F(VideoStreamEncoderTest, RequestInSinkWantsBeforeFirstFrame) {
EXPECT_EQ(video_source_.sink_wants().requested_resolution,
rtc::VideoSinkWants::FrameSize(320, 160));
video_encoder_config_.simulcast_layers[0].requested_resolution->height = 320;
video_encoder_config_.simulcast_layers[0].requested_resolution->width = 640;
video_encoder_config_.simulcast_layers[0].scale_resolution_down_to->height =
320;
video_encoder_config_.simulcast_layers[0].scale_resolution_down_to->width =
640;
video_stream_encoder_->ConfigureEncoder(video_encoder_config_.Copy(),
kMaxPayloadLength);
@ -2617,7 +2619,7 @@ TEST_F(VideoStreamEncoderTest, RequestInSinkWantsBeforeFirstFrame) {
}
TEST_F(VideoStreamEncoderTest, RequestInWrongAspectRatioWithAdapter) {
// Use a real video stream factory or else `requested_resolution` is not
// Use a real video stream factory or else `scale_resolution_down_to` is not
// applied correctly.
video_encoder_config_.video_stream_factory = nullptr;
ConfigureEncoder(video_encoder_config_.Copy());
@ -2631,7 +2633,7 @@ TEST_F(VideoStreamEncoderTest, RequestInWrongAspectRatioWithAdapter) {
&source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
ASSERT_THAT(video_encoder_config_.simulcast_layers, SizeIs(1));
video_encoder_config_.simulcast_layers[0].requested_resolution = {
video_encoder_config_.simulcast_layers[0].scale_resolution_down_to = {
.width = 30, .height = 30};
video_stream_encoder_->ConfigureEncoder(video_encoder_config_.Copy(),
kMaxPayloadLength);
@ -6314,8 +6316,8 @@ TEST_F(VideoStreamEncoderTest,
enum class FrameResolutionChangeMethod {
MODIFY_SOURCE,
MODIFY_REQUESTED_RESOLUTION,
MODIFY_SCALE_RESOLUTION_BY,
MODIFY_SCALE_RESOLUTION_DOWN_TO,
MODIFY_SCALE_RESOLUTION_DOWN_BY,
};
class VideoStreamEncoderInitialFrameDropperTest
: public VideoStreamEncoderTest,
@ -6329,12 +6331,12 @@ class VideoStreamEncoderInitialFrameDropperTest
switch (frame_resolution_change_method_) {
case FrameResolutionChangeMethod::MODIFY_SOURCE:
break;
case FrameResolutionChangeMethod::MODIFY_REQUESTED_RESOLUTION:
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_TO:
video_encoder_config_.video_stream_factory = nullptr;
captureWidth = kWidth;
captureHeight = kHeight;
break;
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_BY:
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_BY:
captureWidth = kWidth;
captureHeight = kHeight;
break;
@ -6347,14 +6349,15 @@ class VideoStreamEncoderInitialFrameDropperTest
captureWidth = width;
captureHeight = height;
break;
case FrameResolutionChangeMethod::MODIFY_REQUESTED_RESOLUTION:
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_TO:
ASSERT_THAT(video_encoder_config_.simulcast_layers, SizeIs(1));
video_encoder_config_.simulcast_layers[0].requested_resolution.emplace(
Resolution({.width = width, .height = height}));
video_encoder_config_.simulcast_layers[0]
.scale_resolution_down_to.emplace(
Resolution({.width = width, .height = height}));
video_stream_encoder_->ConfigureEncoder(video_encoder_config_.Copy(),
kMaxPayloadLength);
break;
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_BY:
case FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_BY:
ASSERT_THAT(video_encoder_config_.simulcast_layers, SizeIs(1));
double scale_height =
static_cast<double>(kHeight) / static_cast<double>(height);
@ -6381,9 +6384,10 @@ class VideoStreamEncoderInitialFrameDropperTest
INSTANTIATE_TEST_SUITE_P(
VideoStreamEncoderInitialFrameDropperTest,
VideoStreamEncoderInitialFrameDropperTest,
::testing::Values(FrameResolutionChangeMethod::MODIFY_SOURCE,
FrameResolutionChangeMethod::MODIFY_REQUESTED_RESOLUTION,
FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_BY));
::testing::Values(
FrameResolutionChangeMethod::MODIFY_SOURCE,
FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_TO,
FrameResolutionChangeMethod::MODIFY_SCALE_RESOLUTION_DOWN_BY));
TEST_P(VideoStreamEncoderInitialFrameDropperTest,
InitialFrameDropActivatesWhenResolutionIncreases) {
@ -6431,7 +6435,7 @@ TEST_P(VideoStreamEncoderInitialFrameDropperTest,
int timestamp = 1;
// By using the `requested_resolution` API, ReconfigureEncoder() gets
// By using the `scale_resolution_down_to` API, ReconfigureEncoder() gets
// triggered from VideoStreamEncoder::OnVideoSourceRestrictionsUpdated().
SetEncoderFrameSize(kWidth, kHeight);