blob: 1ff4956ca2950cebf179723044d9aed1003c95fe [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>
12
13#include "rtc_base/flags.h"
Mirko Bonadei45a4c412018-07-31 13:07:2814#include "rtc_base/logging.h"
Mirko Bonadei17f48782018-09-28 06:51:1015#include "system_wrappers/include/field_trial.h"
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5916#include "test/field_trial.h"
17#include "test/gtest.h"
18#include "test/run_test.h"
19#include "video/video_quality_test.h"
20
21namespace webrtc {
22namespace flags {
23
Sergey Silkin57027362018-05-15 07:12:0524InterLayerPredMode IntToInterLayerPredMode(int inter_layer_pred) {
25 if (inter_layer_pred == 0) {
26 return InterLayerPredMode::kOn;
27 } else if (inter_layer_pred == 1) {
28 return InterLayerPredMode::kOff;
29 } else {
30 RTC_DCHECK_EQ(inter_layer_pred, 2);
31 return InterLayerPredMode::kOnKeyPic;
32 }
33}
34
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5935// Flags for video.
Mirko Bonadei2dfa9982018-10-18 09:35:3236WEBRTC_DEFINE_int(vwidth, 640, "Video width.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5937size_t VideoWidth() {
38 return static_cast<size_t>(FLAG_vwidth);
39}
40
Mirko Bonadei2dfa9982018-10-18 09:35:3241WEBRTC_DEFINE_int(vheight, 480, "Video height.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5942size_t VideoHeight() {
43 return static_cast<size_t>(FLAG_vheight);
44}
45
Mirko Bonadei2dfa9982018-10-18 09:35:3246WEBRTC_DEFINE_int(vfps, 30, "Video frames per second.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5947int VideoFps() {
48 return static_cast<int>(FLAG_vfps);
49}
50
Mirko Bonadei2dfa9982018-10-18 09:35:3251WEBRTC_DEFINE_int(capture_device_index,
52 0,
53 "Capture device to select for video stream");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5954size_t GetCaptureDevice() {
55 return static_cast<size_t>(FLAG_capture_device_index);
56}
57
Mirko Bonadei2dfa9982018-10-18 09:35:3258WEBRTC_DEFINE_int(vtarget_bitrate, 400, "Video stream target bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5959int VideoTargetBitrateKbps() {
60 return static_cast<int>(FLAG_vtarget_bitrate);
61}
62
Mirko Bonadei2dfa9982018-10-18 09:35:3263WEBRTC_DEFINE_int(vmin_bitrate, 100, "Video stream min bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5964int VideoMinBitrateKbps() {
65 return static_cast<int>(FLAG_vmin_bitrate);
66}
67
Mirko Bonadei2dfa9982018-10-18 09:35:3268WEBRTC_DEFINE_int(vmax_bitrate, 2000, "Video stream max bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5969int VideoMaxBitrateKbps() {
70 return static_cast<int>(FLAG_vmax_bitrate);
71}
72
Mirko Bonadei2dfa9982018-10-18 09:35:3273WEBRTC_DEFINE_bool(suspend_below_min_bitrate,
74 false,
75 "Suspends video below the configured min bitrate.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5976
Mirko Bonadei2dfa9982018-10-18 09:35:3277WEBRTC_DEFINE_int(
78 vnum_temporal_layers,
79 1,
80 "Number of temporal layers for video. Set to 1-4 to override.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5981int VideoNumTemporalLayers() {
82 return static_cast<int>(FLAG_vnum_temporal_layers);
83}
84
Mirko Bonadei2dfa9982018-10-18 09:35:3285WEBRTC_DEFINE_int(vnum_streams,
86 0,
87 "Number of video streams to show or analyze.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5988int VideoNumStreams() {
89 return static_cast<int>(FLAG_vnum_streams);
90}
91
Mirko Bonadei2dfa9982018-10-18 09:35:3292WEBRTC_DEFINE_int(vnum_spatial_layers,
93 1,
94 "Number of video spatial layers to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:5995int VideoNumSpatialLayers() {
96 return static_cast<int>(FLAG_vnum_spatial_layers);
97}
98
Mirko Bonadei2dfa9982018-10-18 09:35:3299WEBRTC_DEFINE_int(
100 vinter_layer_pred,
101 2,
102 "Video inter-layer prediction mode. "
103 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 07:12:05104InterLayerPredMode VideoInterLayerPred() {
105 return IntToInterLayerPredMode(FLAG_vinter_layer_pred);
106}
107
Mirko Bonadei2dfa9982018-10-18 09:35:32108WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59109 vstream0,
110 "",
111 "Comma separated values describing VideoStream for video stream #0.");
112std::string VideoStream0() {
113 return static_cast<std::string>(FLAG_vstream0);
114}
115
Mirko Bonadei2dfa9982018-10-18 09:35:32116WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59117 vstream1,
118 "",
119 "Comma separated values describing VideoStream for video stream #1.");
120std::string VideoStream1() {
121 return static_cast<std::string>(FLAG_vstream1);
122}
123
Mirko Bonadei2dfa9982018-10-18 09:35:32124WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59125 vsl0,
126 "",
127 "Comma separated values describing SpatialLayer for video layer #0.");
128std::string VideoSL0() {
129 return static_cast<std::string>(FLAG_vsl0);
130}
131
Mirko Bonadei2dfa9982018-10-18 09:35:32132WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59133 vsl1,
134 "",
135 "Comma separated values describing SpatialLayer for video layer #1.");
136std::string VideoSL1() {
137 return static_cast<std::string>(FLAG_vsl1);
138}
139
Mirko Bonadei2dfa9982018-10-18 09:35:32140WEBRTC_DEFINE_int(
141 vselected_tl,
142 -1,
143 "Temporal layer to show or analyze for screenshare. -1 to disable "
144 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59145int VideoSelectedTL() {
146 return static_cast<int>(FLAG_vselected_tl);
147}
148
Mirko Bonadei2dfa9982018-10-18 09:35:32149WEBRTC_DEFINE_int(vselected_stream,
150 0,
151 "ID of the stream to show or analyze for screenshare."
152 "Set to the number of streams to show them all.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59153int VideoSelectedStream() {
154 return static_cast<int>(FLAG_vselected_stream);
155}
156
Mirko Bonadei2dfa9982018-10-18 09:35:32157WEBRTC_DEFINE_int(
158 vselected_sl,
159 -1,
160 "Spatial layer to show or analyze for screenshare. -1 to disable "
161 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59162int VideoSelectedSL() {
163 return static_cast<int>(FLAG_vselected_sl);
164}
165
166// Flags for screenshare.
Mirko Bonadei2dfa9982018-10-18 09:35:32167WEBRTC_DEFINE_int(min_transmit_bitrate,
168 400,
169 "Min transmit bitrate incl. padding for screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59170int ScreenshareMinTransmitBitrateKbps() {
171 return FLAG_min_transmit_bitrate;
172}
173
Mirko Bonadei2dfa9982018-10-18 09:35:32174WEBRTC_DEFINE_int(swidth, 1850, "Screenshare width (crops source).");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59175size_t ScreenshareWidth() {
176 return static_cast<size_t>(FLAG_swidth);
177}
178
Mirko Bonadei2dfa9982018-10-18 09:35:32179WEBRTC_DEFINE_int(sheight, 1110, "Screenshare height (crops source).");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59180size_t ScreenshareHeight() {
181 return static_cast<size_t>(FLAG_sheight);
182}
183
Mirko Bonadei2dfa9982018-10-18 09:35:32184WEBRTC_DEFINE_int(sfps, 5, "Frames per second for screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59185int ScreenshareFps() {
186 return static_cast<int>(FLAG_sfps);
187}
188
Mirko Bonadei2dfa9982018-10-18 09:35:32189WEBRTC_DEFINE_int(starget_bitrate,
190 100,
191 "Screenshare stream target bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59192int ScreenshareTargetBitrateKbps() {
193 return static_cast<int>(FLAG_starget_bitrate);
194}
195
Mirko Bonadei2dfa9982018-10-18 09:35:32196WEBRTC_DEFINE_int(smin_bitrate, 100, "Screenshare stream min bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59197int ScreenshareMinBitrateKbps() {
198 return static_cast<int>(FLAG_smin_bitrate);
199}
200
Mirko Bonadei2dfa9982018-10-18 09:35:32201WEBRTC_DEFINE_int(smax_bitrate,
202 2000,
203 "Screenshare stream max bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59204int ScreenshareMaxBitrateKbps() {
205 return static_cast<int>(FLAG_smax_bitrate);
206}
207
Mirko Bonadei2dfa9982018-10-18 09:35:32208WEBRTC_DEFINE_int(snum_temporal_layers,
209 2,
210 "Number of temporal layers to use in screenshare.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59211int ScreenshareNumTemporalLayers() {
212 return static_cast<int>(FLAG_snum_temporal_layers);
213}
214
Mirko Bonadei2dfa9982018-10-18 09:35:32215WEBRTC_DEFINE_int(snum_streams,
216 0,
217 "Number of screenshare streams to show or analyze.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59218int ScreenshareNumStreams() {
219 return static_cast<int>(FLAG_snum_streams);
220}
221
Mirko Bonadei2dfa9982018-10-18 09:35:32222WEBRTC_DEFINE_int(snum_spatial_layers,
223 1,
224 "Number of screenshare spatial layers to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59225int ScreenshareNumSpatialLayers() {
226 return static_cast<int>(FLAG_snum_spatial_layers);
227}
228
Mirko Bonadei2dfa9982018-10-18 09:35:32229WEBRTC_DEFINE_int(
230 sinter_layer_pred,
231 0,
232 "Screenshare inter-layer prediction mode. "
233 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 07:12:05234InterLayerPredMode ScreenshareInterLayerPred() {
235 return IntToInterLayerPredMode(FLAG_sinter_layer_pred);
236}
237
Mirko Bonadei2dfa9982018-10-18 09:35:32238WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59239 sstream0,
240 "",
241 "Comma separated values describing VideoStream for screenshare stream #0.");
242std::string ScreenshareStream0() {
243 return static_cast<std::string>(FLAG_sstream0);
244}
245
Mirko Bonadei2dfa9982018-10-18 09:35:32246WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59247 sstream1,
248 "",
249 "Comma separated values describing VideoStream for screenshare stream #1.");
250std::string ScreenshareStream1() {
251 return static_cast<std::string>(FLAG_sstream1);
252}
253
Mirko Bonadei2dfa9982018-10-18 09:35:32254WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59255 ssl0,
256 "",
257 "Comma separated values describing SpatialLayer for screenshare layer #0.");
258std::string ScreenshareSL0() {
259 return static_cast<std::string>(FLAG_ssl0);
260}
261
Mirko Bonadei2dfa9982018-10-18 09:35:32262WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59263 ssl1,
264 "",
265 "Comma separated values describing SpatialLayer for screenshare layer #1.");
266std::string ScreenshareSL1() {
267 return static_cast<std::string>(FLAG_ssl1);
268}
269
Mirko Bonadei2dfa9982018-10-18 09:35:32270WEBRTC_DEFINE_int(
271 sselected_tl,
272 -1,
273 "Temporal layer to show or analyze for screenshare. -1 to disable "
274 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59275int ScreenshareSelectedTL() {
276 return static_cast<int>(FLAG_sselected_tl);
277}
278
Mirko Bonadei2dfa9982018-10-18 09:35:32279WEBRTC_DEFINE_int(sselected_stream,
280 0,
281 "ID of the stream to show or analyze for screenshare."
282 "Set to the number of streams to show them all.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59283int ScreenshareSelectedStream() {
284 return static_cast<int>(FLAG_sselected_stream);
285}
286
Mirko Bonadei2dfa9982018-10-18 09:35:32287WEBRTC_DEFINE_int(
288 sselected_sl,
289 -1,
290 "Spatial layer to show or analyze for screenshare. -1 to disable "
291 "filtering.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59292int ScreenshareSelectedSL() {
293 return static_cast<int>(FLAG_sselected_sl);
294}
295
Mirko Bonadei2dfa9982018-10-18 09:35:32296WEBRTC_DEFINE_bool(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59297 generate_slides,
298 false,
299 "Whether to use randomly generated slides or read them from files.");
300bool GenerateSlides() {
301 return static_cast<int>(FLAG_generate_slides);
302}
303
Mirko Bonadei2dfa9982018-10-18 09:35:32304WEBRTC_DEFINE_int(slide_change_interval,
305 10,
306 "Interval (in seconds) between simulated slide changes.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59307int SlideChangeInterval() {
308 return static_cast<int>(FLAG_slide_change_interval);
309}
310
Mirko Bonadei2dfa9982018-10-18 09:35:32311WEBRTC_DEFINE_int(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59312 scroll_duration,
313 0,
314 "Duration (in seconds) during which a slide will be scrolled into place.");
315int ScrollDuration() {
316 return static_cast<int>(FLAG_scroll_duration);
317}
318
Mirko Bonadei2dfa9982018-10-18 09:35:32319WEBRTC_DEFINE_string(
320 slides,
321 "",
322 "Comma-separated list of *.yuv files to display as slides.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59323std::vector<std::string> Slides() {
324 std::vector<std::string> slides;
325 std::string slides_list = FLAG_slides;
326 rtc::tokenize(slides_list, ',', &slides);
327 return slides;
328}
329
330// Flags common with screenshare and video loopback, with equal default values.
Mirko Bonadei2dfa9982018-10-18 09:35:32331WEBRTC_DEFINE_int(start_bitrate, 600, "Call start bitrate in kbps.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59332int StartBitrateKbps() {
333 return static_cast<int>(FLAG_start_bitrate);
334}
335
Mirko Bonadei2dfa9982018-10-18 09:35:32336WEBRTC_DEFINE_string(codec, "VP8", "Video codec to use.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59337std::string Codec() {
338 return static_cast<std::string>(FLAG_codec);
339}
340
Mirko Bonadei2dfa9982018-10-18 09:35:32341WEBRTC_DEFINE_bool(analyze_video,
342 false,
343 "Analyze video stream (if --duration is present)");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59344bool AnalyzeVideo() {
345 return static_cast<bool>(FLAG_analyze_video);
346}
347
Mirko Bonadei2dfa9982018-10-18 09:35:32348WEBRTC_DEFINE_bool(analyze_screenshare,
349 false,
350 "Analyze screenshare stream (if --duration is present)");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59351bool AnalyzeScreenshare() {
352 return static_cast<bool>(FLAG_analyze_screenshare);
353}
354
Mirko Bonadei2dfa9982018-10-18 09:35:32355WEBRTC_DEFINE_int(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59356 duration,
357 0,
358 "Duration of the test in seconds. If 0, rendered will be shown instead.");
359int DurationSecs() {
360 return static_cast<int>(FLAG_duration);
361}
362
Mirko Bonadei2dfa9982018-10-18 09:35:32363WEBRTC_DEFINE_string(output_filename, "", "Target graph data filename.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59364std::string OutputFilename() {
365 return static_cast<std::string>(FLAG_output_filename);
366}
367
Mirko Bonadei2dfa9982018-10-18 09:35:32368WEBRTC_DEFINE_string(graph_title,
369 "",
370 "If empty, title will be generated automatically.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59371std::string GraphTitle() {
372 return static_cast<std::string>(FLAG_graph_title);
373}
374
Mirko Bonadei2dfa9982018-10-18 09:35:32375WEBRTC_DEFINE_int(loss_percent, 0, "Percentage of packets randomly lost.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59376int LossPercent() {
377 return static_cast<int>(FLAG_loss_percent);
378}
379
Mirko Bonadei2dfa9982018-10-18 09:35:32380WEBRTC_DEFINE_int(avg_burst_loss_length,
381 -1,
382 "Average burst length of lost packets.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59383int AvgBurstLossLength() {
384 return static_cast<int>(FLAG_avg_burst_loss_length);
385}
386
Mirko Bonadei2dfa9982018-10-18 09:35:32387WEBRTC_DEFINE_int(link_capacity,
388 0,
389 "Capacity (kbps) of the fake link. 0 means infinite.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59390int LinkCapacityKbps() {
391 return static_cast<int>(FLAG_link_capacity);
392}
393
Mirko Bonadei2dfa9982018-10-18 09:35:32394WEBRTC_DEFINE_int(queue_size,
395 0,
396 "Size of the bottleneck link queue in packets.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59397int QueueSize() {
398 return static_cast<int>(FLAG_queue_size);
399}
400
Mirko Bonadei2dfa9982018-10-18 09:35:32401WEBRTC_DEFINE_int(avg_propagation_delay_ms,
402 0,
403 "Average link propagation delay in ms.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59404int AvgPropagationDelayMs() {
405 return static_cast<int>(FLAG_avg_propagation_delay_ms);
406}
407
Mirko Bonadei2dfa9982018-10-18 09:35:32408WEBRTC_DEFINE_string(rtc_event_log_name,
409 "",
410 "Filename for rtc event log. Two files "
411 "with \"_send\" and \"_recv\" suffixes will be created. "
412 "Works only when --duration is set.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59413std::string RtcEventLogName() {
414 return static_cast<std::string>(FLAG_rtc_event_log_name);
415}
416
Mirko Bonadei2dfa9982018-10-18 09:35:32417WEBRTC_DEFINE_string(rtp_dump_name,
418 "",
419 "Filename for dumped received RTP stream.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59420std::string RtpDumpName() {
421 return static_cast<std::string>(FLAG_rtp_dump_name);
422}
423
Mirko Bonadei2dfa9982018-10-18 09:35:32424WEBRTC_DEFINE_int(std_propagation_delay_ms,
425 0,
426 "Link propagation delay standard deviation in ms.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59427int StdPropagationDelayMs() {
428 return static_cast<int>(FLAG_std_propagation_delay_ms);
429}
430
Mirko Bonadei2dfa9982018-10-18 09:35:32431WEBRTC_DEFINE_string(
432 encoded_frame_path,
433 "",
434 "The base path for encoded frame logs. Created files will have "
435 "the form <encoded_frame_path>.<n>.(recv|send.<m>).ivf");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59436std::string EncodedFramePath() {
437 return static_cast<std::string>(FLAG_encoded_frame_path);
438}
439
Mirko Bonadei2dfa9982018-10-18 09:35:32440WEBRTC_DEFINE_bool(logs, false, "print logs to stderr");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59441
Mirko Bonadei2dfa9982018-10-18 09:35:32442WEBRTC_DEFINE_bool(send_side_bwe, true, "Use send-side bandwidth estimation");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59443
Mirko Bonadei2dfa9982018-10-18 09:35:32444WEBRTC_DEFINE_bool(generic_descriptor,
445 false,
446 "Use the generic frame descriptor.");
philipel569397f2018-09-26 10:25:31447
Mirko Bonadei2dfa9982018-10-18 09:35:32448WEBRTC_DEFINE_bool(allow_reordering, false, "Allow packet reordering to occur");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59449
Mirko Bonadei2dfa9982018-10-18 09:35:32450WEBRTC_DEFINE_bool(use_ulpfec,
451 false,
452 "Use RED+ULPFEC forward error correction.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59453
Mirko Bonadei2dfa9982018-10-18 09:35:32454WEBRTC_DEFINE_bool(use_flexfec, false, "Use FlexFEC forward error correction.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59455
Mirko Bonadei2dfa9982018-10-18 09:35:32456WEBRTC_DEFINE_bool(audio, false, "Add audio stream");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59457
Mirko Bonadei2dfa9982018-10-18 09:35:32458WEBRTC_DEFINE_bool(audio_video_sync,
459 false,
460 "Sync audio and video stream (no effect if"
461 " audio is false)");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59462
Mirko Bonadei2dfa9982018-10-18 09:35:32463WEBRTC_DEFINE_bool(audio_dtx,
464 false,
465 "Enable audio DTX (no effect if audio is false)");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59466
Mirko Bonadei2dfa9982018-10-18 09:35:32467WEBRTC_DEFINE_bool(video, true, "Add video stream");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59468
Mirko Bonadei2dfa9982018-10-18 09:35:32469WEBRTC_DEFINE_string(
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59470 force_fieldtrials,
471 "",
472 "Field trials control experimental feature code which can be forced. "
473 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
474 " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
475 "trials are separated by \"/\"");
476
477// Video-specific flags.
Mirko Bonadei2dfa9982018-10-18 09:35:32478WEBRTC_DEFINE_string(
479 vclip,
480 "",
481 "Name of the clip to show. If empty, the camera is used. Use "
482 "\"Generator\" for chroma generator.");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59483std::string VideoClip() {
484 return static_cast<std::string>(FLAG_vclip);
485}
486
Mirko Bonadei2dfa9982018-10-18 09:35:32487WEBRTC_DEFINE_bool(help, false, "prints this message");
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59488
489} // namespace flags
490
491void Loopback() {
492 int camera_idx, screenshare_idx;
493 RTC_CHECK(!(flags::AnalyzeScreenshare() && flags::AnalyzeVideo()))
494 << "Select only one of video or screenshare.";
495 RTC_CHECK(!flags::DurationSecs() || flags::AnalyzeScreenshare() ||
496 flags::AnalyzeVideo())
497 << "If duration is set, exactly one of analyze_* flags should be set.";
498 // Default: camera feed first, if nothing selected.
499 if (flags::AnalyzeVideo() || !flags::AnalyzeScreenshare()) {
500 camera_idx = 0;
501 screenshare_idx = 1;
502 } else {
503 camera_idx = 1;
504 screenshare_idx = 0;
505 }
506
Artem Titov75e36472018-10-08 10:28:56507 BuiltInNetworkBehaviorConfig pipe_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59508 pipe_config.loss_percent = flags::LossPercent();
509 pipe_config.avg_burst_loss_length = flags::AvgBurstLossLength();
510 pipe_config.link_capacity_kbps = flags::LinkCapacityKbps();
511 pipe_config.queue_length_packets = flags::QueueSize();
512 pipe_config.queue_delay_ms = flags::AvgPropagationDelayMs();
513 pipe_config.delay_standard_deviation_ms = flags::StdPropagationDelayMs();
514 pipe_config.allow_reordering = flags::FLAG_allow_reordering;
515
Sebastian Janssonfc8d26b2018-02-21 08:52:06516 BitrateConstraints call_bitrate_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59517 call_bitrate_config.min_bitrate_bps =
518 (flags::ScreenshareMinBitrateKbps() + flags::VideoMinBitrateKbps()) *
519 1000;
520 call_bitrate_config.start_bitrate_bps = flags::StartBitrateKbps() * 1000;
521 call_bitrate_config.max_bitrate_bps =
522 (flags::ScreenshareMaxBitrateKbps() + flags::VideoMaxBitrateKbps()) *
523 1000;
524
525 VideoQualityTest::Params params, camera_params, screenshare_params;
philipel569397f2018-09-26 10:25:31526 params.call = {flags::FLAG_send_side_bwe, flags::FLAG_generic_descriptor,
527 call_bitrate_config, 0};
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59528 params.call.dual_video = true;
529 params.video[screenshare_idx] = {
530 true,
531 flags::ScreenshareWidth(),
532 flags::ScreenshareHeight(),
533 flags::ScreenshareFps(),
534 flags::ScreenshareMinBitrateKbps() * 1000,
535 flags::ScreenshareTargetBitrateKbps() * 1000,
536 flags::ScreenshareMaxBitrateKbps() * 1000,
537 false,
538 flags::Codec(),
539 flags::ScreenshareNumTemporalLayers(),
540 flags::ScreenshareSelectedTL(),
541 flags::ScreenshareMinTransmitBitrateKbps() * 1000,
542 false, // ULPFEC disabled.
543 false, // FlexFEC disabled.
Niels Möller6aa415e2018-06-07 09:14:13544 false, // Automatic scaling disabled
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59545 ""};
546 params.video[camera_idx] = {flags::FLAG_video,
547 flags::VideoWidth(),
548 flags::VideoHeight(),
549 flags::VideoFps(),
550 flags::VideoMinBitrateKbps() * 1000,
551 flags::VideoTargetBitrateKbps() * 1000,
552 flags::VideoMaxBitrateKbps() * 1000,
553 flags::FLAG_suspend_below_min_bitrate,
554 flags::Codec(),
555 flags::VideoNumTemporalLayers(),
556 flags::VideoSelectedTL(),
557 0, // No min transmit bitrate.
558 flags::FLAG_use_ulpfec,
559 flags::FLAG_use_flexfec,
Niels Möller6aa415e2018-06-07 09:14:13560 false,
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59561 flags::VideoClip(),
562 flags::GetCaptureDevice()};
563 params.audio = {flags::FLAG_audio, flags::FLAG_audio_video_sync,
564 flags::FLAG_audio_dtx};
Mirko Bonadei45a4c412018-07-31 13:07:28565 params.logging = {flags::FLAG_rtc_event_log_name, flags::FLAG_rtp_dump_name,
566 flags::FLAG_encoded_frame_path};
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59567 params.analyzer = {"dual_streams",
568 0.0,
569 0.0,
570 flags::DurationSecs(),
571 flags::OutputFilename(),
572 flags::GraphTitle()};
Artem Titovf18b3522018-08-28 14:54:24573 params.config = pipe_config;
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59574
575 params.screenshare[camera_idx].enabled = false;
576 params.screenshare[screenshare_idx] = {
577 true, flags::GenerateSlides(), flags::SlideChangeInterval(),
578 flags::ScrollDuration(), flags::Slides()};
579
580 if (flags::VideoNumStreams() > 1 && flags::VideoStream0().empty() &&
581 flags::VideoStream1().empty()) {
582 params.ss[camera_idx].infer_streams = true;
583 }
584
585 if (flags::ScreenshareNumStreams() > 1 &&
586 flags::ScreenshareStream0().empty() &&
587 flags::ScreenshareStream1().empty()) {
588 params.ss[screenshare_idx].infer_streams = true;
589 }
590
591 std::vector<std::string> stream_descriptors;
592 stream_descriptors.push_back(flags::ScreenshareStream0());
593 stream_descriptors.push_back(flags::ScreenshareStream1());
594 std::vector<std::string> SL_descriptors;
595 SL_descriptors.push_back(flags::ScreenshareSL0());
596 SL_descriptors.push_back(flags::ScreenshareSL1());
597 VideoQualityTest::FillScalabilitySettings(
598 &params, screenshare_idx, stream_descriptors,
599 flags::ScreenshareNumStreams(), flags::ScreenshareSelectedStream(),
600 flags::ScreenshareNumSpatialLayers(), flags::ScreenshareSelectedSL(),
Sergey Silkin57027362018-05-15 07:12:05601 flags::ScreenshareInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59602
603 stream_descriptors.clear();
604 stream_descriptors.push_back(flags::VideoStream0());
605 stream_descriptors.push_back(flags::VideoStream1());
606 SL_descriptors.clear();
607 SL_descriptors.push_back(flags::VideoSL0());
608 SL_descriptors.push_back(flags::VideoSL1());
609 VideoQualityTest::FillScalabilitySettings(
610 &params, camera_idx, stream_descriptors, flags::VideoNumStreams(),
611 flags::VideoSelectedStream(), flags::VideoNumSpatialLayers(),
Sergey Silkin57027362018-05-15 07:12:05612 flags::VideoSelectedSL(), flags::VideoInterLayerPred(), SL_descriptors);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59613
Karl Wiberg918f50c2018-07-05 09:40:33614 auto fixture = absl::make_unique<VideoQualityTest>(nullptr);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59615 if (flags::DurationSecs()) {
Patrik Höglundb6b29e02018-06-21 14:58:01616 fixture->RunWithAnalyzer(params);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59617 } else {
Patrik Höglundb6b29e02018-06-21 14:58:01618 fixture->RunWithRenderers(params);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59619 }
620}
621} // namespace webrtc
622
623int main(int argc, char* argv[]) {
624 ::testing::InitGoogleTest(&argc, argv);
625 if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) != 0) {
626 // Fail on unrecognized flags.
627 return 1;
628 }
629 if (webrtc::flags::FLAG_help) {
630 rtc::FlagList::Print(nullptr, false);
631 return 0;
632 }
633
Mirko Bonadei45a4c412018-07-31 13:07:28634 rtc::LogMessage::SetLogToStderr(webrtc::flags::FLAG_logs);
635
Bjorn Tereliusedab3012018-01-31 16:23:40636 webrtc::test::ValidateFieldTrialsStringOrDie(
637 webrtc::flags::FLAG_force_fieldtrials);
638 // InitFieldTrialsFromString stores the char*, so the char array must outlive
639 // the application.
640 webrtc::field_trial::InitFieldTrialsFromString(
641 webrtc::flags::FLAG_force_fieldtrials);
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59642
643 webrtc::test::RunTest(webrtc::Loopback);
644 return 0;
645}