blob: 99ff4493bdc28f91182b24b4cb3ab784bdc34440 [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/types/optional.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "api/test/simulated_network.h"
22#include "api/test/video_quality_test_fixture.h"
Mirko Bonadei738bfa72019-09-17 14:47:38 +020023#include "api/transport/bitrate_settings.h"
Yves Gerey3e707812018-11-28 16:47:49 +010024#include "api/video_codecs/video_codec.h"
25#include "rtc_base/checks.h"
Mirko Bonadei45a4c412018-07-31 15:07:28 +020026#include "rtc_base/logging.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020027#include "system_wrappers/include/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "test/field_trial.h"
29#include "test/gtest.h"
30#include "test/run_test.h"
31#include "video/video_quality_test.h"
sprang@webrtc.org131bea82015-02-18 12:46:06 +000032
sprangce4aef12015-11-02 07:23:20 -080033// Flags common with screenshare loopback, with different default values.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020034ABSL_FLAG(int, width, 640, "Video width.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000035
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020036ABSL_FLAG(int, height, 480, "Video height.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000037
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020038ABSL_FLAG(int, fps, 30, "Frames per second.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000039
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020040ABSL_FLAG(int, capture_device_index, 0, "Capture device to select");
Tarun Chawla8e857d12017-05-31 19:20:57 +053041
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020042ABSL_FLAG(int, min_bitrate, 50, "Call and stream min bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000043
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020044ABSL_FLAG(int, start_bitrate, 300, "Call start bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000045
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020046ABSL_FLAG(int, target_bitrate, 800, "Stream target bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000047
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020048ABSL_FLAG(int, max_bitrate, 800, "Call and stream max bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000049
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020050ABSL_FLAG(bool,
51 suspend_below_min_bitrate,
52 false,
53 "Suspends video below the configured min bitrate.");
mflodman48a4beb2016-07-01 13:03:59 +020054
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020055ABSL_FLAG(int,
56 num_temporal_layers,
57 1,
58 "Number of temporal layers. Set to 1-4 to override.");
sprangce4aef12015-11-02 07:23:20 -080059
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020060ABSL_FLAG(int,
61 inter_layer_pred,
62 2,
63 "Inter-layer prediction mode. "
64 "0 - enabled, 1 - disabled, 2 - enabled only for key pictures.");
Sergey Silkin57027362018-05-15 09:12:05 +020065
sprangce4aef12015-11-02 07:23:20 -080066// Flags common with screenshare loopback, with equal default values.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020067ABSL_FLAG(std::string, codec, "VP8", "Video codec to use.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000068
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020069ABSL_FLAG(int,
70 selected_tl,
71 -1,
72 "Temporal layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 07:23:20 -080073
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020074ABSL_FLAG(
75 int,
sprangce4aef12015-11-02 07:23:20 -080076 duration,
77 0,
78 "Duration of the test in seconds. If 0, rendered will be shown instead.");
sprangce4aef12015-11-02 07:23:20 -080079
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020080ABSL_FLAG(std::string, output_filename, "", "Target graph data filename.");
sprangce4aef12015-11-02 07:23:20 -080081
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020082ABSL_FLAG(std::string,
83 graph_title,
84 "",
85 "If empty, title will be generated automatically.");
sprangce4aef12015-11-02 07:23:20 -080086
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020087ABSL_FLAG(int, loss_percent, 0, "Percentage of packets randomly lost.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000088
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020089ABSL_FLAG(int,
90 avg_burst_loss_length,
91 -1,
92 "Average burst length of lost packets.");
philipel536378b2016-05-31 03:20:23 -070093
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020094ABSL_FLAG(int,
95 link_capacity,
96 0,
97 "Capacity (kbps) of the fake link. 0 means infinite.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +000098
Mirko Bonadei2ab97f62019-07-18 13:44:12 +020099ABSL_FLAG(int, queue_size, 0, "Size of the bottleneck link queue in packets.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000100
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200101ABSL_FLAG(int,
102 avg_propagation_delay_ms,
103 0,
104 "Average link propagation delay in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000105
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200106ABSL_FLAG(std::string,
107 rtc_event_log_name,
108 "",
109 "Filename for rtc event log. Two files "
110 "with \"_send\" and \"_recv\" suffixes will be created.");
ilnik98436952017-07-13 00:47:03 -0700111
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200112ABSL_FLAG(std::string,
113 rtp_dump_name,
114 "",
115 "Filename for dumped received RTP stream.");
ilnik98436952017-07-13 00:47:03 -0700116
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200117ABSL_FLAG(int,
118 std_propagation_delay_ms,
119 0,
120 "Link propagation delay standard deviation in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000121
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200122ABSL_FLAG(int, num_streams, 0, "Number of streams to show or analyze.");
sprang1168fd42017-06-21 09:00:17 -0700123
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200124ABSL_FLAG(int,
125 selected_stream,
126 0,
127 "ID of the stream to show or analyze. "
128 "Set to the number of streams to show them all.");
sprangce4aef12015-11-02 07:23:20 -0800129
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200130ABSL_FLAG(int, num_spatial_layers, 1, "Number of spatial layers to use.");
sprangce4aef12015-11-02 07:23:20 -0800131
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200132ABSL_FLAG(int,
133 selected_sl,
134 -1,
135 "Spatial layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 07:23:20 -0800136
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200137ABSL_FLAG(std::string,
138 stream0,
139 "",
140 "Comma separated values describing VideoStream for stream #0.");
sprangce4aef12015-11-02 07:23:20 -0800141
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200142ABSL_FLAG(std::string,
143 stream1,
144 "",
145 "Comma separated values describing VideoStream for stream #1.");
sprangce4aef12015-11-02 07:23:20 -0800146
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200147ABSL_FLAG(std::string,
148 sl0,
149 "",
150 "Comma separated values describing SpatialLayer for layer #0.");
sprangce4aef12015-11-02 07:23:20 -0800151
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200152ABSL_FLAG(std::string,
153 sl1,
154 "",
155 "Comma separated values describing SpatialLayer for layer #1.");
sprangce4aef12015-11-02 07:23:20 -0800156
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200157ABSL_FLAG(std::string,
158 sl2,
159 "",
160 "Comma separated values describing SpatialLayer for layer #2.");
Sergey Silkina89800c2019-02-19 12:52:56 +0100161
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200162ABSL_FLAG(std::string,
163 encoded_frame_path,
164 "",
165 "The base path for encoded frame logs. Created files will have "
166 "the form <encoded_frame_path>.<n>.(recv|send.<m>).ivf");
palmkviste75f2042016-09-28 06:19:48 -0700167
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200168ABSL_FLAG(bool, logs, false, "print logs to stderr");
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000169
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200170ABSL_FLAG(bool, send_side_bwe, true, "Use send-side bandwidth estimation");
sprangce4aef12015-11-02 07:23:20 -0800171
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200172ABSL_FLAG(bool, generic_descriptor, false, "Use the generic frame descriptor.");
philipel569397f2018-09-26 12:25:31 +0200173
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200174ABSL_FLAG(bool, allow_reordering, false, "Allow packet reordering to occur");
philipela2c55232016-01-26 08:41:53 -0800175
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200176ABSL_FLAG(bool, use_ulpfec, false, "Use RED+ULPFEC forward error correction.");
brandtra62f5822016-11-17 00:21:13 -0800177
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200178ABSL_FLAG(bool, use_flexfec, false, "Use FlexFEC forward error correction.");
philipel274c1dc2016-05-04 06:21:01 -0700179
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200180ABSL_FLAG(bool, audio, false, "Add audio stream");
minyue73208662016-08-18 06:28:55 -0700181
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200182ABSL_FLAG(bool,
183 use_real_adm,
184 false,
185 "Use real ADM instead of fake (no effect if audio is false)");
henrika255750b2018-08-27 16:13:37 +0200186
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200187ABSL_FLAG(bool,
188 audio_video_sync,
189 false,
190 "Sync audio and video stream (no effect if"
191 " audio is false)");
minyue73208662016-08-18 06:28:55 -0700192
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200193ABSL_FLAG(bool,
194 audio_dtx,
195 false,
196 "Enable audio DTX (no effect if audio is false)");
minyue4c8b9422017-03-21 04:11:43 -0700197
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200198ABSL_FLAG(bool, video, true, "Add video stream");
minyuea27172d2016-11-01 05:59:29 -0700199
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200200ABSL_FLAG(
201 std::string,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000202 force_fieldtrials,
203 "",
204 "Field trials control experimental feature code which can be forced. "
Elad Alon1e3ed162018-10-15 17:50:37 +0200205 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enabled/"
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000206 " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
207 "trials are separated by \"/\"");
pbos9874ee02015-06-22 04:44:26 -0700208
sprangce4aef12015-11-02 07:23:20 -0800209// Video-specific flags.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200210ABSL_FLAG(std::string,
211 clip,
212 "",
213 "Name of the clip to show. If empty, using chroma generator.");
214
215namespace webrtc {
216namespace {
217
218size_t Width() {
219 return static_cast<size_t>(absl::GetFlag(FLAGS_width));
ivica5d6a06c2015-09-17 05:30:24 -0700220}
221
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200222size_t Height() {
223 return static_cast<size_t>(absl::GetFlag(FLAGS_height));
224}
sprang1168fd42017-06-21 09:00:17 -0700225
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200226int Fps() {
227 return absl::GetFlag(FLAGS_fps);
228}
229
230size_t GetCaptureDevice() {
231 return static_cast<size_t>(absl::GetFlag(FLAGS_capture_device_index));
232}
233
234int MinBitrateKbps() {
235 return absl::GetFlag(FLAGS_min_bitrate);
236}
237
238int StartBitrateKbps() {
239 return absl::GetFlag(FLAGS_start_bitrate);
240}
241
242int TargetBitrateKbps() {
243 return absl::GetFlag(FLAGS_target_bitrate);
244}
245
246int MaxBitrateKbps() {
247 return absl::GetFlag(FLAGS_max_bitrate);
248}
249
250int NumTemporalLayers() {
251 return absl::GetFlag(FLAGS_num_temporal_layers);
252}
253
254InterLayerPredMode InterLayerPred() {
255 if (absl::GetFlag(FLAGS_inter_layer_pred) == 0) {
256 return InterLayerPredMode::kOn;
257 } else if (absl::GetFlag(FLAGS_inter_layer_pred) == 1) {
258 return InterLayerPredMode::kOff;
259 } else {
260 RTC_DCHECK_EQ(absl::GetFlag(FLAGS_inter_layer_pred), 2);
261 return InterLayerPredMode::kOnKeyPic;
262 }
263}
264
265std::string Codec() {
266 return absl::GetFlag(FLAGS_codec);
267}
268
269int SelectedTL() {
270 return absl::GetFlag(FLAGS_selected_tl);
271}
272
273int DurationSecs() {
274 return absl::GetFlag(FLAGS_duration);
275}
276
277std::string OutputFilename() {
278 return absl::GetFlag(FLAGS_output_filename);
279}
280
281std::string GraphTitle() {
282 return absl::GetFlag(FLAGS_graph_title);
283}
284
285int LossPercent() {
286 return static_cast<int>(absl::GetFlag(FLAGS_loss_percent));
287}
288
289int AvgBurstLossLength() {
290 return static_cast<int>(absl::GetFlag(FLAGS_avg_burst_loss_length));
291}
292
293int LinkCapacityKbps() {
294 return static_cast<int>(absl::GetFlag(FLAGS_link_capacity));
295}
296
297int QueueSize() {
298 return static_cast<int>(absl::GetFlag(FLAGS_queue_size));
299}
300
301int AvgPropagationDelayMs() {
302 return static_cast<int>(absl::GetFlag(FLAGS_avg_propagation_delay_ms));
303}
304
305std::string RtcEventLogName() {
306 return absl::GetFlag(FLAGS_rtc_event_log_name);
307}
308
309std::string RtpDumpName() {
310 return absl::GetFlag(FLAGS_rtp_dump_name);
311}
312
313int StdPropagationDelayMs() {
314 return absl::GetFlag(FLAGS_std_propagation_delay_ms);
315}
316
317int NumStreams() {
318 return absl::GetFlag(FLAGS_num_streams);
319}
320
321int SelectedStream() {
322 return absl::GetFlag(FLAGS_selected_stream);
323}
324
325int NumSpatialLayers() {
326 return absl::GetFlag(FLAGS_num_spatial_layers);
327}
328
329int SelectedSL() {
330 return absl::GetFlag(FLAGS_selected_sl);
331}
332
333std::string Stream0() {
334 return absl::GetFlag(FLAGS_stream0);
335}
336
337std::string Stream1() {
338 return absl::GetFlag(FLAGS_stream1);
339}
340
341std::string SL0() {
342 return absl::GetFlag(FLAGS_sl0);
343}
344
345std::string SL1() {
346 return absl::GetFlag(FLAGS_sl1);
347}
348
349std::string SL2() {
350 return absl::GetFlag(FLAGS_sl2);
351}
352
353std::string EncodedFramePath() {
354 return absl::GetFlag(FLAGS_encoded_frame_path);
355}
356
357std::string Clip() {
358 return absl::GetFlag(FLAGS_clip);
359}
360
361} // namespace
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000362
363void Loopback() {
Artem Titov75e36472018-10-08 12:28:56 +0200364 BuiltInNetworkBehaviorConfig pipe_config;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200365 pipe_config.loss_percent = LossPercent();
366 pipe_config.avg_burst_loss_length = AvgBurstLossLength();
367 pipe_config.link_capacity_kbps = LinkCapacityKbps();
368 pipe_config.queue_length_packets = QueueSize();
369 pipe_config.queue_delay_ms = AvgPropagationDelayMs();
370 pipe_config.delay_standard_deviation_ms = StdPropagationDelayMs();
371 pipe_config.allow_reordering = absl::GetFlag(FLAGS_allow_reordering);
ivica5d6a06c2015-09-17 05:30:24 -0700372
Sebastian Janssonfc8d26b2018-02-21 09:52:06 +0100373 BitrateConstraints call_bitrate_config;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200374 call_bitrate_config.min_bitrate_bps = MinBitrateKbps() * 1000;
375 call_bitrate_config.start_bitrate_bps = StartBitrateKbps() * 1000;
Erik Språng28bb3912018-07-11 16:06:55 +0200376 call_bitrate_config.max_bitrate_bps = -1; // Don't cap bandwidth estimate.
ivica5d6a06c2015-09-17 05:30:24 -0700377
minyue73208662016-08-18 06:28:55 -0700378 VideoQualityTest::Params params;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200379 params.call = {absl::GetFlag(FLAGS_send_side_bwe),
380 absl::GetFlag(FLAGS_generic_descriptor), call_bitrate_config,
381 0};
382 params.video[0] = {absl::GetFlag(FLAGS_video),
383 Width(),
384 Height(),
385 Fps(),
386 MinBitrateKbps() * 1000,
387 TargetBitrateKbps() * 1000,
388 MaxBitrateKbps() * 1000,
389 absl::GetFlag(FLAGS_suspend_below_min_bitrate),
390 Codec(),
391 NumTemporalLayers(),
392 SelectedTL(),
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100393 0, // No min transmit bitrate.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200394 absl::GetFlag(FLAGS_use_ulpfec),
395 absl::GetFlag(FLAGS_use_flexfec),
396 NumStreams() < 2, // Automatic quality scaling.
397 Clip(),
398 GetCaptureDevice()};
399 params.audio = {
400 absl::GetFlag(FLAGS_audio), absl::GetFlag(FLAGS_audio_video_sync),
401 absl::GetFlag(FLAGS_audio_dtx), absl::GetFlag(FLAGS_use_real_adm)};
402 params.logging = {RtcEventLogName(), RtpDumpName(), EncodedFramePath()};
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100403 params.screenshare[0].enabled = false;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200404 params.analyzer = {"video", 0.0, 0.0, DurationSecs(),
405 OutputFilename(), GraphTitle()};
Artem Titovf18b3522018-08-28 16:54:24 +0200406 params.config = pipe_config;
sprang1168fd42017-06-21 09:00:17 -0700407
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200408 if (NumStreams() > 1 && Stream0().empty() && Stream1().empty()) {
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100409 params.ss[0].infer_streams = true;
sprang1168fd42017-06-21 09:00:17 -0700410 }
ivica5d6a06c2015-09-17 05:30:24 -0700411
sprangce4aef12015-11-02 07:23:20 -0800412 std::vector<std::string> stream_descriptors;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200413 stream_descriptors.push_back(Stream0());
414 stream_descriptors.push_back(Stream1());
sprangce4aef12015-11-02 07:23:20 -0800415 std::vector<std::string> SL_descriptors;
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200416 SL_descriptors.push_back(SL0());
417 SL_descriptors.push_back(SL1());
418 SL_descriptors.push_back(SL2());
sprangce4aef12015-11-02 07:23:20 -0800419 VideoQualityTest::FillScalabilitySettings(
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200420 &params, 0, stream_descriptors, NumStreams(), SelectedStream(),
421 NumSpatialLayers(), SelectedSL(), InterLayerPred(), SL_descriptors);
sprangce4aef12015-11-02 07:23:20 -0800422
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200423 auto fixture = std::make_unique<VideoQualityTest>(nullptr);
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200424 if (DurationSecs()) {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200425 fixture->RunWithAnalyzer(params);
sprangce4aef12015-11-02 07:23:20 -0800426 } else {
Patrik Höglundb6b29e02018-06-21 16:58:01 +0200427 fixture->RunWithRenderers(params);
sprangce4aef12015-11-02 07:23:20 -0800428 }
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000429}
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000430
Kári Tristan Helgasonede7cb22019-03-06 10:34:09 +0100431int RunLoopbackTest(int argc, char* argv[]) {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000432 ::testing::InitGoogleTest(&argc, argv);
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200433 absl::ParseCommandLine(argc, argv);
sprang1168fd42017-06-21 09:00:17 -0700434
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200435 rtc::LogMessage::SetLogToStderr(absl::GetFlag(FLAGS_logs));
Mirko Bonadei45a4c412018-07-31 15:07:28 +0200436
Bjorn Tereliusedab3012018-01-31 17:23:40 +0100437 // InitFieldTrialsFromString stores the char*, so the char array must outlive
438 // the application.
Mirko Bonadei2ab97f62019-07-18 13:44:12 +0200439 const std::string field_trials = absl::GetFlag(FLAGS_force_fieldtrials);
440 webrtc::field_trial::InitFieldTrialsFromString(field_trials.c_str());
sprang89c4a7e2017-06-30 13:27:40 -0700441
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000442 webrtc::test::RunTest(webrtc::Loopback);
443 return 0;
444}
Kári Tristan Helgasonede7cb22019-03-06 10:34:09 +0100445} // namespace webrtc