diff --git a/webrtc/video/full_stack.cc b/webrtc/video/full_stack.cc index 6433f6feb7..73744e01ed 100644 --- a/webrtc/video/full_stack.cc +++ b/webrtc/video/full_stack.cc @@ -26,7 +26,7 @@ class FullStackTest : public VideoQualityTest { // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. VideoQualityTest::Params foreman_cif; foreman_cif.video = {true, 352, 288, 30, 700000, 700000, 700000, false, - video_codec, 1, 0, 0, false, "", "foreman_cif"}; + video_codec, 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_net_delay_0_0_plr_0_" + video_codec, 0.0, 0.0, kFullStackTestDurationSecs}; RunTest(foreman_cif); @@ -35,7 +35,7 @@ class FullStackTest : public VideoQualityTest { void ForemanCifPlr5(const std::string& video_codec) { VideoQualityTest::Params foreman_cif; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, - video_codec, 1, 0, 0, false, "", "foreman_cif"}; + video_codec, 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_delay_50_0_plr_5_" + video_codec, 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.loss_percent = 5; @@ -68,7 +68,7 @@ TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) { VideoQualityTest::Params paris_qcif; paris_qcif.call.send_side_bwe = true; paris_qcif.video = {true, 176, 144, 30, 300000, 300000, 300000, false, - "VP8", 1, 0, 0, false, "", "paris_qcif"}; + "VP8", 1, 0, 0, false, false, "", "paris_qcif"}; paris_qcif.analyzer = {"net_delay_0_0_plr_0", 36.0, 0.96, kFullStackTestDurationSecs}; RunTest(paris_qcif); @@ -79,7 +79,7 @@ TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 700000, 700000, 700000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_net_delay_0_0_plr_0", 0.0, 0.0, kFullStackTestDurationSecs}; RunTest(foreman_cif); @@ -89,7 +89,7 @@ TEST_F(FullStackTest, ForemanCifPlr5) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_delay_50_0_plr_5", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.loss_percent = 5; @@ -101,7 +101,7 @@ TEST_F(FullStackTest, ForemanCif500kbps) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_500kbps", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 0; @@ -114,7 +114,7 @@ TEST_F(FullStackTest, ForemanCif500kbpsLimitedQueue) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_500kbps_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 32; @@ -127,7 +127,7 @@ TEST_F(FullStackTest, ForemanCif500kbps100ms) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_500kbps_100ms", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 0; @@ -140,7 +140,7 @@ TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_500kbps_100ms_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 32; @@ -152,7 +152,7 @@ TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) { TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueueRecvBwe) { VideoQualityTest::Params foreman_cif; foreman_cif.video = {true, 352, 288, 30, 30000, 500000, 2000000, false, "VP8", - 1, 0, 0, false, "", "foreman_cif"}; + 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_500kbps_100ms_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 32; @@ -165,7 +165,7 @@ TEST_F(FullStackTest, ForemanCif1000kbps100msLimitedQueue) { VideoQualityTest::Params foreman_cif; foreman_cif.call.send_side_bwe = true; foreman_cif.video = {true, 352, 288, 30, 30000, 2000000, 2000000, false, - "VP8", 1, 0, 0, false, "", "foreman_cif"}; + "VP8", 1, 0, 0, false, false, "", "foreman_cif"}; foreman_cif.analyzer = {"foreman_cif_1000kbps_100ms_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}; foreman_cif.pipe.queue_length_packets = 32; @@ -178,7 +178,7 @@ TEST_F(FullStackTest, ConferenceMotionHd2000kbps100msLimitedQueue) { VideoQualityTest::Params conf_motion_hd; conf_motion_hd.call.send_side_bwe = true; conf_motion_hd.video = {true, 1280, 720, 50, 30000, 3000000, 3000000, false, - "VP8", 1, 0, 0, false, "", + "VP8", 1, 0, 0, false, false, "", "ConferenceMotion_1280_720_50"}; conf_motion_hd.analyzer = {"conference_motion_hd_2000kbps_100ms_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}; @@ -192,7 +192,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL) { VideoQualityTest::Params screenshare; screenshare.call.send_side_bwe = true; screenshare.video = {true, 1850, 1110, 5, 50000, 200000, 2000000, false, - "VP8", 2, 1, 400000, false, "", ""}; + "VP8", 2, 1, 400000, false, false, "", ""}; screenshare.screenshare = {true, 10}; screenshare.analyzer = {"screenshare_slides", 0.0, 0.0, kFullStackTestDurationSecs}; @@ -203,7 +203,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_Scroll) { VideoQualityTest::Params config; config.call.send_side_bwe = true; config.video = {true, 1850, 1110 / 2, 5, 50000, 200000, 2000000, false, - "VP8", 2, 1, 400000, false, "", ""}; + "VP8", 2, 1, 400000, false, false, "", ""}; config.screenshare = {true, 10, 2}; config.analyzer = {"screenshare_slides_scrolling", 0.0, 0.0, kFullStackTestDurationSecs}; @@ -214,7 +214,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_LossyNet) { VideoQualityTest::Params screenshare; screenshare.call.send_side_bwe = true; screenshare.video = {true, 1850, 1110, 5, 50000, 200000, 2000000, false, - "VP8", 2, 1, 400000, false, "", ""}; + "VP8", 2, 1, 400000, false, false, "", ""}; screenshare.screenshare = {true, 10}; screenshare.analyzer = {"screenshare_slides_lossy_net", 0.0, 0.0, kFullStackTestDurationSecs}; @@ -228,7 +228,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_VeryLossyNet) { VideoQualityTest::Params screenshare; screenshare.call.send_side_bwe = true; screenshare.video = {true, 1850, 1110, 5, 50000, 200000, 2000000, false, - "VP8", 2, 1, 400000, false, "", ""}; + "VP8", 2, 1, 400000, false, false, "", ""}; screenshare.screenshare = {true, 10}; screenshare.analyzer = {"screenshare_slides_very_lossy", 0.0, 0.0, kFullStackTestDurationSecs}; @@ -243,7 +243,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP9_2SL) { VideoQualityTest::Params screenshare; screenshare.call.send_side_bwe = true; screenshare.video = {true, 1850, 1110, 5, 50000, 200000, 2000000, false, - "VP9", 1, 0, 400000, false, "", ""}; + "VP9", 1, 0, 400000, false, false, "", ""}; screenshare.screenshare = {true, 10}; screenshare.analyzer = {"screenshare_slides_vp9_2sl", 0.0, 0.0, kFullStackTestDurationSecs}; diff --git a/webrtc/video/screenshare_loopback.cc b/webrtc/video/screenshare_loopback.cc index cfca27f229..91b2902fd7 100644 --- a/webrtc/video/screenshare_loopback.cc +++ b/webrtc/video/screenshare_loopback.cc @@ -244,7 +244,8 @@ void Loopback() { flags::NumTemporalLayers(), flags::SelectedTL(), flags::MinTransmitBitrateKbps() * 1000, - false, + false, // ULPFEC disabled. + false, // FlexFEC disabled. flags::EncodedFramePath(), ""}; params.audio = {false, false}; diff --git a/webrtc/video/video_loopback.cc b/webrtc/video/video_loopback.cc index 26ed9b9d36..658fdb23f5 100644 --- a/webrtc/video/video_loopback.cc +++ b/webrtc/video/video_loopback.cc @@ -253,6 +253,7 @@ void Loopback() { flags::SelectedTL(), 0, // No min transmit bitrate. flags::FLAGS_use_fec, + false, // TODO(brandtr): Wire up FlexFEC in future CL. flags::EncodedFramePath(), flags::Clip()}; params.audio = {flags::FLAGS_audio, flags::FLAGS_audio_video_sync}; diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc index 7186fed3ac..b48c692376 100644 --- a/webrtc/video/video_quality_test.cc +++ b/webrtc/video/video_quality_test.cc @@ -817,7 +817,7 @@ VideoQualityTest::VideoQualityTest() VideoQualityTest::Params::Params() : call({false, Call::Config::BitrateConfig()}), video({false, 640, 480, 30, 50, 800, 800, false, "VP8", 1, -1, 0, false, - "", ""}), + false, "", ""}), audio({false, false}), screenshare({false, 10, 0}), analyzer({"", 0.0, 0.0, 0, "", ""}), @@ -1038,6 +1038,9 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, 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_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) { @@ -1058,6 +1061,38 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, kSendRtxPayloadType; video_receive_configs_[i].rtp.transport_cc = params_.call.send_side_bwe; } + + if (params_.video.flexfec) { + video_send_config_.rtp.flexfec.flexfec_payload_type = kFlexfecPayloadType; + video_send_config_.rtp.flexfec.flexfec_ssrc = kFlexfecSendSsrc; + video_send_config_.rtp.flexfec.protected_media_ssrcs = { + kVideoSendSsrcs[params_.ss.selected_stream]}; + + FlexfecReceiveStream::Config flexfec_receive_config; + flexfec_receive_config.flexfec_payload_type = + video_send_config_.rtp.flexfec.flexfec_payload_type; + flexfec_receive_config.flexfec_ssrc = + video_send_config_.rtp.flexfec.flexfec_ssrc; + flexfec_receive_config.protected_media_ssrcs = + video_send_config_.rtp.flexfec.protected_media_ssrcs; + 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; + + 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; + } } void VideoQualityTest::SetupScreenshare() { @@ -1215,6 +1250,7 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { if (params_.screenshare.enabled) SetupScreenshare(); + CreateFlexfecStreams(); CreateVideoStreams(); analyzer.SetSendStream(video_send_stream_); video_send_stream_->SetSource( @@ -1230,6 +1266,8 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { video_send_stream_->Start(); for (VideoReceiveStream* receive_stream : video_receive_streams_) receive_stream->Start(); + for (FlexfecReceiveStream* receive_stream : flexfec_receive_streams_) + receive_stream->Start(); video_capturer_->Start(); analyzer.Wait(); @@ -1238,6 +1276,8 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { recv_transport.StopSending(); video_capturer_->Stop(); + for (FlexfecReceiveStream* receive_stream : flexfec_receive_streams_) + receive_stream->Stop(); for (VideoReceiveStream* receive_stream : video_receive_streams_) receive_stream->Stop(); video_send_stream_->Stop(); @@ -1317,6 +1357,7 @@ void VideoQualityTest::RunWithRenderers(const Params& params) { transport.SetReceiver(call->Receiver()); VideoReceiveStream* video_receive_stream = nullptr; + FlexfecReceiveStream* flexfec_receive_stream = nullptr; std::unique_ptr local_preview; std::unique_ptr loopback_video; if (params_.video.enabled) { @@ -1337,36 +1378,21 @@ void VideoQualityTest::RunWithRenderers(const Params& params) { params_.ss.streams[stream_id].height)); SetupVideo(&transport, &transport); - - // TODO(minyue): maybe move the following to SetupVideo() to make code - // cleaner. Currently, RunWithRenderers() and RunWithAnalyzer() differ in - // the way they treat FEC etc., which makes it complicated to put these - // additional video setup into SetupVideo(). video_send_config_.pre_encode_callback = local_preview.get(); video_receive_configs_[stream_id].renderer = loopback_video.get(); if (params_.audio.enabled && params_.audio.sync_video) video_receive_configs_[stream_id].sync_group = kSyncGroup; - video_send_config_.suspend_below_min_bitrate = - params_.video.suspend_below_min_bitrate; - - if (params.video.fec) { - 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; - video_receive_configs_[stream_id].rtp.ulpfec.red_payload_type = - kRedPayloadType; - video_receive_configs_[stream_id].rtp.ulpfec.ulpfec_payload_type = - kUlpfecPayloadType; - video_receive_configs_[stream_id].rtp.ulpfec.red_rtx_payload_type = - kRtxRedPayloadType; - } - if (params_.screenshare.enabled) SetupScreenshare(); video_send_stream_ = call->CreateVideoSendStream( video_send_config_.Copy(), video_encoder_config_.Copy()); + if (params_.video.flexfec) { + RTC_DCHECK(!flexfec_receive_configs_.empty()); + flexfec_receive_stream = + call->CreateFlexfecReceiveStream(flexfec_receive_configs_[0]); + } video_receive_stream = call->CreateVideoReceiveStream( video_receive_configs_[stream_id].Copy()); CreateCapturer(); @@ -1386,6 +1412,8 @@ void VideoQualityTest::RunWithRenderers(const Params& params) { // Start sending and receiving video. if (params_.video.enabled) { + if (flexfec_receive_stream) + flexfec_receive_stream->Start(); video_receive_stream->Start(); video_send_stream_->Start(); video_capturer_->Start(); @@ -1420,6 +1448,10 @@ void VideoQualityTest::RunWithRenderers(const Params& params) { video_capturer_->Stop(); video_send_stream_->Stop(); video_receive_stream->Stop(); + if (flexfec_receive_stream) { + flexfec_receive_stream->Stop(); + call->DestroyFlexfecReceiveStream(flexfec_receive_stream); + } call->DestroyVideoReceiveStream(video_receive_stream); call->DestroyVideoSendStream(video_send_stream_); } diff --git a/webrtc/video/video_quality_test.h b/webrtc/video/video_quality_test.h index d06421ce6a..b741ad331a 100644 --- a/webrtc/video/video_quality_test.h +++ b/webrtc/video/video_quality_test.h @@ -46,7 +46,8 @@ class VideoQualityTest : public test::CallTest { int num_temporal_layers; int selected_tl; int min_transmit_bps; - bool fec; + bool ulpfec; + bool flexfec; std::string encoded_frame_base_path; std::string clip_name; } video;