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 #include "webrtc/common_types.h"
     12 #include "webrtc/engine_configurations.h"
     13 #include "webrtc/modules/video_coding/codecs/i420/main/interface/i420.h"
     14 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     15 #include "webrtc/test/channel_transport/include/channel_transport.h"
     16 #include "webrtc/video_engine/include/vie_base.h"
     17 #include "webrtc/video_engine/include/vie_capture.h"
     18 #include "webrtc/video_engine/include/vie_codec.h"
     19 #include "webrtc/video_engine/include/vie_external_codec.h"
     20 #include "webrtc/video_engine/include/vie_network.h"
     21 #include "webrtc/video_engine/include/vie_render.h"
     22 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
     23 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
     24 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
     25 #include "webrtc/video_engine/test/libvietest/include/tb_I420_codec.h"
     26 #include "webrtc/video_engine/test/libvietest/include/tb_capture_device.h"
     27 #include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
     28 #include "webrtc/video_engine/test/libvietest/include/tb_video_channel.h"
     29 #include "webrtc/voice_engine/include/voe_base.h"
     30 
     31 class TestCodecObserver : public webrtc::ViEEncoderObserver,
     32                           public webrtc::ViEDecoderObserver {
     33  public:
     34   int incoming_codec_called_;
     35   int incoming_rate_called_;
     36   int decoder_timing_called_;
     37   int outgoing_rate_called_;
     38 
     39   unsigned char last_payload_type_;
     40   uint16_t last_width_;
     41   uint16_t last_height_;
     42 
     43   unsigned int last_outgoing_framerate_;
     44   unsigned int last_outgoing_bitrate_;
     45   unsigned int last_incoming_framerate_;
     46   unsigned int last_incoming_bitrate_;
     47   unsigned int suspend_change_called_;
     48 
     49   webrtc::VideoCodec incoming_codec_;
     50 
     51   TestCodecObserver()
     52       : incoming_codec_called_(0),
     53         incoming_rate_called_(0),
     54         decoder_timing_called_(0),
     55         outgoing_rate_called_(0),
     56         last_payload_type_(0),
     57         last_width_(0),
     58         last_height_(0),
     59         last_outgoing_framerate_(0),
     60         last_outgoing_bitrate_(0),
     61         last_incoming_framerate_(0),
     62         last_incoming_bitrate_(0),
     63         suspend_change_called_(0) {
     64     memset(&incoming_codec_, 0, sizeof(incoming_codec_));
     65   }
     66   virtual void IncomingCodecChanged(const int video_channel,
     67                                     const webrtc::VideoCodec& video_codec) {
     68     incoming_codec_called_++;
     69     last_payload_type_ = video_codec.plType;
     70     last_width_ = video_codec.width;
     71     last_height_ = video_codec.height;
     72 
     73     memcpy(&incoming_codec_, &video_codec, sizeof(video_codec));
     74   }
     75 
     76   virtual void IncomingRate(const int video_channel,
     77                             const unsigned int framerate,
     78                             const unsigned int bitrate) {
     79     incoming_rate_called_++;
     80     last_incoming_framerate_ += framerate;
     81     last_incoming_bitrate_ += bitrate;
     82   }
     83 
     84   virtual void DecoderTiming(int decode_ms,
     85                              int max_decode_ms,
     86                              int current_delay_ms,
     87                              int target_delay_ms,
     88                              int jitter_buffer_ms,
     89                              int min_playout_delay_ms,
     90                              int render_delay_ms) {
     91     ++decoder_timing_called_;
     92     // TODO(fischman): anything useful to be done with the data here?
     93   }
     94 
     95   virtual void OutgoingRate(const int video_channel,
     96                             const unsigned int framerate,
     97                             const unsigned int bitrate) {
     98     outgoing_rate_called_++;
     99     last_outgoing_framerate_ += framerate;
    100     last_outgoing_bitrate_ += bitrate;
    101   }
    102 
    103   virtual void SuspendChange(int video_channel, bool is_suspended) OVERRIDE {
    104     suspend_change_called_++;
    105   }
    106 
    107   virtual void RequestNewKeyFrame(const int video_channel) {
    108   }
    109 };
    110 
    111 class RenderFilter : public webrtc::ViEEffectFilter {
    112  public:
    113   int num_frames_;
    114   unsigned int last_render_width_;
    115   unsigned int last_render_height_;
    116 
    117   RenderFilter()
    118       : num_frames_(0),
    119         last_render_width_(0),
    120         last_render_height_(0) {
    121   }
    122 
    123   virtual ~RenderFilter() {
    124   }
    125   virtual int Transform(int size,
    126                         unsigned char* frame_buffer,
    127                         int64_t ntp_time_ms,
    128                         unsigned int timestamp,
    129                         unsigned int width,
    130                         unsigned int height)  {
    131     num_frames_++;
    132     last_render_width_ = width;
    133     last_render_height_ = height;
    134     return 0;
    135   }
    136 };
    137 
    138 void ViEAutoTest::ViECodecStandardTest() {
    139   TbInterfaces interfaces("ViECodecStandardTest");
    140 
    141   TbCaptureDevice capture_device = TbCaptureDevice(interfaces);
    142   int capture_id = capture_device.captureId;
    143 
    144   webrtc::VideoEngine* video_engine = interfaces.video_engine;
    145   webrtc::ViEBase* base = interfaces.base;
    146   webrtc::ViECapture* capture = interfaces.capture;
    147   webrtc::ViERender* render = interfaces.render;
    148   webrtc::ViECodec* codec = interfaces.codec;
    149   webrtc::ViERTP_RTCP* rtp_rtcp = interfaces.rtp_rtcp;
    150   webrtc::ViENetwork* network = interfaces.network;
    151 
    152   int video_channel = -1;
    153   EXPECT_EQ(0, base->CreateChannel(video_channel));
    154   EXPECT_EQ(0, capture->ConnectCaptureDevice(capture_id, video_channel));
    155   EXPECT_EQ(0, rtp_rtcp->SetRTCPStatus(
    156       video_channel, webrtc::kRtcpCompound_RFC4585));
    157 
    158   EXPECT_EQ(0, rtp_rtcp->SetKeyFrameRequestMethod(
    159       video_channel, webrtc::kViEKeyFrameRequestPliRtcp));
    160   EXPECT_EQ(0, rtp_rtcp->SetTMMBRStatus(video_channel, true));
    161   EXPECT_EQ(0, render->AddRenderer(capture_id, _window1, 0, 0.0, 0.0, 1.0,
    162                                    1.0));
    163   EXPECT_EQ(0, render->AddRenderer(video_channel, _window2, 1, 0.0, 0.0, 1.0,
    164                                    1.0));
    165   EXPECT_EQ(0, render->StartRender(capture_id));
    166   EXPECT_EQ(0, render->StartRender(video_channel));
    167 
    168   webrtc::VideoCodec video_codec;
    169   memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
    170   for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) {
    171     EXPECT_EQ(0, codec->GetCodec(idx, video_codec));
    172     if (video_codec.codecType != webrtc::kVideoCodecI420) {
    173       video_codec.width = 640;
    174       video_codec.height = 480;
    175     }
    176     if (video_codec.codecType == webrtc::kVideoCodecI420) {
    177       video_codec.width = 176;
    178       video_codec.height = 144;
    179     }
    180     EXPECT_EQ(0, codec->SetReceiveCodec(video_channel, video_codec));
    181   }
    182 
    183   for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) {
    184     EXPECT_EQ(0, codec->GetCodec(idx, video_codec));
    185     if (video_codec.codecType == webrtc::kVideoCodecVP8) {
    186       EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    187       break;
    188     }
    189   }
    190   const char* ip_address = "127.0.0.1";
    191   const uint16_t rtp_port = 6000;
    192 
    193   webrtc::scoped_ptr<webrtc::test::VideoChannelTransport>
    194       video_channel_transport(
    195           new webrtc::test::VideoChannelTransport(network, video_channel));
    196 
    197   ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address,
    198                                                            rtp_port));
    199   ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port));
    200 
    201   EXPECT_EQ(0, base->StartReceive(video_channel));
    202   EXPECT_EQ(0, base->StartSend(video_channel));
    203 
    204   // Make sure all codecs runs
    205   {
    206     webrtc::ViEImageProcess* image_process =
    207         webrtc::ViEImageProcess::GetInterface(video_engine);
    208     TestCodecObserver codec_observer;
    209     EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer));
    210     ViETest::Log("Loop through all codecs for %d seconds",
    211                  kAutoTestSleepTimeMs / 1000);
    212 
    213     for (int i = 0; i < codec->NumberOfCodecs() - 2; i++) {
    214       EXPECT_EQ(0, codec->GetCodec(i, video_codec));
    215       if (video_codec.codecType == webrtc::kVideoCodecI420) {
    216         // Lower resolution to sockets keep up.
    217         video_codec.width = 176;
    218         video_codec.height = 144;
    219         video_codec.maxFramerate = 15;
    220       }
    221       EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    222       ViETest::Log("\t %d. %s", i, video_codec.plName);
    223 
    224       RenderFilter frame_counter;
    225       EXPECT_EQ(0, image_process->RegisterRenderEffectFilter(video_channel,
    226                                                              frame_counter));
    227       AutoTestSleep(kAutoTestSleepTimeMs);
    228 
    229       // Verify we've received and decoded correct payload.
    230       EXPECT_EQ(video_codec.codecType,
    231                 codec_observer.incoming_codec_.codecType);
    232 
    233       // This requirement is quite relaxed, but it's hard to say what's an
    234       // acceptable number of received frames when we take into account the
    235       // wide variety of devices (and that we run under valgrind).
    236       EXPECT_GT(frame_counter.num_frames_, 0);
    237 
    238       EXPECT_EQ(0, image_process->DeregisterRenderEffectFilter(
    239           video_channel));
    240     }
    241     image_process->Release();
    242     EXPECT_EQ(0, codec->DeregisterDecoderObserver(video_channel));
    243     ViETest::Log("Done!");
    244   }
    245 
    246   // Test Callbacks
    247   TestCodecObserver codec_observer;
    248   EXPECT_EQ(0, codec->RegisterEncoderObserver(video_channel, codec_observer));
    249   EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer));
    250 
    251   ViETest::Log("\nTesting codec callbacks...");
    252 
    253   for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) {
    254     EXPECT_EQ(0, codec->GetCodec(idx, video_codec));
    255     if (video_codec.codecType == webrtc::kVideoCodecVP8) {
    256       EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    257       break;
    258     }
    259   }
    260   AutoTestSleep(kAutoTestSleepTimeMs);
    261 
    262   // Verify the delay estimates are larger than 0.
    263   int avg_send_delay = 0;
    264   int max_send_delay = 0;
    265   EXPECT_TRUE(codec->GetSendSideDelay(video_channel, &avg_send_delay,
    266                                       &max_send_delay));
    267   EXPECT_GT(avg_send_delay, 0);
    268   EXPECT_GE(max_send_delay, avg_send_delay);
    269   int receive_delay_ms = 0;
    270   EXPECT_EQ(0, codec->GetReceiveSideDelay(video_channel, &receive_delay_ms));
    271   EXPECT_GT(receive_delay_ms, 0);
    272 
    273   EXPECT_EQ(0, base->StopSend(video_channel));
    274   EXPECT_EQ(0, codec->DeregisterEncoderObserver(video_channel));
    275   EXPECT_EQ(0, codec->DeregisterDecoderObserver(video_channel));
    276 
    277   EXPECT_GT(codec_observer.incoming_codec_called_, 0);
    278   EXPECT_GT(codec_observer.incoming_rate_called_, 0);
    279   EXPECT_GT(codec_observer.decoder_timing_called_, 0);
    280   EXPECT_GT(codec_observer.outgoing_rate_called_, 0);
    281 
    282   EXPECT_EQ(0, base->StopReceive(video_channel));
    283   EXPECT_EQ(0, render->StopRender(video_channel));
    284   EXPECT_EQ(0, render->RemoveRenderer(capture_id));
    285   EXPECT_EQ(0, render->RemoveRenderer(video_channel));
    286   EXPECT_EQ(0, capture->DisconnectCaptureDevice(video_channel));
    287   EXPECT_EQ(0, base->DeleteChannel(video_channel));
    288 }
    289 
    290 void ViEAutoTest::ViECodecExtendedTest() {
    291   {
    292     ViETest::Log(" ");
    293     ViETest::Log("========================================");
    294     ViETest::Log(" ViECodec Extended Test\n");
    295 
    296     ViECodecExternalCodecTest();
    297 
    298     TbInterfaces interfaces("ViECodecExtendedTest");
    299     webrtc::ViEBase* base = interfaces.base;
    300     webrtc::ViECapture* capture = interfaces.capture;
    301     webrtc::ViERender* render = interfaces.render;
    302     webrtc::ViECodec* codec = interfaces.codec;
    303     webrtc::ViERTP_RTCP* rtp_rtcp = interfaces.rtp_rtcp;
    304     webrtc::ViENetwork* network = interfaces.network;
    305 
    306     TbCaptureDevice capture_device = TbCaptureDevice(interfaces);
    307     int capture_id = capture_device.captureId;
    308 
    309     int video_channel = -1;
    310     EXPECT_EQ(0, base->CreateChannel(video_channel));
    311     EXPECT_EQ(0, capture->ConnectCaptureDevice(capture_id, video_channel));
    312     EXPECT_EQ(0, rtp_rtcp->SetRTCPStatus(
    313                 video_channel, webrtc::kRtcpCompound_RFC4585));
    314     EXPECT_EQ(0, rtp_rtcp->SetKeyFrameRequestMethod(
    315                 video_channel, webrtc::kViEKeyFrameRequestPliRtcp));
    316     EXPECT_EQ(0, rtp_rtcp->SetTMMBRStatus(video_channel, true));
    317     EXPECT_EQ(0, render->AddRenderer(capture_id, _window1, 0, 0.0, 0.0, 1.0,
    318                                      1.0));
    319 
    320     EXPECT_EQ(0, render->AddRenderer(video_channel, _window2, 1, 0.0, 0.0, 1.0,
    321                                      1.0));
    322     EXPECT_EQ(0, render->StartRender(capture_id));
    323     EXPECT_EQ(0, render->StartRender(video_channel));
    324 
    325     webrtc::VideoCodec video_codec;
    326     memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
    327     for (int idx = 0; idx < codec->NumberOfCodecs(); idx++) {
    328       EXPECT_EQ(0, codec->GetCodec(idx, video_codec));
    329       if (video_codec.codecType != webrtc::kVideoCodecI420) {
    330         video_codec.width = 640;
    331         video_codec.height = 480;
    332       }
    333       EXPECT_EQ(0, codec->SetReceiveCodec(video_channel, video_codec));
    334     }
    335 
    336     const char* ip_address = "127.0.0.1";
    337     const uint16_t rtp_port = 6000;
    338 
    339     webrtc::scoped_ptr<webrtc::test::VideoChannelTransport>
    340         video_channel_transport(
    341             new webrtc::test::VideoChannelTransport(network, video_channel));
    342 
    343     ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address,
    344                                                              rtp_port));
    345     ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port));
    346 
    347     EXPECT_EQ(0, base->StartSend(video_channel));
    348     EXPECT_EQ(0, base->StartReceive(video_channel));
    349 
    350     // Codec specific tests
    351     memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
    352     EXPECT_EQ(0, base->StopSend(video_channel));
    353 
    354     TestCodecObserver codec_observer;
    355     EXPECT_EQ(0, codec->RegisterEncoderObserver(video_channel, codec_observer));
    356     EXPECT_EQ(0, codec->RegisterDecoderObserver(video_channel, codec_observer));
    357     EXPECT_EQ(0, base->StopReceive(video_channel));
    358 
    359     EXPECT_EQ(0, render->StopRender(video_channel));
    360     EXPECT_EQ(0, render->RemoveRenderer(capture_id));
    361     EXPECT_EQ(0, render->RemoveRenderer(video_channel));
    362     EXPECT_EQ(0, capture->DisconnectCaptureDevice(video_channel));
    363     EXPECT_EQ(0, base->DeleteChannel(video_channel));
    364   }
    365 
    366   // Multiple send channels.
    367   {
    368     // Create two channels, where the second channel is created from the
    369     // first channel. Send different resolutions on the channels and verify
    370     // the received streams.
    371     TbInterfaces video_engine("ViECodecExtendedTest2");
    372     TbCaptureDevice tb_capture(video_engine);
    373     webrtc::ViENetwork* network = video_engine.network;
    374 
    375     // Create channel 1.
    376     int video_channel_1 = -1;
    377     EXPECT_EQ(0, video_engine.base->CreateChannel(video_channel_1));
    378 
    379     // Create channel 2 based on the first channel.
    380     int video_channel_2 = -1;
    381     EXPECT_EQ(0, video_engine.base->CreateChannel(
    382         video_channel_2, video_channel_1));
    383     EXPECT_NE(video_channel_1, video_channel_2)
    384         << "Channel 2 should be unique.";
    385 
    386     const char* ip_address = "127.0.0.1";
    387     uint16_t rtp_port_1 = 12000;
    388     uint16_t rtp_port_2 = 13000;
    389 
    390     webrtc::scoped_ptr<webrtc::test::VideoChannelTransport>
    391         video_channel_transport_1(
    392             new webrtc::test::VideoChannelTransport(network, video_channel_1));
    393 
    394     ASSERT_EQ(0, video_channel_transport_1->SetSendDestination(ip_address,
    395                                                                rtp_port_1));
    396     ASSERT_EQ(0, video_channel_transport_1->SetLocalReceiver(rtp_port_1));
    397 
    398     webrtc::scoped_ptr<webrtc::test::VideoChannelTransport>
    399         video_channel_transport_2(
    400             new webrtc::test::VideoChannelTransport(network, video_channel_2));
    401 
    402     ASSERT_EQ(0, video_channel_transport_2->SetSendDestination(ip_address,
    403                                                                rtp_port_2));
    404     ASSERT_EQ(0, video_channel_transport_2->SetLocalReceiver(rtp_port_2));
    405 
    406     EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_1, 1));
    407     EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_2, 2));
    408     tb_capture.ConnectTo(video_channel_1);
    409     tb_capture.ConnectTo(video_channel_2);
    410     EXPECT_EQ(0, video_engine.rtp_rtcp->SetKeyFrameRequestMethod(
    411         video_channel_1, webrtc::kViEKeyFrameRequestPliRtcp));
    412     EXPECT_EQ(0, video_engine.rtp_rtcp->SetKeyFrameRequestMethod(
    413         video_channel_2, webrtc::kViEKeyFrameRequestPliRtcp));
    414     EXPECT_EQ(0, video_engine.render->AddRenderer(video_channel_1, _window1, 0,
    415                                                   0.0, 0.0, 1.0, 1.0));
    416     EXPECT_EQ(0, video_engine.render->StartRender(video_channel_1));
    417     EXPECT_EQ(0, video_engine.render->AddRenderer(video_channel_2, _window2, 0,
    418                                                   0.0, 0.0, 1.0, 1.0));
    419     EXPECT_EQ(0, video_engine.render->StartRender(video_channel_2));
    420 
    421     // Set Send codec.
    422     uint16_t codec_width = 320;
    423     uint16_t codec_height = 240;
    424     bool codec_set = false;
    425     webrtc::VideoCodec video_codec;
    426     webrtc::VideoCodec send_codec1;
    427     webrtc::VideoCodec send_codec2;
    428     for (int idx = 0; idx < video_engine.codec->NumberOfCodecs(); idx++) {
    429       EXPECT_EQ(0, video_engine.codec->GetCodec(idx, video_codec));
    430       EXPECT_EQ(0, video_engine.codec->SetReceiveCodec(video_channel_1,
    431                                                        video_codec));
    432       if (video_codec.codecType == webrtc::kVideoCodecVP8) {
    433         memcpy(&send_codec1, &video_codec, sizeof(video_codec));
    434         send_codec1.width = codec_width;
    435         send_codec1.height = codec_height;
    436         EXPECT_EQ(0, video_engine.codec->SetSendCodec(
    437                     video_channel_1, send_codec1));
    438         memcpy(&send_codec2, &video_codec, sizeof(video_codec));
    439         send_codec2.width = 2 * codec_width;
    440         send_codec2.height = 2 * codec_height;
    441         EXPECT_EQ(0, video_engine.codec->SetSendCodec(
    442                     video_channel_2, send_codec2));
    443         codec_set = true;
    444         break;
    445       }
    446     }
    447     EXPECT_TRUE(codec_set);
    448 
    449     // We need to verify using render effect filter since we won't trigger
    450     // a decode reset in loopback (due to using the same SSRC).
    451     RenderFilter filter1;
    452     RenderFilter filter2;
    453     EXPECT_EQ(0, video_engine.image_process->RegisterRenderEffectFilter(
    454         video_channel_1, filter1));
    455     EXPECT_EQ(0, video_engine.image_process->RegisterRenderEffectFilter(
    456         video_channel_2, filter2));
    457 
    458     EXPECT_EQ(0, video_engine.base->StartReceive(video_channel_1));
    459     EXPECT_EQ(0, video_engine.base->StartSend(video_channel_1));
    460     EXPECT_EQ(0, video_engine.base->StartReceive(video_channel_2));
    461     EXPECT_EQ(0, video_engine.base->StartSend(video_channel_2));
    462 
    463     AutoTestSleep(kAutoTestSleepTimeMs);
    464 
    465     EXPECT_EQ(0, video_engine.base->StopReceive(video_channel_1));
    466     EXPECT_EQ(0, video_engine.base->StopSend(video_channel_1));
    467     EXPECT_EQ(0, video_engine.base->StopReceive(video_channel_2));
    468     EXPECT_EQ(0, video_engine.base->StopSend(video_channel_2));
    469 
    470     EXPECT_EQ(0, video_engine.image_process->DeregisterRenderEffectFilter(
    471         video_channel_1));
    472     EXPECT_EQ(0, video_engine.image_process->DeregisterRenderEffectFilter(
    473         video_channel_2));
    474     EXPECT_EQ(send_codec1.width, filter1.last_render_width_);
    475     EXPECT_EQ(send_codec1.height, filter1.last_render_height_);
    476     EXPECT_EQ(send_codec2.width, filter2.last_render_width_);
    477     EXPECT_EQ(send_codec2.height, filter2.last_render_height_);
    478 
    479     EXPECT_EQ(0, video_engine.base->DeleteChannel(video_channel_1));
    480     EXPECT_EQ(0, video_engine.base->DeleteChannel(video_channel_2));
    481   }
    482 }
    483 
    484 void ViEAutoTest::ViECodecAPITest() {
    485   webrtc::VideoEngine* video_engine = NULL;
    486   video_engine = webrtc::VideoEngine::Create();
    487   EXPECT_TRUE(video_engine != NULL);
    488 
    489   webrtc::ViEBase* base = webrtc::ViEBase::GetInterface(video_engine);
    490   EXPECT_EQ(0, base->Init());
    491 
    492   int video_channel = -1;
    493   EXPECT_EQ(0, base->CreateChannel(video_channel));
    494 
    495   webrtc::ViECodec* codec = webrtc::ViECodec::GetInterface(video_engine);
    496   EXPECT_TRUE(codec != NULL);
    497 
    498   webrtc::VideoCodec video_codec;
    499   memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
    500 
    501   const int number_of_codecs = codec->NumberOfCodecs();
    502 
    503   for (int i = 0; i < number_of_codecs; i++) {
    504     EXPECT_EQ(0, codec->GetCodec(i, video_codec));
    505     if (video_codec.codecType == webrtc::kVideoCodecVP8) {
    506       video_codec.codecSpecific.VP8.automaticResizeOn = true;
    507       video_codec.codecSpecific.VP8.frameDroppingOn = true;
    508       video_codec.codecSpecific.VP8.keyFrameInterval = 300;
    509       EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    510       break;
    511     }
    512   }
    513   const unsigned int kMinBitrate = 123;
    514   video_codec.minBitrate = kMinBitrate;
    515   video_codec.startBitrate = 50;
    516   EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    517   EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec));
    518   EXPECT_EQ(kMinBitrate, video_codec.startBitrate);
    519 
    520   memset(&video_codec, 0, sizeof(video_codec));
    521   EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec));
    522   EXPECT_EQ(webrtc::kVideoCodecVP8, video_codec.codecType);
    523   EXPECT_TRUE(video_codec.codecSpecific.VP8.automaticResizeOn);
    524   EXPECT_TRUE(video_codec.codecSpecific.VP8.frameDroppingOn);
    525   EXPECT_EQ(300, video_codec.codecSpecific.VP8.keyFrameInterval);
    526 
    527   for (int i = 0; i < number_of_codecs; i++) {
    528     EXPECT_EQ(0, codec->GetCodec(i, video_codec));
    529     if (video_codec.codecType == webrtc::kVideoCodecI420) {
    530       EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    531       break;
    532     }
    533   }
    534 
    535   memset(&video_codec, 0, sizeof(video_codec));
    536   EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec));
    537   EXPECT_EQ(webrtc::kVideoCodecI420, video_codec.codecType);
    538 
    539   // Register a generic codec
    540   memset(&video_codec, 0, sizeof(video_codec));
    541   video_codec.codecType = webrtc::kVideoCodecGeneric;
    542   strcpy(video_codec.plName, "generic-codec");
    543   uint8_t payload_type = 127;
    544   video_codec.plType = payload_type;
    545   video_codec.minBitrate = 100;
    546   video_codec.startBitrate = 500;
    547   video_codec.maxBitrate = 10000;
    548   video_codec.width = 1920;
    549   video_codec.height = 1080;
    550   video_codec.maxFramerate = 30;
    551   video_codec.qpMax = 50;
    552 
    553   webrtc::ViEExternalCodec* external_codec =
    554       webrtc::ViEExternalCodec::GetInterface(video_engine);
    555   EXPECT_TRUE(external_codec != NULL);
    556 
    557   // Any encoder will do.
    558   webrtc::I420Encoder encoder;
    559   EXPECT_EQ(0, external_codec->RegisterExternalSendCodec(video_channel,
    560                                                          payload_type, &encoder,
    561                                                          false));
    562   EXPECT_EQ(0, codec->SetSendCodec(video_channel, video_codec));
    563 
    564   memset(&video_codec, 0, sizeof(video_codec));
    565   EXPECT_EQ(0, codec->GetSendCodec(video_channel, video_codec));
    566   EXPECT_EQ(webrtc::kVideoCodecGeneric, video_codec.codecType);
    567 
    568   EXPECT_EQ(0, base->DeleteChannel(video_channel));
    569 
    570   EXPECT_EQ(0, external_codec->Release());
    571   EXPECT_EQ(0, codec->Release());
    572   EXPECT_EQ(0, base->Release());
    573   EXPECT_TRUE(webrtc::VideoEngine::Delete(video_engine));
    574 }
    575 
    576 void ViEAutoTest::ViECodecExternalCodecTest() {
    577   ViETest::Log(" ");
    578   ViETest::Log("========================================");
    579   ViETest::Log(" ViEExternalCodec Test\n");
    580 
    581   /// **************************************************************
    582   //  Begin create/initialize WebRTC Video Engine for testing
    583   /// **************************************************************
    584 
    585   /// **************************************************************
    586   //  Engine ready. Begin testing class
    587   /// **************************************************************
    588 
    589 #ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
    590   int number_of_errors = 0;
    591   {
    592     int error = 0;
    593     TbInterfaces ViE("ViEExternalCodec");
    594     TbCaptureDevice capture_device(ViE);
    595     TbVideoChannel channel(ViE, webrtc::kVideoCodecI420, 352, 288, 30,
    596                            (352 * 288 * 3 * 8 * 30) / (2 * 1000));
    597     capture_device.ConnectTo(channel.videoChannel);
    598 
    599     error = ViE.render->AddRenderer(channel.videoChannel, _window1, 0, 0.0, 0.0,
    600                                     1.0, 1.0);
    601     number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    602                                            __FUNCTION__, __LINE__);
    603     error = ViE.render->StartRender(channel.videoChannel);
    604     number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    605                                            __FUNCTION__, __LINE__);
    606 
    607     channel.StartReceive();
    608     channel.StartSend();
    609 
    610     ViETest::Log("Using internal I420 codec");
    611     AutoTestSleep(kAutoTestSleepTimeMs / 2);
    612 
    613     webrtc::ViEExternalCodec* vie_external_codec =
    614         webrtc::ViEExternalCodec::GetInterface(ViE.video_engine);
    615     number_of_errors += ViETest::TestError(vie_external_codec != NULL,
    616                                            "ERROR: %s at line %d",
    617                                            __FUNCTION__, __LINE__);
    618     webrtc::VideoCodec codec;
    619     error = ViE.codec->GetSendCodec(channel.videoChannel, codec);
    620     number_of_errors += ViETest::TestError(vie_external_codec != NULL,
    621                                            "ERROR: %s at line %d",
    622                                            __FUNCTION__, __LINE__);
    623 
    624     // Use external encoder instead.
    625     {
    626       TbI420Encoder ext_encoder;
    627 
    628       // Test to register on wrong channel.
    629       error = vie_external_codec->RegisterExternalSendCodec(
    630           channel.videoChannel + 5, codec.plType, &ext_encoder, false);
    631       number_of_errors += ViETest::TestError(error == -1,
    632                                              "ERROR: %s at line %d",
    633                                              __FUNCTION__, __LINE__);
    634       number_of_errors += ViETest::TestError(
    635           ViE.LastError() == kViECodecInvalidArgument,
    636           "ERROR: %s at line %d", __FUNCTION__, __LINE__);
    637 
    638       error = vie_external_codec->RegisterExternalSendCodec(
    639                 channel.videoChannel, codec.plType, &ext_encoder, false);
    640       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    641                                              __FUNCTION__, __LINE__);
    642 
    643       // Use new external encoder
    644       error = ViE.codec->SetSendCodec(channel.videoChannel, codec);
    645       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    646                                              __FUNCTION__, __LINE__);
    647 
    648       TbI420Decoder ext_decoder;
    649       error = vie_external_codec->RegisterExternalReceiveCodec(
    650           channel.videoChannel, codec.plType, &ext_decoder);
    651       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    652                                              __FUNCTION__, __LINE__);
    653 
    654       error = ViE.codec->SetReceiveCodec(channel.videoChannel, codec);
    655       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    656                                              __FUNCTION__, __LINE__);
    657 
    658       ViETest::Log("Using external I420 codec");
    659       AutoTestSleep(kAutoTestSleepTimeMs);
    660 
    661       // Test to deregister on wrong channel
    662       error = vie_external_codec->DeRegisterExternalSendCodec(
    663           channel.videoChannel + 5, codec.plType);
    664       number_of_errors += ViETest::TestError(error == -1,
    665                                              "ERROR: %s at line %d",
    666                                              __FUNCTION__, __LINE__);
    667       number_of_errors += ViETest::TestError(
    668           ViE.LastError() == kViECodecInvalidArgument, "ERROR: %s at line %d",
    669           __FUNCTION__, __LINE__);
    670 
    671       // Test to deregister wrong payload type.
    672       error = vie_external_codec->DeRegisterExternalSendCodec(
    673           channel.videoChannel, codec.plType - 1);
    674       number_of_errors += ViETest::TestError(error == -1,
    675                                              "ERROR: %s at line %d",
    676                                              __FUNCTION__, __LINE__);
    677 
    678       // Deregister external send codec
    679       error = vie_external_codec->DeRegisterExternalSendCodec(
    680           channel.videoChannel, codec.plType);
    681       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    682                                              __FUNCTION__, __LINE__);
    683 
    684       error = vie_external_codec->DeRegisterExternalReceiveCodec(
    685           channel.videoChannel, codec.plType);
    686       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    687                                              __FUNCTION__, __LINE__);
    688 
    689       // Verify that the encoder and decoder has been used
    690       TbI420Encoder::FunctionCalls encode_calls =
    691           ext_encoder.GetFunctionCalls();
    692       number_of_errors += ViETest::TestError(encode_calls.InitEncode == 1,
    693                                              "ERROR: %s at line %d",
    694                                              __FUNCTION__, __LINE__);
    695       number_of_errors += ViETest::TestError(encode_calls.Release == 1,
    696                                              "ERROR: %s at line %d",
    697                                              __FUNCTION__, __LINE__);
    698       number_of_errors += ViETest::TestError(encode_calls.Encode > 30,
    699                                              "ERROR: %s at line %d",
    700                                              __FUNCTION__, __LINE__);
    701       number_of_errors += ViETest::TestError(
    702           encode_calls.RegisterEncodeCompleteCallback == 1,
    703           "ERROR: %s at line %d", __FUNCTION__, __LINE__);
    704       number_of_errors += ViETest::TestError(
    705           encode_calls.SetChannelParameters > 1, "ERROR: %s at line %d",
    706           __FUNCTION__, __LINE__);
    707       number_of_errors += ViETest::TestError(encode_calls.SetRates > 1,
    708                                              "ERROR: %s at line %d",
    709                                              __FUNCTION__, __LINE__);
    710 
    711       TbI420Decoder::FunctionCalls decode_calls =
    712           ext_decoder.GetFunctionCalls();
    713       number_of_errors += ViETest::TestError(decode_calls.InitDecode == 1,
    714                                              "ERROR: %s at line %d",
    715                                              __FUNCTION__, __LINE__);
    716       number_of_errors += ViETest::TestError(decode_calls.Release == 1,
    717                                              "ERROR: %s at line %d",
    718                                              __FUNCTION__, __LINE__);
    719       number_of_errors += ViETest::TestError(decode_calls.Decode > 30,
    720                                              "ERROR: %s at line %d",
    721                                              __FUNCTION__, __LINE__);
    722       number_of_errors += ViETest::TestError(
    723           decode_calls.RegisterDecodeCompleteCallback == 1,
    724           "ERROR: %s at line %d", __FUNCTION__, __LINE__);
    725 
    726       ViETest::Log("Changing payload type Using external I420 codec");
    727 
    728       codec.plType = codec.plType - 1;
    729       error = vie_external_codec->RegisterExternalReceiveCodec(
    730           channel.videoChannel, codec.plType, &ext_decoder);
    731       number_of_errors += ViETest::TestError(error == 0,
    732                                              "ERROR: %s at line %d",
    733                                              __FUNCTION__, __LINE__);
    734 
    735       error = ViE.codec->SetReceiveCodec(channel.videoChannel,
    736                                          codec);
    737       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    738                                              __FUNCTION__, __LINE__);
    739 
    740       error = vie_external_codec->RegisterExternalSendCodec(
    741                 channel.videoChannel, codec.plType, &ext_encoder, false);
    742       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    743                                              __FUNCTION__, __LINE__);
    744 
    745       // Use new external encoder
    746       error = ViE.codec->SetSendCodec(channel.videoChannel,
    747                                       codec);
    748       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    749                                              __FUNCTION__, __LINE__);
    750 
    751       AutoTestSleep(kAutoTestSleepTimeMs / 2);
    752 
    753       /// **************************************************************
    754       //  Testing finished. Tear down Video Engine
    755       /// **************************************************************
    756 
    757       error = vie_external_codec->DeRegisterExternalSendCodec(
    758                 channel.videoChannel, codec.plType);
    759       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    760                                              __FUNCTION__, __LINE__);
    761       error = vie_external_codec->DeRegisterExternalReceiveCodec(
    762                 channel.videoChannel, codec.plType);
    763       number_of_errors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
    764                                              __FUNCTION__, __LINE__);
    765 
    766       // Verify that the encoder and decoder has been used
    767       encode_calls = ext_encoder.GetFunctionCalls();
    768       number_of_errors += ViETest::TestError(encode_calls.InitEncode == 2,
    769                                              "ERROR: %s at line %d",
    770                                              __FUNCTION__, __LINE__);
    771       number_of_errors += ViETest::TestError(encode_calls.Release == 2,
    772                                              "ERROR: %s at line %d",
    773                                              __FUNCTION__, __LINE__);
    774       number_of_errors += ViETest::TestError(encode_calls.Encode > 30,
    775                                              "ERROR: %s at line %d",
    776                                              __FUNCTION__, __LINE__);
    777       number_of_errors += ViETest::TestError(
    778           encode_calls.RegisterEncodeCompleteCallback == 2,
    779           "ERROR: %s at line %d", __FUNCTION__, __LINE__);
    780       number_of_errors += ViETest::TestError(
    781           encode_calls.SetChannelParameters > 1, "ERROR: %s at line %d",
    782           __FUNCTION__, __LINE__);
    783       number_of_errors += ViETest::TestError(encode_calls.SetRates > 1,
    784                                              "ERROR: %s at line %d",
    785                                              __FUNCTION__, __LINE__);
    786       decode_calls = ext_decoder.GetFunctionCalls();
    787       number_of_errors += ViETest::TestError(decode_calls.InitDecode == 2,
    788                                              "ERROR: %s at line %d",
    789                                              __FUNCTION__, __LINE__);
    790       number_of_errors += ViETest::TestError(decode_calls.Release == 2,
    791                                              "ERROR: %s at line %d",
    792                                              __FUNCTION__, __LINE__);
    793       number_of_errors += ViETest::TestError(decode_calls.Decode > 30,
    794                                              "ERROR: %s at line %d",
    795                                              __FUNCTION__, __LINE__);
    796       number_of_errors += ViETest::TestError(
    797           decode_calls.RegisterDecodeCompleteCallback == 2,
    798           "ERROR: %s at line %d", __FUNCTION__, __LINE__);
    799 
    800       int remaining_interfaces = vie_external_codec->Release();
    801       number_of_errors += ViETest::TestError(remaining_interfaces == 0,
    802                                              "ERROR: %s at line %d",
    803                                              __FUNCTION__, __LINE__);
    804     }  // tbI420Encoder and ext_decoder goes out of scope.
    805 
    806     ViETest::Log("Using internal I420 codec");
    807     AutoTestSleep(kAutoTestSleepTimeMs / 2);
    808   }
    809   if (number_of_errors > 0) {
    810     // Test failed
    811     ViETest::Log(" ");
    812     ViETest::Log(" ERROR ViEExternalCodec Test FAILED!");
    813     ViETest::Log(" Number of errors: %d", number_of_errors);
    814     ViETest::Log("========================================");
    815     ViETest::Log(" ");
    816     return;
    817   }
    818 
    819   ViETest::Log(" ");
    820   ViETest::Log(" ViEExternalCodec Test PASSED!");
    821   ViETest::Log("========================================");
    822   ViETest::Log(" ");
    823   return;
    824 
    825 #else
    826   ViETest::Log(" ViEExternalCodec not enabled\n");
    827   return;
    828 #endif
    829 }
    830