Improve tests for reconfiguring encoder from 4:2:1 to non-power of two.
More test coverage for previously fixed bug https://crbug.com/webrtc/369654168. Two tests are added: 1. LibvpxVp9Encoder unit test that 4:2:1 720p can be reconfigured to singlecast (which is what happens for encodings[0] in the bug). 2. Integration test that 4:2:1 720p can change to 180p,360p,540p. This is the exact same test as was added in [1] but using requested_resolution instead of scale_resolution_down_by. [1] https://webrtc-review.googlesource.com/c/src/+/363941 Bug: webrtc:369654168 Change-Id: I83456b9254c1c6f647586d340d0fe5864b5515c6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/364200 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Auto-Submit: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43185}
This commit is contained in:
parent
5680d8199a
commit
1accaf91b5
@ -490,6 +490,78 @@ TEST_F(TestVp9Impl, EncoderAcceptsSvcLikeSimulcast) {
|
||||
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||
}
|
||||
|
||||
TEST_F(TestVp9Impl, SvcSimulcastThenSinglecastWithCorrectSimulcastIndex) {
|
||||
const int kTargetBitrate = 1200;
|
||||
const int kMaxFramerate = 30;
|
||||
|
||||
// Configure 720p 4:2:1
|
||||
codec_settings_.VP9()->numberOfTemporalLayers = 1;
|
||||
codec_settings_.VP9()->numberOfSpatialLayers = 1;
|
||||
codec_settings_.numberOfSimulcastStreams = 3;
|
||||
codec_settings_.width = 1280;
|
||||
codec_settings_.height = 720;
|
||||
codec_settings_.simulcastStream[0].width = codec_settings_.width / 4;
|
||||
codec_settings_.simulcastStream[0].height = codec_settings_.height / 4;
|
||||
codec_settings_.simulcastStream[0].maxFramerate = kMaxFramerate;
|
||||
codec_settings_.simulcastStream[0].minBitrate = kTargetBitrate / 2;
|
||||
codec_settings_.simulcastStream[0].maxBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[0].targetBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[0].active = true;
|
||||
codec_settings_.simulcastStream[1].width = codec_settings_.width / 2;
|
||||
codec_settings_.simulcastStream[1].height = codec_settings_.height / 2;
|
||||
codec_settings_.simulcastStream[1].maxFramerate = kMaxFramerate;
|
||||
codec_settings_.simulcastStream[1].minBitrate = kTargetBitrate / 2;
|
||||
codec_settings_.simulcastStream[1].maxBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[1].targetBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[1].active = true;
|
||||
codec_settings_.simulcastStream[2].width = codec_settings_.width;
|
||||
codec_settings_.simulcastStream[2].height = codec_settings_.height;
|
||||
codec_settings_.simulcastStream[2].maxFramerate = kMaxFramerate;
|
||||
codec_settings_.simulcastStream[2].minBitrate = kTargetBitrate / 2;
|
||||
codec_settings_.simulcastStream[2].maxBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[2].targetBitrate = kTargetBitrate;
|
||||
codec_settings_.simulcastStream[2].active = true;
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||
|
||||
// Bitrate must be set for all layers to be produced.
|
||||
VideoBitrateAllocation bitrate_allocation;
|
||||
bitrate_allocation.SetBitrate(0, 0, kTargetBitrate * 1000);
|
||||
bitrate_allocation.SetBitrate(1, 0, kTargetBitrate * 1000);
|
||||
bitrate_allocation.SetBitrate(2, 0, kTargetBitrate * 1000);
|
||||
encoder_->SetRates(
|
||||
VideoEncoder::RateControlParameters(bitrate_allocation, kMaxFramerate));
|
||||
|
||||
// Encode a frame and confirm simulcast index is set for all layers.
|
||||
{
|
||||
SetWaitForEncodedFramesThreshold(3);
|
||||
std::vector<EncodedImage> encoded_frame;
|
||||
std::vector<CodecSpecificInfo> codec_specific_info;
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder_->Encode(NextInputFrame(), nullptr));
|
||||
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
|
||||
EXPECT_EQ(encoded_frame[0].SimulcastIndex().value_or(-1), 0);
|
||||
EXPECT_EQ(encoded_frame[1].SimulcastIndex().value_or(-1), 1);
|
||||
EXPECT_EQ(encoded_frame[2].SimulcastIndex().value_or(-1), 2);
|
||||
}
|
||||
|
||||
// Reconfigure 720p singlecast.
|
||||
codec_settings_.numberOfSimulcastStreams = 1;
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||
|
||||
// Encode a frame and confirm simulcast index is not set.
|
||||
{
|
||||
SetWaitForEncodedFramesThreshold(1);
|
||||
std::vector<EncodedImage> encoded_frame;
|
||||
std::vector<CodecSpecificInfo> codec_specific_info;
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder_->Encode(NextInputFrame(), nullptr));
|
||||
ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
|
||||
EXPECT_FALSE(encoded_frame[0].SimulcastIndex().has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
|
||||
// Configure encoder to produce N spatial layers. Encode frames of layer 0
|
||||
// then enable layer 1 and encode more frames and so on until layer N-1.
|
||||
|
||||
@ -2480,9 +2480,91 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
|
||||
Resolution({.width = 960, .height = 540}),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
|
||||
// Ensure 180p frames continue to be encoded post reconfiguration.
|
||||
int frames_encoded = EncodedFrames(local_pc_wrapper, "q");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "q") > frames_encoded,
|
||||
// Ensure frames continue to be encoded post reconfiguration.
|
||||
int q_frames_encoded = EncodedFrames(local_pc_wrapper, "q");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "q") > q_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
int h_frames_encoded = EncodedFrames(local_pc_wrapper, "h");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "h") > h_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
int f_frames_encoded = EncodedFrames(local_pc_wrapper, "f");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "f") > f_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
}
|
||||
|
||||
// Simulcast starting in 720p 4:2:1 then changing to {180p, 360p, 540p} using
|
||||
// the `requested_resolution` API.
|
||||
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
|
||||
SimulcastRequestedResolutionNoLongerPowerOfTwo) {
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
|
||||
if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
|
||||
return;
|
||||
}
|
||||
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
|
||||
ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
|
||||
|
||||
std::vector<cricket::SimulcastLayer> layers =
|
||||
CreateLayers({"q", "h", "f"}, /*active=*/true);
|
||||
rtc::scoped_refptr<RtpTransceiverInterface> transceiver =
|
||||
AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
|
||||
layers);
|
||||
std::vector<RtpCodecCapability> codecs =
|
||||
GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
|
||||
transceiver->SetCodecPreferences(codecs);
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
|
||||
|
||||
// Configure {180p, 360p, 720p}.
|
||||
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[1].scalability_mode = "L1T1";
|
||||
parameters.encodings[1].requested_resolution = {.width = 640, .height = 360};
|
||||
parameters.encodings[2].scalability_mode = "L1T1";
|
||||
parameters.encodings[2].requested_resolution = {.width = 1280, .height = 720};
|
||||
sender->SetParameters(parameters);
|
||||
|
||||
NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
|
||||
local_pc_wrapper->WaitForConnection();
|
||||
remote_pc_wrapper->WaitForConnection();
|
||||
|
||||
// Wait for media to flow on all layers.
|
||||
// Needed repro step of https://crbug.com/webrtc/369654168: When the same
|
||||
// LibvpxVp9Encoder instance was used to first produce simulcast and later for
|
||||
// a single encoding, the previously used simulcast index (= 2) would still be
|
||||
// set when producing 180p since non-simulcast config does not reset this,
|
||||
// resulting in the 180p encoding freezing and the 540p encoding having double
|
||||
// frame rate and toggling between 180p and 540p in resolution.
|
||||
ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
|
||||
// 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};
|
||||
sender->SetParameters(parameters);
|
||||
|
||||
// Wait for the new resolutions to be produced.
|
||||
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper, "q") ==
|
||||
Resolution({.width = 320, .height = 180}),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper, "h") ==
|
||||
Resolution({.width = 640, .height = 360}),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
ASSERT_TRUE_WAIT(GetEncodingResolution(local_pc_wrapper, "f") ==
|
||||
Resolution({.width = 960, .height = 540}),
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
|
||||
// Ensure frames continue to be encoded post reconfiguration.
|
||||
int q_frames_encoded = EncodedFrames(local_pc_wrapper, "q");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "q") > q_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
int h_frames_encoded = EncodedFrames(local_pc_wrapper, "h");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "h") > h_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
int f_frames_encoded = EncodedFrames(local_pc_wrapper, "f");
|
||||
ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "f") > f_frames_encoded,
|
||||
kLongTimeoutForRampingUp.ms());
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user