Index: webrtc/video/video_quality_test.cc |
diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc |
index 7caa6367b001444c14cde8f3f764e609c3abde21..15c6a6b513e1893171dba7abbdeaef264c8ea199 100644 |
--- a/webrtc/video/video_quality_test.cc |
+++ b/webrtc/video/video_quality_test.cc |
@@ -68,11 +68,10 @@ constexpr int kSendStatsPollingIntervalMs = 1000; |
constexpr size_t kMaxComparisons = 10; |
constexpr char kSyncGroup[] = "av_sync"; |
-constexpr int kOpusMinBitrateBps = 6000; |
-constexpr int kOpusBitrateFbBps = 32000; |
-constexpr int kFramesSentInQuickTest = 1; |
-constexpr uint32_t kThumbnailSendSsrcStart = 0xE0000; |
-constexpr uint32_t kThumbnailRtxSsrcStart = 0xF0000; |
+// constexpr int kOpusMinBitrateBps = 6000; |
+// constexpr int kOpusBitrateFbBps = 32000; |
+// constexpr uint32_t kThumbnailSendSsrcStart = 0xE0000; |
+// constexpr uint32_t kThumbnailRtxSsrcStart = 0xF0000; |
constexpr int kDefaultMaxQp = cricket::WebRtcVideoChannel::kDefaultQpMax; |
@@ -89,32 +88,32 @@ struct VoiceEngineState { |
int receive_channel_id; |
}; |
-void CreateVoiceEngine( |
- VoiceEngineState* voe, |
- webrtc::AudioProcessing* apm, |
- rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory) { |
- voe->voice_engine = webrtc::VoiceEngine::Create(); |
- voe->base = webrtc::VoEBase::GetInterface(voe->voice_engine); |
- EXPECT_EQ(0, voe->base->Init(nullptr, apm, decoder_factory)); |
- webrtc::VoEBase::ChannelConfig config; |
- config.enable_voice_pacing = true; |
- voe->send_channel_id = voe->base->CreateChannel(config); |
- EXPECT_GE(voe->send_channel_id, 0); |
- voe->receive_channel_id = voe->base->CreateChannel(); |
- EXPECT_GE(voe->receive_channel_id, 0); |
-} |
- |
-void DestroyVoiceEngine(VoiceEngineState* voe) { |
- voe->base->DeleteChannel(voe->send_channel_id); |
- voe->send_channel_id = -1; |
- voe->base->DeleteChannel(voe->receive_channel_id); |
- voe->receive_channel_id = -1; |
- voe->base->Release(); |
- voe->base = nullptr; |
- |
- webrtc::VoiceEngine::Delete(voe->voice_engine); |
- voe->voice_engine = nullptr; |
-} |
+// void CreateVoiceEngine( |
+// VoiceEngineState* voe, |
+// webrtc::AudioProcessing* apm, |
+// rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory) { |
+// voe->voice_engine = webrtc::VoiceEngine::Create(); |
+// voe->base = webrtc::VoEBase::GetInterface(voe->voice_engine); |
+// EXPECT_EQ(0, voe->base->Init(nullptr, apm, decoder_factory)); |
+// webrtc::VoEBase::ChannelConfig config; |
+// config.enable_voice_pacing = true; |
+// voe->send_channel_id = voe->base->CreateChannel(config); |
+// EXPECT_GE(voe->send_channel_id, 0); |
+// voe->receive_channel_id = voe->base->CreateChannel(); |
+// EXPECT_GE(voe->receive_channel_id, 0); |
+// } |
+ |
+// void DestroyVoiceEngine(VoiceEngineState* voe) { |
+// voe->base->DeleteChannel(voe->send_channel_id); |
+// voe->send_channel_id = -1; |
+// voe->base->DeleteChannel(voe->receive_channel_id); |
+// voe->receive_channel_id = -1; |
+// voe->base->Release(); |
+// voe->base = nullptr; |
+ |
+// webrtc::VoiceEngine::Delete(voe->voice_engine); |
+// voe->voice_engine = nullptr; |
+// } |
class VideoStreamFactory |
: public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface { |
@@ -1186,47 +1185,47 @@ void VideoQualityTest::TestBody() {} |
std::string VideoQualityTest::GenerateGraphTitle() const { |
std::stringstream ss; |
- ss << params_.video.codec; |
- ss << " (" << params_.video.target_bitrate_bps / 1000 << "kbps"; |
- ss << ", " << params_.video.fps << " FPS"; |
- if (params_.screenshare.scroll_duration) |
- ss << ", " << params_.screenshare.scroll_duration << "s scroll"; |
- if (params_.ss.streams.size() > 1) |
- ss << ", Stream #" << params_.ss.selected_stream; |
- if (params_.ss.num_spatial_layers > 1) |
- ss << ", Layer #" << params_.ss.selected_sl; |
- ss << ")"; |
+ // ss << params_.video.codec; |
+ // ss << " (" << params_.video.target_bitrate_bps / 1000 << "kbps"; |
+ // ss << ", " << params_.video.fps << " FPS"; |
+ // if (params_.screenshare.scroll_duration) |
+ // ss << ", " << params_.screenshare.scroll_duration << "s scroll"; |
+ // if (params_.ss.streams.size() > 1) |
+ // ss << ", Stream #" << params_.ss.selected_stream; |
+ // if (params_.ss.num_spatial_layers > 1) |
+ // ss << ", Layer #" << params_.ss.selected_sl; |
+ // ss << ")"; |
return ss.str(); |
} |
-void VideoQualityTest::CheckParams() { |
- if (!params_.video.enabled) |
+void VideoQualityTest::CheckParams(Params* params) { |
+ if (!params->video.enabled) |
return; |
// Add a default stream in none specified. |
- if (params_.ss.streams.empty()) |
- params_.ss.streams.push_back(VideoQualityTest::DefaultVideoStream(params_)); |
- if (params_.ss.num_spatial_layers == 0) |
- params_.ss.num_spatial_layers = 1; |
+ if (params->ss.streams.empty()) |
+ params->ss.streams.push_back(VideoQualityTest::DefaultVideoStream(*params)); |
+ if (params->ss.num_spatial_layers == 0) |
+ params->ss.num_spatial_layers = 1; |
- if (params_.pipe.loss_percent != 0 || |
- params_.pipe.queue_length_packets != 0) { |
+ if (params->pipe.loss_percent != 0 || |
+ params->pipe.queue_length_packets != 0) { |
// Since LayerFilteringTransport changes the sequence numbers, we can't |
// use that feature with pack loss, since the NACK request would end up |
// retransmitting the wrong packets. |
- RTC_CHECK(params_.ss.selected_sl == -1 || |
- params_.ss.selected_sl == params_.ss.num_spatial_layers - 1); |
- RTC_CHECK(params_.video.selected_tl == -1 || |
- params_.video.selected_tl == |
- params_.video.num_temporal_layers - 1); |
+ RTC_CHECK(params->ss.selected_sl == -1 || |
+ params->ss.selected_sl == params->ss.num_spatial_layers - 1); |
+ RTC_CHECK(params->video.selected_tl == -1 || |
+ params->video.selected_tl == |
+ params->video.num_temporal_layers - 1); |
} |
// TODO(ivica): Should max_bitrate_bps == -1 represent inf max bitrate, as it |
// does in some parts of the code? |
- RTC_CHECK_GE(params_.video.max_bitrate_bps, params_.video.target_bitrate_bps); |
- RTC_CHECK_GE(params_.video.target_bitrate_bps, params_.video.min_bitrate_bps); |
- RTC_CHECK_LT(params_.video.selected_tl, params_.video.num_temporal_layers); |
- RTC_CHECK_LE(params_.ss.selected_stream, params_.ss.streams.size()); |
- for (const VideoStream& stream : params_.ss.streams) { |
+ RTC_CHECK_GE(params->video.max_bitrate_bps, params->video.target_bitrate_bps); |
+ RTC_CHECK_GE(params->video.target_bitrate_bps, params->video.min_bitrate_bps); |
+ RTC_CHECK_LT(params->video.selected_tl, params->video.num_temporal_layers); |
+ RTC_CHECK_LE(params->ss.selected_stream, params->ss.streams.size()); |
+ for (const VideoStream& stream : params->ss.streams) { |
RTC_CHECK_GE(stream.min_bitrate_bps, 0); |
RTC_CHECK_GE(stream.target_bitrate_bps, stream.min_bitrate_bps); |
RTC_CHECK_GE(stream.max_bitrate_bps, stream.target_bitrate_bps); |
@@ -1234,22 +1233,22 @@ void VideoQualityTest::CheckParams() { |
// TODO(ivica): Should we check if the sum of all streams/layers is equal to |
// the total bitrate? We anyway have to update them in the case bitrate |
// estimator changes the total bitrates. |
- RTC_CHECK_GE(params_.ss.num_spatial_layers, 1); |
- RTC_CHECK_LE(params_.ss.selected_sl, params_.ss.num_spatial_layers); |
- RTC_CHECK(params_.ss.spatial_layers.empty() || |
- params_.ss.spatial_layers.size() == |
- static_cast<size_t>(params_.ss.num_spatial_layers)); |
- if (params_.video.codec == "VP8") { |
- RTC_CHECK_EQ(params_.ss.num_spatial_layers, 1); |
- } else if (params_.video.codec == "VP9") { |
- RTC_CHECK_EQ(params_.ss.streams.size(), 1); |
- } |
- RTC_CHECK_GE(params_.call.num_thumbnails, 0); |
- if (params_.call.num_thumbnails > 0) { |
- RTC_CHECK_EQ(params_.ss.num_spatial_layers, 1); |
- RTC_CHECK_EQ(params_.ss.streams.size(), 3); |
- RTC_CHECK_EQ(params_.video.num_temporal_layers, 3); |
- RTC_CHECK_EQ(params_.video.codec, "VP8"); |
+ RTC_CHECK_GE(params->ss.num_spatial_layers, 1); |
+ RTC_CHECK_LE(params->ss.selected_sl, params->ss.num_spatial_layers); |
+ RTC_CHECK(params->ss.spatial_layers.empty() || |
+ params->ss.spatial_layers.size() == |
+ static_cast<size_t>(params->ss.num_spatial_layers)); |
+ if (params->video.codec == "VP8") { |
+ RTC_CHECK_EQ(params->ss.num_spatial_layers, 1); |
+ } else if (params->video.codec == "VP9") { |
+ RTC_CHECK_EQ(params->ss.streams.size(), 1); |
+ } |
+ RTC_CHECK_GE(params->call.num_thumbnails, 0); |
+ if (params->call.num_thumbnails > 0) { |
+ RTC_CHECK_EQ(params->ss.num_spatial_layers, 1); |
+ RTC_CHECK_EQ(params->ss.streams.size(), 3); |
+ RTC_CHECK_EQ(params->video.num_temporal_layers, 3); |
+ RTC_CHECK_EQ(params->video.codec, "VP8"); |
} |
} |
@@ -1396,251 +1395,206 @@ void VideoQualityTest::FillScalabilitySettings( |
} |
} |
-void VideoQualityTest::SetupVideo(Transport* send_transport, |
- Transport* recv_transport) { |
- if (params_.logging.logs) |
+void VideoQualityTest::SetupVideo( |
+ Transport* send_transport, |
+ Transport* recv_transport, |
+ Params* params, |
+ VideoSendStream::Config* video_send_config, |
+ VideoEncoderConfig* video_encoder_config, |
+ std::unique_ptr<VideoEncoder>* video_encoder, |
+ std::vector<VideoReceiveStream::Config>* video_receive_configs, |
+ std::vector<std::unique_ptr<VideoDecoder>>* allocated_decoders, |
+ std::vector<uint32_t>* send_ssrcs, |
+ std::vector<uint32_t>* send_rtx_ssrcs) { |
+ if (params->logging.logs) |
trace_to_stderr_.reset(new test::TraceToStderr); |
- size_t num_video_streams = params_.ss.streams.size(); |
- size_t num_flexfec_streams = params_.video.flexfec ? 1 : 0; |
- CreateSendConfig(num_video_streams, 0, num_flexfec_streams, send_transport); |
+ size_t num_video_streams = params->ss.streams.size(); |
+ size_t num_flexfec_streams = params->video.flexfec ? 1 : 0; |
+ CreateSendConfig(num_video_streams, 0, num_flexfec_streams, send_transport, |
+ video_send_config, video_encoder_config, send_ssrcs); |
int payload_type; |
- if (params_.video.codec == "H264") { |
- video_encoder_.reset(H264Encoder::Create(cricket::VideoCodec("H264"))); |
+ if (params->video.codec == "H264") { |
+ video_encoder->reset(H264Encoder::Create(cricket::VideoCodec("H264"))); |
payload_type = kPayloadTypeH264; |
- } else if (params_.video.codec == "VP8") { |
- if (params_.screenshare.enabled && params_.ss.streams.size() > 1) { |
+ } else if (params->video.codec == "VP8") { |
+ if (params->screenshare.enabled && params->ss.streams.size() > 1) { |
// Simulcast screenshare needs a simulcast encoder adapter to work, since |
// encoders usually can't natively do simulcast with different frame rates |
// for the different layers. |
- video_encoder_.reset( |
+ video_encoder->reset( |
new SimulcastEncoderAdapter(new Vp8EncoderFactory())); |
} else { |
- video_encoder_.reset(VP8Encoder::Create()); |
+ video_encoder->reset(VP8Encoder::Create()); |
} |
payload_type = kPayloadTypeVP8; |
- } else if (params_.video.codec == "VP9") { |
- video_encoder_.reset(VP9Encoder::Create()); |
+ } else if (params->video.codec == "VP9") { |
+ video_encoder->reset(VP9Encoder::Create()); |
payload_type = kPayloadTypeVP9; |
} else { |
RTC_NOTREACHED() << "Codec not supported!"; |
return; |
} |
- video_send_config_.encoder_settings.encoder = video_encoder_.get(); |
- video_send_config_.encoder_settings.payload_name = params_.video.codec; |
- video_send_config_.encoder_settings.payload_type = payload_type; |
- video_send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
- video_send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; |
+ video_send_config->encoder_settings.encoder = video_encoder->get(); |
+ video_send_config->encoder_settings.payload_name = params->video.codec; |
+ video_send_config->encoder_settings.payload_type = payload_type; |
+ video_send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
+ video_send_config->rtp.rtx.payload_type = kSendRtxPayloadType; |
for (size_t i = 0; i < num_video_streams; ++i) |
- video_send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); |
+ video_send_config->rtp.rtx.ssrcs.push_back(send_rtx_ssrcs->at(i)); |
- video_send_config_.rtp.extensions.clear(); |
- if (params_.call.send_side_bwe) { |
- video_send_config_.rtp.extensions.push_back( |
+ video_send_config->rtp.extensions.clear(); |
+ if (params->call.send_side_bwe) { |
+ video_send_config->rtp.extensions.push_back( |
RtpExtension(RtpExtension::kTransportSequenceNumberUri, |
test::kTransportSequenceNumberExtensionId)); |
} else { |
- video_send_config_.rtp.extensions.push_back(RtpExtension( |
+ video_send_config->rtp.extensions.push_back(RtpExtension( |
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId)); |
} |
- video_send_config_.rtp.extensions.push_back(RtpExtension( |
+ video_send_config->rtp.extensions.push_back(RtpExtension( |
RtpExtension::kVideoContentTypeUri, test::kVideoContentTypeExtensionId)); |
- video_send_config_.rtp.extensions.push_back(RtpExtension( |
+ video_send_config->rtp.extensions.push_back(RtpExtension( |
RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId)); |
- video_encoder_config_.min_transmit_bitrate_bps = |
- params_.video.min_transmit_bps; |
+ video_encoder_config->min_transmit_bitrate_bps = |
+ params->video.min_transmit_bps; |
- video_send_config_.suspend_below_min_bitrate = |
- params_.video.suspend_below_min_bitrate; |
+ video_send_config->suspend_below_min_bitrate = |
+ params->video.suspend_below_min_bitrate; |
- video_encoder_config_.number_of_streams = params_.ss.streams.size(); |
- video_encoder_config_.max_bitrate_bps = 0; |
- for (size_t i = 0; i < params_.ss.streams.size(); ++i) { |
- video_encoder_config_.max_bitrate_bps += |
- params_.ss.streams[i].max_bitrate_bps; |
+ video_encoder_config->number_of_streams = params->ss.streams.size(); |
+ video_encoder_config->max_bitrate_bps = 0; |
+ for (size_t i = 0; i < params->ss.streams.size(); ++i) { |
+ video_encoder_config->max_bitrate_bps += |
+ params->ss.streams[i].max_bitrate_bps; |
} |
- if (params_.ss.infer_streams) { |
- video_encoder_config_.video_stream_factory = |
+ if (params->ss.infer_streams) { |
+ video_encoder_config->video_stream_factory = |
new rtc::RefCountedObject<cricket::EncoderStreamFactory>( |
- params_.video.codec, params_.ss.streams[0].max_qp, |
- params_.video.fps, params_.screenshare.enabled, true); |
+ params->video.codec, params->ss.streams[0].max_qp, |
+ params->video.fps, params->screenshare.enabled, true); |
} else { |
- video_encoder_config_.video_stream_factory = |
- new rtc::RefCountedObject<VideoStreamFactory>(params_.ss.streams); |
+ video_encoder_config->video_stream_factory = |
+ new rtc::RefCountedObject<VideoStreamFactory>(params->ss.streams); |
} |
- video_encoder_config_.spatial_layers = params_.ss.spatial_layers; |
+ video_encoder_config->spatial_layers = params->ss.spatial_layers; |
- CreateMatchingReceiveConfigs(recv_transport); |
+ CreateMatchingReceiveConfigs(recv_transport, video_receive_configs, |
+ allocated_decoders, video_send_config); |
const bool decode_all_receive_streams = |
- params_.ss.selected_stream == params_.ss.streams.size(); |
+ params->ss.selected_stream == params->ss.streams.size(); |
for (size_t i = 0; i < num_video_streams; ++i) { |
- video_receive_configs_[i].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
- video_receive_configs_[i].rtp.rtx_ssrc = kSendRtxSsrcs[i]; |
- video_receive_configs_[i] |
+ video_receive_configs->at(i).rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
+ video_receive_configs->at(i).rtp.rtx_ssrc = send_rtx_ssrcs->at(i); |
+ video_receive_configs->at(i) |
.rtp.rtx_associated_payload_types[kSendRtxPayloadType] = payload_type; |
- video_receive_configs_[i].rtp.transport_cc = params_.call.send_side_bwe; |
- video_receive_configs_[i].rtp.remb = !params_.call.send_side_bwe; |
+ video_receive_configs->at(i).rtp.transport_cc = params->call.send_side_bwe; |
+ video_receive_configs->at(i).rtp.remb = !params->call.send_side_bwe; |
// Enable RTT calculation so NTP time estimator will work. |
- video_receive_configs_[i].rtp.rtcp_xr.receiver_reference_time_report = true; |
+ video_receive_configs->at(i).rtp.rtcp_xr.receiver_reference_time_report = |
+ true; |
// Force fake decoders on non-selected simulcast streams. |
- if (!decode_all_receive_streams && i != params_.ss.selected_stream) { |
+ if (!decode_all_receive_streams && i != params->ss.selected_stream) { |
VideoReceiveStream::Decoder decoder; |
decoder.decoder = new test::FakeDecoder(); |
- decoder.payload_type = video_send_config_.encoder_settings.payload_type; |
- decoder.payload_name = video_send_config_.encoder_settings.payload_name; |
- video_receive_configs_[i].decoders.clear(); |
+ decoder.payload_type = video_send_config->encoder_settings.payload_type; |
+ decoder.payload_name = video_send_config->encoder_settings.payload_name; |
+ video_receive_configs->at(i).decoders.clear(); |
allocated_decoders_.emplace_back(decoder.decoder); |
- video_receive_configs_[i].decoders.push_back(decoder); |
- } |
- } |
- |
- if (params_.video.flexfec) { |
- // Override send config constructed by CreateSendConfig. |
- if (decode_all_receive_streams) { |
- for (uint32_t media_ssrc : video_send_config_.rtp.ssrcs) { |
- video_send_config_.rtp.flexfec.protected_media_ssrcs.push_back( |
- media_ssrc); |
- } |
- } else { |
- video_send_config_.rtp.flexfec.protected_media_ssrcs = { |
- kVideoSendSsrcs[params_.ss.selected_stream]}; |
+ video_receive_configs->at(i).decoders.push_back(decoder); |
} |
- |
- // The matching receive config is _not_ created by |
- // CreateMatchingReceiveConfigs, since VideoQualityTest is not a BaseTest. |
- // Set up the receive config manually instead. |
- FlexfecReceiveStream::Config flexfec_receive_config(recv_transport); |
- flexfec_receive_config.payload_type = |
- video_send_config_.rtp.flexfec.payload_type; |
- flexfec_receive_config.remote_ssrc = video_send_config_.rtp.flexfec.ssrc; |
- flexfec_receive_config.protected_media_ssrcs = |
- video_send_config_.rtp.flexfec.protected_media_ssrcs; |
- flexfec_receive_config.local_ssrc = kReceiverLocalVideoSsrc; |
- flexfec_receive_config.transport_cc = params_.call.send_side_bwe; |
- if (params_.call.send_side_bwe) { |
- flexfec_receive_config.rtp_header_extensions.push_back( |
- RtpExtension(RtpExtension::kTransportSequenceNumberUri, |
- test::kTransportSequenceNumberExtensionId)); |
- } else { |
- flexfec_receive_config.rtp_header_extensions.push_back(RtpExtension( |
- RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId)); |
- } |
- flexfec_receive_configs_.push_back(flexfec_receive_config); |
} |
- if (params_.video.ulpfec) { |
- video_send_config_.rtp.ulpfec.red_payload_type = kRedPayloadType; |
- video_send_config_.rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; |
- video_send_config_.rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType; |
- |
- if (decode_all_receive_streams) { |
- for (auto it = video_receive_configs_.begin(); |
- it != video_receive_configs_.end(); ++it) { |
- it->rtp.ulpfec.red_payload_type = |
- video_send_config_.rtp.ulpfec.red_payload_type; |
- it->rtp.ulpfec.ulpfec_payload_type = |
- video_send_config_.rtp.ulpfec.ulpfec_payload_type; |
- it->rtp.ulpfec.red_rtx_payload_type = |
- video_send_config_.rtp.ulpfec.red_rtx_payload_type; |
- } |
- } else { |
- video_receive_configs_[params_.ss.selected_stream] |
- .rtp.ulpfec.red_payload_type = |
- video_send_config_.rtp.ulpfec.red_payload_type; |
- video_receive_configs_[params_.ss.selected_stream] |
- .rtp.ulpfec.ulpfec_payload_type = |
- video_send_config_.rtp.ulpfec.ulpfec_payload_type; |
- video_receive_configs_[params_.ss.selected_stream] |
- .rtp.ulpfec.red_rtx_payload_type = |
- video_send_config_.rtp.ulpfec.red_rtx_payload_type; |
- } |
- } |
+ RTC_DCHECK(!params->video.flexfec); |
+ RTC_DCHECK(!params->video.ulpfec); |
} |
void VideoQualityTest::SetupThumbnails(Transport* send_transport, |
Transport* recv_transport) { |
- for (int i = 0; i < params_.call.num_thumbnails; ++i) { |
- thumbnail_encoders_.emplace_back(VP8Encoder::Create()); |
- |
- // Thumbnails will be send in the other way: from receiver_call to |
- // sender_call. |
- VideoSendStream::Config thumbnail_send_config(recv_transport); |
- thumbnail_send_config.rtp.ssrcs.push_back(kThumbnailSendSsrcStart + i); |
- thumbnail_send_config.encoder_settings.encoder = |
- thumbnail_encoders_.back().get(); |
- thumbnail_send_config.encoder_settings.payload_name = params_.video.codec; |
- thumbnail_send_config.encoder_settings.payload_type = kPayloadTypeVP8; |
- thumbnail_send_config.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
- thumbnail_send_config.rtp.rtx.payload_type = kSendRtxPayloadType; |
- thumbnail_send_config.rtp.rtx.ssrcs.push_back(kThumbnailRtxSsrcStart + i); |
- thumbnail_send_config.rtp.extensions.clear(); |
- if (params_.call.send_side_bwe) { |
- thumbnail_send_config.rtp.extensions.push_back( |
- RtpExtension(RtpExtension::kTransportSequenceNumberUri, |
- test::kTransportSequenceNumberExtensionId)); |
- } else { |
- thumbnail_send_config.rtp.extensions.push_back(RtpExtension( |
- RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId)); |
- } |
- |
- VideoEncoderConfig thumbnail_encoder_config; |
- thumbnail_encoder_config.min_transmit_bitrate_bps = 7500; |
- thumbnail_send_config.suspend_below_min_bitrate = |
- params_.video.suspend_below_min_bitrate; |
- thumbnail_encoder_config.number_of_streams = 1; |
- thumbnail_encoder_config.max_bitrate_bps = 50000; |
- if (params_.ss.infer_streams) { |
- thumbnail_encoder_config.video_stream_factory = |
- new rtc::RefCountedObject<VideoStreamFactory>(params_.ss.streams); |
- } else { |
- thumbnail_encoder_config.video_stream_factory = |
- new rtc::RefCountedObject<cricket::EncoderStreamFactory>( |
- params_.video.codec, params_.ss.streams[0].max_qp, |
- params_.video.fps, params_.screenshare.enabled, true); |
- } |
- thumbnail_encoder_config.spatial_layers = params_.ss.spatial_layers; |
- |
- VideoReceiveStream::Config thumbnail_receive_config(send_transport); |
- thumbnail_receive_config.rtp.remb = false; |
- thumbnail_receive_config.rtp.transport_cc = true; |
- thumbnail_receive_config.rtp.local_ssrc = kReceiverLocalVideoSsrc; |
- for (const RtpExtension& extension : thumbnail_send_config.rtp.extensions) |
- thumbnail_receive_config.rtp.extensions.push_back(extension); |
- thumbnail_receive_config.renderer = &fake_renderer_; |
- |
- VideoReceiveStream::Decoder decoder = |
- test::CreateMatchingDecoder(thumbnail_send_config.encoder_settings); |
- allocated_decoders_.push_back( |
- std::unique_ptr<VideoDecoder>(decoder.decoder)); |
- thumbnail_receive_config.decoders.clear(); |
- thumbnail_receive_config.decoders.push_back(decoder); |
- thumbnail_receive_config.rtp.remote_ssrc = |
- thumbnail_send_config.rtp.ssrcs[0]; |
- |
- thumbnail_receive_config.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
- thumbnail_receive_config.rtp.rtx_ssrc = kThumbnailRtxSsrcStart + i; |
- thumbnail_receive_config.rtp |
- .rtx_associated_payload_types[kSendRtxPayloadType] = kPayloadTypeVP8; |
- thumbnail_receive_config.rtp.transport_cc = params_.call.send_side_bwe; |
- thumbnail_receive_config.rtp.remb = !params_.call.send_side_bwe; |
- |
- thumbnail_encoder_configs_.push_back(thumbnail_encoder_config.Copy()); |
- thumbnail_send_configs_.push_back(thumbnail_send_config.Copy()); |
- thumbnail_receive_configs_.push_back(thumbnail_receive_config.Copy()); |
- } |
- |
- for (int i = 0; i < params_.call.num_thumbnails; ++i) { |
- thumbnail_send_streams_.push_back(receiver_call_->CreateVideoSendStream( |
- thumbnail_send_configs_[i].Copy(), |
- thumbnail_encoder_configs_[i].Copy())); |
- thumbnail_receive_streams_.push_back(sender_call_->CreateVideoReceiveStream( |
- thumbnail_receive_configs_[i].Copy())); |
- } |
+ // for (int i = 0; i < params_.call.num_thumbnails; ++i) { |
+ // thumbnail_encoders_.emplace_back(VP8Encoder::Create()); |
+ |
+ // // Thumbnails will be send in the other way: from receiver_call to |
+ // // sender_call. |
+ // VideoSendStream::Config thumbnail_send_config(recv_transport); |
+ // thumbnail_send_config.rtp.ssrcs.push_back(kThumbnailSendSsrcStart + i); |
+ // thumbnail_send_config.encoder_settings.encoder = |
+ // thumbnail_encoders_.back().get(); |
+ // thumbnail_send_config.encoder_settings.payload_name = |
+ // params_.video.codec; thumbnail_send_config.encoder_settings.payload_type |
+ // = kPayloadTypeVP8; thumbnail_send_config.rtp.nack.rtp_history_ms = |
+ // kNackRtpHistoryMs; thumbnail_send_config.rtp.rtx.payload_type = |
+ // kSendRtxPayloadType; |
+ // thumbnail_send_config.rtp.rtx.ssrcs.push_back(kThumbnailRtxSsrcStart + |
+ // i); thumbnail_send_config.rtp.extensions.clear(); if |
+ // (params_.call.send_side_bwe) { |
+ // thumbnail_send_config.rtp.extensions.push_back( |
+ // RtpExtension(RtpExtension::kTransportSequenceNumberUri, |
+ // test::kTransportSequenceNumberExtensionId)); |
+ // } else { |
+ // thumbnail_send_config.rtp.extensions.push_back(RtpExtension( |
+ // RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId)); |
+ // } |
+ |
+ // VideoEncoderConfig thumbnail_encoder_config; |
+ // thumbnail_encoder_config.min_transmit_bitrate_bps = 7500; |
+ // thumbnail_send_config.suspend_below_min_bitrate = |
+ // params_.video.suspend_below_min_bitrate; |
+ // thumbnail_encoder_config.number_of_streams = 1; |
+ // thumbnail_encoder_config.max_bitrate_bps = 50000; |
+ // if (params_.ss.infer_streams) { |
+ // thumbnail_encoder_config.video_stream_factory = |
+ // new rtc::RefCountedObject<VideoStreamFactory>(params_.ss.streams); |
+ // } else { |
+ // thumbnail_encoder_config.video_stream_factory = |
+ // new rtc::RefCountedObject<cricket::EncoderStreamFactory>( |
+ // params_.video.codec, params_.ss.streams[0].max_qp, |
+ // params_.video.fps, params_.screenshare.enabled, true); |
+ // } |
+ // thumbnail_encoder_config.spatial_layers = params_.ss.spatial_layers; |
+ |
+ // VideoReceiveStream::Config thumbnail_receive_config(send_transport); |
+ // thumbnail_receive_config.rtp.remb = false; |
+ // thumbnail_receive_config.rtp.transport_cc = true; |
+ // thumbnail_receive_config.rtp.local_ssrc = kReceiverLocalVideoSsrc; |
+ // for (const RtpExtension& extension : |
+ // thumbnail_send_config.rtp.extensions) |
+ // thumbnail_receive_config.rtp.extensions.push_back(extension); |
+ // thumbnail_receive_config.renderer = &fake_renderer_; |
+ |
+ // VideoReceiveStream::Decoder decoder = |
+ // test::CreateMatchingDecoder(thumbnail_send_config.encoder_settings); |
+ // allocated_decoders_.push_back( |
+ // std::unique_ptr<VideoDecoder>(decoder.decoder)); |
+ // thumbnail_receive_config.decoders.clear(); |
+ // thumbnail_receive_config.decoders.push_back(decoder); |
+ // thumbnail_receive_config.rtp.remote_ssrc = |
+ // thumbnail_send_config.rtp.ssrcs[0]; |
+ |
+ // thumbnail_receive_config.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
+ // thumbnail_receive_config.rtp.rtx_ssrc = kThumbnailRtxSsrcStart + i; |
+ // thumbnail_receive_config.rtp.rtx_payload_types[kPayloadTypeVP8] = |
+ // kSendRtxPayloadType; |
+ // thumbnail_receive_config.rtp.transport_cc = params_.call.send_side_bwe; |
+ // thumbnail_receive_config.rtp.remb = !params_.call.send_side_bwe; |
+ |
+ // thumbnail_encoder_configs_.push_back(thumbnail_encoder_config.Copy()); |
+ // thumbnail_send_configs_.push_back(thumbnail_send_config.Copy()); |
+ // thumbnail_receive_configs_.push_back(thumbnail_receive_config.Copy()); |
+ // } |
+ |
+ // for (int i = 0; i < params_.call.num_thumbnails; ++i) { |
+ // thumbnail_send_streams_.push_back(receiver_call_->CreateVideoSendStream( |
+ // thumbnail_send_configs_[i].Copy(), |
+ // thumbnail_encoder_configs_[i].Copy())); |
+ // thumbnail_receive_streams_.push_back(sender_call_->CreateVideoReceiveStream( |
+ // thumbnail_receive_configs_[i].Copy())); |
+ // } |
} |
void VideoQualityTest::DestroyThumbnailStreams() { |
@@ -1658,72 +1612,75 @@ void VideoQualityTest::DestroyThumbnailStreams() { |
} |
} |
-void VideoQualityTest::SetupScreenshareOrSVC() { |
- if (params_.screenshare.enabled) { |
+void VideoQualityTest::SetupScreenshareOrSVC( |
+ Params* params, |
+ VideoEncoderConfig* video_encoder_config, |
+ std::unique_ptr<test::FrameGenerator>* frame_generator) { |
+ if (params->screenshare.enabled) { |
// Fill out codec settings. |
- video_encoder_config_.content_type = |
+ video_encoder_config->content_type = |
VideoEncoderConfig::ContentType::kScreen; |
degradation_preference_ = |
VideoSendStream::DegradationPreference::kMaintainResolution; |
- if (params_.video.codec == "VP8") { |
+ if (params->video.codec == "VP8") { |
VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings(); |
vp8_settings.denoisingOn = false; |
vp8_settings.frameDroppingOn = false; |
vp8_settings.numberOfTemporalLayers = |
- static_cast<unsigned char>(params_.video.num_temporal_layers); |
- video_encoder_config_.encoder_specific_settings = |
+ static_cast<unsigned char>(params->video.num_temporal_layers); |
+ video_encoder_config->encoder_specific_settings = |
new rtc::RefCountedObject< |
VideoEncoderConfig::Vp8EncoderSpecificSettings>(vp8_settings); |
- } else if (params_.video.codec == "VP9") { |
+ } else if (params->video.codec == "VP9") { |
VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings(); |
vp9_settings.denoisingOn = false; |
vp9_settings.frameDroppingOn = false; |
vp9_settings.numberOfTemporalLayers = |
- static_cast<unsigned char>(params_.video.num_temporal_layers); |
+ static_cast<unsigned char>(params->video.num_temporal_layers); |
vp9_settings.numberOfSpatialLayers = |
- static_cast<unsigned char>(params_.ss.num_spatial_layers); |
- video_encoder_config_.encoder_specific_settings = |
+ static_cast<unsigned char>(params->ss.num_spatial_layers); |
+ video_encoder_config->encoder_specific_settings = |
new rtc::RefCountedObject< |
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings); |
} |
// Setup frame generator. |
const size_t kWidth = 1850; |
const size_t kHeight = 1110; |
- std::vector<std::string> slides = params_.screenshare.slides; |
+ std::vector<std::string> slides = params->screenshare.slides; |
if (slides.size() == 0) { |
slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); |
slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); |
slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); |
slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); |
} |
- if (params_.screenshare.scroll_duration == 0) { |
+ if (params->screenshare.scroll_duration == 0) { |
// Cycle image every slide_change_interval seconds. |
- frame_generator_ = test::FrameGenerator::CreateFromYuvFile( |
+ *frame_generator = test::FrameGenerator::CreateFromYuvFile( |
slides, kWidth, kHeight, |
- params_.screenshare.slide_change_interval * params_.video.fps); |
+ params->screenshare.slide_change_interval * params->video.fps); |
} else { |
- RTC_CHECK_LE(params_.video.width, kWidth); |
- RTC_CHECK_LE(params_.video.height, kHeight); |
- RTC_CHECK_GT(params_.screenshare.slide_change_interval, 0); |
- const int kPauseDurationMs = (params_.screenshare.slide_change_interval - |
- params_.screenshare.scroll_duration) * |
+ RTC_CHECK_LE(params->video.width, kWidth); |
+ RTC_CHECK_LE(params->video.height, kHeight); |
+ RTC_CHECK_GT(params->screenshare.slide_change_interval, 0); |
+ const int kPauseDurationMs = (params->screenshare.slide_change_interval - |
+ params->screenshare.scroll_duration) * |
1000; |
- RTC_CHECK_LE(params_.screenshare.scroll_duration, |
- params_.screenshare.slide_change_interval); |
+ RTC_CHECK_LE(params->screenshare.scroll_duration, |
+ params->screenshare.slide_change_interval); |
- frame_generator_ = test::FrameGenerator::CreateScrollingInputFromYuvFiles( |
- clock_, slides, kWidth, kHeight, params_.video.width, |
- params_.video.height, params_.screenshare.scroll_duration * 1000, |
+ *frame_generator = test::FrameGenerator::CreateScrollingInputFromYuvFiles( |
+ clock_, slides, kWidth, kHeight, params->video.width, |
+ params->video.height, params->screenshare.scroll_duration * 1000, |
kPauseDurationMs); |
} |
- } else if (params_.ss.num_spatial_layers > 1) { // For non-screenshare case. |
- RTC_CHECK(params_.video.codec == "VP9"); |
+ } else if (params->ss.num_spatial_layers > 1) { // For non-screenshare case. |
+ RTC_CHECK(params->video.codec == "VP9"); |
VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings(); |
vp9_settings.numberOfTemporalLayers = |
- static_cast<unsigned char>(params_.video.num_temporal_layers); |
+ static_cast<unsigned char>(params->video.num_temporal_layers); |
vp9_settings.numberOfSpatialLayers = |
- static_cast<unsigned char>(params_.ss.num_spatial_layers); |
- video_encoder_config_.encoder_specific_settings = new rtc::RefCountedObject< |
+ static_cast<unsigned char>(params->ss.num_spatial_layers); |
+ video_encoder_config->encoder_specific_settings = new rtc::RefCountedObject< |
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings); |
} |
} |
@@ -1738,411 +1695,277 @@ void VideoQualityTest::SetupThumbnailCapturers(size_t num_thumbnail_streams) { |
} |
} |
-void VideoQualityTest::CreateCapturer() { |
- if (params_.screenshare.enabled) { |
+void VideoQualityTest::CreateCapturer( |
+ Params* params, |
+ std::unique_ptr<test::VideoCapturer>* video_capturer) { |
+ if (params->screenshare.enabled) { |
test::FrameGeneratorCapturer* frame_generator_capturer = |
new test::FrameGeneratorCapturer(clock_, std::move(frame_generator_), |
- params_.video.fps); |
+ params->video.fps); |
EXPECT_TRUE(frame_generator_capturer->Init()); |
- video_capturer_.reset(frame_generator_capturer); |
+ video_capturer->reset(frame_generator_capturer); |
} else { |
- if (params_.video.clip_name == "Generator") { |
- video_capturer_.reset(test::FrameGeneratorCapturer::Create( |
- static_cast<int>(params_.video.width), |
- static_cast<int>(params_.video.height), params_.video.fps, clock_)); |
- } else if (params_.video.clip_name.empty()) { |
- video_capturer_.reset(test::VcmCapturer::Create( |
- params_.video.width, params_.video.height, params_.video.fps, |
- params_.video.capture_device_index)); |
- if (!video_capturer_) { |
+ if (params->video.clip_name == "Generator") { |
+ video_capturer->reset(test::FrameGeneratorCapturer::Create( |
+ static_cast<int>(params->video.width), |
+ static_cast<int>(params->video.height), params->video.fps, clock_)); |
+ } else if (params->video.clip_name.empty()) { |
+ video_capturer->reset(test::VcmCapturer::Create( |
+ params->video.width, params->video.height, params->video.fps, |
+ params->video.capture_device_index)); |
+ if (!video_capturer) { |
// Failed to get actual camera, use chroma generator as backup. |
- video_capturer_.reset(test::FrameGeneratorCapturer::Create( |
- static_cast<int>(params_.video.width), |
- static_cast<int>(params_.video.height), params_.video.fps, clock_)); |
+ video_capturer->reset(test::FrameGeneratorCapturer::Create( |
+ static_cast<int>(params->video.width), |
+ static_cast<int>(params->video.height), params->video.fps, clock_)); |
} |
} else { |
- video_capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile( |
- test::ResourcePath(params_.video.clip_name, "yuv"), |
- params_.video.width, params_.video.height, params_.video.fps, |
+ video_capturer->reset(test::FrameGeneratorCapturer::CreateFromYuvFile( |
+ test::ResourcePath(params->video.clip_name, "yuv"), |
+ params->video.width, params->video.height, params->video.fps, |
clock_)); |
- ASSERT_TRUE(video_capturer_) << "Could not create capturer for " |
- << params_.video.clip_name |
- << ".yuv. Is this resource file present?"; |
+ ASSERT_TRUE(video_capturer) |
+ << "Could not create capturer for " << params->video.clip_name |
+ << ".yuv. Is this resource file present?"; |
} |
} |
- RTC_DCHECK(video_capturer_.get()); |
-} |
- |
-void VideoQualityTest::RunWithAnalyzer(const Params& params) { |
- std::unique_ptr<test::LayerFilteringTransport> send_transport; |
- std::unique_ptr<test::DirectTransport> recv_transport; |
- FILE* graph_data_output_file = nullptr; |
- std::unique_ptr<VideoAnalyzer> analyzer; |
- |
- params_ = params; |
- |
- RTC_CHECK(!params_.audio.enabled); |
- // TODO(ivica): Merge with RunWithRenderer and use a flag / argument to |
- // differentiate between the analyzer and the renderer case. |
- CheckParams(); |
- |
- if (!params_.analyzer.graph_data_output_filename.empty()) { |
- graph_data_output_file = |
- fopen(params_.analyzer.graph_data_output_filename.c_str(), "w"); |
- RTC_CHECK(graph_data_output_file) |
- << "Can't open the file " << params_.analyzer.graph_data_output_filename |
- << "!"; |
- } |
- |
- if (!params.logging.rtc_event_log_name.empty()) { |
- event_log_ = RtcEventLog::Create(clock_); |
- bool event_log_started = |
- event_log_->StartLogging(params.logging.rtc_event_log_name, -1); |
- RTC_DCHECK(event_log_started); |
- } |
- |
- Call::Config call_config(event_log_.get()); |
- call_config.bitrate_config = params.call.call_bitrate_config; |
- |
- task_queue_.SendTask([this, &call_config, &send_transport, |
- &recv_transport]() { |
- CreateCalls(call_config, call_config); |
- |
- send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( |
- &task_queue_, params_.pipe, sender_call_.get(), kPayloadTypeVP8, |
- kPayloadTypeVP9, params_.video.selected_tl, params_.ss.selected_sl, |
- payload_type_map_); |
- |
- recv_transport = rtc::MakeUnique<test::DirectTransport>( |
- &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_); |
- }); |
- |
- std::string graph_title = params_.analyzer.graph_title; |
- if (graph_title.empty()) |
- graph_title = VideoQualityTest::GenerateGraphTitle(); |
- bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest"); |
- analyzer = rtc::MakeUnique<VideoAnalyzer>( |
- send_transport.get(), params_.analyzer.test_label, |
- params_.analyzer.avg_psnr_threshold, params_.analyzer.avg_ssim_threshold, |
- is_quick_test_enabled |
- ? kFramesSentInQuickTest |
- : params_.analyzer.test_durations_secs * params_.video.fps, |
- graph_data_output_file, graph_title, |
- kVideoSendSsrcs[params_.ss.selected_stream], |
- kSendRtxSsrcs[params_.ss.selected_stream], |
- static_cast<size_t>(params_.ss.selected_stream), params.ss.selected_sl, |
- params_.video.selected_tl, is_quick_test_enabled, clock_, |
- params_.logging.rtp_dump_name); |
- |
- task_queue_.SendTask([&]() { |
- analyzer->SetCall(sender_call_.get()); |
- analyzer->SetReceiver(receiver_call_->Receiver()); |
- send_transport->SetReceiver(analyzer.get()); |
- recv_transport->SetReceiver(sender_call_->Receiver()); |
- |
- SetupVideo(analyzer.get(), recv_transport.get()); |
- SetupThumbnails(analyzer.get(), recv_transport.get()); |
- video_receive_configs_[params_.ss.selected_stream].renderer = |
- analyzer.get(); |
- video_send_config_.pre_encode_callback = analyzer->pre_encode_proxy(); |
- RTC_DCHECK(!video_send_config_.post_encode_callback); |
- video_send_config_.post_encode_callback = analyzer->encode_timing_proxy(); |
- |
- SetupScreenshareOrSVC(); |
- |
- CreateFlexfecStreams(); |
- CreateVideoStreams(); |
- analyzer->SetSendStream(video_send_stream_); |
- if (video_receive_streams_.size() == 1) |
- analyzer->SetReceiveStream(video_receive_streams_[0]); |
- |
- video_send_stream_->SetSource(analyzer->OutputInterface(), |
- degradation_preference_); |
- |
- SetupThumbnailCapturers(params_.call.num_thumbnails); |
- for (size_t i = 0; i < thumbnail_send_streams_.size(); ++i) { |
- thumbnail_send_streams_[i]->SetSource(thumbnail_capturers_[i].get(), |
- degradation_preference_); |
- } |
- |
- CreateCapturer(); |
- |
- analyzer->SetSource(video_capturer_.get(), params_.ss.infer_streams); |
- |
- StartEncodedFrameLogs(video_send_stream_); |
- StartEncodedFrameLogs(video_receive_streams_[params_.ss.selected_stream]); |
- video_send_stream_->Start(); |
- for (VideoSendStream* thumbnail_send_stream : thumbnail_send_streams_) |
- thumbnail_send_stream->Start(); |
- for (VideoReceiveStream* receive_stream : video_receive_streams_) |
- receive_stream->Start(); |
- for (VideoReceiveStream* thumbnail_receive_stream : |
- thumbnail_receive_streams_) |
- thumbnail_receive_stream->Start(); |
- |
- analyzer->StartMeasuringCpuProcessTime(); |
- |
- video_capturer_->Start(); |
- for (std::unique_ptr<test::VideoCapturer>& video_caputurer : |
- thumbnail_capturers_) { |
- video_caputurer->Start(); |
- } |
- }); |
- |
- analyzer->Wait(); |
- |
- task_queue_.SendTask([&]() { |
- for (std::unique_ptr<test::VideoCapturer>& video_caputurer : |
- thumbnail_capturers_) |
- video_caputurer->Stop(); |
- video_capturer_->Stop(); |
- for (VideoReceiveStream* thumbnail_receive_stream : |
- thumbnail_receive_streams_) |
- thumbnail_receive_stream->Stop(); |
- for (VideoReceiveStream* receive_stream : video_receive_streams_) |
- receive_stream->Stop(); |
- for (VideoSendStream* thumbnail_send_stream : thumbnail_send_streams_) |
- thumbnail_send_stream->Stop(); |
- video_send_stream_->Stop(); |
- |
- DestroyStreams(); |
- DestroyThumbnailStreams(); |
- |
- event_log_->StopLogging(); |
- if (graph_data_output_file) |
- fclose(graph_data_output_file); |
- |
- video_capturer_.reset(); |
- send_transport.reset(); |
- recv_transport.reset(); |
- |
- DestroyCalls(); |
- }); |
+ RTC_DCHECK(video_capturer->get()); |
} |
void VideoQualityTest::SetupAudio(int send_channel_id, |
int receive_channel_id, |
Transport* transport, |
AudioReceiveStream** audio_receive_stream) { |
- audio_send_config_ = AudioSendStream::Config(transport); |
- audio_send_config_.voe_channel_id = send_channel_id; |
- audio_send_config_.rtp.ssrc = kAudioSendSsrc; |
- |
- // Add extension to enable audio send side BWE, and allow audio bit rate |
- // adaptation. |
- audio_send_config_.rtp.extensions.clear(); |
- if (params_.call.send_side_bwe) { |
- audio_send_config_.rtp.extensions.push_back( |
- webrtc::RtpExtension(webrtc::RtpExtension::kTransportSequenceNumberUri, |
- test::kTransportSequenceNumberExtensionId)); |
- audio_send_config_.min_bitrate_bps = kOpusMinBitrateBps; |
- audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps; |
- } |
- audio_send_config_.send_codec_spec = |
- rtc::Optional<AudioSendStream::Config::SendCodecSpec>( |
- {kAudioSendPayloadType, |
- {"OPUS", 48000, 2, |
- {{"usedtx", (params_.audio.dtx ? "1" : "0")}, |
- {"stereo", "1"}}}}); |
- audio_send_config_.encoder_factory = encoder_factory_; |
- audio_send_stream_ = sender_call_->CreateAudioSendStream(audio_send_config_); |
- |
- AudioReceiveStream::Config audio_config; |
- audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; |
- audio_config.rtcp_send_transport = transport; |
- audio_config.voe_channel_id = receive_channel_id; |
- audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc; |
- audio_config.rtp.transport_cc = params_.call.send_side_bwe; |
- audio_config.rtp.extensions = audio_send_config_.rtp.extensions; |
- audio_config.decoder_factory = decoder_factory_; |
- audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}}; |
- if (params_.video.enabled && params_.audio.sync_video) |
- audio_config.sync_group = kSyncGroup; |
- |
- *audio_receive_stream = |
- receiver_call_->CreateAudioReceiveStream(audio_config); |
+ // audio_send_config_ = AudioSendStream::Config(transport); |
+ // audio_send_config_.voe_channel_id = send_channel_id; |
+ // audio_send_config_.rtp.ssrc = kAudioSendSsrc; |
+ |
+ // // Add extension to enable audio send side BWE, and allow audio bit rate |
+ // // adaptation. |
+ // audio_send_config_.rtp.extensions.clear(); |
+ // if (params_.call.send_side_bwe) { |
+ // audio_send_config_.rtp.extensions.push_back( |
+ // webrtc::RtpExtension(webrtc::RtpExtension::kTransportSequenceNumberUri, |
+ // test::kTransportSequenceNumberExtensionId)); |
+ // audio_send_config_.min_bitrate_bps = kOpusMinBitrateBps; |
+ // audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps; |
+ // } |
+ // audio_send_config_.send_codec_spec = |
+ // rtc::Optional<AudioSendStream::Config::SendCodecSpec>( |
+ // {kAudioSendPayloadType, |
+ // {"OPUS", 48000, 2, |
+ // {{"usedtx", (params_.audio.dtx ? "1" : "0")}, |
+ // {"stereo", "1"}}}}); |
+ // audio_send_config_.encoder_factory = encoder_factory_; |
+ // audio_send_stream_ = |
+ // sender_call_->CreateAudioSendStream(audio_send_config_); |
+ |
+ // AudioReceiveStream::Config audio_config; |
+ // audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; |
+ // audio_config.rtcp_send_transport = transport; |
+ // audio_config.voe_channel_id = receive_channel_id; |
+ // audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc; |
+ // audio_config.rtp.transport_cc = params_.call.send_side_bwe; |
+ // audio_config.rtp.extensions = audio_send_config_.rtp.extensions; |
+ // audio_config.decoder_factory = decoder_factory_; |
+ // audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}}; |
+ // if (params_.video.enabled && params_.audio.sync_video) |
+ // audio_config.sync_group = kSyncGroup; |
+ |
+ // *audio_receive_stream = |
+ // receiver_call_->CreateAudioReceiveStream(audio_config); |
} |
-void VideoQualityTest::RunWithRenderers(const Params& params) { |
- std::unique_ptr<test::LayerFilteringTransport> send_transport; |
- std::unique_ptr<test::DirectTransport> recv_transport; |
- ::VoiceEngineState voe; |
- std::unique_ptr<test::VideoRenderer> local_preview; |
- std::vector<std::unique_ptr<test::VideoRenderer>> loopback_renderers; |
- AudioReceiveStream* audio_receive_stream = nullptr; |
- |
+void VideoQualityTest::RunWithRenderers() { |
+ std::vector<std::unique_ptr<test::VideoRenderer>> local_renderers; |
+ std::vector<std::unique_ptr<test::VideoRenderer>> loopback_renderers_; |
+ std::vector<VideoSendStream::Config> video_send_configs; |
+ std::vector<VideoEncoderConfig> video_encoder_configs; |
+ std::vector<std::unique_ptr<VideoEncoder>> video_encoders; |
+ std::vector<std::vector<VideoReceiveStream::Config>> |
+ video_receive_configs_vector; |
+ std::vector<std::vector<std::unique_ptr<VideoDecoder>>> |
+ allocated_decoders_vector; |
+ std::vector<std::vector<VideoReceiveStream*>> video_receive_streams_vector; |
+ std::vector<std::unique_ptr<test::VideoCapturer>> video_capturers; |
+ std::vector<VideoSendStream*> video_send_streams; |
task_queue_.SendTask([&]() { |
- params_ = params; |
- CheckParams(); |
- |
- // TODO(ivica): Remove bitrate_config and use the default Call::Config(), to |
- // match the full stack tests. |
- Call::Config call_config(event_log_.get()); |
- call_config.bitrate_config = params_.call.call_bitrate_config; |
- |
- rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing( |
- webrtc::AudioProcessing::Create()); |
- |
- if (params_.audio.enabled) { |
- CreateVoiceEngine(&voe, audio_processing.get(), decoder_factory_); |
- AudioState::Config audio_state_config; |
- audio_state_config.voice_engine = voe.voice_engine; |
- audio_state_config.audio_mixer = AudioMixerImpl::Create(); |
- audio_state_config.audio_processing = audio_processing; |
- call_config.audio_state = AudioState::Create(audio_state_config); |
- } |
- |
- CreateCalls(call_config, call_config); |
- |
- // TODO(minyue): consider if this is a good transport even for audio only |
- // calls. |
- send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( |
- &task_queue_, params.pipe, sender_call_.get(), kPayloadTypeVP8, |
- kPayloadTypeVP9, params.video.selected_tl, params_.ss.selected_sl, |
- payload_type_map_); |
- |
- recv_transport = rtc::MakeUnique<test::DirectTransport>( |
- &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_); |
- |
- // TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at |
- // least share as much code as possible. That way this test would also match |
- // the full stack tests better. |
- send_transport->SetReceiver(receiver_call_->Receiver()); |
- recv_transport->SetReceiver(sender_call_->Receiver()); |
- |
- if (params_.video.enabled) { |
- // Create video renderers. |
- local_preview.reset(test::VideoRenderer::Create( |
- "Local Preview", params_.video.width, params_.video.height)); |
- |
- const size_t selected_stream_id = params_.ss.selected_stream; |
- const size_t num_streams = params_.ss.streams.size(); |
- |
- if (selected_stream_id == num_streams) { |
- for (size_t stream_id = 0; stream_id < num_streams; ++stream_id) { |
- std::ostringstream oss; |
- oss << "Loopback Video - Stream #" << static_cast<int>(stream_id); |
- loopback_renderers.emplace_back(test::VideoRenderer::Create( |
- oss.str().c_str(), params_.ss.streams[stream_id].width, |
- params_.ss.streams[stream_id].height)); |
+ int i = 0; |
+ for (Params params : params_) { |
+ if (params.video.enabled) { |
+ // Create video renderers. |
+ std::stringstream preview_ss; |
+ preview_ss << "Local Preview " << i++; |
+ local_renderers.emplace_back(test::VideoRenderer::Create( |
+ preview_ss.str().c_str(), params.video.width, params.video.height)); |
+ |
+ const size_t selected_stream_id = params.ss.selected_stream; |
+ const size_t num_streams = params.ss.streams.size(); |
+ |
+ if (selected_stream_id == num_streams) { |
+ for (size_t stream_id = 0; stream_id < num_streams; ++stream_id) { |
+ std::ostringstream oss; |
+ oss << "Loopback Video " << i << ", Stream #" |
+ << static_cast<int>(stream_id); |
+ loopback_renderers_.emplace_back(test::VideoRenderer::Create( |
+ oss.str().c_str(), params.ss.streams[stream_id].width, |
+ params.ss.streams[stream_id].height)); |
+ } |
+ } else { |
+ std::stringstream loopback_ss; |
+ loopback_ss << "Loopback Video " << i; |
+ loopback_renderers_.emplace_back(test::VideoRenderer::Create( |
+ loopback_ss.str().c_str(), |
+ params.ss.streams[selected_stream_id].width, |
+ params.ss.streams[selected_stream_id].height)); |
} |
- } else { |
- loopback_renderers.emplace_back(test::VideoRenderer::Create( |
- "Loopback Video", params_.ss.streams[selected_stream_id].width, |
- params_.ss.streams[selected_stream_id].height)); |
- } |
- SetupVideo(send_transport.get(), recv_transport.get()); |
- |
- video_send_config_.pre_encode_callback = local_preview.get(); |
- if (selected_stream_id == num_streams) { |
- for (size_t stream_id = 0; stream_id < num_streams; ++stream_id) { |
- video_receive_configs_[stream_id].renderer = |
- loopback_renderers[stream_id].get(); |
- if (params_.audio.enabled && params_.audio.sync_video) |
- video_receive_configs_[stream_id].sync_group = kSyncGroup; |
+ video_send_configs.emplace_back(nullptr); |
+ video_send_configs.back().periodic_alr_bandwidth_probing = true; |
+ video_encoder_configs.emplace_back(); |
+ video_encoders.emplace_back(); |
+ video_receive_configs_vector.emplace_back(); |
+ allocated_decoders_vector.emplace_back(); |
+ std::vector<uint32_t> send_ssrcs; |
+ std::vector<uint32_t> send_rtx_ssrcs; |
+ for (size_t i = 0; i < params.ss.streams.size(); ++i) { |
+ send_ssrcs.emplace_back(last_ssrc++); |
+ send_rtx_ssrcs.emplace_back(last_ssrc++); |
+ } |
+ SetupVideo(send_transport_.get(), recv_transport_.get(), ¶ms, |
+ &video_send_configs.back(), &video_encoder_configs.back(), |
+ &video_encoders.back(), &video_receive_configs_vector.back(), |
+ &allocated_decoders_vector.back(), &send_ssrcs, |
+ &send_rtx_ssrcs); |
+ |
+ video_send_configs.back().pre_encode_callback = |
+ local_renderers.back().get(); |
+ if (selected_stream_id == num_streams) { |
+ for (size_t stream_id = 0; stream_id < num_streams; ++stream_id) { |
+ video_receive_configs_vector.back()[stream_id].renderer = |
+ loopback_renderers_[stream_id].get(); |
+ if (params.audio.enabled && params.audio.sync_video) |
+ video_receive_configs_vector.back()[stream_id].sync_group = |
+ kSyncGroup; |
+ } |
+ } else { |
+ video_receive_configs_vector.back()[selected_stream_id].renderer = |
+ loopback_renderers_.back().get(); |
+ if (params.audio.enabled && params.audio.sync_video) |
+ video_receive_configs_vector.back()[selected_stream_id].sync_group = |
+ kSyncGroup; |
} |
- } else { |
- video_receive_configs_[selected_stream_id].renderer = |
- loopback_renderers.back().get(); |
- if (params_.audio.enabled && params_.audio.sync_video) |
- video_receive_configs_[selected_stream_id].sync_group = kSyncGroup; |
- } |
- if (params_.screenshare.enabled) |
- SetupScreenshareOrSVC(); |
+ if (params.screenshare.enabled) |
+ SetupScreenshareOrSVC(¶ms, &video_encoder_configs.back(), |
+ &frame_generator_); |
- CreateFlexfecStreams(); |
- CreateVideoStreams(); |
+ video_receive_streams_vector.emplace_back(); |
- CreateCapturer(); |
- video_send_stream_->SetSource(video_capturer_.get(), |
- degradation_preference_); |
- } |
+ video_send_streams.emplace_back(CreateVideoStreams( |
+ sender_call_.get(), receiver_call_.get(), |
+ &video_send_configs.back(), &video_receive_configs_vector.back(), |
+ &video_receive_streams_vector.back(), |
+ &video_encoder_configs.back())); |
- if (params_.audio.enabled) { |
- SetupAudio(voe.send_channel_id, voe.receive_channel_id, |
- send_transport.get(), &audio_receive_stream); |
- } |
- |
- for (VideoReceiveStream* receive_stream : video_receive_streams_) |
- StartEncodedFrameLogs(receive_stream); |
- StartEncodedFrameLogs(video_send_stream_); |
+ video_capturers.emplace_back(); |
+ CreateCapturer(¶ms, &video_capturers.back()); |
+ video_send_streams.back()->SetSource(video_capturers.back().get(), |
+ degradation_preference_); |
+ } |
- // Start sending and receiving video. |
- if (params_.video.enabled) { |
- for (VideoReceiveStream* video_receive_stream : video_receive_streams_) |
- video_receive_stream->Start(); |
+ RTC_CHECK(!params.audio.enabled); |
- video_send_stream_->Start(); |
- video_capturer_->Start(); |
- } |
+ for (VideoReceiveStream* receive_stream : |
+ video_receive_streams_vector.back()) |
+ StartEncodedFrameLogs(¶ms, receive_stream); |
+ StartEncodedFrameLogs(¶ms, video_send_streams.back()); |
- if (params_.audio.enabled) { |
- // Start receiving audio. |
- audio_receive_stream->Start(); |
- EXPECT_EQ(0, voe.base->StartPlayout(voe.receive_channel_id)); |
- |
- // Start sending audio. |
- audio_send_stream_->Start(); |
- EXPECT_EQ(0, voe.base->StartSend(voe.send_channel_id)); |
+ // Start sending and receiving video. |
+ if (params.video.enabled) { |
+ for (VideoReceiveStream* receive_stream : |
+ video_receive_streams_vector.back()) |
+ receive_stream->Start(); |
+ video_send_streams.back()->Start(); |
+ video_capturers.back()->Start(); |
+ } |
} |
}); |
test::PressEnterToContinue(); |
task_queue_.SendTask([&]() { |
- if (params_.audio.enabled) { |
- // Stop sending audio. |
- EXPECT_EQ(0, voe.base->StopSend(voe.send_channel_id)); |
- audio_send_stream_->Stop(); |
- |
- // Stop receiving audio. |
- EXPECT_EQ(0, voe.base->StopPlayout(voe.receive_channel_id)); |
- audio_receive_stream->Stop(); |
- sender_call_->DestroyAudioSendStream(audio_send_stream_); |
- receiver_call_->DestroyAudioReceiveStream(audio_receive_stream); |
+ for (std::unique_ptr<test::VideoCapturer>& capturer : video_capturers) |
+ capturer->Stop(); |
+ |
+ for (VideoSendStream* video_send_stream : video_send_streams) { |
+ video_send_stream->Stop(); |
+ sender_call_->DestroyVideoSendStream(video_send_stream); |
} |
- // Stop receiving and sending video. |
- if (params_.video.enabled) { |
- video_capturer_->Stop(); |
- video_send_stream_->Stop(); |
- for (FlexfecReceiveStream* flexfec_receive_stream : |
- flexfec_receive_streams_) { |
- for (VideoReceiveStream* video_receive_stream : |
- video_receive_streams_) { |
- video_receive_stream->RemoveSecondarySink(flexfec_receive_stream); |
- } |
- receiver_call_->DestroyFlexfecReceiveStream(flexfec_receive_stream); |
- } |
- for (VideoReceiveStream* receive_stream : video_receive_streams_) { |
- receive_stream->Stop(); |
- receiver_call_->DestroyVideoReceiveStream(receive_stream); |
+ for (std::vector<VideoReceiveStream*> video_receive_streams : |
+ video_receive_streams_vector) { |
+ for (VideoReceiveStream* video_receive_stream : video_receive_streams) { |
+ video_receive_stream->Stop(); |
+ receiver_call_->DestroyVideoReceiveStream(video_receive_stream); |
} |
- sender_call_->DestroyVideoSendStream(video_send_stream_); |
} |
+ local_renderers.clear(); |
+ loopback_renderers_.clear(); |
+ video_send_configs.clear(); |
+ video_encoder_configs.clear(); |
+ video_receive_configs_vector.clear(); |
+ allocated_decoders_vector.clear(); |
+ video_receive_streams_vector.clear(); |
+ video_capturers.clear(); |
+ video_send_streams.clear(); |
+ send_transport_.reset(); |
+ receive_transport_.reset(); |
+ recv_transport_.reset(); |
video_capturer_.reset(); |
- send_transport.reset(); |
- recv_transport.reset(); |
+ DestroyCalls(); |
+ }); |
+} |
- if (params_.audio.enabled) |
- DestroyVoiceEngine(&voe); |
+void VideoQualityTest::SetupCall( |
+ const Call::Config::BitrateConfig& bitrate_config, |
+ const FakeNetworkPipe::Config& pipe_config) { |
+ // TODO(philipel): Validate bitrate/pipe config. |
+ bitrate_config_ = bitrate_config; |
+ pipe_config_ = pipe_config; |
- local_preview.reset(); |
- loopback_renderers.clear(); |
+ // TODO(ivica): Remove bitrate_config and use the default Call::Config(), to |
+ // match the full stack tests. |
+ Call::Config sender_config(event_log_.get()); |
+ sender_config.bitrate_config = bitrate_config_; |
+ Call::Config receiver_config(RtcEventLog::CreateNull().release()); |
+ receiver_config.bitrate_config = bitrate_config_; |
- DestroyCalls(); |
+ task_queue_.SendTask([&]() { |
+ CreateCalls(sender_config, receiver_config); |
+ send_transport_.reset(new test::DirectTransport( |
+ &task_queue_, pipe_config_, sender_call_.get(), payload_type_map_)); |
+ recv_transport_.reset(new test::DirectTransport( |
+ &task_queue_, pipe_config_, receiver_call_.get(), payload_type_map_)); |
+ |
+ send_transport_->SetReceiver(receiver_call_->Receiver()); |
+ recv_transport_->SetReceiver(sender_call_->Receiver()); |
}); |
} |
-void VideoQualityTest::StartEncodedFrameLogs(VideoSendStream* stream) { |
- if (!params_.logging.encoded_frame_base_path.empty()) { |
+void VideoQualityTest::AddParams(const Params& p) { |
+ params_.push_back(p); |
+ CheckParams(¶ms_.back()); |
+} |
+ |
+void VideoQualityTest::StartEncodedFrameLogs(Params* params, |
+ VideoSendStream* stream) { |
+ if (!params->logging.encoded_frame_base_path.empty()) { |
std::ostringstream str; |
str << send_logs_++; |
std::string prefix = |
- params_.logging.encoded_frame_base_path + "." + str.str() + ".send."; |
+ params->logging.encoded_frame_base_path + "." + str.str() + ".send."; |
stream->EnableEncodedFrameRecording( |
std::vector<rtc::PlatformFile>( |
{rtc::CreatePlatformFile(prefix + "1.ivf"), |
@@ -2152,12 +1975,13 @@ void VideoQualityTest::StartEncodedFrameLogs(VideoSendStream* stream) { |
} |
} |
-void VideoQualityTest::StartEncodedFrameLogs(VideoReceiveStream* stream) { |
- if (!params_.logging.encoded_frame_base_path.empty()) { |
+void VideoQualityTest::StartEncodedFrameLogs(Params* params, |
+ VideoReceiveStream* stream) { |
+ if (!params->logging.encoded_frame_base_path.empty()) { |
std::ostringstream str; |
str << receive_logs_++; |
std::string path = |
- params_.logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; |
+ params->logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; |
stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), |
100000000); |
} |