Update when/how requested_resolution throws for invalid parameters.
This CL makes `requested_resolution`, which is the C++ name for what the spec calls scaleResolutionDownTo, align with the latest PR[1]. The PR says to ignore scaleResolutionDownBy when scaleResolutionDownTo is specified as to be backwards compatible with scaleResolutionDownBy's default scaling factors (e.g. 4:2:1). Ignoring is different than what the code does today which is to throw an InvalidModificationError. We don't want to throw or else get+setParameters() would throw by default due to 4:2:1 defaults so the app would have to remember to delete these attributes every time even though it never specified them (Chrome has a bug here but fixing that would expose this problem, see https://crbug.com/344943229). [1] https://github.com/w3c/webrtc-extensions/pull/221 Bug: none Change-Id: I21165c9b9f9ee7259d88b89f9ae58b862ea4521e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362260 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43002}
This commit is contained in:
parent
1bd331f102
commit
254bd32188
@ -145,6 +145,7 @@ webrtc::RTCError CheckRtpParametersValues(
|
||||
const webrtc::FieldTrialsView& field_trials) {
|
||||
using webrtc::RTCErrorType;
|
||||
|
||||
bool has_requested_resolution = 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,
|
||||
@ -183,11 +184,8 @@ webrtc::RTCError CheckRtpParametersValues(
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp_parameters.encodings[i].requested_resolution &&
|
||||
rtp_parameters.encodings[i].scale_resolution_down_by) {
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
|
||||
"Attempted to set scale_resolution_down_by and "
|
||||
"requested_resolution simultaniously.");
|
||||
if (rtp_parameters.encodings[i].requested_resolution.has_value()) {
|
||||
has_requested_resolution = true;
|
||||
}
|
||||
|
||||
if (!field_trials.IsEnabled("WebRTC-MixedCodecSimulcast")) {
|
||||
@ -200,6 +198,16 @@ webrtc::RTCError CheckRtpParametersValues(
|
||||
}
|
||||
}
|
||||
|
||||
if (has_requested_resolution &&
|
||||
absl::c_any_of(rtp_parameters.encodings,
|
||||
[](const webrtc::RtpEncodingParameters& encoding) {
|
||||
return !encoding.requested_resolution.has_value();
|
||||
})) {
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
|
||||
"If a resolution is specified on any encoding then "
|
||||
"it must be specified on all encodings.");
|
||||
}
|
||||
|
||||
return CheckScalabilityModeValues(rtp_parameters, send_codecs, send_codec);
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +187,24 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test {
|
||||
local_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate);
|
||||
}
|
||||
|
||||
// Negotiate without any tweaks (does not work for simulcast loopback).
|
||||
void Negotiate(
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper,
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper) {
|
||||
std::unique_ptr<SessionDescriptionInterface> offer =
|
||||
CreateOffer(local_pc_wrapper);
|
||||
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p1 =
|
||||
SetLocalDescription(local_pc_wrapper, offer.get());
|
||||
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p2 =
|
||||
SetRemoteDescription(remote_pc_wrapper, offer.get());
|
||||
EXPECT_TRUE(Await({p1, p2}));
|
||||
std::unique_ptr<SessionDescriptionInterface> answer =
|
||||
CreateAnswer(remote_pc_wrapper);
|
||||
p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
|
||||
p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
|
||||
EXPECT_TRUE(Await({p1, p2}));
|
||||
}
|
||||
|
||||
void NegotiateWithSimulcastTweaks(
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper,
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper) {
|
||||
@ -2098,6 +2116,86 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
|
||||
ASSERT_TRUE(transceiver_or_error.ok());
|
||||
}
|
||||
|
||||
TEST_F(PeerConnectionEncodingsIntegrationTest,
|
||||
RequestedResolutionParameterChecking) {
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper = CreatePc();
|
||||
|
||||
// AddTransceiver: If `requested_resolution` is specified on any encoding it
|
||||
// must be specified on all encodings.
|
||||
RtpTransceiverInit init;
|
||||
RtpEncodingParameters encoding;
|
||||
encoding.requested_resolution = std::nullopt;
|
||||
init.send_encodings.push_back(encoding);
|
||||
encoding.requested_resolution = {.width = 1280, .height = 720};
|
||||
init.send_encodings.push_back(encoding);
|
||||
auto 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
|
||||
// `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_by = 1.0;
|
||||
init.send_encodings[1].requested_resolution = {.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 encoding it
|
||||
// must be specified on all 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;
|
||||
auto error = sender->SetParameters(parameters);
|
||||
EXPECT_FALSE(error.ok());
|
||||
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
|
||||
|
||||
// SetParameters: Specifying both `requested_resolution` 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_by = 2.0;
|
||||
parameters.encodings[1].requested_resolution = {.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) {
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
|
||||
|
||||
rtc::scoped_refptr<MediaStreamInterface> stream =
|
||||
local_pc_wrapper->GetUserMedia(
|
||||
/*audio=*/false, {}, /*video=*/true, {.width = 640, .height = 360});
|
||||
rtc::scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];
|
||||
|
||||
// Configure contradicting scaling factors (180p vs 360p).
|
||||
RtpTransceiverInit init;
|
||||
RtpEncodingParameters encoding;
|
||||
encoding.scale_resolution_down_by = 2.0;
|
||||
encoding.requested_resolution = {.width = 640, .height = 360};
|
||||
init.send_encodings.push_back(encoding);
|
||||
auto transceiver_or_error =
|
||||
local_pc_wrapper->pc()->AddTransceiver(track, init);
|
||||
|
||||
// Negotiate singlecast.
|
||||
ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
|
||||
Negotiate(local_pc_wrapper, remote_pc_wrapper);
|
||||
|
||||
// Confirm 640x360 is sent.
|
||||
// If `scale_resolution_down_by` was not ignored we would never ramp up to
|
||||
// full resolution.
|
||||
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper) ==
|
||||
(Resolution{.width = 640, .height = 360}),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
}
|
||||
|
||||
// Tests that use the standard path (specifying both `scalability_mode` and
|
||||
// `scale_resolution_down_by` or `requested_resolution`) should pass for all
|
||||
// codecs.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user