blob: 368fa89f0bc460dc3dbf7df6d362f7f4c993d4b4 [file] [log] [blame]
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 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 <climits>
12#include <cstdarg>
13#include <cstdio>
14
15#include <algorithm>
16
phoglund@webrtc.org75e66692013-02-07 08:52:08 +000017#include "gflags/gflags.h"
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +000018#include "webrtc/system_wrappers/interface/scoped_ptr.h"
19#include "webrtc/test/channel_transport/include/channel_transport.h"
20#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
21#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
22#include "webrtc/video_engine/test/auto_test/primitives/choice_helpers.h"
23#include "webrtc/video_engine/test/auto_test/primitives/general_primitives.h"
24#include "webrtc/video_engine/test/auto_test/primitives/input_helpers.h"
25#include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h"
26#include "webrtc/voice_engine/include/voe_network.h"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000027
28#define VCM_RED_PAYLOAD_TYPE 96
29#define VCM_ULPFEC_PAYLOAD_TYPE 97
30#define DEFAULT_SEND_IP "127.0.0.1"
31#define DEFAULT_VIDEO_PORT "11111"
32#define DEFAULT_VIDEO_CODEC "VP8"
33#define DEFAULT_VIDEO_CODEC_WIDTH "640"
34#define DEFAULT_VIDEO_CODEC_HEIGHT "480"
35#define DEFAULT_VIDEO_CODEC_BITRATE "300"
36#define DEFAULT_VIDEO_CODEC_MIN_BITRATE "100"
37#define DEFAULT_VIDEO_CODEC_MAX_BITRATE "1000"
38#define DEFAULT_AUDIO_PORT "11113"
39#define DEFAULT_AUDIO_CODEC "ISAC"
40#define DEFAULT_INCOMING_FILE_NAME "IncomingFile.avi"
41#define DEFAULT_OUTGOING_FILE_NAME "OutgoingFile.avi"
42#define DEFAULT_VIDEO_CODEC_MAX_FRAMERATE "30"
43#define DEFAULT_VIDEO_PROTECTION_METHOD "None"
44#define DEFAULT_TEMPORAL_LAYER "0"
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +000045#define DEFAULT_BUFFERING_DELAY_MS "0"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000046
phoglund@webrtc.org75e66692013-02-07 08:52:08 +000047DEFINE_string(render_custom_call_remote_to, "", "Specify to render the remote "
48 "stream of a custom call to the provided filename instead of showing it in "
49 "window 2. The file will end up in the default output directory (out/).");
50
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000051enum StatisticsType {
52 kSendStatistic,
53 kReceivedStatistic
54};
55
56enum VideoProtectionMethod {
57 kProtectionMethodNone = 1,
58 kProtectionMethodFecOnly,
59 kProtectionMethodNackOnly,
60 kProtectionMethodHybridNackAndFec,
61};
62
63using webrtc::FromChoices;
64using webrtc::TypedInput;
65
66class ViEAutotestFileObserver : public webrtc::ViEFileObserver {
67 public:
68 ViEAutotestFileObserver() {}
69 ~ViEAutotestFileObserver() {}
70
pbos@webrtc.org2a5d2292013-04-09 13:41:51 +000071 void PlayFileEnded(const int32_t file_id) {
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000072 ViETest::Log("PlayFile ended");
73 }
74};
75
76class ViEAutotestEncoderObserver : public webrtc::ViEEncoderObserver {
77 public:
78 ViEAutotestEncoderObserver() {}
79 ~ViEAutotestEncoderObserver() {}
80
81 void OutgoingRate(const int video_channel,
82 const unsigned int framerate,
83 const unsigned int bitrate) {
84 std::cout << "Send FR: " << framerate
85 << " BR: " << bitrate << std::endl;
86 }
87};
88
89class ViEAutotestDecoderObserver : public webrtc::ViEDecoderObserver {
90 public:
91 ViEAutotestDecoderObserver() {}
92 ~ViEAutotestDecoderObserver() {}
93
94 void IncomingRate(const int video_channel,
95 const unsigned int framerate,
96 const unsigned int bitrate) {
97 std::cout << "Received FR: " << framerate
98 << " BR: " << bitrate << std::endl;
99 }
100 void IncomingCodecChanged(const int video_channel,
101 const webrtc::VideoCodec& codec) {}
102 void RequestNewKeyFrame(const int video_channel) {
103 std::cout << "Decoder requesting a new key frame." << std::endl;
104 }
105};
106
107// The following are general helper functions.
108bool GetVideoDevice(webrtc::ViEBase* vie_base,
109 webrtc::ViECapture* vie_capture,
110 char* capture_device_name, char* capture_device_unique_id);
111std::string GetIPAddress();
112bool ValidateIP(std::string i_str);
113
114// The following are Print to stdout functions.
115void PrintCallInformation(const char* IP,
116 const char* video_capture_device_name,
117 const char* video_capture_unique_id,
118 webrtc::VideoCodec video_codec,
119 int video_tx_port,
120 int video_rx_port,
121 const char* audio_capture_device_name,
122 const char* audio_playbackDeviceName,
123 webrtc::CodecInst audio_codec,
124 int audio_tx_port,
125 int audio_rx_port,
126 int protection_method);
127void PrintRTCCPStatistics(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
128 int video_channel,
129 StatisticsType stat_type);
130void PrintRTPStatistics(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
131 int video_channel);
132void PrintBandwidthUsage(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
133 int video_channel);
134void PrintCodecStatistics(webrtc::ViECodec* vie_codec,
135 int video_channel,
136 StatisticsType stat_type);
137void PrintGetDiscardedPackets(webrtc::ViECodec* vie_codec,
138 int video_channel);
139void PrintVideoStreamInformation(webrtc::ViECodec* vie_codec,
140 int video_channel);
141void PrintVideoCodec(webrtc::VideoCodec video_codec);
142
143// The following are video functions.
144void GetVideoPorts(int* tx_port, int* rx_port);
145void SetVideoCodecType(webrtc::ViECodec* vie_codec,
146 webrtc::VideoCodec* video_codec);
147void SetVideoCodecResolution(webrtc::VideoCodec* video_codec);
148void SetVideoCodecSize(webrtc::VideoCodec* video_codec);
149void SetVideoCodecBitrate(webrtc::VideoCodec* video_codec);
150void SetVideoCodecMinBitrate(webrtc::VideoCodec* video_codec);
151void SetVideoCodecMaxBitrate(webrtc::VideoCodec* video_codec);
152void SetVideoCodecMaxFramerate(webrtc::VideoCodec* video_codec);
153void SetVideoCodecTemporalLayer(webrtc::VideoCodec* video_codec);
154VideoProtectionMethod GetVideoProtection();
155bool SetVideoProtection(webrtc::ViECodec* vie_codec,
156 webrtc::ViERTP_RTCP* vie_rtp_rtcp,
157 int video_channel,
158 VideoProtectionMethod protection_method);
159bool GetBitrateSignaling();
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +0000160int GetBufferingDelay();
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000161
162// The following are audio helper functions.
163bool GetAudioDevices(webrtc::VoEBase* voe_base,
164 webrtc::VoEHardware* voe_hardware,
165 char* recording_device_name, int& recording_device_index,
166 char* playback_device_name, int& playback_device_index);
167bool GetAudioDevices(webrtc::VoEBase* voe_base,
168 webrtc::VoEHardware* voe_hardware,
169 int& recording_device_index, int& playback_device_index);
170void GetAudioPorts(int* tx_port, int* rx_port);
171bool GetAudioCodec(webrtc::VoECodec* voe_codec,
172 webrtc::CodecInst& audio_codec);
173
174int ViEAutoTest::ViECustomCall() {
175 ViETest::Log(" ");
176 ViETest::Log("========================================");
177 ViETest::Log(" Enter values to use custom settings\n");
178
179 int error = 0;
180 int number_of_errors = 0;
181 std::string str;
182
183 // Create the VoE and get the VoE interfaces.
184 webrtc::VoiceEngine* voe = webrtc::VoiceEngine::Create();
185 number_of_errors += ViETest::TestError(voe != NULL, "ERROR: %s at line %d",
186 __FUNCTION__, __LINE__);
187
188 webrtc::VoEBase* voe_base = webrtc::VoEBase::GetInterface(voe);
189 number_of_errors += ViETest::TestError(voe_base != NULL,
190 "ERROR: %s at line %d", __FUNCTION__,
191 __LINE__);
192
193 error = voe_base->Init();
194 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
195 __FUNCTION__, __LINE__);
196
197 webrtc::VoECodec* voe_codec = webrtc::VoECodec::GetInterface(voe);
198 number_of_errors += ViETest::TestError(voe_codec != NULL,
199 "ERROR: %s at line %d", __FUNCTION__,
200 __LINE__);
201
202 webrtc::VoEHardware* voe_hardware =
203 webrtc::VoEHardware::GetInterface(voe);
204 number_of_errors += ViETest::TestError(voe_hardware != NULL,
205 "ERROR: %s at line %d", __FUNCTION__,
206 __LINE__);
207
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000208 webrtc::VoENetwork* voe_network=
209 webrtc::VoENetwork::GetInterface(voe);
210 number_of_errors += ViETest::TestError(voe_network != NULL,
211 "ERROR: %s at line %d", __FUNCTION__,
212 __LINE__);
213
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000214 webrtc::VoEAudioProcessing* voe_apm =
215 webrtc::VoEAudioProcessing::GetInterface(voe);
216 number_of_errors += ViETest::TestError(voe_apm != NULL,
217 "ERROR: %s at line %d", __FUNCTION__,
218 __LINE__);
219
220 // Create the ViE and get the ViE Interfaces.
221 webrtc::VideoEngine* vie = webrtc::VideoEngine::Create();
222 number_of_errors += ViETest::TestError(vie != NULL,
223 "ERROR: %s at line %d", __FUNCTION__,
224 __LINE__);
225
226 webrtc::ViEBase* vie_base = webrtc::ViEBase::GetInterface(vie);
227 number_of_errors += ViETest::TestError(vie_base != NULL,
228 "ERROR: %s at line %d", __FUNCTION__,
229 __LINE__);
230
231 error = vie_base->Init();
232 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
233 __FUNCTION__, __LINE__);
234
235 webrtc::ViECapture* vie_capture =
236 webrtc::ViECapture::GetInterface(vie);
237 number_of_errors += ViETest::TestError(vie_capture != NULL,
238 "ERROR: %s at line %d", __FUNCTION__,
239 __LINE__);
240
241 webrtc::ViERender* vie_renderer = webrtc::ViERender::GetInterface(vie);
242 number_of_errors += ViETest::TestError(vie_renderer != NULL,
243 "ERROR: %s at line %d", __FUNCTION__,
244 __LINE__);
245
246 webrtc::ViECodec* vie_codec = webrtc::ViECodec::GetInterface(vie);
247 number_of_errors += ViETest::TestError(vie_codec != NULL,
248 "ERROR: %s at line %d", __FUNCTION__,
249 __LINE__);
250
251 webrtc::ViENetwork* vie_network = webrtc::ViENetwork::GetInterface(vie);
252 number_of_errors += ViETest::TestError(vie_network != NULL,
253 "ERROR: %s at line %d", __FUNCTION__,
254 __LINE__);
255
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000256 bool start_call = false;
257 std::string ip_address;
258 const unsigned int KMaxUniqueIdLength = 256;
259 char unique_id[KMaxUniqueIdLength] = "";
260 char device_name[KMaxUniqueIdLength] = "";
261 int video_tx_port = 0;
262 int video_rx_port = 0;
263 int video_channel = -1;
264 webrtc::VideoCodec video_send_codec;
265 char audio_capture_device_name[KMaxUniqueIdLength] = "";
266 char audio_playbackDeviceName[KMaxUniqueIdLength] = "";
267 int audio_capture_device_index = -1;
268 int audio_playback_device_index = -1;
269 int audio_tx_port = 0;
270 int audio_rx_port = 0;
271 webrtc::CodecInst audio_codec;
272 int audio_channel = -1;
273 VideoProtectionMethod protection_method = kProtectionMethodNone;
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +0000274 int buffer_delay_ms = 0;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000275 bool is_image_scale_enabled = false;
276 bool remb = true;
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000277 webrtc::scoped_ptr<webrtc::test::VideoChannelTransport>
278 video_channel_transport;
279 webrtc::scoped_ptr<webrtc::test::VoiceChannelTransport>
280 voice_channel_transport;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000281
282 while (!start_call) {
283 // Get the IP address to use from call.
284 ip_address = GetIPAddress();
285
286 // Get the video device to use for call.
287 memset(device_name, 0, KMaxUniqueIdLength);
288 memset(unique_id, 0, KMaxUniqueIdLength);
289 if (!GetVideoDevice(vie_base, vie_capture, device_name, unique_id))
290 return number_of_errors;
291
292 // Get and set the video ports for the call.
293 video_tx_port = 0;
294 video_rx_port = 0;
295 GetVideoPorts(&video_tx_port, &video_rx_port);
296
297 // Get and set the video codec parameters for the call.
298 memset(&video_send_codec, 0, sizeof(webrtc::VideoCodec));
299 SetVideoCodecType(vie_codec, &video_send_codec);
300 SetVideoCodecSize(&video_send_codec);
301 SetVideoCodecBitrate(&video_send_codec);
302 SetVideoCodecMinBitrate(&video_send_codec);
303 SetVideoCodecMaxBitrate(&video_send_codec);
304 SetVideoCodecMaxFramerate(&video_send_codec);
305 SetVideoCodecTemporalLayer(&video_send_codec);
306 remb = GetBitrateSignaling();
307
308 // Get the video protection method for the call.
309 protection_method = GetVideoProtection();
310
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +0000311 // Get the call mode (Real-Time/Buffered).
312 buffer_delay_ms = GetBufferingDelay();
313
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000314 // Get the audio device for the call.
315 memset(audio_capture_device_name, 0, KMaxUniqueIdLength);
316 memset(audio_playbackDeviceName, 0, KMaxUniqueIdLength);
317 GetAudioDevices(voe_base, voe_hardware, audio_capture_device_name,
318 audio_capture_device_index, audio_playbackDeviceName,
319 audio_playback_device_index);
320
321 // Get the audio port for the call.
322 audio_tx_port = 0;
323 audio_rx_port = 0;
324 GetAudioPorts(&audio_tx_port, &audio_rx_port);
325
326 // Get the audio codec for the call.
327 memset(static_cast<void*>(&audio_codec), 0, sizeof(audio_codec));
328 GetAudioCodec(voe_codec, audio_codec);
329
330 // Now ready to start the call. Check user wants to continue.
331 PrintCallInformation(ip_address.c_str(), device_name, unique_id,
332 video_send_codec, video_tx_port, video_rx_port,
333 audio_capture_device_name, audio_playbackDeviceName,
334 audio_codec, audio_tx_port, audio_rx_port,
335 protection_method);
336
337 printf("\n");
338 int selection =
phoglund@webrtc.org71210082012-11-08 12:18:19 +0000339 FromChoices("Ready to start:",
340 "Start the call\n"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000341 "Reconfigure call settings\n")
342 .WithDefault("Start the call").Choose();
343 start_call = (selection == 1);
344 }
345 /// **************************************************************
346 // Begin create/initialize WebRTC Video Engine for testing.
347 /// **************************************************************
348 if (start_call == true) {
349 // Configure audio channel first.
350 audio_channel = voe_base->CreateChannel();
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000351
352 voice_channel_transport.reset(
353 new webrtc::test::VoiceChannelTransport(voe_network, audio_channel));
354
355 error = voice_channel_transport->SetSendDestination(ip_address.c_str(),
356 audio_tx_port);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000357 number_of_errors += ViETest::TestError(error == 0,
358 "ERROR: %s at line %d",
359 __FUNCTION__, __LINE__);
360
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000361 error = voice_channel_transport->SetLocalReceiver(audio_rx_port);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000362 number_of_errors += ViETest::TestError(error == 0,
363 "ERROR: %s at line %d",
364 __FUNCTION__, __LINE__);
365
366 error = voe_hardware->SetRecordingDevice(audio_capture_device_index);
367 number_of_errors += ViETest::TestError(error == 0,
368 "ERROR: %s at line %d",
369 __FUNCTION__, __LINE__);
370
371 error = voe_hardware->SetPlayoutDevice(audio_playback_device_index);
372 number_of_errors += ViETest::TestError(error == 0,
373 "ERROR: %s at line %d",
374 __FUNCTION__, __LINE__);
375
376 error = voe_codec->SetSendCodec(audio_channel, audio_codec);
377 number_of_errors += ViETest::TestError(error == 0,
378 "ERROR: %s at line %d",
379 __FUNCTION__, __LINE__);
380
381 error = voe_apm->SetAgcStatus(true, webrtc::kAgcDefault);
382 number_of_errors += ViETest::TestError(error == 0,
383 "ERROR: %s at line %d",
384 __FUNCTION__, __LINE__);
385
386 error = voe_apm->SetNsStatus(true, webrtc::kNsHighSuppression);
387 number_of_errors += ViETest::TestError(error == 0,
388 "ERROR: %s at line %d",
389 __FUNCTION__, __LINE__);
390 // Now configure the video channel.
391 error = vie->SetTraceFilter(webrtc::kTraceAll);
392 number_of_errors += ViETest::TestError(error == 0,
393 "ERROR: %s at line %d",
394 __FUNCTION__, __LINE__);
395
396 std::string trace_file =
397 ViETest::GetResultOutputPath() + "ViECustomCall_trace.txt";
398 error = vie->SetTraceFile(trace_file.c_str());
399 number_of_errors += ViETest::TestError(error == 0,
400 "ERROR: %s at line %d",
401 __FUNCTION__, __LINE__);
402
403 error = vie_base->SetVoiceEngine(voe);
404 number_of_errors += ViETest::TestError(error == 0,
405 "ERROR: %s at line %d",
406 __FUNCTION__, __LINE__);
407
408 error = vie_base->CreateChannel(video_channel);
409 number_of_errors += ViETest::TestError(error == 0,
410 "ERROR: %s at line %d",
411 __FUNCTION__, __LINE__);
412
413 error = vie_base->ConnectAudioChannel(video_channel, audio_channel);
414 number_of_errors += ViETest::TestError(error == 0,
415 "ERROR: %s at line %d",
416 __FUNCTION__, __LINE__);
417
418 int capture_id = 0;
419 error = vie_capture->AllocateCaptureDevice(unique_id,
420 KMaxUniqueIdLength,
421 capture_id);
422 number_of_errors += ViETest::TestError(error == 0,
423 "ERROR: %s at line %d",
424 __FUNCTION__, __LINE__);
425
426 error = vie_capture->ConnectCaptureDevice(capture_id, video_channel);
427 number_of_errors += ViETest::TestError(error == 0,
428 "ERROR: %s at line %d",
429 __FUNCTION__, __LINE__);
430
431 error = vie_capture->StartCapture(capture_id);
432 number_of_errors += ViETest::TestError(error == 0,
433 "ERROR: %s at line %d",
434 __FUNCTION__, __LINE__);
435
436 webrtc::ViERTP_RTCP* vie_rtp_rtcp =
437 webrtc::ViERTP_RTCP::GetInterface(vie);
438 number_of_errors += ViETest::TestError(vie != NULL,
439 "ERROR: %s at line %d",
440 __FUNCTION__, __LINE__);
441
442 error = vie_rtp_rtcp->SetRTCPStatus(video_channel,
443 webrtc::kRtcpCompound_RFC4585);
444 number_of_errors += ViETest::TestError(error == 0,
445 "ERROR: %s at line %d",
446 __FUNCTION__, __LINE__);
447
448 error = vie_rtp_rtcp->SetKeyFrameRequestMethod(
449 video_channel, webrtc::kViEKeyFrameRequestPliRtcp);
450 number_of_errors += ViETest::TestError(error == 0,
451 "ERROR: %s at line %d",
452 __FUNCTION__, __LINE__);
453
454 if (remb) {
455 error = vie_rtp_rtcp->SetRembStatus(video_channel, true, true);
456 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
457 __FUNCTION__, __LINE__);
458 } else {
459 error = vie_rtp_rtcp->SetTMMBRStatus(video_channel, true);
460 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
461 __FUNCTION__, __LINE__);
462 }
463
464 error = vie_renderer->AddRenderer(capture_id, _window1, 0, 0.0, 0.0, 1.0,
465 1.0);
466 number_of_errors += ViETest::TestError(error == 0,
467 "ERROR: %s at line %d",
468 __FUNCTION__, __LINE__);
469
phoglund@webrtc.org75e66692013-02-07 08:52:08 +0000470
471 ViEToFileRenderer file_renderer;
472 if (FLAGS_render_custom_call_remote_to == "") {
473 error = vie_renderer->AddRenderer(video_channel, _window2, 1, 0.0, 0.0,
474 1.0, 1.0);
475 number_of_errors += ViETest::TestError(error == 0,
476 "ERROR: %s at line %d",
477 __FUNCTION__, __LINE__);
478 } else {
479 std::string output_path = ViETest::GetResultOutputPath();
480 std::string filename = FLAGS_render_custom_call_remote_to;
481 ViETest::Log("Rendering remote stream to %s: you will not see any output "
482 "in the second window.", (output_path + filename).c_str());
483
484 file_renderer.PrepareForRendering(output_path, filename);
485 RenderToFile(vie_renderer, video_channel, &file_renderer);
486 }
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000487
488 video_channel_transport.reset(
489 new webrtc::test::VideoChannelTransport(vie_network, video_channel));
490
491 error = video_channel_transport->SetSendDestination(ip_address.c_str(),
492 video_tx_port);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000493 number_of_errors += ViETest::TestError(error == 0,
494 "ERROR: %s at line %d",
495 __FUNCTION__, __LINE__);
496
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000497 error = video_channel_transport->SetLocalReceiver(video_rx_port);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000498 number_of_errors += ViETest::TestError(error == 0,
499 "ERROR: %s at line %d",
500 __FUNCTION__, __LINE__);
501
502 error = vie_codec->SetSendCodec(video_channel, video_send_codec);
503 number_of_errors += ViETest::TestError(error == 0,
504 "ERROR: %s at line %d",
505 __FUNCTION__, __LINE__);
506
507 error = vie_codec->SetReceiveCodec(video_channel, video_send_codec);
508 number_of_errors += ViETest::TestError(error == 0,
509 "ERROR: %s at line %d",
510 __FUNCTION__, __LINE__);
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +0000511
512 // Set the call mode (conferencing/buffering)
513 error = vie_rtp_rtcp->SetSenderBufferingMode(video_channel,
514 buffer_delay_ms);
515 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
516 __FUNCTION__, __LINE__);
517 error = vie_rtp_rtcp->SetReceiverBufferingMode(video_channel,
518 buffer_delay_ms);
519 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
520 __FUNCTION__, __LINE__);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000521 // Set the Video Protection before start send and receive.
522 SetVideoProtection(vie_codec, vie_rtp_rtcp,
523 video_channel, protection_method);
524
525 // Start Voice Playout and Receive.
526 error = voe_base->StartReceive(audio_channel);
527 number_of_errors += ViETest::TestError(error == 0,
528 "ERROR: %s at line %d",
529 __FUNCTION__, __LINE__);
530
531 error = voe_base->StartPlayout(audio_channel);
532 number_of_errors += ViETest::TestError(error == 0,
533 "ERROR: %s at line %d",
534 __FUNCTION__, __LINE__);
535
536 error = voe_base->StartSend(audio_channel);
537 number_of_errors += ViETest::TestError(error == 0,
538 "ERROR: %s at line %d",
539 __FUNCTION__, __LINE__);
540
541 // Now start the Video Send & Receive.
542 error = vie_base->StartSend(video_channel);
543 number_of_errors += ViETest::TestError(error == 0,
544 "ERROR: %s at line %d",
545 __FUNCTION__, __LINE__);
546
547 error = vie_base->StartReceive(video_channel);
548 number_of_errors += ViETest::TestError(error == 0,
549 "ERROR: %s at line %d",
550 __FUNCTION__, __LINE__);
551
552 error = vie_renderer->StartRender(capture_id);
553 number_of_errors += ViETest::TestError(error == 0,
554 "ERROR: %s at line %d",
555 __FUNCTION__, __LINE__);
556
557 error = vie_renderer->StartRender(video_channel);
558 number_of_errors += ViETest::TestError(error == 0,
559 "ERROR: %s at line %d",
560 __FUNCTION__, __LINE__);
561 ViEAutotestFileObserver file_observer;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000562
563 ViEAutotestEncoderObserver* codec_encoder_observer = NULL;
564 ViEAutotestDecoderObserver* codec_decoder_observer = NULL;
565
566 // Engine ready, wait for input.
567
568 // Call started.
569 std::cout << std::endl;
570 std::cout << "Custom call started" << std::endl;
571
572 // Modify call or stop call.
573 printf("\n");
574 int selection = FromChoices(
phoglund@webrtc.org71210082012-11-08 12:18:19 +0000575 "And now?",
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000576 "Stop the call\n"
kjellander@webrtc.org34d11102013-02-06 09:36:37 +0000577 "Modify the call\n"
578 "Keep the call running indefinitely\n")
579 .WithDefault("Keep the call running indefinitely").Choose();
580 if (selection == 3) {
andrew@webrtc.orgd3d364e2013-05-09 02:12:07 +0000581 AutoTestSleep(std::numeric_limits<int>::max());
kjellander@webrtc.org34d11102013-02-06 09:36:37 +0000582 }
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000583
584 while (selection == 2) {
585 // Keep on modifying the call until user stops the call.
586 int modify_selection = FromChoices(
phoglund@webrtc.org71210082012-11-08 12:18:19 +0000587 "Modify the call:",
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000588 "Stop call\n"
589 "Change Video Send Codec\n"
590 "Change Video Send Size by Common Resolutions\n"
591 "Change Video Send Size by Width & Height\n"
592 "Change Video Capture Device\n"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000593 "Change Video Protection Method\n"
594 "Toggle Encoder Observer\n"
595 "Toggle Decoder Observer\n"
596 "Print Call Information\n"
597 "Print Call Statistics\n"
598 "Toggle Image Scaling (Warning: high CPU usage when enabled)\n")
599 .WithDefault("Stop call")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000600 .Choose();
601
602 switch (modify_selection) {
603 case 1:
604 selection = 1;
605 break;
606 case 2:
607 // Change video codec.
608 SetVideoCodecType(vie_codec, &video_send_codec);
609 SetVideoCodecSize(&video_send_codec);
610 SetVideoCodecBitrate(&video_send_codec);
611 SetVideoCodecMinBitrate(&video_send_codec);
612 SetVideoCodecMaxBitrate(&video_send_codec);
613 SetVideoCodecMaxFramerate(&video_send_codec);
614 SetVideoCodecTemporalLayer(&video_send_codec);
615 PrintCallInformation(ip_address.c_str(), device_name,
616 unique_id, video_send_codec,
617 video_tx_port, video_rx_port,
618 audio_capture_device_name,
619 audio_playbackDeviceName, audio_codec,
620 audio_tx_port, audio_rx_port, protection_method);
621 error = vie_codec->SetSendCodec(video_channel, video_send_codec);
622 number_of_errors += ViETest::TestError(error == 0,
623 "ERROR: %s at line %d",
624 __FUNCTION__, __LINE__);
625 error = vie_codec->SetReceiveCodec(video_channel, video_send_codec);
626 number_of_errors += ViETest::TestError(error == 0,
627 "ERROR: %s at line %d",
628 __FUNCTION__, __LINE__);
629 break;
630 case 3:
631 // Change Video codec size by common resolution.
632 SetVideoCodecResolution(&video_send_codec);
633 PrintCallInformation(ip_address.c_str(), device_name,
634 unique_id, video_send_codec,
635 video_tx_port, video_rx_port,
636 audio_capture_device_name,
637 audio_playbackDeviceName, audio_codec,
638 audio_tx_port, audio_rx_port, protection_method);
639 error = vie_codec->SetSendCodec(video_channel, video_send_codec);
640 number_of_errors += ViETest::TestError(error == 0,
641 "ERROR: %s at line %d",
642 __FUNCTION__, __LINE__);
643 error = vie_codec->SetReceiveCodec(video_channel, video_send_codec);
644 number_of_errors += ViETest::TestError(error == 0,
645 "ERROR: %s at line %d",
646 __FUNCTION__, __LINE__);
647 break;
648 case 4:
649 // Change video codec by size height and width.
650 SetVideoCodecSize(&video_send_codec);
651 PrintCallInformation(ip_address.c_str(), device_name,
652 unique_id, video_send_codec,
653 video_tx_port, video_rx_port,
654 audio_capture_device_name,
655 audio_playbackDeviceName, audio_codec,
656 audio_tx_port, audio_rx_port, protection_method);
657 error = vie_codec->SetSendCodec(video_channel, video_send_codec);
658 number_of_errors += ViETest::TestError(error == 0,
659 "ERROR: %s at line %d",
660 __FUNCTION__, __LINE__);
661 error = vie_codec->SetReceiveCodec(video_channel, video_send_codec);
662 number_of_errors += ViETest::TestError(error == 0,
663 "ERROR: %s at line %d",
664 __FUNCTION__, __LINE__);
665 break;
666 case 5:
667 error = vie_renderer->StopRender(capture_id);
668 number_of_errors += ViETest::TestError(error == 0,
669 "ERROR: %s at line %d",
670 __FUNCTION__, __LINE__);
671 error = vie_renderer->RemoveRenderer(capture_id);
672 number_of_errors += ViETest::TestError(error == 0,
673 "ERROR: %s at line %d",
674 __FUNCTION__, __LINE__);
675 error = vie_capture->StopCapture(capture_id);
676 number_of_errors += ViETest::TestError(error == 0,
677 "ERROR: %s at line %d",
678 __FUNCTION__, __LINE__);
679 error = vie_capture->DisconnectCaptureDevice(video_channel);
680 number_of_errors += ViETest::TestError(error == 0,
681 "ERROR: %s at line %d",
682 __FUNCTION__, __LINE__);
683 error = vie_capture->ReleaseCaptureDevice(capture_id);
684 number_of_errors += ViETest::TestError(error == 0,
685 "ERROR: %s at line %d",
686 __FUNCTION__, __LINE__);
687 memset(device_name, 0, KMaxUniqueIdLength);
688 memset(unique_id, 0, KMaxUniqueIdLength);
689 if (!GetVideoDevice(vie_base, vie_capture, device_name, unique_id))
690 return number_of_errors;
691 capture_id = 0;
692 error = vie_capture->AllocateCaptureDevice(unique_id,
693 KMaxUniqueIdLength,
694 capture_id);
695 number_of_errors += ViETest::TestError(error == 0,
696 "ERROR: %s at line %d",
697 __FUNCTION__, __LINE__);
698 error = vie_capture->ConnectCaptureDevice(capture_id,
699 video_channel);
700 number_of_errors += ViETest::TestError(error == 0,
701 "ERROR: %s at line %d",
702 __FUNCTION__, __LINE__);
phoglund@webrtc.org75e66692013-02-07 08:52:08 +0000703
704 assert(FLAGS_render_custom_call_remote_to == "" &&
705 "Not implemented to change video capture device when "
706 "rendering to file!");
707
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000708 error = vie_capture->StartCapture(capture_id);
709 number_of_errors += ViETest::TestError(error == 0,
710 "ERROR: %s at line %d",
711 __FUNCTION__, __LINE__);
712 error = vie_renderer->AddRenderer(capture_id, _window1, 0, 0.0, 0.0,
713 1.0, 1.0);
714 number_of_errors += ViETest::TestError(error == 0,
715 "ERROR: %s at line %d",
716 __FUNCTION__, __LINE__);
717 error = vie_renderer->StartRender(capture_id);
718 number_of_errors += ViETest::TestError(error == 0,
719 "ERROR: %s at line %d",
720 __FUNCTION__, __LINE__);
721 break;
722 case 6:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000723 // Change the Video Protection.
724 protection_method = GetVideoProtection();
725 SetVideoProtection(vie_codec, vie_rtp_rtcp,
726 video_channel, protection_method);
727 break;
mikhal@webrtc.org8a159ad2013-04-26 20:09:54 +0000728 case 7:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000729 // Toggle Encoder Observer.
730 if (!codec_encoder_observer) {
731 std::cout << "Registering Encoder Observer" << std::endl;
732 codec_encoder_observer = new ViEAutotestEncoderObserver();
733 error = vie_codec->RegisterEncoderObserver(video_channel,
734 *codec_encoder_observer);
735 number_of_errors += ViETest::TestError(error == 0,
736 "ERROR: %s at line %d",
737 __FUNCTION__, __LINE__);
738 } else {
739 std::cout << "Deregistering Encoder Observer" << std::endl;
740 error = vie_codec->DeregisterEncoderObserver(video_channel);
741 delete codec_encoder_observer;
742 codec_encoder_observer = NULL;
743 number_of_errors += ViETest::TestError(error == 0,
744 "ERROR: %s at line %d",
745 __FUNCTION__, __LINE__);
746 }
747 break;
mikhal@webrtc.org8a159ad2013-04-26 20:09:54 +0000748 case 8:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000749 // Toggle Decoder Observer.
750 if (!codec_decoder_observer) {
751 std::cout << "Registering Decoder Observer" << std::endl;
752 codec_decoder_observer = new ViEAutotestDecoderObserver();
753 error = vie_codec->RegisterDecoderObserver(video_channel,
754 *codec_decoder_observer);
755 number_of_errors += ViETest::TestError(error == 0,
756 "ERROR: %s at line %d",
757 __FUNCTION__, __LINE__);
758 } else {
759 std::cout << "Deregistering Decoder Observer" << std::endl;
760 error = vie_codec->DeregisterDecoderObserver(video_channel);
761 delete codec_decoder_observer;
762 codec_decoder_observer = NULL;
763 number_of_errors += ViETest::TestError(error == 0,
764 "ERROR: %s at line %d",
765 __FUNCTION__, __LINE__);
766 }
767 break;
mikhal@webrtc.org8a159ad2013-04-26 20:09:54 +0000768 case 9:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000769 // Print Call information..
770 PrintCallInformation(ip_address.c_str(), device_name,
771 unique_id, video_send_codec,
772 video_tx_port, video_rx_port,
773 audio_capture_device_name,
774 audio_playbackDeviceName,
775 audio_codec, audio_tx_port,
776 audio_rx_port, protection_method);
777 PrintVideoStreamInformation(vie_codec,
778 video_channel);
779 break;
mikhal@webrtc.org8a159ad2013-04-26 20:09:54 +0000780 case 10:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000781 // Print Call statistics.
782 PrintRTCCPStatistics(vie_rtp_rtcp, video_channel,
783 kSendStatistic);
784 PrintRTCCPStatistics(vie_rtp_rtcp, video_channel,
785 kReceivedStatistic);
786 PrintRTPStatistics(vie_rtp_rtcp, video_channel);
787 PrintBandwidthUsage(vie_rtp_rtcp, video_channel);
788 PrintCodecStatistics(vie_codec, video_channel,
789 kSendStatistic);
790 PrintCodecStatistics(vie_codec, video_channel,
791 kReceivedStatistic);
792 PrintGetDiscardedPackets(vie_codec, video_channel);
793 break;
mikhal@webrtc.org8a159ad2013-04-26 20:09:54 +0000794 case 11:
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000795 is_image_scale_enabled = !is_image_scale_enabled;
796 vie_codec->SetImageScaleStatus(video_channel, is_image_scale_enabled);
797 if (is_image_scale_enabled) {
798 std::cout << "Image Scale is now enabled" << std::endl;
799 } else {
800 std::cout << "Image Scale is now disabled" << std::endl;
801 }
802 break;
803 default:
804 assert(false);
805 break;
806 }
807 }
808
phoglund@webrtc.org75e66692013-02-07 08:52:08 +0000809 if (FLAGS_render_custom_call_remote_to != "")
810 file_renderer.StopRendering();
811
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000812 // Testing finished. Tear down Voice and Video Engine.
813 // Tear down the VoE first.
814 error = voe_base->StopReceive(audio_channel);
815 number_of_errors += ViETest::TestError(error == 0,
816 "ERROR: %s at line %d",
817 __FUNCTION__, __LINE__);
818
819 error = voe_base->StopPlayout(audio_channel);
820 number_of_errors += ViETest::TestError(error == 0,
821 "ERROR: %s at line %d",
822 __FUNCTION__, __LINE__);
823
824 error = voe_base->DeleteChannel(audio_channel);
825 number_of_errors += ViETest::TestError(error == 0,
826 "ERROR: %s at line %d",
827 __FUNCTION__, __LINE__);
828 // Now tear down the ViE engine.
829 error = vie_base->DisconnectAudioChannel(video_channel);
830
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000831 voice_channel_transport.reset(NULL);
pwestin@webrtc.org9c3b7bd2013-03-22 19:21:27 +0000832
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000833 // If Encoder/Decoder Observer is running, delete them.
834 if (codec_encoder_observer) {
835 error = vie_codec->DeregisterEncoderObserver(video_channel);
836 delete codec_encoder_observer;
837 number_of_errors += ViETest::TestError(error == 0,
838 "ERROR: %s at line %d",
839 __FUNCTION__, __LINE__);
840 }
841 if (codec_decoder_observer) {
842 error = vie_codec->DeregisterDecoderObserver(video_channel);
843 delete codec_decoder_observer;
844 number_of_errors += ViETest::TestError(error == 0,
845 "ERROR: %s at line %d",
846 __FUNCTION__, __LINE__);
847 }
848
849 error = vie_base->StopReceive(video_channel);
850 number_of_errors += ViETest::TestError(error == 0,
851 "ERROR: %s at line %d",
852 __FUNCTION__, __LINE__);
853
854 error = vie_base->StopSend(video_channel);
855 number_of_errors += ViETest::TestError(error == 0,
856 "ERROR: %s at line %d",
857 __FUNCTION__, __LINE__);
858
859 error = vie_renderer->StopRender(capture_id);
860 number_of_errors += ViETest::TestError(error == 0,
861 "ERROR: %s at line %d",
862 __FUNCTION__, __LINE__);
863
864 error = vie_renderer->StopRender(video_channel);
865 number_of_errors += ViETest::TestError(error == 0,
866 "ERROR: %s at line %d",
867 __FUNCTION__, __LINE__);
868
869 error = vie_renderer->RemoveRenderer(capture_id);
870 number_of_errors += ViETest::TestError(error == 0,
871 "ERROR: %s at line %d",
872 __FUNCTION__, __LINE__);
873
874 error = vie_renderer->RemoveRenderer(video_channel);
875 number_of_errors += ViETest::TestError(error == 0,
876 "ERROR: %s at line %d",
877 __FUNCTION__, __LINE__);
878
879 error = vie_capture->StopCapture(capture_id);
880 number_of_errors += ViETest::TestError(error == 0,
881 "ERROR: %s at line %d",
882 __FUNCTION__, __LINE__);
883
884 error = vie_capture->DisconnectCaptureDevice(video_channel);
885 number_of_errors += ViETest::TestError(error == 0,
886 "ERROR: %s at line %d",
887 __FUNCTION__, __LINE__);
888
889 error = vie_capture->ReleaseCaptureDevice(capture_id);
890 number_of_errors += ViETest::TestError(error == 0,
891 "ERROR: %s at line %d",
892 __FUNCTION__, __LINE__);
893
pwestin@webrtc.org8f5edba2013-05-02 18:25:03 +0000894 video_channel_transport.reset(NULL);
895
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000896 error = vie_base->DeleteChannel(video_channel);
897 number_of_errors += ViETest::TestError(error == 0,
898 "ERROR: %s at line %d",
899 __FUNCTION__, __LINE__);
900
901 int remaining_interfaces = 0;
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000902 remaining_interfaces = vie_codec->Release();
903 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
904 "ERROR: %s at line %d",
905 __FUNCTION__, __LINE__);
906
907 remaining_interfaces = vie_capture->Release();
908 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
909 "ERROR: %s at line %d",
910 __FUNCTION__, __LINE__);
911
912 remaining_interfaces = vie_rtp_rtcp->Release();
913 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
914 "ERROR: %s at line %d",
915 __FUNCTION__, __LINE__);
916
917 remaining_interfaces = vie_renderer->Release();
918 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
919 "ERROR: %s at line %d",
920 __FUNCTION__, __LINE__);
921
922 remaining_interfaces = vie_network->Release();
923 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
924 "ERROR: %s at line %d",
925 __FUNCTION__, __LINE__);
926
927 remaining_interfaces = vie_base->Release();
928 number_of_errors += ViETest::TestError(remaining_interfaces == 0,
929 "ERROR: %s at line %d",
930 __FUNCTION__, __LINE__);
931
932 bool deleted = webrtc::VideoEngine::Delete(vie);
933 number_of_errors += ViETest::TestError(deleted == true,
934 "ERROR: %s at line %d",
935 __FUNCTION__, __LINE__);
936
937 ViETest::Log(" ");
938 ViETest::Log(" ViE Autotest Custom Call Started");
939 ViETest::Log("========================================");
940 ViETest::Log(" ");
941 }
942 return number_of_errors;
943}
944
945bool GetVideoDevice(webrtc::ViEBase* vie_base,
946 webrtc::ViECapture* vie_capture,
947 char* capture_device_name,
948 char* capture_device_unique_id) {
949 int error = 0;
950 int number_of_errors = 0;
951
952 const unsigned int KMaxDeviceNameLength = 128;
953 const unsigned int KMaxUniqueIdLength = 256;
954 char device_name[KMaxDeviceNameLength];
955 char unique_id[KMaxUniqueIdLength];
956
957 if (vie_capture->NumberOfCaptureDevices() == 0) {
958 printf("You have no capture devices plugged into your system.\n");
959 return false;
960 }
961
962 std::string capture_choices;
963 std::string first_device;
964 for (int i = 0; i < vie_capture->NumberOfCaptureDevices(); i++) {
965 memset(device_name, 0, KMaxDeviceNameLength);
966 memset(unique_id, 0, KMaxUniqueIdLength);
967
968 error = vie_capture->GetCaptureDevice(i, device_name,
969 KMaxDeviceNameLength,
970 unique_id,
971 KMaxUniqueIdLength);
972 number_of_errors += ViETest::TestError(error == 0,
973 "ERROR: %s at line %d",
974 __FUNCTION__, __LINE__);
975 const int kCaptureLineLength =
976 KMaxDeviceNameLength + KMaxUniqueIdLength + 8;
977 char capture_line[kCaptureLineLength];
978 sprintf(capture_line, "%s (%s)", device_name, unique_id);
979 capture_choices += capture_line;
980 capture_choices += "\n";
981 if (first_device.empty())
982 first_device = capture_line;
983 }
984
phoglund@webrtc.org71210082012-11-08 12:18:19 +0000985 int choice = FromChoices("Available Video Capture Devices", capture_choices)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000986 .WithDefault(first_device)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000987 .Choose();
988
989 error = vie_capture->GetCaptureDevice(
990 choice - 1, device_name, KMaxDeviceNameLength, unique_id,
991 KMaxUniqueIdLength);
992 number_of_errors += ViETest::TestError(error == 0,
993 "ERROR: %s at line %d",
994 __FUNCTION__, __LINE__);
995 strcpy(capture_device_unique_id, unique_id);
996 strcpy(capture_device_name, device_name);
997 return true;
998}
999
1000bool GetAudioDevices(webrtc::VoEBase* voe_base,
1001 webrtc::VoEHardware* voe_hardware,
1002 char* recording_device_name,
1003 int& recording_device_index,
1004 char* playback_device_name,
1005 int& playback_device_index) {
1006 int error = 0;
1007 int number_of_errors = 0;
1008
1009 const unsigned int KMaxDeviceNameLength = 128;
1010 const unsigned int KMaxUniqueIdLength = 128;
1011 char recording_device_unique_name[KMaxDeviceNameLength];
1012 char playback_device_unique_name[KMaxUniqueIdLength];
1013
1014 int number_of_recording_devices = -1;
1015 error = voe_hardware->GetNumOfRecordingDevices(number_of_recording_devices);
1016 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
1017 __FUNCTION__, __LINE__);
1018
1019 recording_device_index = -1;
1020 playback_device_index = -1;
1021
1022 std::string device_choices;
1023 std::string default_recording_line;
1024 for (int i = 0; i < number_of_recording_devices; ++i) {
1025 error = voe_hardware->GetRecordingDeviceName(
1026 i, recording_device_name, recording_device_unique_name);
1027 number_of_errors += ViETest::TestError(error == 0,
1028 "ERROR: %s at line %d",
1029 __FUNCTION__, __LINE__);
1030
1031 device_choices += recording_device_name;
1032 device_choices += "\n";
1033 if (default_recording_line.empty())
1034 default_recording_line = recording_device_name;
1035 }
1036
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001037 int choice = FromChoices("Available audio capture devices:", device_choices)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001038 .WithDefault(default_recording_line)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001039 .Choose();
1040
1041 recording_device_index = choice - 1;
1042 error = voe_hardware->GetRecordingDeviceName(
1043 recording_device_index, recording_device_name,
1044 recording_device_unique_name);
1045 number_of_errors += ViETest::TestError(
1046 error == 0, "ERROR: %s at line %d", __FUNCTION__, __LINE__);
1047
1048 int number_of_playback_devices = -1;
1049 error = voe_hardware->GetNumOfPlayoutDevices(number_of_playback_devices);
1050 number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
1051 __FUNCTION__, __LINE__);
1052
1053
1054 std::string playback_choices;
1055 std::string default_playback_line;
1056 for (int i = 0; i < number_of_playback_devices; i++) {
1057 error = voe_hardware->GetPlayoutDeviceName(i,
1058 playback_device_name,
1059 playback_device_unique_name);
1060 number_of_errors += ViETest::TestError(
1061 error == 0, "ERROR: %s at line %d", __FUNCTION__, __LINE__);
1062 playback_choices += playback_device_name;
1063 playback_choices += "\n";
1064 if (default_playback_line.empty())
1065 default_playback_line = playback_device_name;
1066 }
1067
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001068 choice = FromChoices("Available audio playout devices:", playback_choices)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001069 .WithDefault(default_playback_line)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001070 .Choose();
1071
1072 playback_device_index = choice - 1;
1073 error = voe_hardware->GetPlayoutDeviceName(playback_device_index,
1074 playback_device_name,
1075 playback_device_unique_name);
1076 number_of_errors += ViETest::TestError(error == 0,
1077 "ERROR: %s at line %d",
1078 __FUNCTION__, __LINE__);
1079 return true;
1080}
1081
1082// General helper functions.
1083
1084std::string GetIPAddress() {
1085 class IpValidator : public webrtc::InputValidator {
1086 public:
1087 bool InputOk(const std::string& input) const {
1088 // Just check quickly that it's on the form x.y.z.w
1089 return std::count(input.begin(), input.end(), '.') == 3;
1090 }
1091 };
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001092 return TypedInput("Enter destination IP.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001093 .WithDefault(DEFAULT_SEND_IP)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001094 .WithInputValidator(new IpValidator())
1095 .AskForInput();
1096}
1097
1098// Video settings functions.
1099
1100void GetVideoPorts(int* tx_port, int* rx_port) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001101 std::string tx_input = TypedInput("Enter video send port.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001102 .WithDefault(DEFAULT_VIDEO_PORT)
1103 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, 65536))
1104 .AskForInput();
1105 *tx_port = atoi(tx_input.c_str());
1106
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001107 std::string rx_input = TypedInput("Enter video receive port.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001108 .WithDefault(DEFAULT_VIDEO_PORT)
1109 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, 65536))
1110 .AskForInput();
1111 *rx_port = atoi(rx_input.c_str());
1112}
1113
1114// Audio settings functions.
1115
1116void GetAudioPorts(int* tx_port, int* rx_port) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001117 std::string tx_input = TypedInput("Enter audio send port.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001118 .WithDefault(DEFAULT_AUDIO_PORT)
1119 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, 65536))
1120 .AskForInput();
1121 *tx_port = atoi(tx_input.c_str());
1122
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001123 std::string rx_input = TypedInput("Enter audio receive port.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001124 .WithDefault(DEFAULT_AUDIO_PORT)
1125 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, 65536))
1126 .AskForInput();
1127 *rx_port = atoi(rx_input.c_str());
1128}
1129
1130bool GetAudioCodec(webrtc::VoECodec* voe_codec,
1131 webrtc::CodecInst& audio_codec) {
1132 int error = 0;
1133 memset(&audio_codec, 0, sizeof(webrtc::CodecInst));
1134
1135 std::string default_codec_line;
1136 std::string codec_choices;
1137 for (int codec_idx = 0; codec_idx < voe_codec->NumOfCodecs(); codec_idx++) {
1138 error = voe_codec->GetCodec(codec_idx, audio_codec);
1139 ViETest::TestError(error == 0,
1140 "ERROR: %s at line %d",
1141 __FUNCTION__, __LINE__);
1142
1143 char codec_line[128];
1144 sprintf(codec_line, "%s type: %d freq: %d chan: %d",
1145 audio_codec.plname, audio_codec.pltype, audio_codec.plfreq,
1146 audio_codec.channels);
1147 codec_choices += codec_line;
1148 codec_choices += "\n";
1149
1150 if (strcmp(audio_codec.plname, DEFAULT_AUDIO_CODEC) == 0) {
1151 default_codec_line = codec_line;
1152 }
1153 }
1154 assert(!default_codec_line.empty() && "Default codec doesn't exist.");
1155
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001156 int codec_selection = FromChoices("Available Audio Codecs:", codec_choices)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001157 .WithDefault(default_codec_line)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001158 .Choose();
1159
1160 error = voe_codec->GetCodec(codec_selection - 1, audio_codec);
1161 ViETest::TestError(error == 0,
1162 "ERROR: %s at line %d",
1163 __FUNCTION__, __LINE__);
1164 return true;
1165}
1166
1167void PrintCallInformation(const char* IP, const char* video_capture_device_name,
1168 const char* video_capture_unique_id,
1169 webrtc::VideoCodec video_codec,
1170 int video_tx_port, int video_rx_port,
1171 const char* audio_capture_device_name,
1172 const char* audio_playbackDeviceName,
1173 webrtc::CodecInst audio_codec,
1174 int audio_tx_port, int audio_rx_port,
1175 int protection_method) {
1176 std::string str;
1177
1178 std::cout << "************************************************"
1179 << std::endl;
1180 std::cout << "The call has the following settings: " << std::endl;
1181 std::cout << "\tIP: " << IP << std::endl;
1182 std::cout << "\tVideo Capture Device: " << video_capture_device_name
1183 << std::endl;
1184 std::cout << "\t\tName: " << video_capture_device_name << std::endl;
1185 std::cout << "\t\tUniqueId: " << video_capture_unique_id << std::endl;
1186 PrintVideoCodec(video_codec);
1187 std::cout << "\t Video Tx Port: " << video_tx_port << std::endl;
1188 std::cout << "\t Video Rx Port: " << video_rx_port << std::endl;
1189 std::cout << "\t Video Protection Method (NOTE: Starts at 1 now): "
1190 << protection_method << std::endl;
1191 std::cout << "\tAudio Capture Device: " << audio_capture_device_name
1192 << std::endl;
1193 std::cout << "\tAudio Playback Device: " << audio_playbackDeviceName
1194 << std::endl;
1195 std::cout << "\tAudio Codec: " << std::endl;
1196 std::cout << "\t\tplname: " << audio_codec.plname << std::endl;
1197 std::cout << "\t\tpltype: " << static_cast<int>(audio_codec.pltype)
1198 << std::endl;
1199 std::cout << "\t Audio Tx Port: " << audio_tx_port << std::endl;
1200 std::cout << "\t Audio Rx Port: " << audio_rx_port << std::endl;
1201 std::cout << "************************************************"
1202 << std::endl;
1203}
1204
1205void SetVideoCodecType(webrtc::ViECodec* vie_codec,
1206 webrtc::VideoCodec* video_codec) {
1207 int error = 0;
1208 int number_of_errors = 0;
1209 memset(video_codec, 0, sizeof(webrtc::VideoCodec));
1210
1211 std::string codec_choices;
1212 std::string default_codec_line;
1213 for (int i = 0; i < vie_codec->NumberOfCodecs(); i++) {
1214 error = vie_codec->GetCodec(i, *video_codec);
1215 number_of_errors += ViETest::TestError(
1216 error == 0, "ERROR: %s at line %d", __FUNCTION__, __LINE__);
1217
1218 codec_choices += video_codec->plName;
1219 codec_choices += "\n";
1220 if (strcmp(video_codec->plName, DEFAULT_VIDEO_CODEC) == 0)
1221 default_codec_line = video_codec->plName;
1222 }
1223 assert(!default_codec_line.empty() && "Default does not exist.");
1224
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001225 int choice = FromChoices("Available Video Codecs", codec_choices)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001226 .WithDefault(default_codec_line)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001227 .Choose();
1228 error = vie_codec->GetCodec(choice - 1, *video_codec);
1229 number_of_errors += ViETest::TestError(
1230 error == 0, "ERROR: %s at line %d", __FUNCTION__, __LINE__);
1231
1232 if (video_codec->codecType == webrtc::kVideoCodecI420) {
1233 video_codec->width = 176;
1234 video_codec->height = 144;
1235 }
1236}
1237
1238void SetVideoCodecResolution(webrtc::VideoCodec* video_codec) {
1239 if (video_codec->codecType != webrtc::kVideoCodecVP8) {
1240 printf("Can only change codec size if it's VP8\n");
1241 return;
1242 }
1243
1244 int choice = FromChoices(
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001245 "Available Common Resolutions:",
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001246 "SQCIF (128X96)\n"
1247 "QQVGA (160X120)\n"
1248 "QCIF (176X144)\n"
1249 "CIF (352X288)\n"
1250 "VGA (640X480)\n"
1251 "WVGA (800x480)\n"
1252 "4CIF (704X576)\n"
1253 "SVGA (800X600)\n"
1254 "HD (1280X720)\n"
1255 "XGA (1024x768)\n")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001256 .Choose();
1257
1258 switch (choice) {
1259 case 1:
1260 video_codec->width = 128;
1261 video_codec->height = 96;
1262 break;
1263 case 2:
1264 video_codec->width = 160;
1265 video_codec->height = 120;
1266 break;
1267 case 3:
1268 video_codec->width = 176;
1269 video_codec->height = 144;
1270 break;
1271 case 4:
1272 video_codec->width = 352;
1273 video_codec->height = 288;
1274 break;
1275 case 5:
1276 video_codec->width = 640;
1277 video_codec->height = 480;
1278 break;
1279 case 6:
1280 video_codec->width = 800;
1281 video_codec->height = 480;
1282 break;
1283 case 7:
1284 video_codec->width = 704;
1285 video_codec->height = 576;
1286 break;
1287 case 8:
1288 video_codec->width = 800;
1289 video_codec->height = 600;
1290 break;
1291 case 9:
1292 video_codec->width = 1280;
1293 video_codec->height = 720;
1294 break;
1295 case 10:
1296 video_codec->width = 1024;
1297 video_codec->height = 768;
1298 break;
1299 }
1300}
1301
1302void SetVideoCodecSize(webrtc::VideoCodec* video_codec) {
1303 if (video_codec->codecType != webrtc::kVideoCodecVP8) {
1304 printf("Can only change codec size if it's VP8\n");
1305 return;
1306 }
1307
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001308 std::string input = TypedInput("Choose video width.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001309 .WithDefault(DEFAULT_VIDEO_CODEC_WIDTH)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001310 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1311 .AskForInput();
1312 video_codec->width = atoi(input.c_str());
1313
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001314 input = TypedInput("Choose video height.")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001315 .WithDefault(DEFAULT_VIDEO_CODEC_HEIGHT)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001316 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1317 .AskForInput();
1318 video_codec->height = atoi(input.c_str());
1319}
1320
1321void SetVideoCodecBitrate(webrtc::VideoCodec* video_codec) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001322 std::string input = TypedInput("Choose start rate (in kbps).")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001323 .WithDefault(DEFAULT_VIDEO_CODEC_BITRATE)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001324 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1325 .AskForInput();
1326
1327 video_codec->startBitrate = atoi(input.c_str());
1328}
1329
1330void SetVideoCodecMaxBitrate(webrtc::VideoCodec* video_codec) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001331 std::string input = TypedInput("Choose max bitrate (in kbps).")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001332 .WithDefault(DEFAULT_VIDEO_CODEC_MAX_BITRATE)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001333 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1334 .AskForInput();
1335
1336 video_codec->maxBitrate = atoi(input.c_str());
1337}
1338
1339void SetVideoCodecMinBitrate(webrtc::VideoCodec* video_codec) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001340 std::string input = TypedInput("Choose min bitrate (in kbps).")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001341 .WithDefault(DEFAULT_VIDEO_CODEC_MIN_BITRATE)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001342 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1343 .AskForInput();
1344
1345 video_codec->minBitrate = atoi(input.c_str());
1346}
1347
1348void SetVideoCodecMaxFramerate(webrtc::VideoCodec* video_codec) {
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001349 std::string input = TypedInput("Choose max framerate (in fps).")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001350 .WithDefault(DEFAULT_VIDEO_CODEC_MAX_FRAMERATE)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001351 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(1, INT_MAX))
1352 .AskForInput();
1353 video_codec->maxFramerate = atoi(input.c_str());
1354}
1355
1356void SetVideoCodecTemporalLayer(webrtc::VideoCodec* video_codec) {
1357 if (video_codec->codecType != webrtc::kVideoCodecVP8)
1358 return;
1359
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001360 std::string input = TypedInput("Choose number of temporal layers (0 to 4).")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001361 .WithDefault(DEFAULT_TEMPORAL_LAYER)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001362 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(0, 4))
1363 .AskForInput();
1364 video_codec->codecSpecific.VP8.numberOfTemporalLayers = atoi(input.c_str());
1365}
1366
1367// GetVideoProtection only prints the prompt to get a number
1368// that SetVideoProtection method uses.
1369VideoProtectionMethod GetVideoProtection() {
1370 int choice = FromChoices(
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001371 "Available Video Protection Methods:",
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001372 "None\n"
1373 "FEC\n"
1374 "NACK\n"
1375 "NACK+FEC\n")
1376 .WithDefault(DEFAULT_VIDEO_PROTECTION_METHOD)
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001377 .Choose();
1378
1379 assert(choice >= kProtectionMethodNone &&
1380 choice <= kProtectionMethodHybridNackAndFec);
1381 return static_cast<VideoProtectionMethod>(choice);
1382}
1383
1384bool SetVideoProtection(webrtc::ViECodec* vie_codec,
1385 webrtc::ViERTP_RTCP* vie_rtp_rtcp,
1386 int video_channel,
1387 VideoProtectionMethod protection_method) {
1388 int error = 0;
1389 int number_of_errors = 0;
1390 webrtc::VideoCodec video_codec;
1391
1392 memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
1393
1394 // Set all video protection to false initially
1395 error = vie_rtp_rtcp->SetHybridNACKFECStatus(video_channel, false,
1396 VCM_RED_PAYLOAD_TYPE,
1397 VCM_ULPFEC_PAYLOAD_TYPE);
1398 number_of_errors += ViETest::TestError(error == 0,
1399 "ERROR: %s at line %d",
1400 __FUNCTION__, __LINE__);
1401 error = vie_rtp_rtcp->SetFECStatus(video_channel, false,
1402 VCM_RED_PAYLOAD_TYPE,
1403 VCM_ULPFEC_PAYLOAD_TYPE);
1404 number_of_errors += ViETest::TestError(error == 0,
1405 "ERROR: %s at line %d",
1406 __FUNCTION__, __LINE__);
1407 error = vie_rtp_rtcp->SetNACKStatus(video_channel, false);
1408 number_of_errors += ViETest::TestError(error == 0,
1409 "ERROR: %s at line %d",
1410 __FUNCTION__, __LINE__);
1411 // Set video protection for FEC, NACK or Hybrid.
1412 switch (protection_method) {
1413 case kProtectionMethodNone:
1414 // No protection selected, all protection already at false.
1415 std::cout << "Call using None protection Method" << std::endl;
1416 break;
1417 case kProtectionMethodFecOnly:
1418 std::cout << "Call using FEC protection Method" << std::endl;
1419 error = vie_rtp_rtcp->SetFECStatus(video_channel, true,
1420 VCM_RED_PAYLOAD_TYPE,
1421 VCM_ULPFEC_PAYLOAD_TYPE);
1422 number_of_errors += ViETest::TestError(error == 0,
1423 "ERROR: %s at line %d",
1424 __FUNCTION__, __LINE__);
1425 break;
1426 case kProtectionMethodNackOnly:
1427 std::cout << "Call using NACK protection Method" << std::endl;
1428 error = vie_rtp_rtcp->SetNACKStatus(video_channel, true);
1429 number_of_errors += ViETest::TestError(error == 0,
1430 "ERROR: %s at line %d",
1431 __FUNCTION__, __LINE__);
1432 break;
1433 case kProtectionMethodHybridNackAndFec:
1434 std::cout << "Call using Hybrid NACK and FEC protection Method"
1435 << std::endl;
1436 error = vie_rtp_rtcp->SetHybridNACKFECStatus(video_channel, true,
1437 VCM_RED_PAYLOAD_TYPE,
1438 VCM_ULPFEC_PAYLOAD_TYPE);
1439 number_of_errors += ViETest::TestError(error == 0,
1440 "ERROR: %s at line %d",
1441 __FUNCTION__, __LINE__);
1442 break;
1443 }
1444
1445 // Set receive codecs for FEC and hybrid NACK/FEC.
1446 if (protection_method == kProtectionMethodFecOnly ||
1447 protection_method == kProtectionMethodHybridNackAndFec) {
1448 // RED.
1449 error = vie_codec->GetCodec(vie_codec->NumberOfCodecs() - 2,
1450 video_codec);
1451 number_of_errors += ViETest::TestError(error == 0,
1452 "ERROR: %s at line %d",
1453 __FUNCTION__, __LINE__);
1454 video_codec.plType = VCM_RED_PAYLOAD_TYPE;
1455 error = vie_codec->SetReceiveCodec(video_channel, video_codec);
1456 number_of_errors += ViETest::TestError(error == 0,
1457 "ERROR: %s at line %d",
1458 __FUNCTION__, __LINE__);
1459 std::cout << "RED Codec Information:" << std::endl;
1460 PrintVideoCodec(video_codec);
1461 // ULPFEC.
1462 error = vie_codec->GetCodec(vie_codec->NumberOfCodecs() - 1,
1463 video_codec);
1464 number_of_errors += ViETest::TestError(error == 0,
1465 "ERROR: %s at line %d",
1466 __FUNCTION__, __LINE__);
1467 video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
1468 error = vie_codec->SetReceiveCodec(video_channel, video_codec);
1469 number_of_errors += ViETest::TestError(error == 0,
1470 "ERROR: %s at line %d",
1471 __FUNCTION__, __LINE__);
1472 std::cout << "ULPFEC Codec Information:" << std::endl;
1473 PrintVideoCodec(video_codec);
1474 }
1475
1476 return true;
1477}
1478
1479// Returns true if REMB, false if TMMBR.
1480bool GetBitrateSignaling() {
1481 int choice = FromChoices(
phoglund@webrtc.org71210082012-11-08 12:18:19 +00001482 "Available Bitrate Signaling Methods:",
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001483 "REMB\n"
1484 "TMMBR\n")
1485 .WithDefault("REMB")
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001486 .Choose();
1487 return choice == 1;
1488}
1489
mikhal@webrtc.org4db69af2013-02-15 23:22:18 +00001490int GetBufferingDelay() {
1491 std::string input = TypedInput("Choose buffering delay (mS).")
1492 .WithDefault(DEFAULT_BUFFERING_DELAY_MS)
1493 .WithInputValidator(new webrtc::IntegerWithinRangeValidator(0, 10000))
1494 .AskForInput();
1495 std::string delay_ms = input;
1496 return atoi(delay_ms.c_str());
1497}
1498
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001499void PrintRTCCPStatistics(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
1500 int video_channel,
1501 StatisticsType stat_type) {
1502 int error = 0;
1503 int number_of_errors = 0;
1504 uint16_t fraction_lost = 0;
1505 unsigned int cumulative_lost = 0;
1506 unsigned int extended_max = 0;
1507 unsigned int jitter = 0;
1508 int rtt_ms = 0;
1509
1510 switch (stat_type) {
1511 case kReceivedStatistic:
1512 std::cout << "RTCP Received statistics"
1513 << std::endl;
1514 // Get and print the Received RTCP Statistics
1515 error = vie_rtp_rtcp->GetReceivedRTCPStatistics(video_channel,
1516 fraction_lost,
1517 cumulative_lost,
1518 extended_max,
1519 jitter, rtt_ms);
1520 number_of_errors += ViETest::TestError(error == 0,
1521 "ERROR: %s at line %d",
1522 __FUNCTION__, __LINE__);
1523 break;
1524 case kSendStatistic:
1525 std::cout << "RTCP Sent statistics"
1526 << std::endl;
1527 // Get and print the Sent RTCP Statistics
1528 error = vie_rtp_rtcp->GetSentRTCPStatistics(video_channel, fraction_lost,
1529 cumulative_lost, extended_max,
1530 jitter, rtt_ms);
1531 number_of_errors += ViETest::TestError(error == 0,
1532 "ERROR: %s at line %d",
1533 __FUNCTION__, __LINE__);
1534 break;
1535 }
1536 std::cout << "\tRTCP fraction of lost packets: "
1537 << fraction_lost << std::endl;
1538 std::cout << "\tRTCP cumulative number of lost packets: "
1539 << cumulative_lost << std::endl;
1540 std::cout << "\tRTCP max received sequence number "
1541 << extended_max << std::endl;
1542 std::cout << "\tRTCP jitter: "
1543 << jitter << std::endl;
1544 std::cout << "\tRTCP round trip (ms): "
1545 << rtt_ms << std::endl;
1546}
1547
1548void PrintRTPStatistics(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
1549 int video_channel) {
1550 int error = 0;
1551 int number_of_errors = 0;
1552 unsigned int bytes_sent = 0;
1553 unsigned int packets_sent = 0;
1554 unsigned int bytes_received = 0;
1555 unsigned int packets_received = 0;
1556
1557 std::cout << "RTP statistics"
1558 << std::endl;
1559
1560 // Get and print the RTP Statistics
1561 error = vie_rtp_rtcp->GetRTPStatistics(video_channel, bytes_sent,
1562 packets_sent, bytes_received,
1563 packets_received);
1564 number_of_errors += ViETest::TestError(error == 0,
1565 "ERROR: %s at line %d",
1566 __FUNCTION__, __LINE__);
1567 std::cout << "\tRTP bytes sent: "
1568 << bytes_sent << std::endl;
1569 std::cout << "\tRTP packets sent: "
1570 << packets_sent << std::endl;
1571 std::cout << "\tRTP bytes received: "
1572 << bytes_received << std::endl;
1573 std::cout << "\tRTP packets received: "
1574 << packets_received << std::endl;
1575}
1576
1577void PrintBandwidthUsage(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
1578 int video_channel) {
1579 int error = 0;
1580 int number_of_errors = 0;
1581 unsigned int total_bitrate_sent = 0;
1582 unsigned int video_bitrate_sent = 0;
1583 unsigned int fec_bitrate_sent = 0;
1584 unsigned int nack_bitrate_sent = 0;
1585 double percentage_fec = 0;
1586 double percentage_nack = 0;
1587
1588 std::cout << "Bandwidth Usage" << std::endl;
1589
1590 // Get and print Bandwidth usage
1591 error = vie_rtp_rtcp->GetBandwidthUsage(video_channel, total_bitrate_sent,
1592 video_bitrate_sent, fec_bitrate_sent,
1593 nack_bitrate_sent);
1594 number_of_errors += ViETest::TestError(error == 0,
1595 "ERROR: %s at line %d",
1596 __FUNCTION__, __LINE__);
1597 std::cout << "\tTotal bitrate sent (Kbit/s): "
1598 << total_bitrate_sent << std::endl;
1599 std::cout << "\tVideo bitrate sent (Kbit/s): "
1600 << video_bitrate_sent << std::endl;
1601 std::cout << "\tFEC bitrate sent (Kbit/s): "
1602 << fec_bitrate_sent << std::endl;
1603 percentage_fec =
1604 (static_cast<double>(fec_bitrate_sent) /
1605 static_cast<double>(total_bitrate_sent)) * 100;
1606 std::cout << "\tPercentage FEC bitrate sent from total bitrate: "
1607 << percentage_fec << std::endl;
1608 std::cout << "\tNACK bitrate sent (Kbit/s): "
1609 << nack_bitrate_sent << std::endl;
1610 percentage_nack =
1611 (static_cast<double>(nack_bitrate_sent) /
1612 static_cast<double>(total_bitrate_sent)) * 100;
1613 std::cout << "\tPercentage NACK bitrate sent from total bitrate: "
1614 << percentage_nack << std::endl;
1615}
1616
1617void PrintCodecStatistics(webrtc::ViECodec* vie_codec,
1618 int video_channel,
1619 StatisticsType stat_type) {
1620 int error = 0;
1621 int number_of_errors = 0;
1622 unsigned int key_frames = 0;
1623 unsigned int delta_frames = 0;
1624 switch (stat_type) {
1625 case kReceivedStatistic:
1626 std::cout << "Codec Receive statistics"
1627 << std::endl;
1628 // Get and print the Receive Codec Statistics
1629 error = vie_codec->GetReceiveCodecStastistics(video_channel, key_frames,
1630 delta_frames);
1631 number_of_errors += ViETest::TestError(error == 0,
1632 "ERROR: %s at line %d",
1633 __FUNCTION__, __LINE__);
1634 break;
1635 case kSendStatistic:
1636 std::cout << "Codec Send statistics"
1637 << std::endl;
1638 // Get and print the Send Codec Statistics
1639 error = vie_codec->GetSendCodecStastistics(video_channel, key_frames,
1640 delta_frames);
1641 number_of_errors += ViETest::TestError(error == 0,
1642 "ERROR: %s at line %d",
1643 __FUNCTION__, __LINE__);
1644 break;
1645 }
1646 std::cout << "\tNumber of encoded key frames: "
1647 << key_frames << std::endl;
1648 std::cout << "\tNumber of encoded delta frames: "
1649 << delta_frames << std::endl;
1650}
1651
1652void PrintGetDiscardedPackets(webrtc::ViECodec* vie_codec, int video_channel) {
1653 std::cout << "Discarded Packets" << std::endl;
1654 int discarded_packets = 0;
1655 discarded_packets = vie_codec->GetDiscardedPackets(video_channel);
1656 std::cout << "\tNumber of discarded packets: "
1657 << discarded_packets << std::endl;
1658}
1659
1660void PrintVideoStreamInformation(webrtc::ViECodec* vie_codec,
1661 int video_channel) {
1662 webrtc::VideoCodec outgoing_codec;
1663 webrtc::VideoCodec incoming_codec;
1664
1665 memset(&outgoing_codec, 0, sizeof(webrtc::VideoCodec));
1666 memset(&incoming_codec, 0, sizeof(webrtc::VideoCodec));
1667
1668 vie_codec->GetSendCodec(video_channel, outgoing_codec);
1669 vie_codec->GetReceiveCodec(video_channel, incoming_codec);
1670
1671 std::cout << "************************************************"
1672 << std::endl;
1673 std::cout << "ChannelId: " << video_channel << std::endl;
1674 std::cout << "Outgoing Stream information:" << std::endl;
1675 PrintVideoCodec(outgoing_codec);
1676 std::cout << "Incoming Stream information:" << std::endl;
1677 PrintVideoCodec(incoming_codec);
1678 std::cout << "************************************************"
1679 << std::endl;
1680}
1681
1682void PrintVideoCodec(webrtc::VideoCodec video_codec) {
1683 std::cout << "\t\tplName: " << video_codec.plName << std::endl;
1684 std::cout << "\t\tplType: " << static_cast<int>(video_codec.plType)
1685 << std::endl;
1686 std::cout << "\t\twidth: " << video_codec.width << std::endl;
1687 std::cout << "\t\theight: " << video_codec.height << std::endl;
1688 std::cout << "\t\tstartBitrate: " << video_codec.startBitrate
1689 << std::endl;
1690 std::cout << "\t\tminBitrate: " << video_codec.minBitrate
1691 << std::endl;
1692 std::cout << "\t\tmaxBitrate: " << video_codec.maxBitrate
1693 << std::endl;
1694 std::cout << "\t\tmaxFramerate: "
1695 << static_cast<int>(video_codec.maxFramerate) << std::endl;
1696 if (video_codec.codecType == webrtc::kVideoCodecVP8) {
1697 int number_of_layers =
1698 static_cast<int>(video_codec.codecSpecific.VP8.numberOfTemporalLayers);
1699 std::cout << "\t\tVP8 Temporal Layer: " << number_of_layers << std::endl;
1700 }
1701}