blob: 7d22030ce21ffe70ee55f38bed90acb0ecc73154 [file] [log] [blame]
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:591/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <stdio.h>
Jonas Olsson5b2eda42019-06-11 12:29:4012
Yves Gerey3e707812018-11-28 15:47:4913#include <memory>
Florent Castelli8037fc62024-08-29 13:00:4014#include <optional>
Yves Gerey3e707812018-11-28 15:47:4915#include <string>
16#include <vector>
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5917
Mirko Bonadei2ab97f62019-07-18 11:44:1218#include "absl/flags/flag.h"
19#include "absl/flags/parse.h"
Yves Gerey3e707812018-11-28 15:47:4920#include "api/test/simulated_network.h"
21#include "api/test/video_quality_test_fixture.h"
Mirko Bonadei738bfa72019-09-17 12:47:3822#include "api/transport/bitrate_settings.h"
Per K5566b912024-05-15 15:53:0223#include "api/units/data_rate.h"
Yves Gerey3e707812018-11-28 15:47:4924#include "api/video_codecs/video_codec.h"
25#include "rtc_base/checks.h"
Mirko Bonadei45a4c412018-07-31 13:07:2826#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 17:11:0027#include "rtc_base/string_encode.h"
Mirko Bonadei17f48782018-09-28 06:51:1028#include "system_wrappers/include/field_trial.h"
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5929#include "test/field_trial.h"
30#include "test/gtest.h"
31#include "test/run_test.h"
Danil Chapovalovf2443a72023-10-09 14:39:4032#include "test/test_flags.h"
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5933#include "video/video_quality_test.h"
34
Mirko Bonadei2ab97f62019-07-18 11:44:1235// Flags for video.
36ABSL_FLAG(int, vwidth, 640, "Video width.");
37
38ABSL_FLAG(int, vheight, 480, "Video height.");
39
40ABSL_FLAG(int, vfps, 30, "Video frames per second.");
41
42ABSL_FLAG(int,
43 capture_device_index,
44 0,
45 "Capture device to select for video stream");
46
47ABSL_FLAG(int, vtarget_bitrate, 400, "Video stream target bitrate in kbps.");
48
49ABSL_FLAG(int, vmin_bitrate, 100, "Video stream min bitrate in kbps.");
50
51ABSL_FLAG(int, vmax_bitrate, 2000, "Video stream max bitrate in kbps.");
52
53ABSL_FLAG(bool,
54 suspend_below_min_bitrate,
55 false,
56 "Suspends video below the configured min bitrate.");
57
58ABSL_FLAG(int,
59 vnum_temporal_layers,
60 1,
61 "Number of temporal layers for video. Set to 1-4 to override.");
62
63ABSL_FLAG(int, vnum_streams, 0, "Number of video streams to show or analyze.");
64
65ABSL_FLAG(int,
66 vnum_spatial_layers,
67 1,
68 "Number of video spatial layers to use.");
69
70ABSL_FLAG(int,
71 vinter_layer_pred,
72 2,
73 "Video inter-layer prediction mode. "
74 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
75
76ABSL_FLAG(std::string,
77 vstream0,
78 "",
79 "Comma separated values describing VideoStream for video stream #0.");
80
81ABSL_FLAG(std::string,
82 vstream1,
83 "",
84 "Comma separated values describing VideoStream for video stream #1.");
85
86ABSL_FLAG(std::string,
87 vsl0,
88 "",
89 "Comma separated values describing SpatialLayer for video layer #0.");
90
91ABSL_FLAG(std::string,
92 vsl1,
93 "",
94 "Comma separated values describing SpatialLayer for video layer #1.");
95
96ABSL_FLAG(int,
97 vselected_tl,
98 -1,
99 "Temporal layer to show or analyze for screenshare. -1 to disable "
100 "filtering.");
101
102ABSL_FLAG(int,
103 vselected_stream,
104 0,
105 "ID of the stream to show or analyze for screenshare."
106 "Set to the number of streams to show them all.");
107
108ABSL_FLAG(int,
109 vselected_sl,
110 -1,
111 "Spatial layer to show or analyze for screenshare. -1 to disable "
112 "filtering.");
113
114// Flags for screenshare.
115ABSL_FLAG(int,
116 min_transmit_bitrate,
117 400,
118 "Min transmit bitrate incl. padding for screenshare.");
119
120ABSL_FLAG(int, swidth, 1850, "Screenshare width (crops source).");
121
122ABSL_FLAG(int, sheight, 1110, "Screenshare height (crops source).");
123
124ABSL_FLAG(int, sfps, 5, "Frames per second for screenshare.");
125
126ABSL_FLAG(int,
127 starget_bitrate,
128 100,
129 "Screenshare stream target bitrate in kbps.");
130
131ABSL_FLAG(int, smin_bitrate, 100, "Screenshare stream min bitrate in kbps.");
132
133ABSL_FLAG(int, smax_bitrate, 2000, "Screenshare stream max bitrate in kbps.");
134
135ABSL_FLAG(int,
136 snum_temporal_layers,
137 2,
138 "Number of temporal layers to use in screenshare.");
139
140ABSL_FLAG(int,
141 snum_streams,
142 0,
143 "Number of screenshare streams to show or analyze.");
144
145ABSL_FLAG(int,
146 snum_spatial_layers,
147 1,
148 "Number of screenshare spatial layers to use.");
149
150ABSL_FLAG(int,
151 sinter_layer_pred,
152 0,
153 "Screenshare inter-layer prediction mode. "
154 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
155
156ABSL_FLAG(
157 std::string,
158 sstream0,
159 "",
160 "Comma separated values describing VideoStream for screenshare stream #0.");
161
162ABSL_FLAG(
163 std::string,
164 sstream1,
165 "",
166 "Comma separated values describing VideoStream for screenshare stream #1.");
167
168ABSL_FLAG(
169 std::string,
170 ssl0,
171 "",
172 "Comma separated values describing SpatialLayer for screenshare layer #0.");
173
174ABSL_FLAG(
175 std::string,
176 ssl1,
177 "",
178 "Comma separated values describing SpatialLayer for screenshare layer #1.");
179
180ABSL_FLAG(int,
181 sselected_tl,
182 -1,
183 "Temporal layer to show or analyze for screenshare. -1 to disable "
184 "filtering.");
185
186ABSL_FLAG(int,
187 sselected_stream,
188 0,
189 "ID of the stream to show or analyze for screenshare."
190 "Set to the number of streams to show them all.");
191
192ABSL_FLAG(int,
193 sselected_sl,
194 -1,
195 "Spatial layer to show or analyze for screenshare. -1 to disable "
196 "filtering.");
197
198ABSL_FLAG(bool,
199 generate_slides,
200 false,
201 "Whether to use randomly generated slides or read them from files.");
202
203ABSL_FLAG(int,
204 slide_change_interval,
205 10,
206 "Interval (in seconds) between simulated slide changes.");
207
208ABSL_FLAG(
209 int,
210 scroll_duration,
211 0,
212 "Duration (in seconds) during which a slide will be scrolled into place.");
213
214ABSL_FLAG(std::string,
215 slides,
216 "",
217 "Comma-separated list of *.yuv files to display as slides.");
218
219// Flags common with screenshare and video loopback, with equal default values.
220ABSL_FLAG(int, start_bitrate, 600, "Call start bitrate in kbps.");
221
222ABSL_FLAG(std::string, codec, "VP8", "Video codec to use.");
223
224ABSL_FLAG(bool,
225 analyze_video,
226 false,
227 "Analyze video stream (if --duration is present)");
228
229ABSL_FLAG(bool,
230 analyze_screenshare,
231 false,
232 "Analyze screenshare stream (if --duration is present)");
233
234ABSL_FLAG(
235 int,
236 duration,
237 0,
238 "Duration of the test in seconds. If 0, rendered will be shown instead.");
239
240ABSL_FLAG(std::string, output_filename, "", "Target graph data filename.");
241
242ABSL_FLAG(std::string,
243 graph_title,
244 "",
245 "If empty, title will be generated automatically.");
246
247ABSL_FLAG(int, loss_percent, 0, "Percentage of packets randomly lost.");
248
249ABSL_FLAG(int,
250 avg_burst_loss_length,
251 -1,
252 "Average burst length of lost packets.");
253
254ABSL_FLAG(int,
255 link_capacity,
256 0,
257 "Capacity (kbps) of the fake link. 0 means infinite.");
258
259ABSL_FLAG(int, queue_size, 0, "Size of the bottleneck link queue in packets.");
260
261ABSL_FLAG(int,
262 avg_propagation_delay_ms,
263 0,
264 "Average link propagation delay in ms.");
265
266ABSL_FLAG(std::string,
267 rtc_event_log_name,
268 "",
269 "Filename for rtc event log. Two files "
270 "with \"_send\" and \"_recv\" suffixes will be created. "
271 "Works only when --duration is set.");
272
273ABSL_FLAG(std::string,
274 rtp_dump_name,
275 "",
276 "Filename for dumped received RTP stream.");
277
278ABSL_FLAG(int,
279 std_propagation_delay_ms,
280 0,
281 "Link propagation delay standard deviation in ms.");
282
283ABSL_FLAG(std::string,
284 encoded_frame_path,
285 "",
286 "The base path for encoded frame logs. Created files will have "
287 "the form <encoded_frame_path>.<n>.(recv|send.<m>).ivf");
288
289ABSL_FLAG(bool, logs, false, "print logs to stderr");
290
291ABSL_FLAG(bool, send_side_bwe, true, "Use send-side bandwidth estimation");
292
293ABSL_FLAG(bool, generic_descriptor, false, "Use the generic frame descriptor.");
294
295ABSL_FLAG(bool, allow_reordering, false, "Allow packet reordering to occur");
296
297ABSL_FLAG(bool, use_ulpfec, false, "Use RED+ULPFEC forward error correction.");
298
299ABSL_FLAG(bool, use_flexfec, false, "Use FlexFEC forward error correction.");
300
301ABSL_FLAG(bool, audio, false, "Add audio stream");
302
303ABSL_FLAG(bool,
304 audio_video_sync,
305 false,
306 "Sync audio and video stream (no effect if"
307 " audio is false)");
308
309ABSL_FLAG(bool,
310 audio_dtx,
311 false,
312 "Enable audio DTX (no effect if audio is false)");
313
314ABSL_FLAG(bool, video, true, "Add video stream");
315
Mirko Bonadei2ab97f62019-07-18 11:44:12316// Video-specific flags.
317ABSL_FLAG(std::string,
318 vclip,
319 "",
320 "Name of the clip to show. If empty, the camera is used. Use "
321 "\"Generator\" for chroma generator.");
322
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59323namespace webrtc {
Mirko Bonadei2ab97f62019-07-18 11:44:12324namespace {
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59325
Sergey Silkin57027362018-05-15 07:12:05326InterLayerPredMode IntToInterLayerPredMode(int inter_layer_pred) {
327 if (inter_layer_pred == 0) {
328 return InterLayerPredMode::kOn;
329 } else if (inter_layer_pred == 1) {
330 return InterLayerPredMode::kOff;
331 } else {
332 RTC_DCHECK_EQ(inter_layer_pred, 2);
333 return InterLayerPredMode::kOnKeyPic;
334 }
335}
336
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59337size_t VideoWidth() {
Mirko Bonadei2ab97f62019-07-18 11:44:12338 return static_cast<size_t>(absl::GetFlag(FLAGS_vwidth));
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59339}
340
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59341size_t VideoHeight() {
Mirko Bonadei2ab97f62019-07-18 11:44:12342 return static_cast<size_t>(absl::GetFlag(FLAGS_vheight));
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59343}
344
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59345int VideoFps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12346 return absl::GetFlag(FLAGS_vfps);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59347}
348
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59349size_t GetCaptureDevice() {
Mirko Bonadei2ab97f62019-07-18 11:44:12350 return static_cast<size_t>(absl::GetFlag(FLAGS_capture_device_index));
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59351}
352
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59353int VideoTargetBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12354 return absl::GetFlag(FLAGS_vtarget_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59355}
356
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59357int VideoMinBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12358 return absl::GetFlag(FLAGS_vmin_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59359}
360
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59361int VideoMaxBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12362 return absl::GetFlag(FLAGS_vmax_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59363}
364
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59365int VideoNumTemporalLayers() {
Mirko Bonadei2ab97f62019-07-18 11:44:12366 return absl::GetFlag(FLAGS_vnum_temporal_layers);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59367}
368
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59369int VideoNumStreams() {
Mirko Bonadei2ab97f62019-07-18 11:44:12370 return absl::GetFlag(FLAGS_vnum_streams);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59371}
372
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59373int VideoNumSpatialLayers() {
Mirko Bonadei2ab97f62019-07-18 11:44:12374 return absl::GetFlag(FLAGS_vnum_spatial_layers);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59375}
376
Sergey Silkin57027362018-05-15 07:12:05377InterLayerPredMode VideoInterLayerPred() {
Mirko Bonadei2ab97f62019-07-18 11:44:12378 return IntToInterLayerPredMode(absl::GetFlag(FLAGS_vinter_layer_pred));
Sergey Silkin57027362018-05-15 07:12:05379}
380
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59381std::string VideoStream0() {
Mirko Bonadei2ab97f62019-07-18 11:44:12382 return absl::GetFlag(FLAGS_vstream0);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59383}
384
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59385std::string VideoStream1() {
Mirko Bonadei2ab97f62019-07-18 11:44:12386 return absl::GetFlag(FLAGS_vstream1);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59387}
388
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59389std::string VideoSL0() {
Mirko Bonadei2ab97f62019-07-18 11:44:12390 return absl::GetFlag(FLAGS_vsl0);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59391}
392
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59393std::string VideoSL1() {
Mirko Bonadei2ab97f62019-07-18 11:44:12394 return absl::GetFlag(FLAGS_vsl1);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59395}
396
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59397int VideoSelectedTL() {
Mirko Bonadei2ab97f62019-07-18 11:44:12398 return absl::GetFlag(FLAGS_vselected_tl);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59399}
400
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59401int VideoSelectedStream() {
Mirko Bonadei2ab97f62019-07-18 11:44:12402 return absl::GetFlag(FLAGS_vselected_stream);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59403}
404
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59405int VideoSelectedSL() {
Mirko Bonadei2ab97f62019-07-18 11:44:12406 return absl::GetFlag(FLAGS_vselected_sl);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59407}
408
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59409int ScreenshareMinTransmitBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12410 return absl::GetFlag(FLAGS_min_transmit_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59411}
412
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59413size_t ScreenshareWidth() {
Mirko Bonadei2ab97f62019-07-18 11:44:12414 return static_cast<size_t>(absl::GetFlag(FLAGS_swidth));
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59415}
416
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59417size_t ScreenshareHeight() {
Mirko Bonadei2ab97f62019-07-18 11:44:12418 return static_cast<size_t>(absl::GetFlag(FLAGS_sheight));
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59419}
420
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59421int ScreenshareFps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12422 return absl::GetFlag(FLAGS_sfps);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59423}
424
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59425int ScreenshareTargetBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12426 return absl::GetFlag(FLAGS_starget_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59427}
428
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59429int ScreenshareMinBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12430 return absl::GetFlag(FLAGS_smin_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59431}
432
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59433int ScreenshareMaxBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12434 return absl::GetFlag(FLAGS_smax_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59435}
436
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59437int ScreenshareNumTemporalLayers() {
Mirko Bonadei2ab97f62019-07-18 11:44:12438 return absl::GetFlag(FLAGS_snum_temporal_layers);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59439}
440
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59441int ScreenshareNumStreams() {
Mirko Bonadei2ab97f62019-07-18 11:44:12442 return absl::GetFlag(FLAGS_snum_streams);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59443}
444
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59445int ScreenshareNumSpatialLayers() {
Mirko Bonadei2ab97f62019-07-18 11:44:12446 return absl::GetFlag(FLAGS_snum_spatial_layers);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59447}
448
Sergey Silkin57027362018-05-15 07:12:05449InterLayerPredMode ScreenshareInterLayerPred() {
Mirko Bonadei2ab97f62019-07-18 11:44:12450 return IntToInterLayerPredMode(absl::GetFlag(FLAGS_sinter_layer_pred));
Sergey Silkin57027362018-05-15 07:12:05451}
452
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59453std::string ScreenshareStream0() {
Mirko Bonadei2ab97f62019-07-18 11:44:12454 return absl::GetFlag(FLAGS_sstream0);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59455}
456
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59457std::string ScreenshareStream1() {
Mirko Bonadei2ab97f62019-07-18 11:44:12458 return absl::GetFlag(FLAGS_sstream1);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59459}
460
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59461std::string ScreenshareSL0() {
Mirko Bonadei2ab97f62019-07-18 11:44:12462 return absl::GetFlag(FLAGS_ssl0);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59463}
464
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59465std::string ScreenshareSL1() {
Mirko Bonadei2ab97f62019-07-18 11:44:12466 return absl::GetFlag(FLAGS_ssl1);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59467}
468
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59469int ScreenshareSelectedTL() {
Mirko Bonadei2ab97f62019-07-18 11:44:12470 return absl::GetFlag(FLAGS_sselected_tl);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59471}
472
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59473int ScreenshareSelectedStream() {
Mirko Bonadei2ab97f62019-07-18 11:44:12474 return absl::GetFlag(FLAGS_sselected_stream);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59475}
476
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59477int ScreenshareSelectedSL() {
Mirko Bonadei2ab97f62019-07-18 11:44:12478 return absl::GetFlag(FLAGS_sselected_sl);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59479}
480
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59481bool GenerateSlides() {
Mirko Bonadei2ab97f62019-07-18 11:44:12482 return absl::GetFlag(FLAGS_generate_slides);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59483}
484
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59485int SlideChangeInterval() {
Mirko Bonadei2ab97f62019-07-18 11:44:12486 return absl::GetFlag(FLAGS_slide_change_interval);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59487}
488
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59489int ScrollDuration() {
Mirko Bonadei2ab97f62019-07-18 11:44:12490 return absl::GetFlag(FLAGS_scroll_duration);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59491}
492
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59493std::vector<std::string> Slides() {
494 std::vector<std::string> slides;
Mirko Bonadei2ab97f62019-07-18 11:44:12495 std::string slides_list = absl::GetFlag(FLAGS_slides);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59496 rtc::tokenize(slides_list, ',', &slides);
497 return slides;
498}
499
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59500int StartBitrateKbps() {
Mirko Bonadei2ab97f62019-07-18 11:44:12501 return absl::GetFlag(FLAGS_start_bitrate);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59502}
503
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59504std::string Codec() {
Mirko Bonadei2ab97f62019-07-18 11:44:12505 return absl::GetFlag(FLAGS_codec);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59506}
507
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59508bool AnalyzeVideo() {
Mirko Bonadei2ab97f62019-07-18 11:44:12509 return absl::GetFlag(FLAGS_analyze_video);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59510}
511
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59512bool AnalyzeScreenshare() {
Mirko Bonadei2ab97f62019-07-18 11:44:12513 return absl::GetFlag(FLAGS_analyze_screenshare);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59514}
515
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59516int DurationSecs() {
Mirko Bonadei2ab97f62019-07-18 11:44:12517 return absl::GetFlag(FLAGS_duration);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59518}
519
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59520std::string OutputFilename() {
Mirko Bonadei2ab97f62019-07-18 11:44:12521 return absl::GetFlag(FLAGS_output_filename);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59522}
523
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59524std::string GraphTitle() {
Mirko Bonadei2ab97f62019-07-18 11:44:12525 return absl::GetFlag(FLAGS_graph_title);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59526}
527
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59528int LossPercent() {
Mirko Bonadei2ab97f62019-07-18 11:44:12529 return absl::GetFlag(FLAGS_loss_percent);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59530}
531
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59532int AvgBurstLossLength() {
Mirko Bonadei2ab97f62019-07-18 11:44:12533 return absl::GetFlag(FLAGS_avg_burst_loss_length);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59534}
535
Johannes Kron6724f1b2024-06-12 22:57:26536DataRate LinkCapacity() {
537 int link_capacity_kbps = absl::GetFlag(FLAGS_link_capacity);
538 return link_capacity_kbps == 0 ? DataRate::Infinity()
539 : DataRate::KilobitsPerSec(link_capacity_kbps);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59540}
541
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59542int QueueSize() {
Mirko Bonadei2ab97f62019-07-18 11:44:12543 return absl::GetFlag(FLAGS_queue_size);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59544}
545
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59546int AvgPropagationDelayMs() {
Mirko Bonadei2ab97f62019-07-18 11:44:12547 return absl::GetFlag(FLAGS_avg_propagation_delay_ms);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59548}
549
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59550std::string RtcEventLogName() {
Mirko Bonadei2ab97f62019-07-18 11:44:12551 return absl::GetFlag(FLAGS_rtc_event_log_name);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59552}
553
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59554std::string RtpDumpName() {
Mirko Bonadei2ab97f62019-07-18 11:44:12555 return absl::GetFlag(FLAGS_rtp_dump_name);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59556}
557
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59558int StdPropagationDelayMs() {
Mirko Bonadei2ab97f62019-07-18 11:44:12559 return absl::GetFlag(FLAGS_std_propagation_delay_ms);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59560}
561
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59562std::string EncodedFramePath() {
Mirko Bonadei2ab97f62019-07-18 11:44:12563 return absl::GetFlag(FLAGS_encoded_frame_path);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59564}
565
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59566std::string VideoClip() {
Mirko Bonadei2ab97f62019-07-18 11:44:12567 return absl::GetFlag(FLAGS_vclip);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59568}
569
Mirko Bonadei2ab97f62019-07-18 11:44:12570} // namespace
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59571
572void Loopback() {
573 int camera_idx, screenshare_idx;
Mirko Bonadei2ab97f62019-07-18 11:44:12574 RTC_CHECK(!(AnalyzeScreenshare() && AnalyzeVideo()))
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59575 << "Select only one of video or screenshare.";
Mirko Bonadei2ab97f62019-07-18 11:44:12576 RTC_CHECK(!DurationSecs() || AnalyzeScreenshare() || AnalyzeVideo())
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59577 << "If duration is set, exactly one of analyze_* flags should be set.";
578 // Default: camera feed first, if nothing selected.
Mirko Bonadei2ab97f62019-07-18 11:44:12579 if (AnalyzeVideo() || !AnalyzeScreenshare()) {
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59580 camera_idx = 0;
581 screenshare_idx = 1;
582 } else {
583 camera_idx = 1;
584 screenshare_idx = 0;
585 }
586
Artem Titov75e36472018-10-08 10:28:56587 BuiltInNetworkBehaviorConfig pipe_config;
Mirko Bonadei2ab97f62019-07-18 11:44:12588 pipe_config.loss_percent = LossPercent();
589 pipe_config.avg_burst_loss_length = AvgBurstLossLength();
Johannes Kron6724f1b2024-06-12 22:57:26590 pipe_config.link_capacity = LinkCapacity();
Mirko Bonadei2ab97f62019-07-18 11:44:12591 pipe_config.queue_length_packets = QueueSize();
592 pipe_config.queue_delay_ms = AvgPropagationDelayMs();
593 pipe_config.delay_standard_deviation_ms = StdPropagationDelayMs();
594 pipe_config.allow_reordering = absl::GetFlag(FLAGS_allow_reordering);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59595
Sebastian Janssonfc8d26b2018-02-21 08:52:06596 BitrateConstraints call_bitrate_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59597 call_bitrate_config.min_bitrate_bps =
Mirko Bonadei2ab97f62019-07-18 11:44:12598 (ScreenshareMinBitrateKbps() + VideoMinBitrateKbps()) * 1000;
599 call_bitrate_config.start_bitrate_bps = StartBitrateKbps() * 1000;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59600 call_bitrate_config.max_bitrate_bps =
Mirko Bonadei2ab97f62019-07-18 11:44:12601 (ScreenshareMaxBitrateKbps() + VideoMaxBitrateKbps()) * 1000;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59602
Danil Chapovalov059f4f72020-07-07 12:16:47603 VideoQualityTest::Params params;
604 params.call.send_side_bwe = absl::GetFlag(FLAGS_send_side_bwe);
605 params.call.generic_descriptor = absl::GetFlag(FLAGS_generic_descriptor);
606 params.call.call_bitrate_config = call_bitrate_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59607 params.call.dual_video = true;
Danil Chapovalov059f4f72020-07-07 12:16:47608 params.video[screenshare_idx].enabled = true;
609 params.video[screenshare_idx].width = ScreenshareWidth();
610 params.video[screenshare_idx].height = ScreenshareHeight();
611 params.video[screenshare_idx].fps = ScreenshareFps();
612 params.video[screenshare_idx].min_bitrate_bps =
613 ScreenshareMinBitrateKbps() * 1000;
614 params.video[screenshare_idx].target_bitrate_bps =
615 ScreenshareTargetBitrateKbps() * 1000;
616 params.video[screenshare_idx].max_bitrate_bps =
617 ScreenshareMaxBitrateKbps() * 1000;
618 params.video[screenshare_idx].codec = Codec();
619 params.video[screenshare_idx].num_temporal_layers =
620 ScreenshareNumTemporalLayers();
621 params.video[screenshare_idx].selected_tl = ScreenshareSelectedTL();
622 params.video[screenshare_idx].min_transmit_bps =
623 ScreenshareMinTransmitBitrateKbps() * 1000;
624 params.video[camera_idx].enabled = absl::GetFlag(FLAGS_video);
625 params.video[camera_idx].width = VideoWidth();
626 params.video[camera_idx].height = VideoHeight();
627 params.video[camera_idx].fps = VideoFps();
628 params.video[camera_idx].min_bitrate_bps = VideoMinBitrateKbps() * 1000;
629 params.video[camera_idx].target_bitrate_bps = VideoTargetBitrateKbps() * 1000;
630 params.video[camera_idx].max_bitrate_bps = VideoMaxBitrateKbps() * 1000;
631 params.video[camera_idx].suspend_below_min_bitrate =
632 absl::GetFlag(FLAGS_suspend_below_min_bitrate);
633 params.video[camera_idx].codec = Codec();
634 params.video[camera_idx].num_temporal_layers = VideoNumTemporalLayers();
635 params.video[camera_idx].selected_tl = VideoSelectedTL();
636 params.video[camera_idx].ulpfec = absl::GetFlag(FLAGS_use_ulpfec);
637 params.video[camera_idx].flexfec = absl::GetFlag(FLAGS_use_flexfec);
638 params.video[camera_idx].clip_path = VideoClip();
639 params.video[camera_idx].capture_device_index = GetCaptureDevice();
640 params.audio.enabled = absl::GetFlag(FLAGS_audio);
641 params.audio.sync_video = absl::GetFlag(FLAGS_audio_video_sync);
642 params.audio.dtx = absl::GetFlag(FLAGS_audio_dtx);
643 params.logging.rtc_event_log_name = RtcEventLogName();
644 params.logging.rtp_dump_name = RtpDumpName();
645 params.logging.encoded_frame_base_path = EncodedFramePath();
646 params.analyzer.test_label = "dual_streams";
647 params.analyzer.test_durations_secs = DurationSecs();
648 params.analyzer.graph_data_output_filename = OutputFilename();
649 params.analyzer.graph_title = GraphTitle();
Artem Titovf18b3522018-08-28 14:54:24650 params.config = pipe_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59651
652 params.screenshare[camera_idx].enabled = false;
Danil Chapovalov059f4f72020-07-07 12:16:47653 params.screenshare[screenshare_idx].enabled = true;
654 params.screenshare[screenshare_idx].generate_slides = GenerateSlides();
655 params.screenshare[screenshare_idx].slide_change_interval =
656 SlideChangeInterval();
657 params.screenshare[screenshare_idx].scroll_duration = ScrollDuration();
658 params.screenshare[screenshare_idx].slides = Slides();
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59659
Mirko Bonadei2ab97f62019-07-18 11:44:12660 if (VideoNumStreams() > 1 && VideoStream0().empty() &&
661 VideoStream1().empty()) {
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59662 params.ss[camera_idx].infer_streams = true;
663 }
664
Mirko Bonadei2ab97f62019-07-18 11:44:12665 if (ScreenshareNumStreams() > 1 && ScreenshareStream0().empty() &&
666 ScreenshareStream1().empty()) {
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59667 params.ss[screenshare_idx].infer_streams = true;
668 }
669
Danil Chapovalov44ab2002024-04-17 10:11:29670 VideoQualityTest fixture(nullptr);
671
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59672 std::vector<std::string> stream_descriptors;
Mirko Bonadei2ab97f62019-07-18 11:44:12673 stream_descriptors.push_back(ScreenshareStream0());
674 stream_descriptors.push_back(ScreenshareStream1());
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59675 std::vector<std::string> SL_descriptors;
Mirko Bonadei2ab97f62019-07-18 11:44:12676 SL_descriptors.push_back(ScreenshareSL0());
677 SL_descriptors.push_back(ScreenshareSL1());
Danil Chapovalov44ab2002024-04-17 10:11:29678 fixture.FillScalabilitySettings(
Mirko Bonadei2ab97f62019-07-18 11:44:12679 &params, screenshare_idx, stream_descriptors, ScreenshareNumStreams(),
680 ScreenshareSelectedStream(), ScreenshareNumSpatialLayers(),
681 ScreenshareSelectedSL(), ScreenshareInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59682
683 stream_descriptors.clear();
Mirko Bonadei2ab97f62019-07-18 11:44:12684 stream_descriptors.push_back(VideoStream0());
685 stream_descriptors.push_back(VideoStream1());
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59686 SL_descriptors.clear();
Mirko Bonadei2ab97f62019-07-18 11:44:12687 SL_descriptors.push_back(VideoSL0());
688 SL_descriptors.push_back(VideoSL1());
Danil Chapovalov44ab2002024-04-17 10:11:29689 fixture.FillScalabilitySettings(&params, camera_idx, stream_descriptors,
690 VideoNumStreams(), VideoSelectedStream(),
691 VideoNumSpatialLayers(), VideoSelectedSL(),
692 VideoInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59693
Mirko Bonadei2ab97f62019-07-18 11:44:12694 if (DurationSecs()) {
Danil Chapovalov44ab2002024-04-17 10:11:29695 fixture.RunWithAnalyzer(params);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59696 } else {
Danil Chapovalov44ab2002024-04-17 10:11:29697 fixture.RunWithRenderers(params);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59698 }
699}
700} // namespace webrtc
701
702int main(int argc, char* argv[]) {
703 ::testing::InitGoogleTest(&argc, argv);
Mirko Bonadei2ab97f62019-07-18 11:44:12704 absl::ParseCommandLine(argc, argv);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59705
Mirko Bonadei2ab97f62019-07-18 11:44:12706 rtc::LogMessage::SetLogToStderr(absl::GetFlag(FLAGS_logs));
Mirko Bonadei45a4c412018-07-31 13:07:28707
Bjorn Tereliusedab3012018-01-31 16:23:40708 // InitFieldTrialsFromString stores the char*, so the char array must outlive
709 // the application.
Mirko Bonadei2ab97f62019-07-18 11:44:12710 const std::string field_trials = absl::GetFlag(FLAGS_force_fieldtrials);
711 webrtc::field_trial::InitFieldTrialsFromString(field_trials.c_str());
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59712
713 webrtc::test::RunTest(webrtc::Loopback);
714 return 0;
715}