blob: 4270ba96d738fa2a02fa0007cb1e3fe547ea2a21 [file] [log] [blame]
sprang@webrtc.org131bea82015-02-18 12:46:06 +00001/*
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 */
Kári Tristan Helgasonede7cb22019-03-06 10:34:09 +010010#include "video/video_loopback.h"
sprang@webrtc.org131bea82015-02-18 12:46:06 +000011
12#include <stdio.h>
Jonas Olsson5b2eda42019-06-11 14:29:40 +020013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <memory>
15#include <string>
16#include <vector>
sprang@webrtc.org131bea82015-02-18 12:46:06 +000017
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020018#include "absl/flags/flag.h"
19#include "absl/flags/parse.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "absl/memory/memory.h"
21#include "absl/types/optional.h"
22#include "api/bitrate_constraints.h"
23#include "api/test/simulated_network.h"
24#include "api/test/video_quality_test_fixture.h"
25#include "api/video_codecs/video_codec.h"
26#include "rtc_base/checks.h"
Mirko Bonadei45a4c412018-07-31 15:07:28 +020027#include "rtc_base/logging.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020028#include "system_wrappers/include/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "test/field_trial.h"
30#include "test/gtest.h"
31#include "test/run_test.h"
32#include "video/video_quality_test.h"
sprang@webrtc.org131bea82015-02-18 12:46:06 +000033
sprangce4aef12015-11-02 07:23:20 -080034// Flags common with screenshare loopback, with different default values.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020035ABSL_FLAG(int, width, 640, "Video width.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000036
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020037ABSL_FLAG(int, height, 480, "Video height.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000038
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020039ABSL_FLAG(int, fps, 30, "Frames per second.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000040
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020041ABSL_FLAG(int, capture_device_index, 0, "Capture device to select");
Tarun Chawla8e857d12017-05-31 19:20:57 +053042
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020043ABSL_FLAG(int, min_bitrate, 50, "Call and stream min bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000044
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020045ABSL_FLAG(int, start_bitrate, 300, "Call start bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000046
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020047ABSL_FLAG(int, target_bitrate, 800, "Stream target bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000048
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020049ABSL_FLAG(int, max_bitrate, 800, "Call and stream max bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000050
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020051ABSL_FLAG(bool,
52 suspend_below_min_bitrate,
53 false,
54 "Suspends video below the configured min bitrate.");
mflodman48a4beb2016-07-01 13:03:59 +020055
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020056ABSL_FLAG(int,
57 num_temporal_layers,
58 1,
59 "Number of temporal layers. Set to 1-4 to override.");
sprangce4aef12015-11-02 07:23:20 -080060
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020061ABSL_FLAG(int,
62 inter_layer_pred,
63 2,
64 "Inter-layer prediction mode. "
65 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 09:12:05 +020066
sprangce4aef12015-11-02 07:23:20 -080067// Flags common with screenshare loopback, with equal default values.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020068ABSL_FLAG(std::string, codec, "VP8", "Video codec to use.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000069
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020070ABSL_FLAG(int,
71 selected_tl,
72 -1,
73 "Temporal layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 07:23:20 -080074
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020075ABSL_FLAG(
76 int,
sprangce4aef12015-11-02 07:23:20 -080077 duration,
78 0,
79 "Duration of the test in seconds. If 0, rendered will be shown instead.");
sprangce4aef12015-11-02 07:23:20 -080080
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020081ABSL_FLAG(std::string, output_filename, "", "Target graph data filename.");
sprangce4aef12015-11-02 07:23:20 -080082
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020083ABSL_FLAG(std::string,
84 graph_title,
85 "",
86 "If empty, title will be generated automatically.");
sprangce4aef12015-11-02 07:23:20 -080087
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020088ABSL_FLAG(int, loss_percent, 0, "Percentage of packets randomly lost.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000089
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020090ABSL_FLAG(int,
91 avg_burst_loss_length,
92 -1,
93 "Average burst length of lost packets.");
philipel536378b2016-05-31 03:20:23 -070094
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020095ABSL_FLAG(int,
96 link_capacity,
97 0,
98 "Capacity (kbps) of the fake link. 0 means infinite.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000099
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200100ABSL_FLAG(int, queue_size, 0, "Size of the bottleneck link queue in packets.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000101
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200102ABSL_FLAG(int,
103 avg_propagation_delay_ms,
104 0,
105 "Average link propagation delay in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000106
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200107ABSL_FLAG(std::string,
108 rtc_event_log_name,
109 "",
110 "Filename for rtc event log. Two files "
111 "with \"_send\" and \"_recv\" suffixes will be created.");
ilnik98436952017-07-13 00:47:03 -0700112
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200113ABSL_FLAG(std::string,
114 rtp_dump_name,
115 "",
116 "Filename for dumped received RTP stream.");
ilnik98436952017-07-13 00:47:03 -0700117
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200118ABSL_FLAG(int,
119 std_propagation_delay_ms,
120 0,
121 "Link propagation delay standard deviation in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000122
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200123ABSL_FLAG(int, num_streams, 0, "Number of streams to show or analyze.");
sprang1168fd42017-06-21 09:00:17 -0700124
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200125ABSL_FLAG(int,
126 selected_stream,
127 0,
128 "ID of the stream to show or analyze. "
129 "Set to the number of streams to show them all.");
sprangce4aef12015-11-02 07:23:20 -0800130
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200131ABSL_FLAG(int, num_spatial_layers, 1, "Number of spatial layers to use.");
sprangce4aef12015-11-02 07:23:20 -0800132
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200133ABSL_FLAG(int,
134 selected_sl,
135 -1,
136 "Spatial layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 07:23:20 -0800137
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200138ABSL_FLAG(std::string,
139 stream0,
140 "",
141 "Comma separated values describing VideoStream for stream #0.");
sprangce4aef12015-11-02 07:23:20 -0800142
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200143ABSL_FLAG(std::string,
144 stream1,
145 "",
146 "Comma separated values describing VideoStream for stream #1.");
sprangce4aef12015-11-02 07:23:20 -0800147
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200148ABSL_FLAG(std::string,
149 sl0,
150 "",
151 "Comma separated values describing SpatialLayer for layer #0.");
sprangce4aef12015-11-02 07:23:20 -0800152
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200153ABSL_FLAG(std::string,
154 sl1,
155 "",
156 "Comma separated values describing SpatialLayer for layer #1.");
sprangce4aef12015-11-02 07:23:20 -0800157
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200158ABSL_FLAG(std::string,
159 sl2,
160 "",
161 "Comma separated values describing SpatialLayer for layer #2.");
Sergey Silkina89800c2019-02-19 12:52:56 +0100162
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200163ABSL_FLAG(std::string,
164 encoded_frame_path,
165 "",
166 "The base path for encoded frame logs. Created files will have "
167 "the form <encoded_frame_path>.<n>.(recv|send.<m>).ivf");
palmkviste75f2042016-09-28 06:19:48 -0700168
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200169ABSL_FLAG(bool, logs, false, "print logs to stderr");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000170
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200171ABSL_FLAG(bool, send_side_bwe, true, "Use send-side bandwidth estimation");
sprangce4aef12015-11-02 07:23:20 -0800172
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200173ABSL_FLAG(bool, generic_descriptor, false, "Use the generic frame descriptor.");
philipel569397f2018-09-26 12:25:31 +0200174
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200175ABSL_FLAG(bool, allow_reordering, false, "Allow packet reordering to occur");
philipela2c55232016-01-26 08:41:53 -0800176
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200177ABSL_FLAG(bool, use_ulpfec, false, "Use RED+ULPFEC forward error correction.");
brandtra62f5822016-11-17 00:21:13 -0800178
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200179ABSL_FLAG(bool, use_flexfec, false, "Use FlexFEC forward error correction.");
philipel274c1dc2016-05-04 06:21:01 -0700180
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200181ABSL_FLAG(bool, audio, false, "Add audio stream");
minyue73208662016-08-18 06:28:55 -0700182
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200183ABSL_FLAG(bool,
184 use_real_adm,
185 false,
186 "Use real ADM instead of fake (no effect if audio is false)");
henrika255750b2018-08-27 16:13:37 +0200187
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200188ABSL_FLAG(bool,
189 audio_video_sync,
190 false,
191 "Sync audio and video stream (no effect if"
192 " audio is false)");
minyue73208662016-08-18 06:28:55 -0700193
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200194ABSL_FLAG(bool,
195 audio_dtx,
196 false,
197 "Enable audio DTX (no effect if audio is false)");
minyue4c8b9422017-03-21 04:11:43 -0700198
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200199ABSL_FLAG(bool, video, true, "Add video stream");
minyuea27172d2016-11-01 05:59:29 -0700200
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200201ABSL_FLAG(
202 std::string,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000203 force_fieldtrials,
204 "",
205 "Field trials control experimental feature code which can be forced. "
Elad Alon1e3ed162018-10-15 17:50:37 +0200206 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enabled/"
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000207 " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
208 "trials are separated by \"/\"");
pbos9874ee02015-06-22 04:44:26 -0700209
sprangce4aef12015-11-02 07:23:20 -0800210// Video-specific flags.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200211ABSL_FLAG(std::string,
212 clip,
213 "",
214 "Name of the clip to show. If empty, using chroma generator.");
215
216namespace webrtc {
217namespace {
218
219size_t Width() {
220 return static_cast<size_t>(absl::GetFlag(FLAGS_width));
ivica5d6a06c2015-09-17 05:30:24 -0700221}
222
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200223size_t Height() {
224 return static_cast<size_t>(absl::GetFlag(FLAGS_height));
225}
sprang1168fd42017-06-21 09:00:17 -0700226
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200227int Fps() {
228 return absl::GetFlag(FLAGS_fps);
229}
230
231size_t GetCaptureDevice() {
232 return static_cast<size_t>(absl::GetFlag(FLAGS_capture_device_index));
233}
234
235int MinBitrateKbps() {
236 return absl::GetFlag(FLAGS_min_bitrate);
237}
238
239int StartBitrateKbps() {
240 return absl::GetFlag(FLAGS_start_bitrate);
241}
242
243int TargetBitrateKbps() {
244 return absl::GetFlag(FLAGS_target_bitrate);
245}
246
247int MaxBitrateKbps() {
248 return absl::GetFlag(FLAGS_max_bitrate);
249}
250
251int NumTemporalLayers() {
252 return absl::GetFlag(FLAGS_num_temporal_layers);
253}
254
255InterLayerPredMode InterLayerPred() {
256 if (absl::GetFlag(FLAGS_inter_layer_pred) == 0) {
257 return InterLayerPredMode::kOn;
258 } else if (absl::GetFlag(FLAGS_inter_layer_pred) == 1) {
259 return InterLayerPredMode::kOff;
260 } else {
261 RTC_DCHECK_EQ(absl::GetFlag(FLAGS_inter_layer_pred), 2);
262 return InterLayerPredMode::kOnKeyPic;
263 }
264}
265
266std::string Codec() {
267 return absl::GetFlag(FLAGS_codec);
268}
269
270int SelectedTL() {
271 return absl::GetFlag(FLAGS_selected_tl);
272}
273
274int DurationSecs() {
275 return absl::GetFlag(FLAGS_duration);
276}
277
278std::string OutputFilename() {
279 return absl::GetFlag(FLAGS_output_filename);
280}
281
282std::string GraphTitle() {
283 return absl::GetFlag(FLAGS_graph_title);
284}
285
286int LossPercent() {
287 return static_cast<int>(absl::GetFlag(FLAGS_loss_percent));
288}
289
290int AvgBurstLossLength() {
291 return static_cast<int>(absl::GetFlag(FLAGS_avg_burst_loss_length));
292}
293
294int LinkCapacityKbps() {
295 return static_cast<int>(absl::GetFlag(FLAGS_link_capacity));
296}
297
298int QueueSize() {
299 return static_cast<int>(absl::GetFlag(FLAGS_queue_size));
300}
301
302int AvgPropagationDelayMs() {
303 return static_cast<int>(absl::GetFlag(FLAGS_avg_propagation_delay_ms));
304}
305
306std::string RtcEventLogName() {
307 return absl::GetFlag(FLAGS_rtc_event_log_name);
308}
309
310std::string RtpDumpName() {
311 return absl::GetFlag(FLAGS_rtp_dump_name);
312}
313
314int StdPropagationDelayMs() {
315 return absl::GetFlag(FLAGS_std_propagation_delay_ms);
316}
317
318int NumStreams() {
319 return absl::GetFlag(FLAGS_num_streams);
320}
321
322int SelectedStream() {
323 return absl::GetFlag(FLAGS_selected_stream);
324}
325
326int NumSpatialLayers() {
327 return absl::GetFlag(FLAGS_num_spatial_layers);
328}
329
330int SelectedSL() {
331 return absl::GetFlag(FLAGS_selected_sl);
332}
333
334std::string Stream0() {
335 return absl::GetFlag(FLAGS_stream0);
336}
337
338std::string Stream1() {
339 return absl::GetFlag(FLAGS_stream1);
340}
341
342std::string SL0() {
343 return absl::GetFlag(FLAGS_sl0);
344}
345
346std::string SL1() {
347 return absl::GetFlag(FLAGS_sl1);
348}
349
350std::string SL2() {
351 return absl::GetFlag(FLAGS_sl2);
352}
353
354std::string EncodedFramePath() {
355 return absl::GetFlag(FLAGS_encoded_frame_path);
356}
357
358std::string Clip() {
359 return absl::GetFlag(FLAGS_clip);
360}
361
362} // namespace
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000363
364void Loopback() {
Artem Titov75e36472018-10-08 12:28:56 +0200365 BuiltInNetworkBehaviorConfig pipe_config;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200366 pipe_config.loss_percent = LossPercent();
367 pipe_config.avg_burst_loss_length = AvgBurstLossLength();
368 pipe_config.link_capacity_kbps = LinkCapacityKbps();
369 pipe_config.queue_length_packets = QueueSize();
370 pipe_config.queue_delay_ms = AvgPropagationDelayMs();
371 pipe_config.delay_standard_deviation_ms = StdPropagationDelayMs();
372 pipe_config.allow_reordering = absl::GetFlag(FLAGS_allow_reordering);
ivica5d6a06c2015-09-17 05:30:24 -0700373
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100374 BitrateConstraints call_bitrate_config;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200375 call_bitrate_config.min_bitrate_bps = MinBitrateKbps() * 1000;
376 call_bitrate_config.start_bitrate_bps = StartBitrateKbps() * 1000;
Erik Språng28bb3912018-07-11 16:06:55 +0200377 call_bitrate_config.max_bitrate_bps = -1; // Don't cap bandwidth estimate.
ivica5d6a06c2015-09-17 05:30:24 -0700378
minyue73208662016-08-18 06:28:55 -0700379 VideoQualityTest::Params params;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200380 params.call = {absl::GetFlag(FLAGS_send_side_bwe),
381 absl::GetFlag(FLAGS_generic_descriptor), call_bitrate_config,
382 0};
383 params.video[0] = {absl::GetFlag(FLAGS_video),
384 Width(),
385 Height(),
386 Fps(),
387 MinBitrateKbps() * 1000,
388 TargetBitrateKbps() * 1000,
389 MaxBitrateKbps() * 1000,
390 absl::GetFlag(FLAGS_suspend_below_min_bitrate),
391 Codec(),
392 NumTemporalLayers(),
393 SelectedTL(),
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100394 0, // No min transmit bitrate.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200395 absl::GetFlag(FLAGS_use_ulpfec),
396 absl::GetFlag(FLAGS_use_flexfec),
397 NumStreams() < 2, // Automatic quality scaling.
398 Clip(),
399 GetCaptureDevice()};
400 params.audio = {
401 absl::GetFlag(FLAGS_audio), absl::GetFlag(FLAGS_audio_video_sync),
402 absl::GetFlag(FLAGS_audio_dtx), absl::GetFlag(FLAGS_use_real_adm)};
403 params.logging = {RtcEventLogName(), RtpDumpName(), EncodedFramePath()};
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100404 params.screenshare[0].enabled = false;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200405 params.analyzer = {"video", 0.0, 0.0, DurationSecs(),
406 OutputFilename(), GraphTitle()};
Artem Titovf18b3522018-08-28 16:54:24 +0200407 params.config = pipe_config;
sprang1168fd42017-06-21 09:00:17 -0700408
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200409 if (NumStreams() > 1 && Stream0().empty() && Stream1().empty()) {
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100410 params.ss[0].infer_streams = true;
sprang1168fd42017-06-21 09:00:17 -0700411 }
ivica5d6a06c2015-09-17 05:30:24 -0700412
sprangce4aef12015-11-02 07:23:20 -0800413 std::vector<std::string> stream_descriptors;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200414 stream_descriptors.push_back(Stream0());
415 stream_descriptors.push_back(Stream1());
sprangce4aef12015-11-02 07:23:20 -0800416 std::vector<std::string> SL_descriptors;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200417 SL_descriptors.push_back(SL0());
418 SL_descriptors.push_back(SL1());
419 SL_descriptors.push_back(SL2());
sprangce4aef12015-11-02 07:23:20 -0800420 VideoQualityTest::FillScalabilitySettings(
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200421 &params, 0, stream_descriptors, NumStreams(), SelectedStream(),
422 NumSpatialLayers(), SelectedSL(), InterLayerPred(), SL_descriptors);
sprangce4aef12015-11-02 07:23:20 -0800423
Karl Wiberg918f50c2018-07-05 11:40:33 +0200424 auto fixture = absl::make_unique<VideoQualityTest>(nullptr);
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200425 if (DurationSecs()) {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200426 fixture->RunWithAnalyzer(params);
sprangce4aef12015-11-02 07:23:20 -0800427 } else {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200428 fixture->RunWithRenderers(params);
sprangce4aef12015-11-02 07:23:20 -0800429 }
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000430}
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000431
Kári Tristan Helgasonede7cb22019-03-06 10:34:09 +0100432int RunLoopbackTest(int argc, char* argv[]) {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000433 ::testing::InitGoogleTest(&argc, argv);
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200434 absl::ParseCommandLine(argc, argv);
sprang1168fd42017-06-21 09:00:17 -0700435
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200436 rtc::LogMessage::SetLogToStderr(absl::GetFlag(FLAGS_logs));
Mirko Bonadei45a4c412018-07-31 15:07:28 +0200437
Bjorn Tereliusedab3012018-01-31 17:23:40 +0100438 // InitFieldTrialsFromString stores the char*, so the char array must outlive
439 // the application.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200440 const std::string field_trials = absl::GetFlag(FLAGS_force_fieldtrials);
441 webrtc::field_trial::InitFieldTrialsFromString(field_trials.c_str());
sprang89c4a7e2017-06-30 13:27:40 -0700442
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000443 webrtc::test::RunTest(webrtc::Loopback);
444 return 0;
445}
Kári Tristan Helgasonede7cb22019-03-06 10:34:09 +0100446} // namespace webrtc