blob: 248708e6b20fd5c78103abcf6d941ade21e754cb [file] [log] [blame]
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +01001/*
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 14:29:40 +020012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <memory>
14#include <string>
15#include <vector>
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010016
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "absl/memory/memory.h"
18#include "absl/types/optional.h"
19#include "api/bitrate_constraints.h"
20#include "api/test/simulated_network.h"
21#include "api/test/video_quality_test_fixture.h"
22#include "api/video_codecs/video_codec.h"
23#include "rtc_base/checks.h"
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010024#include "rtc_base/flags.h"
Mirko Bonadei45a4c412018-07-31 15:07:28 +020025#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/string_encode.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020027#include "system_wrappers/include/field_trial.h"
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010028#include "test/field_trial.h"
29#include "test/gtest.h"
30#include "test/run_test.h"
31#include "video/video_quality_test.h"
32
33namespace webrtc {
34namespace flags {
35
Sergey Silkin57027362018-05-15 09:12:05 +020036InterLayerPredMode IntToInterLayerPredMode(int inter_layer_pred) {
37 if (inter_layer_pred == 0) {
38 return InterLayerPredMode::kOn;
39 } else if (inter_layer_pred == 1) {
40 return InterLayerPredMode::kOff;
41 } else {
42 RTC_DCHECK_EQ(inter_layer_pred, 2);
43 return InterLayerPredMode::kOnKeyPic;
44 }
45}
46
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010047// Flags for video.
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020048WEBRTC_DEFINE_int(vwidth, 640, "Video width.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010049size_t VideoWidth() {
50 return static_cast<size_t>(FLAG_vwidth);
51}
52
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020053WEBRTC_DEFINE_int(vheight, 480, "Video height.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010054size_t VideoHeight() {
55 return static_cast<size_t>(FLAG_vheight);
56}
57
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020058WEBRTC_DEFINE_int(vfps, 30, "Video frames per second.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010059int VideoFps() {
60 return static_cast<int>(FLAG_vfps);
61}
62
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020063WEBRTC_DEFINE_int(capture_device_index,
64 0,
65 "Capture device to select for video stream");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010066size_t GetCaptureDevice() {
67 return static_cast<size_t>(FLAG_capture_device_index);
68}
69
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020070WEBRTC_DEFINE_int(vtarget_bitrate, 400, "Video stream target bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010071int VideoTargetBitrateKbps() {
72 return static_cast<int>(FLAG_vtarget_bitrate);
73}
74
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020075WEBRTC_DEFINE_int(vmin_bitrate, 100, "Video stream min bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010076int VideoMinBitrateKbps() {
77 return static_cast<int>(FLAG_vmin_bitrate);
78}
79
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020080WEBRTC_DEFINE_int(vmax_bitrate, 2000, "Video stream max bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010081int VideoMaxBitrateKbps() {
82 return static_cast<int>(FLAG_vmax_bitrate);
83}
84
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020085WEBRTC_DEFINE_bool(suspend_below_min_bitrate,
86 false,
87 "Suspends video below the configured min bitrate.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010088
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020089WEBRTC_DEFINE_int(
90 vnum_temporal_layers,
91 1,
92 "Number of temporal layers for video. Set to 1-4 to override.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +010093int VideoNumTemporalLayers() {
94 return static_cast<int>(FLAG_vnum_temporal_layers);
95}
96
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020097WEBRTC_DEFINE_int(vnum_streams,
98 0,
99 "Number of video streams to show or analyze.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100100int VideoNumStreams() {
101 return static_cast<int>(FLAG_vnum_streams);
102}
103
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200104WEBRTC_DEFINE_int(vnum_spatial_layers,
105 1,
106 "Number of video spatial layers to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100107int VideoNumSpatialLayers() {
108 return static_cast<int>(FLAG_vnum_spatial_layers);
109}
110
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200111WEBRTC_DEFINE_int(
112 vinter_layer_pred,
113 2,
114 "Video inter-layer prediction mode. "
115 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 09:12:05 +0200116InterLayerPredMode VideoInterLayerPred() {
117 return IntToInterLayerPredMode(FLAG_vinter_layer_pred);
118}
119
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200120WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100121 vstream0,
122 "",
123 "Comma separated values describing VideoStream for video stream #0.");
124std::string VideoStream0() {
125 return static_cast<std::string>(FLAG_vstream0);
126}
127
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200128WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100129 vstream1,
130 "",
131 "Comma separated values describing VideoStream for video stream #1.");
132std::string VideoStream1() {
133 return static_cast<std::string>(FLAG_vstream1);
134}
135
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200136WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100137 vsl0,
138 "",
139 "Comma separated values describing SpatialLayer for video layer #0.");
140std::string VideoSL0() {
141 return static_cast<std::string>(FLAG_vsl0);
142}
143
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200144WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100145 vsl1,
146 "",
147 "Comma separated values describing SpatialLayer for video layer #1.");
148std::string VideoSL1() {
149 return static_cast<std::string>(FLAG_vsl1);
150}
151
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200152WEBRTC_DEFINE_int(
153 vselected_tl,
154 -1,
155 "Temporal layer to show or analyze for screenshare. -1 to disable "
156 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100157int VideoSelectedTL() {
158 return static_cast<int>(FLAG_vselected_tl);
159}
160
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200161WEBRTC_DEFINE_int(vselected_stream,
162 0,
163 "ID of the stream to show or analyze for screenshare."
164 "Set to the number of streams to show them all.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100165int VideoSelectedStream() {
166 return static_cast<int>(FLAG_vselected_stream);
167}
168
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200169WEBRTC_DEFINE_int(
170 vselected_sl,
171 -1,
172 "Spatial layer to show or analyze for screenshare. -1 to disable "
173 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100174int VideoSelectedSL() {
175 return static_cast<int>(FLAG_vselected_sl);
176}
177
178// Flags for screenshare.
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200179WEBRTC_DEFINE_int(min_transmit_bitrate,
180 400,
181 "Min transmit bitrate incl. padding for screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100182int ScreenshareMinTransmitBitrateKbps() {
183 return FLAG_min_transmit_bitrate;
184}
185
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200186WEBRTC_DEFINE_int(swidth, 1850, "Screenshare width (crops source).");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100187size_t ScreenshareWidth() {
188 return static_cast<size_t>(FLAG_swidth);
189}
190
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200191WEBRTC_DEFINE_int(sheight, 1110, "Screenshare height (crops source).");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100192size_t ScreenshareHeight() {
193 return static_cast<size_t>(FLAG_sheight);
194}
195
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200196WEBRTC_DEFINE_int(sfps, 5, "Frames per second for screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100197int ScreenshareFps() {
198 return static_cast<int>(FLAG_sfps);
199}
200
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200201WEBRTC_DEFINE_int(starget_bitrate,
202 100,
203 "Screenshare stream target bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100204int ScreenshareTargetBitrateKbps() {
205 return static_cast<int>(FLAG_starget_bitrate);
206}
207
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200208WEBRTC_DEFINE_int(smin_bitrate, 100, "Screenshare stream min bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100209int ScreenshareMinBitrateKbps() {
210 return static_cast<int>(FLAG_smin_bitrate);
211}
212
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200213WEBRTC_DEFINE_int(smax_bitrate,
214 2000,
215 "Screenshare stream max bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100216int ScreenshareMaxBitrateKbps() {
217 return static_cast<int>(FLAG_smax_bitrate);
218}
219
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200220WEBRTC_DEFINE_int(snum_temporal_layers,
221 2,
222 "Number of temporal layers to use in screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100223int ScreenshareNumTemporalLayers() {
224 return static_cast<int>(FLAG_snum_temporal_layers);
225}
226
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200227WEBRTC_DEFINE_int(snum_streams,
228 0,
229 "Number of screenshare streams to show or analyze.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100230int ScreenshareNumStreams() {
231 return static_cast<int>(FLAG_snum_streams);
232}
233
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200234WEBRTC_DEFINE_int(snum_spatial_layers,
235 1,
236 "Number of screenshare spatial layers to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100237int ScreenshareNumSpatialLayers() {
238 return static_cast<int>(FLAG_snum_spatial_layers);
239}
240
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200241WEBRTC_DEFINE_int(
242 sinter_layer_pred,
243 0,
244 "Screenshare inter-layer prediction mode. "
245 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 09:12:05 +0200246InterLayerPredMode ScreenshareInterLayerPred() {
247 return IntToInterLayerPredMode(FLAG_sinter_layer_pred);
248}
249
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200250WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100251 sstream0,
252 "",
253 "Comma separated values describing VideoStream for screenshare stream #0.");
254std::string ScreenshareStream0() {
255 return static_cast<std::string>(FLAG_sstream0);
256}
257
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200258WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100259 sstream1,
260 "",
261 "Comma separated values describing VideoStream for screenshare stream #1.");
262std::string ScreenshareStream1() {
263 return static_cast<std::string>(FLAG_sstream1);
264}
265
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200266WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100267 ssl0,
268 "",
269 "Comma separated values describing SpatialLayer for screenshare layer #0.");
270std::string ScreenshareSL0() {
271 return static_cast<std::string>(FLAG_ssl0);
272}
273
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200274WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100275 ssl1,
276 "",
277 "Comma separated values describing SpatialLayer for screenshare layer #1.");
278std::string ScreenshareSL1() {
279 return static_cast<std::string>(FLAG_ssl1);
280}
281
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200282WEBRTC_DEFINE_int(
283 sselected_tl,
284 -1,
285 "Temporal layer to show or analyze for screenshare. -1 to disable "
286 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100287int ScreenshareSelectedTL() {
288 return static_cast<int>(FLAG_sselected_tl);
289}
290
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200291WEBRTC_DEFINE_int(sselected_stream,
292 0,
293 "ID of the stream to show or analyze for screenshare."
294 "Set to the number of streams to show them all.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100295int ScreenshareSelectedStream() {
296 return static_cast<int>(FLAG_sselected_stream);
297}
298
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200299WEBRTC_DEFINE_int(
300 sselected_sl,
301 -1,
302 "Spatial layer to show or analyze for screenshare. -1 to disable "
303 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100304int ScreenshareSelectedSL() {
305 return static_cast<int>(FLAG_sselected_sl);
306}
307
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200308WEBRTC_DEFINE_bool(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100309 generate_slides,
310 false,
311 "Whether to use randomly generated slides or read them from files.");
312bool GenerateSlides() {
313 return static_cast<int>(FLAG_generate_slides);
314}
315
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200316WEBRTC_DEFINE_int(slide_change_interval,
317 10,
318 "Interval (in seconds) between simulated slide changes.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100319int SlideChangeInterval() {
320 return static_cast<int>(FLAG_slide_change_interval);
321}
322
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200323WEBRTC_DEFINE_int(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100324 scroll_duration,
325 0,
326 "Duration (in seconds) during which a slide will be scrolled into place.");
327int ScrollDuration() {
328 return static_cast<int>(FLAG_scroll_duration);
329}
330
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200331WEBRTC_DEFINE_string(
332 slides,
333 "",
334 "Comma-separated list of *.yuv files to display as slides.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100335std::vector<std::string> Slides() {
336 std::vector<std::string> slides;
337 std::string slides_list = FLAG_slides;
338 rtc::tokenize(slides_list, ',', &slides);
339 return slides;
340}
341
342// Flags common with screenshare and video loopback, with equal default values.
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200343WEBRTC_DEFINE_int(start_bitrate, 600, "Call start bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100344int StartBitrateKbps() {
345 return static_cast<int>(FLAG_start_bitrate);
346}
347
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200348WEBRTC_DEFINE_string(codec, "VP8", "Video codec to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100349std::string Codec() {
350 return static_cast<std::string>(FLAG_codec);
351}
352
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200353WEBRTC_DEFINE_bool(analyze_video,
354 false,
355 "Analyze video stream (if --duration is present)");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100356bool AnalyzeVideo() {
357 return static_cast<bool>(FLAG_analyze_video);
358}
359
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200360WEBRTC_DEFINE_bool(analyze_screenshare,
361 false,
362 "Analyze screenshare stream (if --duration is present)");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100363bool AnalyzeScreenshare() {
364 return static_cast<bool>(FLAG_analyze_screenshare);
365}
366
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200367WEBRTC_DEFINE_int(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100368 duration,
369 0,
370 "Duration of the test in seconds. If 0, rendered will be shown instead.");
371int DurationSecs() {
372 return static_cast<int>(FLAG_duration);
373}
374
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200375WEBRTC_DEFINE_string(output_filename, "", "Target graph data filename.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100376std::string OutputFilename() {
377 return static_cast<std::string>(FLAG_output_filename);
378}
379
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200380WEBRTC_DEFINE_string(graph_title,
381 "",
382 "If empty, title will be generated automatically.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100383std::string GraphTitle() {
384 return static_cast<std::string>(FLAG_graph_title);
385}
386
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200387WEBRTC_DEFINE_int(loss_percent, 0, "Percentage of packets randomly lost.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100388int LossPercent() {
389 return static_cast<int>(FLAG_loss_percent);
390}
391
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200392WEBRTC_DEFINE_int(avg_burst_loss_length,
393 -1,
394 "Average burst length of lost packets.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100395int AvgBurstLossLength() {
396 return static_cast<int>(FLAG_avg_burst_loss_length);
397}
398
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200399WEBRTC_DEFINE_int(link_capacity,
400 0,
401 "Capacity (kbps) of the fake link. 0 means infinite.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100402int LinkCapacityKbps() {
403 return static_cast<int>(FLAG_link_capacity);
404}
405
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200406WEBRTC_DEFINE_int(queue_size,
407 0,
408 "Size of the bottleneck link queue in packets.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100409int QueueSize() {
410 return static_cast<int>(FLAG_queue_size);
411}
412
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200413WEBRTC_DEFINE_int(avg_propagation_delay_ms,
414 0,
415 "Average link propagation delay in ms.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100416int AvgPropagationDelayMs() {
417 return static_cast<int>(FLAG_avg_propagation_delay_ms);
418}
419
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200420WEBRTC_DEFINE_string(rtc_event_log_name,
421 "",
422 "Filename for rtc event log. Two files "
423 "with \"_send\" and \"_recv\" suffixes will be created. "
424 "Works only when --duration is set.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100425std::string RtcEventLogName() {
426 return static_cast<std::string>(FLAG_rtc_event_log_name);
427}
428
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200429WEBRTC_DEFINE_string(rtp_dump_name,
430 "",
431 "Filename for dumped received RTP stream.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100432std::string RtpDumpName() {
433 return static_cast<std::string>(FLAG_rtp_dump_name);
434}
435
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200436WEBRTC_DEFINE_int(std_propagation_delay_ms,
437 0,
438 "Link propagation delay standard deviation in ms.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100439int StdPropagationDelayMs() {
440 return static_cast<int>(FLAG_std_propagation_delay_ms);
441}
442
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200443WEBRTC_DEFINE_string(
444 encoded_frame_path,
445 "",
446 "The base path for encoded frame logs. Created files will have "
447 "the form <encoded_frame_path>.<n>.(recv|send.<m>).ivf");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100448std::string EncodedFramePath() {
449 return static_cast<std::string>(FLAG_encoded_frame_path);
450}
451
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200452WEBRTC_DEFINE_bool(logs, false, "print logs to stderr");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100453
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200454WEBRTC_DEFINE_bool(send_side_bwe, true, "Use send-side bandwidth estimation");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100455
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200456WEBRTC_DEFINE_bool(generic_descriptor,
457 false,
458 "Use the generic frame descriptor.");
philipel569397f2018-09-26 12:25:31 +0200459
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200460WEBRTC_DEFINE_bool(allow_reordering, false, "Allow packet reordering to occur");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100461
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200462WEBRTC_DEFINE_bool(use_ulpfec,
463 false,
464 "Use RED+ULPFEC forward error correction.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100465
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200466WEBRTC_DEFINE_bool(use_flexfec, false, "Use FlexFEC forward error correction.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100467
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200468WEBRTC_DEFINE_bool(audio, false, "Add audio stream");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100469
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200470WEBRTC_DEFINE_bool(audio_video_sync,
471 false,
472 "Sync audio and video stream (no effect if"
473 " audio is false)");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100474
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200475WEBRTC_DEFINE_bool(audio_dtx,
476 false,
477 "Enable audio DTX (no effect if audio is false)");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100478
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200479WEBRTC_DEFINE_bool(video, true, "Add video stream");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100480
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200481WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100482 force_fieldtrials,
483 "",
484 "Field trials control experimental feature code which can be forced. "
485 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
486 " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
487 "trials are separated by \"/\"");
488
489// Video-specific flags.
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200490WEBRTC_DEFINE_string(
491 vclip,
492 "",
493 "Name of the clip to show. If empty, the camera is used. Use "
494 "\"Generator\" for chroma generator.");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100495std::string VideoClip() {
496 return static_cast<std::string>(FLAG_vclip);
497}
498
Mirko Bonadei2dfa9982018-10-18 11:35:32 +0200499WEBRTC_DEFINE_bool(help, false, "prints this message");
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100500
501} // namespace flags
502
503void Loopback() {
504 int camera_idx, screenshare_idx;
505 RTC_CHECK(!(flags::AnalyzeScreenshare() && flags::AnalyzeVideo()))
506 << "Select only one of video or screenshare.";
507 RTC_CHECK(!flags::DurationSecs() || flags::AnalyzeScreenshare() ||
508 flags::AnalyzeVideo())
509 << "If duration is set, exactly one of analyze_* flags should be set.";
510 // Default: camera feed first, if nothing selected.
511 if (flags::AnalyzeVideo() || !flags::AnalyzeScreenshare()) {
512 camera_idx = 0;
513 screenshare_idx = 1;
514 } else {
515 camera_idx = 1;
516 screenshare_idx = 0;
517 }
518
Artem Titov75e36472018-10-08 12:28:56 +0200519 BuiltInNetworkBehaviorConfig pipe_config;
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100520 pipe_config.loss_percent = flags::LossPercent();
521 pipe_config.avg_burst_loss_length = flags::AvgBurstLossLength();
522 pipe_config.link_capacity_kbps = flags::LinkCapacityKbps();
523 pipe_config.queue_length_packets = flags::QueueSize();
524 pipe_config.queue_delay_ms = flags::AvgPropagationDelayMs();
525 pipe_config.delay_standard_deviation_ms = flags::StdPropagationDelayMs();
526 pipe_config.allow_reordering = flags::FLAG_allow_reordering;
527
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100528 BitrateConstraints call_bitrate_config;
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100529 call_bitrate_config.min_bitrate_bps =
530 (flags::ScreenshareMinBitrateKbps() + flags::VideoMinBitrateKbps()) *
531 1000;
532 call_bitrate_config.start_bitrate_bps = flags::StartBitrateKbps() * 1000;
533 call_bitrate_config.max_bitrate_bps =
534 (flags::ScreenshareMaxBitrateKbps() + flags::VideoMaxBitrateKbps()) *
535 1000;
536
537 VideoQualityTest::Params params, camera_params, screenshare_params;
philipel569397f2018-09-26 12:25:31 +0200538 params.call = {flags::FLAG_send_side_bwe, flags::FLAG_generic_descriptor,
539 call_bitrate_config, 0};
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100540 params.call.dual_video = true;
541 params.video[screenshare_idx] = {
542 true,
543 flags::ScreenshareWidth(),
544 flags::ScreenshareHeight(),
545 flags::ScreenshareFps(),
546 flags::ScreenshareMinBitrateKbps() * 1000,
547 flags::ScreenshareTargetBitrateKbps() * 1000,
548 flags::ScreenshareMaxBitrateKbps() * 1000,
549 false,
550 flags::Codec(),
551 flags::ScreenshareNumTemporalLayers(),
552 flags::ScreenshareSelectedTL(),
553 flags::ScreenshareMinTransmitBitrateKbps() * 1000,
554 false, // ULPFEC disabled.
555 false, // FlexFEC disabled.
Niels Möller6aa415e2018-06-07 11:14:13 +0200556 false, // Automatic scaling disabled
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100557 ""};
558 params.video[camera_idx] = {flags::FLAG_video,
559 flags::VideoWidth(),
560 flags::VideoHeight(),
561 flags::VideoFps(),
562 flags::VideoMinBitrateKbps() * 1000,
563 flags::VideoTargetBitrateKbps() * 1000,
564 flags::VideoMaxBitrateKbps() * 1000,
565 flags::FLAG_suspend_below_min_bitrate,
566 flags::Codec(),
567 flags::VideoNumTemporalLayers(),
568 flags::VideoSelectedTL(),
569 0, // No min transmit bitrate.
570 flags::FLAG_use_ulpfec,
571 flags::FLAG_use_flexfec,
Niels Möller6aa415e2018-06-07 11:14:13 +0200572 false,
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100573 flags::VideoClip(),
574 flags::GetCaptureDevice()};
575 params.audio = {flags::FLAG_audio, flags::FLAG_audio_video_sync,
576 flags::FLAG_audio_dtx};
Mirko Bonadei45a4c412018-07-31 15:07:28 +0200577 params.logging = {flags::FLAG_rtc_event_log_name, flags::FLAG_rtp_dump_name,
578 flags::FLAG_encoded_frame_path};
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100579 params.analyzer = {"dual_streams",
580 0.0,
581 0.0,
582 flags::DurationSecs(),
583 flags::OutputFilename(),
584 flags::GraphTitle()};
Artem Titovf18b3522018-08-28 16:54:24 +0200585 params.config = pipe_config;
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100586
587 params.screenshare[camera_idx].enabled = false;
588 params.screenshare[screenshare_idx] = {
589 true, flags::GenerateSlides(), flags::SlideChangeInterval(),
590 flags::ScrollDuration(), flags::Slides()};
591
592 if (flags::VideoNumStreams() > 1 && flags::VideoStream0().empty() &&
593 flags::VideoStream1().empty()) {
594 params.ss[camera_idx].infer_streams = true;
595 }
596
597 if (flags::ScreenshareNumStreams() > 1 &&
598 flags::ScreenshareStream0().empty() &&
599 flags::ScreenshareStream1().empty()) {
600 params.ss[screenshare_idx].infer_streams = true;
601 }
602
603 std::vector<std::string> stream_descriptors;
604 stream_descriptors.push_back(flags::ScreenshareStream0());
605 stream_descriptors.push_back(flags::ScreenshareStream1());
606 std::vector<std::string> SL_descriptors;
607 SL_descriptors.push_back(flags::ScreenshareSL0());
608 SL_descriptors.push_back(flags::ScreenshareSL1());
609 VideoQualityTest::FillScalabilitySettings(
610 &params, screenshare_idx, stream_descriptors,
611 flags::ScreenshareNumStreams(), flags::ScreenshareSelectedStream(),
612 flags::ScreenshareNumSpatialLayers(), flags::ScreenshareSelectedSL(),
Sergey Silkin57027362018-05-15 09:12:05 +0200613 flags::ScreenshareInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100614
615 stream_descriptors.clear();
616 stream_descriptors.push_back(flags::VideoStream0());
617 stream_descriptors.push_back(flags::VideoStream1());
618 SL_descriptors.clear();
619 SL_descriptors.push_back(flags::VideoSL0());
620 SL_descriptors.push_back(flags::VideoSL1());
621 VideoQualityTest::FillScalabilitySettings(
622 &params, camera_idx, stream_descriptors, flags::VideoNumStreams(),
623 flags::VideoSelectedStream(), flags::VideoNumSpatialLayers(),
Sergey Silkin57027362018-05-15 09:12:05 +0200624 flags::VideoSelectedSL(), flags::VideoInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100625
Karl Wiberg918f50c2018-07-05 11:40:33 +0200626 auto fixture = absl::make_unique<VideoQualityTest>(nullptr);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100627 if (flags::DurationSecs()) {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200628 fixture->RunWithAnalyzer(params);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100629 } else {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200630 fixture->RunWithRenderers(params);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100631 }
632}
633} // namespace webrtc
634
635int main(int argc, char* argv[]) {
636 ::testing::InitGoogleTest(&argc, argv);
637 if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) != 0) {
638 // Fail on unrecognized flags.
639 return 1;
640 }
641 if (webrtc::flags::FLAG_help) {
642 rtc::FlagList::Print(nullptr, false);
643 return 0;
644 }
645
Mirko Bonadei45a4c412018-07-31 15:07:28 +0200646 rtc::LogMessage::SetLogToStderr(webrtc::flags::FLAG_logs);
647
Bjorn Tereliusedab3012018-01-31 17:23:40 +0100648 // InitFieldTrialsFromString stores the char*, so the char array must outlive
649 // the application.
650 webrtc::field_trial::InitFieldTrialsFromString(
651 webrtc::flags::FLAG_force_fieldtrials);
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100652
653 webrtc::test::RunTest(webrtc::Loopback);
654 return 0;
655}