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:
parent
115aea4774
commit
e8c97c0d09
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 "
|
||||
|
||||
@ -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_ = {};
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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},
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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) ==
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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_);
|
||||
};
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user