Home | History | Annotate | Download | only in source
      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 //
     12 // vie_autotest_record.cc
     13 //
     14 // This code is also used as sample code for ViE 3.0
     15 //
     16 
     17 #include <fstream>
     18 #include <stdio.h>
     19 
     20 #include "webrtc/common_types.h"
     21 #include "webrtc/system_wrappers/interface/tick_util.h"
     22 #include "webrtc/test/channel_transport/include/channel_transport.h"
     23 #include "webrtc/video_engine/include/vie_base.h"
     24 #include "webrtc/video_engine/include/vie_capture.h"
     25 #include "webrtc/video_engine/include/vie_codec.h"
     26 #include "webrtc/video_engine/include/vie_network.h"
     27 #include "webrtc/video_engine/include/vie_render.h"
     28 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
     29 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
     30 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
     31 #include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h"
     32 #include "webrtc/voice_engine/include/voe_base.h"
     33 #include "webrtc/voice_engine/include/voe_network.h"
     34 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
     35 
     36 #define VCM_RED_PAYLOAD_TYPE            96
     37 #define VCM_ULPFEC_PAYLOAD_TYPE         97
     38 #define DEFAULT_AUDIO_PORT              11113
     39 #define DEFAULT_AUDIO_CODEC             "ISAC"
     40 #define DEFAULT_VIDEO_CODEC_WIDTH       640
     41 #define DEFAULT_VIDEO_CODEC_HEIGHT      480
     42 #define DEFAULT_VIDEO_CODEC_START_RATE  1000
     43 #define DEFAULT_RECORDING_FOLDER        "RECORDING"
     44 #define DEFAULT_RECORDING_AUDIO         "/audio_debug.aec"
     45 #define DEFAULT_RECORDING_VIDEO         "/video_debug.yuv"
     46 #define DEFAULT_RECORDING_AUDIO_RTP     "/audio_rtpdump.rtp"
     47 #define DEFAULT_RECORDING_VIDEO_RTP     "/video_rtpdump.rtp"
     48 
     49 bool GetAudioDevices(webrtc::VoEBase* voe_base,
     50                      webrtc::VoEHardware* voe_hardware,
     51                      char* recording_device_name,
     52                      int& recording_device_index,
     53                      char* playbackDeviceName,
     54                      int& playback_device_index);
     55 bool GetAudioCodecRecord(webrtc::VoECodec* voe_codec,
     56                          webrtc::CodecInst& audio_codec);
     57 
     58 int VideoEngineSampleRecordCode(void* window1, void* window2) {
     59   int error = 0;
     60   // Audio settings.
     61   int audio_tx_port = DEFAULT_AUDIO_PORT;
     62   int audio_rx_port = DEFAULT_AUDIO_PORT;
     63   webrtc::CodecInst audio_codec;
     64   int audio_channel = -1;
     65   int audio_capture_device_index = -1;
     66   int audio_playback_device_index = -1;
     67   const unsigned int KMaxDeviceNameLength = 128;
     68   const unsigned int KMaxUniqueIdLength = 256;
     69   char deviceName[KMaxDeviceNameLength];
     70   char audio_capture_device_name[KMaxUniqueIdLength] = "";
     71   char audio_playbackDeviceName[KMaxUniqueIdLength] = "";
     72 
     73   // Network settings.
     74   const char* ipAddress = "127.0.0.1";
     75   const int rtpPort = 6000;
     76 
     77   //
     78   // Create a VideoEngine instance
     79   //
     80   webrtc::VideoEngine* ptrViE = NULL;
     81   ptrViE = webrtc::VideoEngine::Create();
     82   if (ptrViE == NULL) {
     83     printf("ERROR in VideoEngine::Create\n");
     84     return -1;
     85   }
     86 
     87   error = ptrViE->SetTraceFilter(webrtc::kTraceAll);
     88   if (error == -1) {
     89     printf("ERROR in VideoEngine::SetTraceLevel\n");
     90     return -1;
     91   }
     92 
     93   std::string trace_file =
     94     ViETest::GetResultOutputPath() + "ViERecordCall_trace.txt";
     95   error = ptrViE->SetTraceFile(trace_file.c_str());
     96   if (error == -1) {
     97     printf("ERROR in VideoEngine::SetTraceFile\n");
     98     return -1;
     99   }
    100 
    101   //
    102   // Create a VoE instance
    103   //
    104   webrtc::VoiceEngine* voe = webrtc::VoiceEngine::Create();
    105   //
    106   // Init VideoEngine and create a channel
    107   //
    108   webrtc::ViEBase* ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE);
    109   if (ptrViEBase == NULL) {
    110     printf("ERROR in ViEBase::GetInterface\n");
    111     return -1;
    112   }
    113 
    114   error = ptrViEBase->Init();
    115   if (error == -1) {
    116     printf("ERROR in ViEBase::Init\n");
    117     return -1;
    118   }
    119 
    120   webrtc::VoEBase* voe_base = webrtc::VoEBase::GetInterface(voe);
    121   if (voe_base == NULL) {
    122     printf("ERROR in VoEBase::GetInterface\n");
    123     return -1;
    124   }
    125   error = voe_base->Init();
    126   if (error == -1) {
    127     printf("ERROR in VoEBase::Init\n");
    128     return -1;
    129   }
    130 
    131   int videoChannel = -1;
    132   error = ptrViEBase->CreateChannel(videoChannel);
    133   if (error == -1) {
    134     printf("ERROR in ViEBase::CreateChannel\n");
    135     return -1;
    136   }
    137 
    138   webrtc::VoEHardware* voe_hardware =
    139     webrtc::VoEHardware::GetInterface(voe);
    140   webrtc::VoECodec* voe_codec = webrtc::VoECodec::GetInterface(voe);
    141   webrtc::VoEAudioProcessing* voe_apm =
    142        webrtc::VoEAudioProcessing::GetInterface(voe);
    143   webrtc::VoENetwork* voe_network =
    144     webrtc::VoENetwork::GetInterface(voe);
    145 
    146   // Get the audio device for the call.
    147   memset(audio_capture_device_name, 0, KMaxUniqueIdLength);
    148   memset(audio_playbackDeviceName, 0, KMaxUniqueIdLength);
    149   GetAudioDevices(voe_base, voe_hardware, audio_capture_device_name,
    150                   audio_capture_device_index, audio_playbackDeviceName,
    151                   audio_playback_device_index);
    152 
    153   // Get the audio codec for the call.
    154   memset(static_cast<void*>(&audio_codec), 0, sizeof(audio_codec));
    155   GetAudioCodecRecord(voe_codec, audio_codec);
    156 
    157   audio_channel = voe_base->CreateChannel();
    158 
    159   webrtc::scoped_ptr<webrtc::test::VoiceChannelTransport>
    160       voice_channel_transport(
    161           new webrtc::test::VoiceChannelTransport(voe_network, audio_channel));
    162 
    163   voice_channel_transport->SetSendDestination(ipAddress, audio_tx_port);
    164   voice_channel_transport->SetLocalReceiver(audio_rx_port);
    165 
    166   voe_hardware->SetRecordingDevice(audio_capture_device_index);
    167   voe_hardware->SetPlayoutDevice(audio_playback_device_index);
    168   voe_codec->SetSendCodec(audio_channel, audio_codec);
    169   voe_apm->SetAgcStatus(true, webrtc::kAgcDefault);
    170   voe_apm->SetNsStatus(true, webrtc::kNsHighSuppression);
    171 
    172   //
    173   // List available capture devices, allocate and connect.
    174   //
    175   webrtc::ViECapture* ptrViECapture =
    176       webrtc::ViECapture::GetInterface(ptrViE);
    177   if (ptrViECapture == NULL) {
    178     printf("ERROR in ViECapture::GetInterface\n");
    179     return -1;
    180   }
    181 
    182   webrtc::VoERTP_RTCP* ptrVoERtpRtcp =
    183     webrtc::VoERTP_RTCP::GetInterface(voe);
    184   if (ptrVoERtpRtcp == NULL) {
    185     printf("ERROR in VoERTP_RTCP::GetInterface\n");
    186     return -1;
    187   }
    188 
    189   memset(deviceName, 0, KMaxDeviceNameLength);
    190   char uniqueId[KMaxUniqueIdLength];
    191   memset(uniqueId, 0, KMaxUniqueIdLength);
    192 
    193   printf("Available capture devices:\n");
    194   int captureIdx = 0;
    195   for (captureIdx = 0;
    196        captureIdx < ptrViECapture->NumberOfCaptureDevices();
    197        captureIdx++) {
    198     memset(deviceName, 0, KMaxDeviceNameLength);
    199     memset(uniqueId, 0, KMaxUniqueIdLength);
    200 
    201     error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
    202                                             KMaxDeviceNameLength, uniqueId,
    203                                             KMaxUniqueIdLength);
    204     if (error == -1) {
    205       printf("ERROR in ViECapture::GetCaptureDevice\n");
    206       return -1;
    207     }
    208     printf("\t %d. %s\n", captureIdx + 1, deviceName);
    209   }
    210   printf("\nChoose capture device: ");
    211 #ifdef WEBRTC_ANDROID
    212   captureIdx = 0;
    213   printf("0\n");
    214 #else
    215   if (scanf("%d", &captureIdx) != 1) {
    216     printf("Error in scanf()\n");
    217     return -1;
    218   }
    219   getchar();
    220   captureIdx = captureIdx - 1;  // Compensate for idx start at 1.
    221 #endif
    222   error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
    223                                           KMaxDeviceNameLength, uniqueId,
    224                                           KMaxUniqueIdLength);
    225   if (error == -1) {
    226     printf("ERROR in ViECapture::GetCaptureDevice\n");
    227     return -1;
    228   }
    229 
    230   int captureId = 0;
    231   error = ptrViECapture->AllocateCaptureDevice(uniqueId, KMaxUniqueIdLength,
    232                                                captureId);
    233   if (error == -1) {
    234     printf("ERROR in ViECapture::AllocateCaptureDevice\n");
    235     return -1;
    236   }
    237 
    238   error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel);
    239   if (error == -1) {
    240     printf("ERROR in ViECapture::ConnectCaptureDevice\n");
    241     return -1;
    242   }
    243 
    244   error = ptrViECapture->StartCapture(captureId);
    245   if (error == -1) {
    246     printf("ERROR in ViECapture::StartCapture\n");
    247     return -1;
    248   }
    249 
    250   //
    251   // RTP/RTCP settings
    252   //
    253   webrtc::ViERTP_RTCP* ptrViERtpRtcp =
    254       webrtc::ViERTP_RTCP::GetInterface(ptrViE);
    255   if (ptrViERtpRtcp == NULL) {
    256     printf("ERROR in ViERTP_RTCP::GetInterface\n");
    257     return -1;
    258   }
    259 
    260   error = ptrViERtpRtcp->SetRTCPStatus(videoChannel,
    261                                        webrtc::kRtcpCompound_RFC4585);
    262   if (error == -1) {
    263     printf("ERROR in ViERTP_RTCP::SetRTCPStatus\n");
    264     return -1;
    265   }
    266 
    267   error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
    268       videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
    269   if (error == -1) {
    270     printf("ERROR in ViERTP_RTCP::SetKeyFrameRequestMethod\n");
    271     return -1;
    272   }
    273 
    274   error = ptrViERtpRtcp->SetRembStatus(videoChannel, true, true);
    275   if (error == -1) {
    276     printf("ERROR in ViERTP_RTCP::SetTMMBRStatus\n");
    277     return -1;
    278   }
    279 
    280   //
    281   // Set up rendering
    282   //
    283   webrtc::ViERender* ptrViERender = webrtc::ViERender::GetInterface(ptrViE);
    284   if (ptrViERender == NULL) {
    285     printf("ERROR in ViERender::GetInterface\n");
    286     return -1;
    287   }
    288 
    289   error = ptrViERender->AddRenderer(captureId, window1, 0, 0.0, 0.0, 1.0, 1.0);
    290   if (error == -1) {
    291     printf("ERROR in ViERender::AddRenderer\n");
    292     return -1;
    293   }
    294 
    295   error = ptrViERender->StartRender(captureId);
    296   if (error == -1) {
    297     printf("ERROR in ViERender::StartRender\n");
    298     return -1;
    299   }
    300 
    301   error = ptrViERender->AddRenderer(videoChannel, window2, 1, 0.0, 0.0, 1.0,
    302                                     1.0);
    303   if (error == -1) {
    304     printf("ERROR in ViERender::AddRenderer\n");
    305     return -1;
    306   }
    307 
    308   error = ptrViERender->StartRender(videoChannel);
    309   if (error == -1) {
    310     printf("ERROR in ViERender::StartRender\n");
    311     return -1;
    312   }
    313 
    314   //
    315   // Setup codecs
    316   //
    317   webrtc::ViECodec* ptrViECodec = webrtc::ViECodec::GetInterface(ptrViE);
    318   if (ptrViECodec == NULL) {
    319     printf("ERROR in ViECodec::GetInterface\n");
    320     return -1;
    321   }
    322 
    323   webrtc::VideoCodec videoCodec;
    324   memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
    325   int codecIdx = 0;
    326 
    327 #ifdef WEBRTC_ANDROID
    328   codecIdx = 0;
    329   printf("0\n");
    330 #else
    331   codecIdx = 0;  // Compensate for idx start at 1.
    332 #endif
    333 
    334   error = ptrViECodec->GetCodec(codecIdx, videoCodec);
    335   if (error == -1) {
    336      printf("ERROR in ViECodec::GetCodec\n");
    337      return -1;
    338   }
    339 
    340   // Set spatial resolution option
    341   videoCodec.width = DEFAULT_VIDEO_CODEC_WIDTH;
    342   videoCodec.height = DEFAULT_VIDEO_CODEC_HEIGHT;
    343 
    344   // Set start bit rate
    345   videoCodec.startBitrate = DEFAULT_VIDEO_CODEC_START_RATE;
    346 
    347   error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
    348   if (error == -1) {
    349     printf("ERROR in ViECodec::SetSendCodec\n");
    350     return -1;
    351   }
    352 
    353   //
    354   // Address settings
    355   //
    356   webrtc::ViENetwork* ptrViENetwork =
    357       webrtc::ViENetwork::GetInterface(ptrViE);
    358   if (ptrViENetwork == NULL) {
    359     printf("ERROR in ViENetwork::GetInterface\n");
    360     return -1;
    361   }
    362   webrtc::test::VideoChannelTransport* video_channel_transport =
    363       new webrtc::test::VideoChannelTransport(ptrViENetwork, videoChannel);
    364 
    365   error = video_channel_transport->SetSendDestination(ipAddress, rtpPort);
    366   if (error == -1) {
    367     printf("ERROR in SetSendDestination\n");
    368     return -1;
    369   }
    370   error = video_channel_transport->SetLocalReceiver(rtpPort);
    371   if (error == -1) {
    372     printf("ERROR in SetLocalReceiver\n");
    373     return -1;
    374   }
    375 
    376   std::string str;
    377   int enable_labeling = 0;
    378   std::cout << std::endl;
    379   std::cout << "Do you want to label this recording?" << std::endl;
    380   std::cout << "0. No (default)." << std::endl;
    381   std::cout << "1. This call will be labeled on the fly." << std::endl;
    382   std::getline(std::cin, str);
    383   enable_labeling = atoi(str.c_str());
    384 
    385   uint32_t folder_time = static_cast<uint32_t>
    386     (webrtc::TickTime::MillisecondTimestamp());
    387   std::stringstream folder_time_str;
    388   folder_time_str <<  folder_time;
    389   const std::string folder_name = "recording" + folder_time_str.str();
    390   printf("recording name = %s\n", folder_name.c_str());
    391   // TODO(mikhal): use file_utils.
    392 #ifdef WIN32
    393   _mkdir(folder_name.c_str());
    394 #else
    395   mkdir(folder_name.c_str(), 0777);
    396 #endif
    397   const std::string audio_filename =  folder_name + DEFAULT_RECORDING_AUDIO;
    398   const std::string video_filename =  folder_name + DEFAULT_RECORDING_VIDEO;
    399   const std::string audio_rtp_filename = folder_name +
    400     DEFAULT_RECORDING_AUDIO_RTP;
    401   const std::string video_rtp_filename = folder_name +
    402     DEFAULT_RECORDING_VIDEO_RTP;
    403   std::fstream timing;
    404   if (enable_labeling == 1) {
    405     std::cout << "Press enter to stamp current time."<< std::endl;
    406     std::string timing_file = folder_name + "/labeling.txt";
    407     timing.open(timing_file.c_str(), std::fstream::out | std::fstream::app);
    408   }
    409   printf("\nPress enter to start recording\n");
    410   std::getline(std::cin, str);
    411   printf("\nRecording started\n\n");
    412 
    413   error = ptrViEBase->StartReceive(videoChannel);
    414   if (error == -1) {
    415     printf("ERROR in ViENetwork::StartReceive\n");
    416     return -1;
    417   }
    418 
    419   error = ptrViEBase->StartSend(videoChannel);
    420   if (error == -1) {
    421     printf("ERROR in ViENetwork::StartSend\n");
    422     return -1;
    423   }
    424   error = voe_base->StartSend(audio_channel);
    425   if (error == -1) {
    426     printf("ERROR in VoENetwork::StartSend\n");
    427     return -1;
    428   }
    429 
    430   //  Engine started
    431 
    432   voe_apm->StartDebugRecording(audio_filename.c_str());
    433   ptrViECodec->StartDebugRecording(videoChannel, video_filename.c_str());
    434   ptrViERtpRtcp->StartRTPDump(videoChannel,
    435                               video_rtp_filename.c_str(), webrtc::kRtpOutgoing);
    436   ptrVoERtpRtcp->StartRTPDump(audio_channel,
    437                               audio_rtp_filename.c_str(), webrtc::kRtpOutgoing);
    438   printf("Press s + enter to stop...");
    439   int64_t clock_time;
    440   if (enable_labeling == 1) {
    441     clock_time = webrtc::TickTime::MillisecondTimestamp();
    442     timing << clock_time << std::endl;
    443   }
    444   char c = getchar();
    445   fflush(stdin);
    446   while (c != 's') {
    447     if (c == '\n' && enable_labeling == 1) {
    448       clock_time = webrtc::TickTime::MillisecondTimestamp();
    449       timing << clock_time << std::endl;
    450     }
    451     c = getchar();
    452   }
    453   if (enable_labeling == 1) {
    454     clock_time = webrtc::TickTime::MillisecondTimestamp();
    455     timing << clock_time << std::endl;
    456   }
    457 
    458   ptrViERtpRtcp->StopRTPDump(videoChannel, webrtc::kRtpOutgoing);
    459   ptrVoERtpRtcp->StopRTPDump(audio_channel, webrtc::kRtpOutgoing);
    460   voe_apm->StopDebugRecording();
    461   ptrViECodec->StopDebugRecording(videoChannel);
    462   if (enable_labeling == 1)
    463     timing.close();
    464 
    465   //  Recording finished. Tear down Video Engine.
    466 
    467   error = ptrViEBase->StopReceive(videoChannel);
    468   if (error == -1) {
    469     printf("ERROR in ViEBase::StopReceive\n");
    470     return -1;
    471   }
    472 
    473   error = ptrViEBase->StopSend(videoChannel);
    474   if (error == -1) {
    475     printf("ERROR in ViEBase::StopSend\n");
    476     return -1;
    477   }
    478   error = voe_base->StopSend(audio_channel);
    479 
    480   error = ptrViERender->StopRender(captureId);
    481   if (error == -1) {
    482     printf("ERROR in ViERender::StopRender\n");
    483     return -1;
    484   }
    485 
    486   error = ptrViERender->RemoveRenderer(captureId);
    487   if (error == -1) {
    488     printf("ERROR in ViERender::RemoveRenderer\n");
    489     return -1;
    490   }
    491 
    492   error = ptrViERender->StopRender(videoChannel);
    493   if (error == -1) {
    494     printf("ERROR in ViERender::StopRender\n");
    495     return -1;
    496   }
    497 
    498   error = ptrViERender->RemoveRenderer(videoChannel);
    499   if (error == -1) {
    500     printf("ERROR in ViERender::RemoveRenderer\n");
    501     return -1;
    502   }
    503 
    504   error = ptrViECapture->StopCapture(captureId);
    505   if (error == -1) {
    506     printf("ERROR in ViECapture::StopCapture\n");
    507     return -1;
    508   }
    509 
    510   error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
    511   if (error == -1) {
    512     printf("ERROR in ViECapture::DisconnectCaptureDevice\n");
    513     return -1;
    514   }
    515 
    516   error = ptrViECapture->ReleaseCaptureDevice(captureId);
    517   if (error == -1) {
    518     printf("ERROR in ViECapture::ReleaseCaptureDevice\n");
    519     return -1;
    520   }
    521 
    522   error = ptrViEBase->DeleteChannel(videoChannel);
    523   if (error == -1) {
    524     printf("ERROR in ViEBase::DeleteChannel\n");
    525     return -1;
    526   }
    527   delete video_channel_transport;
    528 
    529   int remainingInterfaces = 0;
    530   remainingInterfaces = ptrViECodec->Release();
    531   remainingInterfaces += ptrViECapture->Release();
    532   remainingInterfaces += ptrViERtpRtcp->Release();
    533   remainingInterfaces += ptrViERender->Release();
    534   remainingInterfaces += ptrViENetwork->Release();
    535   remainingInterfaces += ptrViEBase->Release();
    536   if (remainingInterfaces > 0) {
    537     printf("ERROR: Could not release all interfaces\n");
    538     return -1;
    539   }
    540   bool deleted = webrtc::VideoEngine::Delete(ptrViE);
    541   if (deleted == false) {
    542     printf("ERROR in VideoEngine::Delete\n");
    543     return -1;
    544   }
    545   return 0;
    546 }
    547 
    548 
    549 // TODO(mikhal): Place above functionality under this class.
    550 int ViEAutoTest::ViERecordCall() {
    551   ViETest::Log(" ");
    552   ViETest::Log("========================================");
    553   ViETest::Log(" ViE Record Call\n");
    554 
    555   if (VideoEngineSampleRecordCode(_window1, _window2) == 0) {
    556     ViETest::Log(" ");
    557     ViETest::Log(" ViE Autotest Record Call Done");
    558     ViETest::Log("========================================");
    559     ViETest::Log(" ");
    560     return 0;
    561   }
    562 
    563   ViETest::Log(" ");
    564   ViETest::Log(" ViE Autotest Record Call Failed");
    565   ViETest::Log("========================================");
    566   ViETest::Log(" ");
    567   return 1;
    568 }
    569 
    570 bool GetAudioCodecRecord(webrtc::VoECodec* voe_codec,
    571                          webrtc::CodecInst& audio_codec) {
    572   int error = 0;
    573   int number_of_errors = 0;
    574   memset(&audio_codec, 0, sizeof(webrtc::CodecInst));
    575 
    576   while (1) {
    577     int codec_idx = 0;
    578     int default_codec_idx = 0;
    579     for (codec_idx = 0; codec_idx < voe_codec->NumOfCodecs(); codec_idx++) {
    580       error = voe_codec->GetCodec(codec_idx, audio_codec);
    581       number_of_errors += ViETest::TestError(error == 0,
    582                                              "ERROR: %s at line %d",
    583                                              __FUNCTION__, __LINE__);
    584 
    585       // Test for default codec index.
    586       if (strcmp(audio_codec.plname, DEFAULT_AUDIO_CODEC) == 0) {
    587         default_codec_idx = codec_idx;
    588       }
    589     }
    590     error = voe_codec->GetCodec(default_codec_idx, audio_codec);
    591     number_of_errors += ViETest::TestError(error == 0,
    592                                            "ERROR: %s at line %d",
    593                                            __FUNCTION__, __LINE__);
    594     return true;
    595   }
    596   assert(false);
    597   return false;
    598 }
    599