Moving functionality from VideoQualityTest to CallTest
Bug: webrtc:9510
Change-Id: Ie1cd34693e08d2c4b8fd79470573a6069564ded5
Reviewed-on: https://webrtc-review.googlesource.com/88182
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23969}
diff --git a/test/call_test.cc b/test/call_test.cc
index 641f03c..99bedaa 100644
--- a/test/call_test.cc
+++ b/test/call_test.cc
@@ -47,15 +47,13 @@
num_flexfec_streams_(0),
audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()),
audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()),
- task_queue_("CallTestTaskQueue"),
- video_send_config_(nullptr),
- video_send_stream_(nullptr) {}
+ task_queue_("CallTestTaskQueue") {}
CallTest::~CallTest() {
task_queue_.SendTask([this]() {
fake_send_audio_device_ = nullptr;
fake_recv_audio_device_ = nullptr;
- frame_generator_capturer_.reset();
+ video_capturers_.clear();
});
}
@@ -140,7 +138,7 @@
}
if (num_video_streams_ > 0) {
CreateVideoStreams();
- test->OnVideoStreamsCreated(video_send_stream_, video_receive_streams_);
+ test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
}
if (num_audio_streams_ > 0) {
CreateAudioStreams();
@@ -153,7 +151,7 @@
int frame_rate = kDefaultFramerate;
test->ModifyVideoCaptureStartResolution(&width, &height, &frame_rate);
CreateFrameGeneratorCapturer(frame_rate, width, height);
- test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
+ test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_);
}
Start();
@@ -218,8 +216,11 @@
kTransportSequenceNumberExtensionId));
video_config->rtp.extensions.push_back(RtpExtension(
RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
- FillEncoderConfiguration(kVideoCodecGeneric, num_video_streams,
- &video_encoder_config_);
+ if (video_encoder_configs_.empty()) {
+ video_encoder_configs_.emplace_back();
+ FillEncoderConfiguration(kVideoCodecGeneric, num_video_streams,
+ &video_encoder_configs_.back());
+ }
for (size_t i = 0; i < num_video_streams; ++i)
video_config->rtp.ssrcs.push_back(kVideoSendSsrcs[num_used_ssrcs + i]);
@@ -233,98 +234,184 @@
RTC_DCHECK_LE(num_audio_streams, 1);
RTC_DCHECK_LE(num_flexfec_streams, 1);
if (num_audio_streams > 0) {
- audio_send_config_ = AudioSendStream::Config(send_transport);
- audio_send_config_.rtp.ssrc = kAudioSendSsrc;
- audio_send_config_.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
+ AudioSendStream::Config audio_send_config(send_transport);
+ audio_send_config.rtp.ssrc = kAudioSendSsrc;
+ audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
kAudioSendPayloadType, {"opus", 48000, 2, {{"stereo", "1"}}});
- audio_send_config_.encoder_factory = audio_encoder_factory_;
+ audio_send_config.encoder_factory = audio_encoder_factory_;
+ SetAudioConfig(audio_send_config);
}
// TODO(brandtr): Update this when we support multistream protection.
if (num_flexfec_streams > 0) {
- GetVideoSendConfig()->rtp.flexfec.payload_type = kFlexfecPayloadType;
- GetVideoSendConfig()->rtp.flexfec.ssrc = kFlexfecSendSsrc;
- GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs = {
- kVideoSendSsrcs[0]};
+ SetSendFecConfig({kVideoSendSsrcs[0]});
}
}
+void CallTest::SetAudioConfig(const AudioSendStream::Config& config) {
+ audio_send_config_ = config;
+}
+
+void CallTest::SetSendFecConfig(std::vector<uint32_t> video_send_ssrcs) {
+ GetVideoSendConfig()->rtp.flexfec.payload_type = kFlexfecPayloadType;
+ GetVideoSendConfig()->rtp.flexfec.ssrc = kFlexfecSendSsrc;
+ GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs = video_send_ssrcs;
+}
+
+void CallTest::SetSendUlpFecConfig(VideoSendStream::Config* send_config) {
+ send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
+ send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
+ send_config->rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType;
+}
+
+void CallTest::SetReceiveUlpFecConfig(
+ VideoReceiveStream::Config* receive_config) {
+ receive_config->rtp.red_payload_type = kRedPayloadType;
+ receive_config->rtp.ulpfec_payload_type = kUlpfecPayloadType;
+ receive_config->rtp.rtx_associated_payload_types[kRtxRedPayloadType] =
+ kRedPayloadType;
+}
+
void CallTest::CreateSendConfig(size_t num_video_streams,
size_t num_audio_streams,
size_t num_flexfec_streams,
Transport* send_transport) {
if (num_video_streams > 0) {
- CreateVideoSendConfig(&video_send_config_, num_video_streams, 0,
+ video_send_configs_.clear();
+ video_send_configs_.emplace_back(nullptr);
+ CreateVideoSendConfig(&video_send_configs_.back(), num_video_streams, 0,
send_transport);
}
CreateAudioAndFecSendConfigs(num_audio_streams, num_flexfec_streams,
send_transport);
}
-std::vector<VideoReceiveStream::Config>
-CallTest::CreateMatchingVideoReceiveConfigs(
+void CallTest::CreateMatchingVideoReceiveConfigs(
const VideoSendStream::Config& video_send_config,
Transport* rtcp_send_transport) {
- std::vector<VideoReceiveStream::Config> result;
+ CreateMatchingVideoReceiveConfigs(video_send_config, rtcp_send_transport,
+ true, absl::nullopt, false, 0);
+}
+
+void CallTest::CreateMatchingVideoReceiveConfigs(
+ const VideoSendStream::Config& video_send_config,
+ Transport* rtcp_send_transport,
+ bool send_side_bwe,
+ absl::optional<size_t> decode_sub_stream,
+ bool receiver_reference_time_report,
+ int rtp_history_ms) {
+ AddMatchingVideoReceiveConfigs(
+ &video_receive_configs_, video_send_config, rtcp_send_transport,
+ send_side_bwe, decode_sub_stream, receiver_reference_time_report,
+ rtp_history_ms);
+}
+
+void CallTest::AddMatchingVideoReceiveConfigs(
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ const VideoSendStream::Config& video_send_config,
+ Transport* rtcp_send_transport,
+ bool send_side_bwe,
+ absl::optional<size_t> decode_sub_stream,
+ bool receiver_reference_time_report,
+ int rtp_history_ms) {
RTC_DCHECK(!video_send_config.rtp.ssrcs.empty());
- VideoReceiveStream::Config video_config(rtcp_send_transport);
- video_config.rtp.remb = false;
- video_config.rtp.transport_cc = true;
- video_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
+ VideoReceiveStream::Config default_config(rtcp_send_transport);
+ default_config.rtp.remb = !send_side_bwe;
+ default_config.rtp.transport_cc = send_side_bwe;
+ default_config.rtp.local_ssrc = kReceiverLocalVideoSsrc;
for (const RtpExtension& extension : video_send_config.rtp.extensions)
- video_config.rtp.extensions.push_back(extension);
- video_config.renderer = &fake_renderer_;
+ default_config.rtp.extensions.push_back(extension);
+ default_config.rtp.nack.rtp_history_ms = rtp_history_ms;
+ // Enable RTT calculation so NTP time estimator will work.
+ default_config.rtp.rtcp_xr.receiver_reference_time_report =
+ receiver_reference_time_report;
+ default_config.renderer = &fake_renderer_;
+
for (size_t i = 0; i < video_send_config.rtp.ssrcs.size(); ++i) {
- VideoReceiveStream::Decoder decoder =
- test::CreateMatchingDecoder(video_send_config);
- allocated_decoders_.push_back(
- std::unique_ptr<VideoDecoder>(decoder.decoder));
- video_config.decoders.clear();
- video_config.decoders.push_back(decoder);
- video_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i];
- result.push_back(video_config.Copy());
+ VideoReceiveStream::Config video_recv_config(default_config.Copy());
+ video_recv_config.decoders.clear();
+ if (!video_send_config.rtp.rtx.ssrcs.empty()) {
+ video_recv_config.rtp.rtx_ssrc = video_send_config.rtp.rtx.ssrcs[i];
+ video_recv_config.rtp.rtx_associated_payload_types[kSendRtxPayloadType] =
+ video_send_config.rtp.payload_type;
+ }
+ video_recv_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i];
+ VideoReceiveStream::Decoder decoder;
+
+ // Force fake decoders on non-selected simulcast streams.
+ if (!decode_sub_stream || i == *decode_sub_stream) {
+ decoder = test::CreateMatchingDecoder(video_send_config);
+ } else {
+ decoder.decoder = new test::FakeDecoder();
+ decoder.payload_type = video_send_config.rtp.payload_type;
+ decoder.payload_name = video_send_config.rtp.payload_name;
+ }
+ allocated_decoders_.emplace_back(decoder.decoder);
+ video_recv_config.decoders.push_back(decoder);
+ receive_configs->emplace_back(std::move(video_recv_config));
}
- result[0].rtp.protected_by_flexfec = (num_flexfec_streams_ == 1);
- return result;
}
void CallTest::CreateMatchingAudioAndFecConfigs(
Transport* rtcp_send_transport) {
RTC_DCHECK_GE(1, num_audio_streams_);
if (num_audio_streams_ == 1) {
- AudioReceiveStream::Config audio_config;
- audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
- audio_config.rtcp_send_transport = rtcp_send_transport;
- audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc;
- audio_config.decoder_factory = audio_decoder_factory_;
- audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
- audio_receive_configs_.push_back(audio_config);
+ CreateMatchingAudioConfigs(rtcp_send_transport, "");
}
// TODO(brandtr): Update this when we support multistream protection.
RTC_DCHECK(num_flexfec_streams_ <= 1);
if (num_flexfec_streams_ == 1) {
- FlexfecReceiveStream::Config config(rtcp_send_transport);
- config.payload_type = kFlexfecPayloadType;
- config.remote_ssrc = kFlexfecSendSsrc;
- config.protected_media_ssrcs = {kVideoSendSsrcs[0]};
- config.local_ssrc = kReceiverLocalVideoSsrc;
+ CreateMatchingFecConfig(rtcp_send_transport, *GetVideoSendConfig());
for (const RtpExtension& extension : GetVideoSendConfig()->rtp.extensions)
- config.rtp_header_extensions.push_back(extension);
- flexfec_receive_configs_.push_back(config);
+ GetFlexFecConfig()->rtp_header_extensions.push_back(extension);
}
}
+void CallTest::CreateMatchingAudioConfigs(Transport* transport,
+ std::string sync_group) {
+ audio_receive_configs_.push_back(CreateMatchingAudioConfig(
+ audio_send_config_, audio_decoder_factory_, transport, sync_group));
+}
+
+AudioReceiveStream::Config CallTest::CreateMatchingAudioConfig(
+ const AudioSendStream::Config& send_config,
+ rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+ Transport* transport,
+ std::string sync_group) {
+ AudioReceiveStream::Config audio_config;
+ audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc;
+ audio_config.rtcp_send_transport = transport;
+ audio_config.rtp.remote_ssrc = send_config.rtp.ssrc;
+ audio_config.rtp.transport_cc =
+ send_config.send_codec_spec
+ ? send_config.send_codec_spec->transport_cc_enabled
+ : false;
+ audio_config.rtp.extensions = send_config.rtp.extensions;
+ audio_config.decoder_factory = audio_decoder_factory;
+ audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
+ audio_config.sync_group = sync_group;
+ return audio_config;
+}
+
+void CallTest::CreateMatchingFecConfig(
+ Transport* transport,
+ const VideoSendStream::Config& send_config) {
+ FlexfecReceiveStream::Config config(transport);
+ config.payload_type = send_config.rtp.flexfec.payload_type;
+ config.remote_ssrc = send_config.rtp.flexfec.ssrc;
+ config.protected_media_ssrcs = send_config.rtp.flexfec.protected_media_ssrcs;
+ config.local_ssrc = kReceiverLocalVideoSsrc;
+ if (!video_receive_configs_.empty())
+ video_receive_configs_[0].rtp.protected_by_flexfec = true;
+ flexfec_receive_configs_.push_back(config);
+}
+
void CallTest::CreateMatchingReceiveConfigs(Transport* rtcp_send_transport) {
video_receive_configs_.clear();
allocated_decoders_.clear();
- if (num_video_streams_ > 0) {
- std::vector<VideoReceiveStream::Config> new_configs =
- CreateMatchingVideoReceiveConfigs(*GetVideoSendConfig(),
- rtcp_send_transport);
- for (VideoReceiveStream::Config& config : new_configs) {
- video_receive_configs_.push_back(config.Copy());
- }
+ for (VideoSendStream::Config& video_send_config : video_send_configs_) {
+ CreateMatchingVideoReceiveConfigs(video_send_config, rtcp_send_transport);
}
CreateMatchingAudioAndFecConfigs(rtcp_send_transport);
}
@@ -334,16 +421,26 @@
int framerate,
int width,
int height) {
- frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
- width, height, absl::nullopt, absl::nullopt, framerate * speed, clock));
+ video_sources_.clear();
+ video_capturers_.clear();
+ frame_generator_capturer_ = test::FrameGeneratorCapturer::Create(
+ width, height, absl::nullopt, absl::nullopt, framerate * speed, clock);
+ video_capturers_.emplace_back(
+ std::unique_ptr<FrameGeneratorCapturer>(frame_generator_capturer_));
+ video_sources_.push_back(video_capturers_.back().get());
ConnectVideoSourcesToStreams();
}
void CallTest::CreateFrameGeneratorCapturer(int framerate,
int width,
int height) {
- frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
- width, height, absl::nullopt, absl::nullopt, framerate, clock_));
+ video_sources_.clear();
+ video_capturers_.clear();
+ frame_generator_capturer_ = test::FrameGeneratorCapturer::Create(
+ width, height, absl::nullopt, absl::nullopt, framerate, clock_);
+ video_capturers_.emplace_back(
+ std::unique_ptr<FrameGeneratorCapturer>(frame_generator_capturer_));
+ video_sources_.push_back(video_capturers_.back().get());
ConnectVideoSourcesToStreams();
}
@@ -368,15 +465,45 @@
}
void CallTest::CreateVideoSendStreams() {
- RTC_DCHECK(video_send_stream_ == nullptr);
- video_send_stream_ = sender_call_->CreateVideoSendStream(
- GetVideoSendConfig()->Copy(), GetVideoEncoderConfig()->Copy());
+ RTC_DCHECK(video_send_streams_.empty());
+
+ // We currently only support testing external fec controllers with a single
+ // VideoSendStream.
+ if (fec_controller_factory_.get()) {
+ RTC_DCHECK_LE(video_send_configs_.size(), 1);
+ }
+
+ // TODO(http://crbug/818127):
+ // Remove this workaround when ALR is not screenshare-specific.
+ std::list<size_t> streams_creation_order;
+ for (size_t i = 0; i < video_send_configs_.size(); ++i) {
+ // If dual streams are created, add the screenshare stream last.
+ if (video_encoder_configs_[i].content_type ==
+ VideoEncoderConfig::ContentType::kScreen) {
+ streams_creation_order.push_back(i);
+ } else {
+ streams_creation_order.push_front(i);
+ }
+ }
+
+ video_send_streams_.resize(video_send_configs_.size(), nullptr);
+
+ for (size_t i : streams_creation_order) {
+ if (fec_controller_factory_.get()) {
+ video_send_streams_[i] = sender_call_->CreateVideoSendStream(
+ video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy(),
+ fec_controller_factory_->CreateFecController());
+ } else {
+ video_send_streams_[i] = sender_call_->CreateVideoSendStream(
+ video_send_configs_[i].Copy(), video_encoder_configs_[i].Copy());
+ }
+ }
}
void CallTest::CreateVideoSendStream(const VideoEncoderConfig& encoder_config) {
- RTC_DCHECK(video_send_stream_ == nullptr);
- video_send_stream_ = sender_call_->CreateVideoSendStream(
- GetVideoSendConfig()->Copy(), encoder_config.Copy());
+ RTC_DCHECK(video_send_streams_.empty());
+ video_send_streams_.push_back(sender_call_->CreateVideoSendStream(
+ GetVideoSendConfig()->Copy(), encoder_config.Copy()));
}
void CallTest::CreateAudioStreams() {
@@ -400,8 +527,9 @@
}
void CallTest::ConnectVideoSourcesToStreams() {
- GetVideoSendStream()->SetSource(frame_generator_capturer_.get(),
- degradation_preference_);
+ for (size_t i = 0; i < video_sources_.size(); ++i)
+ video_send_streams_[i]->SetSource(video_sources_[i],
+ degradation_preference_);
}
void CallTest::AssociateFlexfecStreamsWithVideoStreams() {
@@ -432,29 +560,37 @@
}
void CallTest::StartVideoStreams() {
- if (video_send_stream_)
- video_send_stream_->Start();
+ for (VideoSendStream* video_send_stream : video_send_streams_)
+ video_send_stream->Start();
for (VideoReceiveStream* video_recv_stream : video_receive_streams_)
video_recv_stream->Start();
}
void CallTest::StartVideoCapture() {
- if (frame_generator_capturer_.get() != NULL)
- frame_generator_capturer_->Start();
+ for (auto& capturer : video_capturers_)
+ capturer->Start();
}
void CallTest::Stop() {
- if (frame_generator_capturer_.get() != NULL)
- frame_generator_capturer_->Stop();
+ StopVideoCapture();
for (AudioReceiveStream* audio_recv_stream : audio_receive_streams_)
audio_recv_stream->Stop();
if (audio_send_stream_) {
audio_send_stream_->Stop();
}
+ StopVideoStreams();
+}
+
+void CallTest::StopVideoCapture() {
+ for (auto& capturer : video_capturers_)
+ capturer->Stop();
+}
+
+void CallTest::StopVideoStreams() {
+ for (VideoSendStream* video_send_stream : video_send_streams_)
+ video_send_stream->Stop();
for (VideoReceiveStream* video_recv_stream : video_receive_streams_)
video_recv_stream->Stop();
- if (video_send_stream_)
- video_send_stream_->Stop();
}
void CallTest::DestroyStreams() {
@@ -479,9 +615,9 @@
}
void CallTest::DestroyVideoSendStreams() {
- if (video_send_stream_)
- sender_call_->DestroyVideoSendStream(video_send_stream_);
- video_send_stream_ = nullptr;
+ for (VideoSendStream* video_send_stream : video_send_streams_)
+ sender_call_->DestroyVideoSendStream(video_send_stream);
+ video_send_streams_.clear();
}
void CallTest::SetFakeVideoCaptureRotation(VideoRotation rotation) {
@@ -489,27 +625,32 @@
}
void CallTest::SetVideoDegradation(DegradationPreference preference) {
- GetVideoSendStream()->SetSource(frame_generator_capturer_.get(), preference);
+ GetVideoSendStream()->SetSource(frame_generator_capturer_, preference);
}
VideoSendStream::Config* CallTest::GetVideoSendConfig() {
- return &video_send_config_;
+ return &video_send_configs_[0];
}
void CallTest::SetVideoSendConfig(const VideoSendStream::Config& config) {
- video_send_config_ = config.Copy();
+ video_send_configs_.clear();
+ video_send_configs_.push_back(config.Copy());
}
VideoEncoderConfig* CallTest::GetVideoEncoderConfig() {
- return &video_encoder_config_;
+ return &video_encoder_configs_[0];
}
void CallTest::SetVideoEncoderConfig(const VideoEncoderConfig& config) {
- video_encoder_config_ = config.Copy();
+ video_encoder_configs_.clear();
+ video_encoder_configs_.push_back(config.Copy());
}
VideoSendStream* CallTest::GetVideoSendStream() {
- return video_send_stream_;
+ return video_send_streams_[0];
+}
+FlexfecReceiveStream::Config* CallTest::GetFlexFecConfig() {
+ return &flexfec_receive_configs_[0];
}
constexpr size_t CallTest::kNumSsrcs;