PageRenderTime 123ms CodeModel.GetById 3ms app.highlight 109ms RepoModel.GetById 1ms app.codeStats 0ms

/webrtc/video_engine/test/auto_test/source/vie_autotest_custom_call.cc

https://bitbucket.org/bohlooli/webrtc
C++ | 1729 lines | 1476 code | 182 blank | 71 comment | 184 complexity | 6cf6978a8687dc3d1c1498530e41cd78 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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_uniqu

Large files files are truncated, but you can click here to view the full file