blob: ba0a0e5745c860630d1ae96ab3ffb699b213c1bd [file] [log] [blame]
sprang@webrtc.org131bea82015-02-18 12:46:061/*
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 09:34:0910#include "video/video_loopback.h"
sprang@webrtc.org131bea82015-02-18 12:46:0611
12#include <stdio.h>
Jonas Olsson5b2eda42019-06-11 12:29:4013
Yves Gerey3e707812018-11-28 15:47:4914#include <memory>
15#include <string>
16#include <vector>
sprang@webrtc.org131bea82015-02-18 12:46:0617
Mirko Bonadei2ab97f62019-07-18 11:44:1218#include "absl/flags/flag.h"
19#include "absl/flags/parse.h"
Yves Gerey3e707812018-11-28 15:47:4920#include "absl/types/optional.h"
Yves Gerey3e707812018-11-28 15:47:4921#include "api/test/simulated_network.h"
22#include "api/test/video_quality_test_fixture.h"
Mirko Bonadei738bfa72019-09-17 12:47:3823#include "api/transport/bitrate_settings.h"
Yves Gerey3e707812018-11-28 15:47:4924#include "api/video_codecs/video_codec.h"
25#include "rtc_base/checks.h"
Mirko Bonadei45a4c412018-07-31 13:07:2826#include "rtc_base/logging.h"
Mirko Bonadei17f48782018-09-28 06:51:1027#include "system_wrappers/include/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3128#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:0632
sprangce4aef12015-11-02 15:23:2033// Flags common with screenshare loopback, with different default values.
Mirko Bonadei2ab97f62019-07-18 11:44:1234ABSL_FLAG(int, width, 640, "Video width.");
sprang@webrtc.org131bea82015-02-18 12:46:0635
Mirko Bonadei2ab97f62019-07-18 11:44:1236ABSL_FLAG(int, height, 480, "Video height.");
sprang@webrtc.org131bea82015-02-18 12:46:0637
Mirko Bonadei2ab97f62019-07-18 11:44:1238ABSL_FLAG(int, fps, 30, "Frames per second.");
sprang@webrtc.org131bea82015-02-18 12:46:0639
Mirko Bonadei2ab97f62019-07-18 11:44:1240ABSL_FLAG(int, capture_device_index, 0, "Capture device to select");
Tarun Chawla8e857d12017-05-31 13:50:5741
Mirko Bonadei2ab97f62019-07-18 11:44:1242ABSL_FLAG(int, min_bitrate, 50, "Call and stream min bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:0643
Mirko Bonadei2ab97f62019-07-18 11:44:1244ABSL_FLAG(int, start_bitrate, 300, "Call start bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:0645
Mirko Bonadei2ab97f62019-07-18 11:44:1246ABSL_FLAG(int, target_bitrate, 800, "Stream target bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:0647
Mirko Bonadei2ab97f62019-07-18 11:44:1248ABSL_FLAG(int, max_bitrate, 800, "Call and stream max bitrate in kbps.");
sprang@webrtc.org131bea82015-02-18 12:46:0649
Mirko Bonadei2ab97f62019-07-18 11:44:1250ABSL_FLAG(bool,
51 suspend_below_min_bitrate,
52 false,
53 "Suspends video below the configured min bitrate.");
mflodman48a4beb2016-07-01 11:03:5954
Mirko Bonadei2ab97f62019-07-18 11:44:1255ABSL_FLAG(int,
56 num_temporal_layers,
57 1,
58 "Number of temporal layers. Set to 1-4 to override.");
sprangce4aef12015-11-02 15:23:2059
Mirko Bonadei2ab97f62019-07-18 11:44:1260ABSL_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 07:12:0565
sprangce4aef12015-11-02 15:23:2066// Flags common with screenshare loopback, with equal default values.
Mirko Bonadei2ab97f62019-07-18 11:44:1267ABSL_FLAG(std::string, codec, "VP8", "Video codec to use.");
sprang@webrtc.org131bea82015-02-18 12:46:0668
Mirko Bonadei2ab97f62019-07-18 11:44:1269ABSL_FLAG(int,
70 selected_tl,
71 -1,
72 "Temporal layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 15:23:2073
Mirko Bonadei2ab97f62019-07-18 11:44:1274ABSL_FLAG(
75 int,
sprangce4aef12015-11-02 15:23:2076 duration,
77 0,
78 "Duration of the test in seconds. If 0, rendered will be shown instead.");
sprangce4aef12015-11-02 15:23:2079
Mirko Bonadei2ab97f62019-07-18 11:44:1280ABSL_FLAG(std::string, output_filename, "", "Target graph data filename.");
sprangce4aef12015-11-02 15:23:2081
Mirko Bonadei2ab97f62019-07-18 11:44:1282ABSL_FLAG(std::string,
83 graph_title,
84 "",
85 "If empty, title will be generated automatically.");
sprangce4aef12015-11-02 15:23:2086
Mirko Bonadei2ab97f62019-07-18 11:44:1287ABSL_FLAG(int, loss_percent, 0, "Percentage of packets randomly lost.");
sprang@webrtc.org131bea82015-02-18 12:46:0688
Mirko Bonadei2ab97f62019-07-18 11:44:1289ABSL_FLAG(int,
90 avg_burst_loss_length,
91 -1,
92 "Average burst length of lost packets.");
philipel536378b2016-05-31 10:20:2393
Mirko Bonadei2ab97f62019-07-18 11:44:1294ABSL_FLAG(int,
95 link_capacity,
96 0,
97 "Capacity (kbps) of the fake link. 0 means infinite.");
sprang@webrtc.org131bea82015-02-18 12:46:0698
Mirko Bonadei2ab97f62019-07-18 11:44:1299ABSL_FLAG(int, queue_size, 0, "Size of the bottleneck link queue in packets.");
sprang@webrtc.org131bea82015-02-18 12:46:06100
Mirko Bonadei2ab97f62019-07-18 11:44:12101ABSL_FLAG(int,
102 avg_propagation_delay_ms,
103 0,
104 "Average link propagation delay in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06105
Mirko Bonadei2ab97f62019-07-18 11:44:12106ABSL_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 07:47:03111
Mirko Bonadei2ab97f62019-07-18 11:44:12112ABSL_FLAG(std::string,
113 rtp_dump_name,
114 "",
115 "Filename for dumped received RTP stream.");
ilnik98436952017-07-13 07:47:03116
Mirko Bonadei2ab97f62019-07-18 11:44:12117ABSL_FLAG(int,
118 std_propagation_delay_ms,
119 0,
120 "Link propagation delay standard deviation in ms.");
sprang@webrtc.org131bea82015-02-18 12:46:06121
Mirko Bonadei2ab97f62019-07-18 11:44:12122ABSL_FLAG(int, num_streams, 0, "Number of streams to show or analyze.");
sprang1168fd42017-06-21 16:00:17123
Mirko Bonadei2ab97f62019-07-18 11:44:12124ABSL_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 15:23:20129
Mirko Bonadei2ab97f62019-07-18 11:44:12130ABSL_FLAG(int, num_spatial_layers, 1, "Number of spatial layers to use.");
sprangce4aef12015-11-02 15:23:20131
Mirko Bonadei2ab97f62019-07-18 11:44:12132ABSL_FLAG(int,
133 selected_sl,
134 -1,
135 "Spatial layer to show or analyze. -1 to disable filtering.");
sprangce4aef12015-11-02 15:23:20136
Mirko Bonadei2ab97f62019-07-18 11:44:12137ABSL_FLAG(std::string,
138 stream0,
139 "",
140 "Comma separated values describing VideoStream for stream #0.");
sprangce4aef12015-11-02 15:23:20141
Mirko Bonadei2ab97f62019-07-18 11:44:12142ABSL_FLAG(std::string,
143 stream1,
144 "",
145 "Comma separated values describing VideoStream for stream #1.");
sprangce4aef12015-11-02 15:23:20146
Mirko Bonadei2ab97f62019-07-18 11:44:12147ABSL_FLAG(std::string,
148 sl0,
149 "",
150 "Comma separated values describing SpatialLayer for layer #0.");
sprangce4aef12015-11-02 15:23:20151
Mirko Bonadei2ab97f62019-07-18 11:44:12152ABSL_FLAG(std::string,
153 sl1,
154 "",
155 "Comma separated values describing SpatialLayer for layer #1.");
sprangce4aef12015-11-02 15:23:20156
Mirko Bonadei2ab97f62019-07-18 11:44:12157ABSL_FLAG(std::string,
158 sl2,
159 "",
160 "Comma separated values describing SpatialLayer for layer #2.");
Sergey Silkina89800c2019-02-19 11:52:56161
Mirko Bonadei2ab97f62019-07-18 11:44:12162ABSL_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 13:19:48167
Mirko Bonadei2ab97f62019-07-18 11:44:12168ABSL_FLAG(bool, logs, false, "print logs to stderr");
sprang@webrtc.org131bea82015-02-18 12:46:06169
Mirko Bonadei2ab97f62019-07-18 11:44:12170ABSL_FLAG(bool, send_side_bwe, true, "Use send-side bandwidth estimation");
sprangce4aef12015-11-02 15:23:20171
Mirko Bonadei2ab97f62019-07-18 11:44:12172ABSL_FLAG(bool, generic_descriptor, false, "Use the generic frame descriptor.");
philipel569397f2018-09-26 10:25:31173
philipel7496ff62022-12-30 12:21:07174ABSL_FLAG(bool, dependency_descriptor, false, "Use the dependency descriptor.");
175
Mirko Bonadei2ab97f62019-07-18 11:44:12176ABSL_FLAG(bool, allow_reordering, false, "Allow packet reordering to occur");
philipela2c55232016-01-26 16:41:53177
Mirko Bonadei2ab97f62019-07-18 11:44:12178ABSL_FLAG(bool, use_ulpfec, false, "Use RED+ULPFEC forward error correction.");
brandtra62f5822016-11-17 08:21:13179
Mirko Bonadei2ab97f62019-07-18 11:44:12180ABSL_FLAG(bool, use_flexfec, false, "Use FlexFEC forward error correction.");
philipel274c1dc2016-05-04 13:21:01181
Mirko Bonadei2ab97f62019-07-18 11:44:12182ABSL_FLAG(bool, audio, false, "Add audio stream");
minyue73208662016-08-18 13:28:55183
Mirko Bonadei2ab97f62019-07-18 11:44:12184ABSL_FLAG(bool,
185 use_real_adm,
186 false,
187 "Use real ADM instead of fake (no effect if audio is false)");
henrika255750b2018-08-27 14:13:37188
Mirko Bonadei2ab97f62019-07-18 11:44:12189ABSL_FLAG(bool,
190 audio_video_sync,
191 false,
192 "Sync audio and video stream (no effect if"
193 " audio is false)");
minyue73208662016-08-18 13:28:55194
Mirko Bonadei2ab97f62019-07-18 11:44:12195ABSL_FLAG(bool,
196 audio_dtx,
197 false,
198 "Enable audio DTX (no effect if audio is false)");
minyue4c8b9422017-03-21 11:11:43199
Mirko Bonadei2ab97f62019-07-18 11:44:12200ABSL_FLAG(bool, video, true, "Add video stream");
minyuea27172d2016-11-01 12:59:29201
Mirko Bonadei2ab97f62019-07-18 11:44:12202ABSL_FLAG(
203 std::string,
sprang@webrtc.org131bea82015-02-18 12:46:06204 force_fieldtrials,
205 "",
206 "Field trials control experimental feature code which can be forced. "
Elad Alon1e3ed162018-10-15 15:50:37207 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enabled/"
sprang@webrtc.org131bea82015-02-18 12:46:06208 " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
209 "trials are separated by \"/\"");
pbos9874ee02015-06-22 11:44:26210
sprangce4aef12015-11-02 15:23:20211// Video-specific flags.
Mirko Bonadei2ab97f62019-07-18 11:44:12212ABSL_FLAG(std::string,
213 clip,
214 "",
215 "Name of the clip to show. If empty, using chroma generator.");
216
217namespace webrtc {
218namespace {
219
220size_t Width() {
221 return static_cast<size_t>(absl::GetFlag(FLAGS_width));
ivica5d6a06c2015-09-17 12:30:24222}
223
Mirko Bonadei2ab97f62019-07-18 11:44:12224size_t Height() {
225 return static_cast<size_t>(absl::GetFlag(FLAGS_height));
226}
sprang1168fd42017-06-21 16:00:17227
Mirko Bonadei2ab97f62019-07-18 11:44:12228int Fps() {
229 return absl::GetFlag(FLAGS_fps);
230}
231
232size_t GetCaptureDevice() {
233 return static_cast<size_t>(absl::GetFlag(FLAGS_capture_device_index));
234}
235
236int MinBitrateKbps() {
237 return absl::GetFlag(FLAGS_min_bitrate);
238}
239
240int StartBitrateKbps() {
241 return absl::GetFlag(FLAGS_start_bitrate);
242}
243
244int TargetBitrateKbps() {
245 return absl::GetFlag(FLAGS_target_bitrate);
246}
247
248int MaxBitrateKbps() {
249 return absl::GetFlag(FLAGS_max_bitrate);
250}
251
252int NumTemporalLayers() {
253 return absl::GetFlag(FLAGS_num_temporal_layers);
254}
255
256InterLayerPredMode InterLayerPred() {
257 if (absl::GetFlag(FLAGS_inter_layer_pred) == 0) {
258 return InterLayerPredMode::kOn;
259 } else if (absl::GetFlag(FLAGS_inter_layer_pred) == 1) {
260 return InterLayerPredMode::kOff;
261 } else {
262 RTC_DCHECK_EQ(absl::GetFlag(FLAGS_inter_layer_pred), 2);
263 return InterLayerPredMode::kOnKeyPic;
264 }
265}
266
267std::string Codec() {
268 return absl::GetFlag(FLAGS_codec);
269}
270
271int SelectedTL() {
272 return absl::GetFlag(FLAGS_selected_tl);
273}
274
275int DurationSecs() {
276 return absl::GetFlag(FLAGS_duration);
277}
278
279std::string OutputFilename() {
280 return absl::GetFlag(FLAGS_output_filename);
281}
282
283std::string GraphTitle() {
284 return absl::GetFlag(FLAGS_graph_title);
285}
286
287int LossPercent() {
288 return static_cast<int>(absl::GetFlag(FLAGS_loss_percent));
289}
290
291int AvgBurstLossLength() {
292 return static_cast<int>(absl::GetFlag(FLAGS_avg_burst_loss_length));
293}
294
295int LinkCapacityKbps() {
296 return static_cast<int>(absl::GetFlag(FLAGS_link_capacity));
297}
298
299int QueueSize() {
300 return static_cast<int>(absl::GetFlag(FLAGS_queue_size));
301}
302
303int AvgPropagationDelayMs() {
304 return static_cast<int>(absl::GetFlag(FLAGS_avg_propagation_delay_ms));
305}
306
307std::string RtcEventLogName() {
308 return absl::GetFlag(FLAGS_rtc_event_log_name);
309}
310
311std::string RtpDumpName() {
312 return absl::GetFlag(FLAGS_rtp_dump_name);
313}
314
315int StdPropagationDelayMs() {
316 return absl::GetFlag(FLAGS_std_propagation_delay_ms);
317}
318
319int NumStreams() {
320 return absl::GetFlag(FLAGS_num_streams);
321}
322
323int SelectedStream() {
324 return absl::GetFlag(FLAGS_selected_stream);
325}
326
327int NumSpatialLayers() {
328 return absl::GetFlag(FLAGS_num_spatial_layers);
329}
330
331int SelectedSL() {
332 return absl::GetFlag(FLAGS_selected_sl);
333}
334
335std::string Stream0() {
336 return absl::GetFlag(FLAGS_stream0);
337}
338
339std::string Stream1() {
340 return absl::GetFlag(FLAGS_stream1);
341}
342
343std::string SL0() {
344 return absl::GetFlag(FLAGS_sl0);
345}
346
347std::string SL1() {
348 return absl::GetFlag(FLAGS_sl1);
349}
350
351std::string SL2() {
352 return absl::GetFlag(FLAGS_sl2);
353}
354
355std::string EncodedFramePath() {
356 return absl::GetFlag(FLAGS_encoded_frame_path);
357}
358
359std::string Clip() {
360 return absl::GetFlag(FLAGS_clip);
361}
362
363} // namespace
sprang@webrtc.org131bea82015-02-18 12:46:06364
365void Loopback() {
Artem Titov75e36472018-10-08 10:28:56366 BuiltInNetworkBehaviorConfig pipe_config;
Mirko Bonadei2ab97f62019-07-18 11:44:12367 pipe_config.loss_percent = LossPercent();
368 pipe_config.avg_burst_loss_length = AvgBurstLossLength();
369 pipe_config.link_capacity_kbps = LinkCapacityKbps();
370 pipe_config.queue_length_packets = QueueSize();
371 pipe_config.queue_delay_ms = AvgPropagationDelayMs();
372 pipe_config.delay_standard_deviation_ms = StdPropagationDelayMs();
373 pipe_config.allow_reordering = absl::GetFlag(FLAGS_allow_reordering);
ivica5d6a06c2015-09-17 12:30:24374
Sebastian Janssonfc8d26b2018-02-21 08:52:06375 BitrateConstraints call_bitrate_config;
Mirko Bonadei2ab97f62019-07-18 11:44:12376 call_bitrate_config.min_bitrate_bps = MinBitrateKbps() * 1000;
377 call_bitrate_config.start_bitrate_bps = StartBitrateKbps() * 1000;
Erik Språng28bb3912018-07-11 14:06:55378 call_bitrate_config.max_bitrate_bps = -1; // Don't cap bandwidth estimate.
ivica5d6a06c2015-09-17 12:30:24379
minyue73208662016-08-18 13:28:55380 VideoQualityTest::Params params;
Danil Chapovalov059f4f72020-07-07 12:16:47381 params.call.send_side_bwe = absl::GetFlag(FLAGS_send_side_bwe);
382 params.call.generic_descriptor = absl::GetFlag(FLAGS_generic_descriptor);
philipel7496ff62022-12-30 12:21:07383 params.call.dependency_descriptor =
384 absl::GetFlag(FLAGS_dependency_descriptor);
Danil Chapovalov059f4f72020-07-07 12:16:47385 params.call.call_bitrate_config = call_bitrate_config;
386
387 params.video[0].enabled = absl::GetFlag(FLAGS_video);
388 params.video[0].width = Width();
389 params.video[0].height = Height();
390 params.video[0].fps = Fps();
391 params.video[0].min_bitrate_bps = MinBitrateKbps() * 1000;
392 params.video[0].target_bitrate_bps = TargetBitrateKbps() * 1000;
393 params.video[0].max_bitrate_bps = MaxBitrateKbps() * 1000;
394 params.video[0].suspend_below_min_bitrate =
395 absl::GetFlag(FLAGS_suspend_below_min_bitrate);
396 params.video[0].codec = Codec();
397 params.video[0].num_temporal_layers = NumTemporalLayers();
398 params.video[0].selected_tl = SelectedTL();
399 params.video[0].min_transmit_bps = 0;
400 params.video[0].ulpfec = absl::GetFlag(FLAGS_use_ulpfec);
401 params.video[0].flexfec = absl::GetFlag(FLAGS_use_flexfec);
402 params.video[0].automatic_scaling = NumStreams() < 2;
403 params.video[0].clip_path = Clip();
404 params.video[0].capture_device_index = GetCaptureDevice();
405 params.audio.enabled = absl::GetFlag(FLAGS_audio);
406 params.audio.sync_video = absl::GetFlag(FLAGS_audio_video_sync);
407 params.audio.dtx = absl::GetFlag(FLAGS_audio_dtx);
408 params.audio.use_real_adm = absl::GetFlag(FLAGS_use_real_adm);
409 params.logging.rtc_event_log_name = RtcEventLogName();
410 params.logging.rtp_dump_name = RtpDumpName();
411 params.logging.encoded_frame_base_path = EncodedFramePath();
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59412 params.screenshare[0].enabled = false;
Danil Chapovalov059f4f72020-07-07 12:16:47413 params.analyzer.test_label = "video";
414 params.analyzer.test_durations_secs = DurationSecs();
415 params.analyzer.graph_data_output_filename = OutputFilename();
416 params.analyzer.graph_title = GraphTitle();
Artem Titovf18b3522018-08-28 14:54:24417 params.config = pipe_config;
sprang1168fd42017-06-21 16:00:17418
Mirko Bonadei2ab97f62019-07-18 11:44:12419 if (NumStreams() > 1 && Stream0().empty() && Stream1().empty()) {
Ilya Nikolaevskiy255d1cd2017-12-21 17:02:59420 params.ss[0].infer_streams = true;
sprang1168fd42017-06-21 16:00:17421 }
ivica5d6a06c2015-09-17 12:30:24422
sprangce4aef12015-11-02 15:23:20423 std::vector<std::string> stream_descriptors;
Mirko Bonadei2ab97f62019-07-18 11:44:12424 stream_descriptors.push_back(Stream0());
425 stream_descriptors.push_back(Stream1());
sprangce4aef12015-11-02 15:23:20426 std::vector<std::string> SL_descriptors;
Mirko Bonadei2ab97f62019-07-18 11:44:12427 SL_descriptors.push_back(SL0());
428 SL_descriptors.push_back(SL1());
429 SL_descriptors.push_back(SL2());
sprangce4aef12015-11-02 15:23:20430 VideoQualityTest::FillScalabilitySettings(
Mirko Bonadei2ab97f62019-07-18 11:44:12431 &params, 0, stream_descriptors, NumStreams(), SelectedStream(),
432 NumSpatialLayers(), SelectedSL(), InterLayerPred(), SL_descriptors);
sprangce4aef12015-11-02 15:23:20433
Mirko Bonadei317a1f02019-09-17 15:06:18434 auto fixture = std::make_unique<VideoQualityTest>(nullptr);
Mirko Bonadei2ab97f62019-07-18 11:44:12435 if (DurationSecs()) {
Patrik Höglundb6b29e02018-06-21 14:58:01436 fixture->RunWithAnalyzer(params);
sprangce4aef12015-11-02 15:23:20437 } else {
Patrik Höglundb6b29e02018-06-21 14:58:01438 fixture->RunWithRenderers(params);
sprangce4aef12015-11-02 15:23:20439 }
sprang@webrtc.org131bea82015-02-18 12:46:06440}
sprang@webrtc.org131bea82015-02-18 12:46:06441
Kári Tristan Helgasonede7cb22019-03-06 09:34:09442int RunLoopbackTest(int argc, char* argv[]) {
sprang@webrtc.org131bea82015-02-18 12:46:06443 ::testing::InitGoogleTest(&argc, argv);
Mirko Bonadei2ab97f62019-07-18 11:44:12444 absl::ParseCommandLine(argc, argv);
sprang1168fd42017-06-21 16:00:17445
Mirko Bonadei2ab97f62019-07-18 11:44:12446 rtc::LogMessage::SetLogToStderr(absl::GetFlag(FLAGS_logs));
Mirko Bonadei45a4c412018-07-31 13:07:28447
Bjorn Tereliusedab3012018-01-31 16:23:40448 // InitFieldTrialsFromString stores the char*, so the char array must outlive
449 // the application.
Mirko Bonadei2ab97f62019-07-18 11:44:12450 const std::string field_trials = absl::GetFlag(FLAGS_force_fieldtrials);
451 webrtc::field_trial::InitFieldTrialsFromString(field_trials.c_str());
sprang89c4a7e2017-06-30 20:27:40452
sprang@webrtc.org131bea82015-02-18 12:46:06453 webrtc::test::RunTest(webrtc::Loopback);
454 return 0;
455}
Kári Tristan Helgasonede7cb22019-03-06 09:34:09456} // namespace webrtc