blob: b274069bd4c0a04a778c0fa0454b922aaafd2b58 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2013 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
Ivo Creusenf81b0f12018-09-11 10:30:58 +020011#include <iostream>
12#include <string>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000013
Mirko Bonadei14be7992019-06-27 15:59:09 +020014#include "absl/flags/flag.h"
15#include "absl/flags/parse.h"
Alessio Bazzica5ad789c2019-03-13 11:51:44 +010016#include "absl/strings/string_view.h"
17#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/audio_coding/neteq/tools/neteq_test.h"
Ivo Creusen55de08e2018-09-03 11:49:27 +020019#include "modules/audio_coding/neteq/tools/neteq_test_factory.h"
Alessio Bazzica5ad789c2019-03-13 11:51:44 +010020#include "rtc_base/strings/string_builder.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020021#include "system_wrappers/include/field_trial.h"
Ivo Creusenf81b0f12018-09-11 10:30:58 +020022#include "test/field_trial.h"
23
Ivo Creusenba7886b2019-02-26 13:03:21 +010024using TestConfig = webrtc::test::NetEqTestFactory::Config;
25
Mirko Bonadei14be7992019-06-27 15:59:09 +020026ABSL_FLAG(bool,
27 codec_map,
28 false,
29 "Prints the mapping between RTP payload type and "
30 "codec");
31ABSL_FLAG(std::string,
32 force_fieldtrials,
33 "",
34 "Field trials control experimental feature code which can be forced. "
35 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
36 " will assign the group Enable to field trial WebRTC-FooFeature.");
37ABSL_FLAG(int, pcmu, TestConfig::default_pcmu(), "RTP payload type for PCM-u");
38ABSL_FLAG(int, pcma, TestConfig::default_pcma(), "RTP payload type for PCM-a");
39ABSL_FLAG(int, ilbc, TestConfig::default_ilbc(), "RTP payload type for iLBC");
40ABSL_FLAG(int, isac, TestConfig::default_isac(), "RTP payload type for iSAC");
41ABSL_FLAG(int,
42 isac_swb,
43 TestConfig::default_isac_swb(),
44 "RTP payload type for iSAC-swb (32 kHz)");
45ABSL_FLAG(int, opus, TestConfig::default_opus(), "RTP payload type for Opus");
46ABSL_FLAG(int,
47 pcm16b,
48 TestConfig::default_pcm16b(),
49 "RTP payload type for PCM16b-nb (8 kHz)");
50ABSL_FLAG(int,
51 pcm16b_wb,
52 TestConfig::default_pcm16b_wb(),
53 "RTP payload type for PCM16b-wb (16 kHz)");
54ABSL_FLAG(int,
55 pcm16b_swb32,
56 TestConfig::default_pcm16b_swb32(),
57 "RTP payload type for PCM16b-swb32 (32 kHz)");
58ABSL_FLAG(int,
59 pcm16b_swb48,
60 TestConfig::default_pcm16b_swb48(),
61 "RTP payload type for PCM16b-swb48 (48 kHz)");
62ABSL_FLAG(int, g722, TestConfig::default_g722(), "RTP payload type for G.722");
63ABSL_FLAG(int,
64 avt,
65 TestConfig::default_avt(),
66 "RTP payload type for AVT/DTMF (8 kHz)");
67ABSL_FLAG(int,
68 avt_16,
69 TestConfig::default_avt_16(),
70 "RTP payload type for AVT/DTMF (16 kHz)");
71ABSL_FLAG(int,
72 avt_32,
73 TestConfig::default_avt_32(),
74 "RTP payload type for AVT/DTMF (32 kHz)");
75ABSL_FLAG(int,
76 avt_48,
77 TestConfig::default_avt_48(),
78 "RTP payload type for AVT/DTMF (48 kHz)");
79ABSL_FLAG(int,
80 red,
81 TestConfig::default_red(),
82 "RTP payload type for redundant audio (RED)");
83ABSL_FLAG(int,
84 cn_nb,
85 TestConfig::default_cn_nb(),
86 "RTP payload type for comfort noise (8 kHz)");
87ABSL_FLAG(int,
88 cn_wb,
89 TestConfig::default_cn_wb(),
90 "RTP payload type for comfort noise (16 kHz)");
91ABSL_FLAG(int,
92 cn_swb32,
93 TestConfig::default_cn_swb32(),
94 "RTP payload type for comfort noise (32 kHz)");
95ABSL_FLAG(int,
96 cn_swb48,
97 TestConfig::default_cn_swb48(),
98 "RTP payload type for comfort noise (48 kHz)");
99ABSL_FLAG(std::string,
100 replacement_audio_file,
101 "",
102 "A PCM file that will be used to populate dummy"
103 " RTP packets");
104ABSL_FLAG(std::string,
105 ssrc,
106 "",
107 "Only use packets with this SSRC (decimal or hex, the latter "
108 "starting with 0x)");
109ABSL_FLAG(int,
110 audio_level,
111 TestConfig::default_audio_level(),
112 "Extension ID for audio level (RFC 6464)");
113ABSL_FLAG(int,
114 abs_send_time,
115 TestConfig::default_abs_send_time(),
116 "Extension ID for absolute sender time");
117ABSL_FLAG(int,
118 transport_seq_no,
119 TestConfig::default_transport_seq_no(),
120 "Extension ID for transport sequence number");
121ABSL_FLAG(int,
122 video_content_type,
123 TestConfig::default_video_content_type(),
124 "Extension ID for video content type");
125ABSL_FLAG(int,
126 video_timing,
127 TestConfig::default_video_timing(),
128 "Extension ID for video timing");
129ABSL_FLAG(std::string,
130 output_files_base_name,
131 "",
132 "Custom path used as prefix for the output files - i.e., "
133 "matlab plot, python plot, text log.");
134ABSL_FLAG(bool,
135 matlabplot,
136 false,
137 "Generates a matlab script for plotting the delay profile");
138ABSL_FLAG(bool,
139 pythonplot,
140 false,
141 "Generates a python script for plotting the delay profile");
142ABSL_FLAG(bool,
143 textlog,
144 false,
145 "Generates a text log describing the simulation on a "
146 "step-by-step basis.");
147ABSL_FLAG(bool, concealment_events, false, "Prints concealment events");
148ABSL_FLAG(int,
149 max_nr_packets_in_buffer,
150 TestConfig::default_max_nr_packets_in_buffer(),
151 "Maximum allowed number of packets in the buffer");
152ABSL_FLAG(bool,
153 enable_fast_accelerate,
154 false,
155 "Enables jitter buffer fast accelerate");
156
157namespace {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100158
159// Parses the input string for a valid SSRC (at the start of the string). If a
Artem Titovd00ce742021-07-28 20:00:17 +0200160// valid SSRC is found, it is written to the output variable `ssrc`, and true is
Ivo Creusenba7886b2019-02-26 13:03:21 +0100161// returned. Otherwise, false is returned.
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200162bool ParseSsrc(absl::string_view str, uint32_t* ssrc) {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100163 if (str.empty())
164 return true;
165 int base = 10;
166 // Look for "0x" or "0X" at the start and change base to 16 if found.
167 if ((str.compare(0, 2, "0x") == 0) || (str.compare(0, 2, "0X") == 0))
168 base = 16;
169 errno = 0;
170 char* end_ptr;
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200171 std::string str_str = std::string(str);
172 unsigned long value = strtoul(str_str.c_str(), &end_ptr, base); // NOLINT
Ivo Creusenba7886b2019-02-26 13:03:21 +0100173 if (value == ULONG_MAX && errno == ERANGE)
174 return false; // Value out of range for unsigned long.
175 if (sizeof(unsigned long) > sizeof(uint32_t) && value > 0xFFFFFFFF) // NOLINT
176 return false; // Value out of range for uint32_t.
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200177 if (end_ptr - str_str.c_str() < static_cast<ptrdiff_t>(str.length()))
Ivo Creusenba7886b2019-02-26 13:03:21 +0100178 return false; // Part of the string was not parsed.
179 *ssrc = static_cast<uint32_t>(value);
180 return true;
181}
182
183static bool ValidateExtensionId(int value) {
184 if (value > 0 && value <= 255) // Value is ok.
185 return true;
186 printf("Extension ID must be between 1 and 255, not %d\n",
187 static_cast<int>(value));
188 return false;
189}
190
191// Flag validators.
192bool ValidatePayloadType(int value) {
193 if (value >= 0 && value <= 127) // Value is ok.
194 return true;
195 printf("Payload type must be between 0 and 127, not %d\n",
196 static_cast<int>(value));
197 return false;
198}
199
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200200bool ValidateSsrcValue(absl::string_view str) {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100201 uint32_t dummy_ssrc;
202 if (ParseSsrc(str, &dummy_ssrc)) // Value is ok.
203 return true;
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200204 printf("Invalid SSRC: %.*s\n", static_cast<int>(str.size()), str.data());
Ivo Creusenba7886b2019-02-26 13:03:21 +0100205 return false;
206}
207
Ali Tofigh714e3cb2022-07-20 12:53:07 +0200208void PrintCodecMappingEntry(absl::string_view codec, int flag) {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100209 std::cout << codec << ": " << flag << std::endl;
210}
211
212void PrintCodecMapping() {
Mirko Bonadei14be7992019-06-27 15:59:09 +0200213 PrintCodecMappingEntry("PCM-u", absl::GetFlag(FLAGS_pcmu));
214 PrintCodecMappingEntry("PCM-a", absl::GetFlag(FLAGS_pcma));
215 PrintCodecMappingEntry("iLBC", absl::GetFlag(FLAGS_ilbc));
216 PrintCodecMappingEntry("iSAC", absl::GetFlag(FLAGS_isac));
217 PrintCodecMappingEntry("iSAC-swb (32 kHz)", absl::GetFlag(FLAGS_isac_swb));
218 PrintCodecMappingEntry("Opus", absl::GetFlag(FLAGS_opus));
219 PrintCodecMappingEntry("PCM16b-nb (8 kHz)", absl::GetFlag(FLAGS_pcm16b));
220 PrintCodecMappingEntry("PCM16b-wb (16 kHz)", absl::GetFlag(FLAGS_pcm16b_wb));
221 PrintCodecMappingEntry("PCM16b-swb32 (32 kHz)",
222 absl::GetFlag(FLAGS_pcm16b_swb32));
223 PrintCodecMappingEntry("PCM16b-swb48 (48 kHz)",
224 absl::GetFlag(FLAGS_pcm16b_swb48));
225 PrintCodecMappingEntry("G.722", absl::GetFlag(FLAGS_g722));
226 PrintCodecMappingEntry("AVT/DTMF (8 kHz)", absl::GetFlag(FLAGS_avt));
227 PrintCodecMappingEntry("AVT/DTMF (16 kHz)", absl::GetFlag(FLAGS_avt_16));
228 PrintCodecMappingEntry("AVT/DTMF (32 kHz)", absl::GetFlag(FLAGS_avt_32));
229 PrintCodecMappingEntry("AVT/DTMF (48 kHz)", absl::GetFlag(FLAGS_avt_48));
230 PrintCodecMappingEntry("redundant audio (RED)", absl::GetFlag(FLAGS_red));
231 PrintCodecMappingEntry("comfort noise (8 kHz)", absl::GetFlag(FLAGS_cn_nb));
232 PrintCodecMappingEntry("comfort noise (16 kHz)", absl::GetFlag(FLAGS_cn_wb));
233 PrintCodecMappingEntry("comfort noise (32 kHz)",
234 absl::GetFlag(FLAGS_cn_swb32));
235 PrintCodecMappingEntry("comfort noise (48 kHz)",
236 absl::GetFlag(FLAGS_cn_swb48));
Ivo Creusenba7886b2019-02-26 13:03:21 +0100237}
238
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100239bool ValidateOutputFilesOptions(bool textlog,
240 bool plotting,
241 absl::string_view output_files_base_name,
242 absl::string_view output_audio_filename) {
243 bool output_files_base_name_specified = !output_files_base_name.empty();
244 if (!textlog && !plotting && output_files_base_name_specified) {
245 std::cout << "Error: --output_files_base_name cannot be used without at "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100246 "least one of the following flags: --textlog, --matlabplot, "
247 "--pythonplot."
248 << std::endl;
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100249 return false;
250 }
Artem Titovd00ce742021-07-28 20:00:17 +0200251 // Without `output_audio_filename`, `output_files_base_name` is required when
Alessio Bazzicaa88655d2019-11-25 16:35:12 +0100252 // plotting output files must be generated (in order to form a valid output
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100253 // file name).
Alessio Bazzicaa88655d2019-11-25 16:35:12 +0100254 if (output_audio_filename.empty() && plotting &&
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100255 !output_files_base_name_specified) {
Alessio Bazzicaa88655d2019-11-25 16:35:12 +0100256 std::cout << "Error: when no output audio file is specified and "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100257 "--matlabplot and/or --pythonplot are used, "
258 "--output_files_base_name must be also used."
259 << std::endl;
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100260 return false;
261 }
262 return true;
263}
264
265absl::optional<std::string> CreateOptionalOutputFileName(
266 bool output_requested,
267 absl::string_view basename,
268 absl::string_view output_audio_filename,
269 absl::string_view suffix) {
270 if (!output_requested) {
271 return absl::nullopt;
272 }
273 if (!basename.empty()) {
274 // Override the automatic assignment.
275 rtc::StringBuilder sb(basename);
276 sb << suffix;
277 return sb.str();
278 }
279 if (!output_audio_filename.empty()) {
280 // Automatically assign name.
281 rtc::StringBuilder sb(output_audio_filename);
282 sb << suffix;
283 return sb.str();
284 }
285 std::cout << "Error: invalid text log file parameters.";
286 return absl::nullopt;
287}
288
Ivo Creusenba7886b2019-02-26 13:03:21 +0100289} // namespace
henrik.lundin303d3e12016-05-26 05:56:03 -0700290
291int main(int argc, char* argv[]) {
Mirko Bonadei14be7992019-06-27 15:59:09 +0200292 std::vector<char*> args = absl::ParseCommandLine(argc, argv);
Ivo Creusen55de08e2018-09-03 11:49:27 +0200293 webrtc::test::NetEqTestFactory factory;
Ivo Creusenf81b0f12018-09-11 10:30:58 +0200294 std::string usage =
295 "Tool for decoding an RTP dump file using NetEq.\n"
Mirko Bonadei14be7992019-06-27 15:59:09 +0200296 "Example usage:\n"
297 "./neteq_rtpplay input.rtp [output.{pcm, wav}]\n";
298 if (absl::GetFlag(FLAGS_codec_map)) {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100299 PrintCodecMapping();
300 exit(0);
Ivo Creusenf81b0f12018-09-11 10:30:58 +0200301 }
Mirko Bonadei14be7992019-06-27 15:59:09 +0200302 if (args.size() != 2 &&
303 args.size() != 3) { // The output audio file is optional.
Ivo Creusenf81b0f12018-09-11 10:30:58 +0200304 // Print usage information.
305 std::cout << usage;
306 exit(0);
307 }
Mirko Bonadei14be7992019-06-27 15:59:09 +0200308 const std::string output_audio_filename((args.size() == 3) ? args[2] : "");
309 const std::string output_files_base_name(
310 absl::GetFlag(FLAGS_output_files_base_name));
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100311 RTC_CHECK(ValidateOutputFilesOptions(
Mirko Bonadei14be7992019-06-27 15:59:09 +0200312 absl::GetFlag(FLAGS_textlog),
313 absl::GetFlag(FLAGS_matlabplot) || absl::GetFlag(FLAGS_pythonplot),
314 output_files_base_name, output_audio_filename));
315 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcmu)));
316 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcma)));
317 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_ilbc)));
318 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_isac)));
319 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_isac_swb)));
320 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_opus)));
321 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcm16b)));
322 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcm16b_wb)));
323 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcm16b_swb32)));
324 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_pcm16b_swb48)));
325 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_g722)));
326 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_avt)));
327 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_avt_16)));
328 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_avt_32)));
329 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_avt_48)));
330 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_red)));
331 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_cn_nb)));
332 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_cn_wb)));
333 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_cn_swb32)));
334 RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_cn_swb48)));
335 RTC_CHECK(ValidateSsrcValue(absl::GetFlag(FLAGS_ssrc)));
336 RTC_CHECK(ValidateExtensionId(absl::GetFlag(FLAGS_audio_level)));
337 RTC_CHECK(ValidateExtensionId(absl::GetFlag(FLAGS_abs_send_time)));
338 RTC_CHECK(ValidateExtensionId(absl::GetFlag(FLAGS_transport_seq_no)));
339 RTC_CHECK(ValidateExtensionId(absl::GetFlag(FLAGS_video_content_type)));
340 RTC_CHECK(ValidateExtensionId(absl::GetFlag(FLAGS_video_timing)));
Ivo Creusenba7886b2019-02-26 13:03:21 +0100341
Ruslan Burakovca5f21e2019-07-10 16:08:48 +0200342 // Make force_fieldtrials persistent string during entire program live as
343 // absl::GetFlag creates temporary string and c_str() will point to
344 // deallocated string.
345 const std::string force_fieldtrials = absl::GetFlag(FLAGS_force_fieldtrials);
346 webrtc::field_trial::InitFieldTrialsFromString(force_fieldtrials.c_str());
347
Ivo Creusenba7886b2019-02-26 13:03:21 +0100348 webrtc::test::NetEqTestFactory::Config config;
Mirko Bonadei14be7992019-06-27 15:59:09 +0200349 config.pcmu = absl::GetFlag(FLAGS_pcmu);
350 config.pcma = absl::GetFlag(FLAGS_pcma);
351 config.ilbc = absl::GetFlag(FLAGS_ilbc);
352 config.isac = absl::GetFlag(FLAGS_isac);
353 config.isac_swb = absl::GetFlag(FLAGS_isac_swb);
354 config.opus = absl::GetFlag(FLAGS_opus);
355 config.pcm16b = absl::GetFlag(FLAGS_pcm16b);
356 config.pcm16b_wb = absl::GetFlag(FLAGS_pcm16b_wb);
357 config.pcm16b_swb32 = absl::GetFlag(FLAGS_pcm16b_swb32);
358 config.pcm16b_swb48 = absl::GetFlag(FLAGS_pcm16b_swb48);
359 config.g722 = absl::GetFlag(FLAGS_g722);
360 config.avt = absl::GetFlag(FLAGS_avt);
361 config.avt_16 = absl::GetFlag(FLAGS_avt_16);
362 config.avt_32 = absl::GetFlag(FLAGS_avt_32);
363 config.avt_48 = absl::GetFlag(FLAGS_avt_48);
364 config.red = absl::GetFlag(FLAGS_red);
365 config.cn_nb = absl::GetFlag(FLAGS_cn_nb);
366 config.cn_wb = absl::GetFlag(FLAGS_cn_wb);
367 config.cn_swb32 = absl::GetFlag(FLAGS_cn_swb32);
368 config.cn_swb48 = absl::GetFlag(FLAGS_cn_swb48);
369 config.replacement_audio_file = absl::GetFlag(FLAGS_replacement_audio_file);
370 config.audio_level = absl::GetFlag(FLAGS_audio_level);
371 config.abs_send_time = absl::GetFlag(FLAGS_abs_send_time);
372 config.transport_seq_no = absl::GetFlag(FLAGS_transport_seq_no);
373 config.video_content_type = absl::GetFlag(FLAGS_video_content_type);
374 config.video_timing = absl::GetFlag(FLAGS_video_timing);
375 config.matlabplot = absl::GetFlag(FLAGS_matlabplot);
376 config.pythonplot = absl::GetFlag(FLAGS_pythonplot);
377 config.concealment_events = absl::GetFlag(FLAGS_concealment_events);
378 config.max_nr_packets_in_buffer =
379 absl::GetFlag(FLAGS_max_nr_packets_in_buffer);
380 config.enable_fast_accelerate = absl::GetFlag(FLAGS_enable_fast_accelerate);
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100381 if (!output_audio_filename.empty()) {
382 config.output_audio_filename = output_audio_filename;
383 }
Alessio Bazzicaa88655d2019-11-25 16:35:12 +0100384 config.textlog = absl::GetFlag(FLAGS_textlog);
Mirko Bonadei14be7992019-06-27 15:59:09 +0200385 config.textlog_filename = CreateOptionalOutputFileName(
386 absl::GetFlag(FLAGS_textlog), output_files_base_name,
387 output_audio_filename, ".text_log.txt");
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100388 config.plot_scripts_basename = CreateOptionalOutputFileName(
Mirko Bonadei14be7992019-06-27 15:59:09 +0200389 absl::GetFlag(FLAGS_matlabplot) || absl::GetFlag(FLAGS_pythonplot),
390 output_files_base_name, output_audio_filename, "");
Alessio Bazzica5ad789c2019-03-13 11:51:44 +0100391
Ivo Creusenba7886b2019-02-26 13:03:21 +0100392 // Check if an SSRC value was provided.
Mirko Bonadei14be7992019-06-27 15:59:09 +0200393 if (absl::GetFlag(FLAGS_ssrc).size() > 0) {
Ivo Creusenba7886b2019-02-26 13:03:21 +0100394 uint32_t ssrc;
Mirko Bonadei14be7992019-06-27 15:59:09 +0200395 RTC_CHECK(ParseSsrc(absl::GetFlag(FLAGS_ssrc), &ssrc))
396 << "Flag verification has failed.";
Ivo Creusenba7886b2019-02-26 13:03:21 +0100397 config.ssrc_filter = absl::make_optional(ssrc);
398 }
399
Ivo Creusen5ec61562019-03-20 10:52:18 +0100400 std::unique_ptr<webrtc::test::NetEqTest> test =
Ivo Creusencee751a2020-01-16 17:17:09 +0100401 factory.InitializeTestFromFile(/*input_filename=*/args[1],
402 /*factory=*/nullptr, config);
Ivo Creusenab9735f2019-03-20 18:01:51 +0100403 RTC_CHECK(test) << "ERROR: Unable to run test";
Ivo Creusen55de08e2018-09-03 11:49:27 +0200404 test->Run();
405 return 0;
henrik.lundin303d3e12016-05-26 05:56:03 -0700406}