pc: Add asynchronous RtpSender::SetParameters() call

As the synchronous version only posts a task to recreate the encoder
later, it is not possible to catch errors and state changes that
could appear then.
The asynchronous version of SetParameters() aims to solve this by
providing a callback to wait for the completion of the encoder
reconfiguration, allowing any error to be propagate and subsequent
getParameters() call to have up to date information.

Bug: webrtc:11607
Change-Id: I5548e75aa14a97f8d9c0c94df1e72e9cd40887b2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278420
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38627}
This commit is contained in:
Florent Castelli
2022-10-18 17:05:16 +02:00
committed by WebRTC LUCI CQ
parent 7d8d64323c
commit acabb3641b
43 changed files with 567 additions and 95 deletions

View File

@ -855,6 +855,20 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParameters) {
DestroyAudioRtpSender();
}
TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersAsync) {
CreateAudioRtpSender();
RtpParameters params = audio_rtp_sender_->GetParameters();
EXPECT_EQ(1u, params.encodings.size());
absl::optional<webrtc::RTCError> result;
audio_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
DestroyAudioRtpSender();
}
TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
audio_rtp_sender_ =
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
@ -865,8 +879,34 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
params = audio_rtp_sender_->GetParameters();
EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
DestroyAudioRtpSender();
}
TEST_F(RtpSenderReceiverTest,
AudioSenderCanSetParametersAsyncBeforeNegotiation) {
audio_rtp_sender_ =
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
absl::optional<webrtc::RTCError> result;
RtpParameters params = audio_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size());
params.encodings[0].max_bitrate_bps = 90000;
audio_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
params = audio_rtp_sender_->GetParameters();
EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
audio_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
DestroyAudioRtpSender();
}
@ -941,6 +981,25 @@ TEST_F(RtpSenderReceiverTest,
DestroyAudioRtpSender();
}
TEST_F(RtpSenderReceiverTest,
AudioSenderSetParametersAsyncInvalidatesTransactionId) {
CreateAudioRtpSender();
RtpParameters params = audio_rtp_sender_->GetParameters();
EXPECT_EQ(1u, params.encodings.size());
absl::optional<webrtc::RTCError> result;
audio_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
audio_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_EQ(RTCErrorType::INVALID_STATE, result->type());
DestroyAudioRtpSender();
}
TEST_F(RtpSenderReceiverTest, AudioSenderDetectTransactionIdModification) {
CreateAudioRtpSender();
@ -1047,6 +1106,20 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParameters) {
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersAsync) {
CreateVideoRtpSender();
RtpParameters params = video_rtp_sender_->GetParameters();
EXPECT_EQ(1u, params.encodings.size());
absl::optional<webrtc::RTCError> result;
video_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
video_rtp_sender_ =
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
@ -1063,6 +1136,30 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest,
VideoSenderCanSetParametersAsyncBeforeNegotiation) {
video_rtp_sender_ =
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
absl::optional<webrtc::RTCError> result;
RtpParameters params = video_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size());
params.encodings[0].max_bitrate_bps = 90000;
video_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
params = video_rtp_sender_->GetParameters();
EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
video_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) {
AddVideoTrack(false);
@ -1215,6 +1312,25 @@ TEST_F(RtpSenderReceiverTest,
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest,
VideoSenderSetParametersAsyncInvalidatesTransactionId) {
CreateVideoRtpSender();
RtpParameters params = video_rtp_sender_->GetParameters();
EXPECT_EQ(1u, params.encodings.size());
absl::optional<webrtc::RTCError> result;
video_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_TRUE(result->ok());
video_rtp_sender_->SetParametersAsync(
params, [&result](webrtc::RTCError error) { result = error; });
run_loop_.Flush();
EXPECT_EQ(RTCErrorType::INVALID_STATE, result->type());
DestroyVideoRtpSender();
}
TEST_F(RtpSenderReceiverTest, VideoSenderDetectTransactionIdModification) {
CreateVideoRtpSender();
@ -1745,9 +1861,9 @@ TEST_F(RtpSenderReceiverTest,
RtpParameters parameters = video_rtp_sender_->GetParameters();
RtpParameters new_parameters = video_rtp_sender_->GetParametersInternal();
new_parameters.encodings[0].active = false;
video_rtp_sender_->SetParametersInternal(new_parameters);
video_rtp_sender_->SetParametersInternal(new_parameters, nullptr, true);
new_parameters.encodings[0].active = true;
video_rtp_sender_->SetParametersInternal(new_parameters);
video_rtp_sender_->SetParametersInternal(new_parameters, nullptr, true);
parameters.encodings[0].active = false;
EXPECT_TRUE(video_rtp_sender_->SetParameters(parameters).ok());
}