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