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_render.cc
     13 //
     14 
     15 #include "webrtc/engine_configurations.h"
     16 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
     17 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
     18 
     19 #include "webrtc/modules/video_render/include/video_render.h"
     20 
     21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
     22 #include "webrtc/video_engine/test/libvietest/include/tb_capture_device.h"
     23 #include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
     24 #include "webrtc/video_engine/test/libvietest/include/tb_video_channel.h"
     25 
     26 #if defined(WIN32)
     27 #include <ddraw.h>
     28 #include <tchar.h>
     29 #include <windows.h>
     30 #elif defined(WEBRTC_LINUX)
     31     //From windgi.h
     32     #undef RGB
     33     #define RGB(r,g,b)          ((unsigned long)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
     34     //From ddraw.h
     35 /*    typedef struct _DDCOLORKEY
     36  {
     37  DWORD       dwColorSpaceLowValue;   // low boundary of color space that is to
     38  DWORD       dwColorSpaceHighValue;  // high boundary of color space that is
     39  } DDCOLORKEY;*/
     40 #elif defined(WEBRTC_MAC)
     41 #endif
     42 
     43 class ViEAutoTestExternalRenderer: public webrtc::ExternalRenderer
     44 {
     45 public:
     46     ViEAutoTestExternalRenderer() :
     47         _width(0),
     48         _height(0)
     49     {
     50     }
     51     virtual int FrameSizeChange(unsigned int width, unsigned int height,
     52                                 unsigned int numberOfStreams)
     53     {
     54         _width = width;
     55         _height = height;
     56         return 0;
     57     }
     58 
     59     virtual int DeliverFrame(unsigned char* buffer,
     60                              int bufferSize,
     61                              uint32_t time_stamp,
     62                              int64_t ntp_time_ms,
     63                              int64_t render_time,
     64                              void* /*handle*/) {
     65       if (bufferSize != CalcBufferSize(webrtc::kI420, _width, _height)) {
     66         ViETest::Log("Incorrect render buffer received, of length = %d\n",
     67                      bufferSize);
     68         return 0;
     69       }
     70       return 0;
     71     }
     72 
     73     virtual bool IsTextureSupported() { return false; }
     74 
     75 public:
     76     virtual ~ViEAutoTestExternalRenderer()
     77     {
     78     }
     79 private:
     80     int _width, _height;
     81 };
     82 
     83 void ViEAutoTest::ViERenderStandardTest()
     84 {
     85     //***************************************************************
     86     //	Begin create/initialize WebRTC Video Engine for testing
     87     //***************************************************************
     88     int rtpPort = 6000;
     89 
     90     TbInterfaces ViE("ViERenderStandardTest");
     91 
     92     // Create a video channel
     93     TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
     94     TbCaptureDevice tbCapture(ViE); // Create a capture device
     95     tbCapture.ConnectTo(tbChannel.videoChannel);
     96     tbChannel.StartReceive(rtpPort);
     97     tbChannel.StartSend(rtpPort);
     98 
     99     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm1));
    100     EXPECT_EQ(0, ViE.render->AddRenderer(
    101         tbCapture.captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
    102     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    103     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm2));
    104     EXPECT_EQ(0, ViE.render->AddRenderer(
    105         tbChannel.videoChannel, _window2, 1, 0.0, 0.0, 1.0, 1.0));
    106     EXPECT_EQ(0, ViE.render->StartRender(tbChannel.videoChannel));
    107 
    108     ViETest::Log("\nCapture device is renderered in Window 1");
    109     ViETest::Log("Remote stream is renderered in Window 2");
    110     AutoTestSleep(kAutoTestSleepTimeMs);
    111 
    112     EXPECT_EQ(0, ViE.render->StopRender(tbCapture.captureId));
    113     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    114 
    115     // PIP and full screen rendering is not supported on Android
    116 #ifndef WEBRTC_ANDROID
    117     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm1));
    118     EXPECT_EQ(0, ViE.render->AddRenderer(
    119         tbCapture.captureId, _window2, 0, 0.75, 0.75, 1.0, 1.0));
    120     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    121 
    122     ViETest::Log("\nCapture device is now rendered in Window 2, PiP.");
    123     ViETest::Log("Switching to full screen rendering in %d seconds.\n",
    124                  kAutoTestSleepTimeMs / 1000);
    125     AutoTestSleep(kAutoTestSleepTimeMs);
    126 
    127     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    128     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbChannel.videoChannel));
    129     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm2));
    130 
    131     // Destroy render module and create new in full screen mode
    132     webrtc::VideoRender::DestroyVideoRender(_vrm1);
    133     _vrm1 = NULL;
    134     _vrm1 = webrtc::VideoRender::CreateVideoRender(
    135         4563, _window1, true, _renderType);
    136     EXPECT_TRUE(_vrm1 != NULL);
    137 
    138     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm1));
    139     EXPECT_EQ(0, ViE.render->AddRenderer(
    140         tbCapture.captureId, _window1, 0, 0.75f, 0.75f, 1.0f, 1.0f));
    141     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    142     EXPECT_EQ(0, ViE.render->AddRenderer(
    143         tbChannel.videoChannel, _window1, 1, 0.0, 0.0, 1.0, 1.0));
    144     EXPECT_EQ(0, ViE.render->StartRender(tbChannel.videoChannel));
    145 
    146     AutoTestSleep(kAutoTestSleepTimeMs);
    147 
    148     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    149 
    150     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbChannel.videoChannel));
    151     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm1));
    152 
    153     // Destroy full screen render module and create new in normal mode
    154     webrtc::VideoRender::DestroyVideoRender(_vrm1);
    155     _vrm1 = NULL;
    156     _vrm1 = webrtc::VideoRender::CreateVideoRender(
    157         4561, _window1, false, _renderType);
    158     EXPECT_TRUE(_vrm1 != NULL);
    159 #endif
    160 
    161     //***************************************************************
    162     //	Engine ready. Begin testing class
    163     //***************************************************************
    164 
    165 
    166     //***************************************************************
    167     //	Testing finished. Tear down Video Engine
    168     //***************************************************************
    169     tbCapture.Disconnect(tbChannel.videoChannel);
    170 }
    171 
    172 void ViEAutoTest::ViERenderExtendedTest()
    173 {
    174     int rtpPort = 6000;
    175 
    176     TbInterfaces ViE("ViERenderExtendedTest");
    177 
    178     // Create a video channel
    179     TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    180     TbCaptureDevice tbCapture(ViE); // Create a capture device
    181     tbCapture.ConnectTo(tbChannel.videoChannel);
    182     tbChannel.StartReceive(rtpPort);
    183     tbChannel.StartSend(rtpPort);
    184 
    185     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm1));
    186     EXPECT_EQ(0, ViE.render->AddRenderer(
    187         tbCapture.captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
    188     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    189     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm2));
    190     EXPECT_EQ(0, ViE.render->AddRenderer(
    191         tbChannel.videoChannel, _window2, 1, 0.0, 0.0, 1.0, 1.0));
    192     EXPECT_EQ(0, ViE.render->StartRender(tbChannel.videoChannel));
    193 
    194     ViETest::Log("\nCapture device is renderered in Window 1");
    195     ViETest::Log("Remote stream is renderered in Window 2");
    196     AutoTestSleep(kAutoTestSleepTimeMs);
    197 
    198 #ifdef _WIN32
    199     ViETest::Log("\nConfiguring Window2");
    200     ViETest::Log("you will see video only in first quadrant");
    201     EXPECT_EQ(0, ViE.render->ConfigureRender(
    202         tbChannel.videoChannel, 0, 0.0f, 0.0f, 0.5f, 0.5f));
    203     AutoTestSleep(kAutoTestSleepTimeMs);
    204 
    205     ViETest::Log("you will see video only in fourth quadrant");
    206     EXPECT_EQ(0, ViE.render->ConfigureRender(
    207         tbChannel.videoChannel, 0, 0.5f, 0.5f, 1.0f, 1.0f));
    208     AutoTestSleep(kAutoTestSleepTimeMs);
    209 
    210     ViETest::Log("normal video on Window2");
    211     EXPECT_EQ(0, ViE.render->ConfigureRender(
    212         tbChannel.videoChannel, 0, 0.0f, 0.0f, 1.0f, 1.0f));
    213     AutoTestSleep(kAutoTestSleepTimeMs);
    214 #endif
    215 
    216     ViETest::Log("Mirroring Local Preview (Window1) Left-Right");
    217     EXPECT_EQ(0, ViE.render->MirrorRenderStream(
    218         tbCapture.captureId, true, false, true));
    219     AutoTestSleep(kAutoTestSleepTimeMs);
    220 
    221     ViETest::Log("\nMirroring Local Preview (Window1) Left-Right and Up-Down");
    222     EXPECT_EQ(0, ViE.render->MirrorRenderStream(
    223         tbCapture.captureId, true, true, true));
    224     AutoTestSleep(kAutoTestSleepTimeMs);
    225 
    226     ViETest::Log("\nMirroring Remote Window(Window2) Up-Down");
    227     EXPECT_EQ(0, ViE.render->MirrorRenderStream(
    228         tbChannel.videoChannel, true, true, false));
    229     AutoTestSleep(kAutoTestSleepTimeMs);
    230 
    231     ViETest::Log("Disabling Mirroing on Window1 and Window2");
    232     EXPECT_EQ(0, ViE.render->MirrorRenderStream(
    233         tbCapture.captureId, false, false, false));
    234     AutoTestSleep(kAutoTestSleepTimeMs);
    235     EXPECT_EQ(0, ViE.render->MirrorRenderStream(
    236         tbChannel.videoChannel, false, false, false));
    237     AutoTestSleep(kAutoTestSleepTimeMs);
    238 
    239     ViETest::Log("\nEnabling Full Screen render in 5 sec");
    240 
    241     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    242     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm1));
    243     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbChannel.videoChannel));
    244     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm2));
    245 
    246     // Destroy render module and create new in full screen mode
    247     webrtc::VideoRender::DestroyVideoRender(_vrm1);
    248     _vrm1 = NULL;
    249     _vrm1 = webrtc::VideoRender::CreateVideoRender(
    250         4563, _window1, true, _renderType);
    251     EXPECT_TRUE(_vrm1 != NULL);
    252 
    253     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm1));
    254     EXPECT_EQ(0, ViE.render->AddRenderer(
    255         tbCapture.captureId, _window1, 0, 0.0f, 0.0f, 1.0f, 1.0f));
    256     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    257     AutoTestSleep(kAutoTestSleepTimeMs);
    258 
    259     ViETest::Log("\nStop renderer");
    260     EXPECT_EQ(0, ViE.render->StopRender(tbCapture.captureId));
    261     ViETest::Log("\nRemove renderer");
    262     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    263 
    264     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm1));
    265 
    266     // Destroy full screen render module and create new for external rendering
    267     webrtc::VideoRender::DestroyVideoRender(_vrm1);
    268     _vrm1 = NULL;
    269     _vrm1 = webrtc::VideoRender::CreateVideoRender(4564, NULL, false,
    270                                                    _renderType);
    271     EXPECT_TRUE(_vrm1 != NULL);
    272 
    273     EXPECT_EQ(0, ViE.render->RegisterVideoRenderModule(*_vrm1));
    274 
    275     ViETest::Log("\nExternal Render Test");
    276     ViEAutoTestExternalRenderer externalRenderObj;
    277     EXPECT_EQ(0, ViE.render->AddRenderer(
    278         tbCapture.captureId, webrtc::kVideoI420, &externalRenderObj));
    279     EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    280     AutoTestSleep(kAutoTestSleepTimeMs);
    281 
    282     EXPECT_EQ(0, ViE.render->StopRender(tbCapture.captureId));
    283     EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));
    284     EXPECT_EQ(0, ViE.render->DeRegisterVideoRenderModule(*_vrm1));
    285 
    286     // Destroy render module for external rendering and create new in normal
    287     // mode
    288     webrtc::VideoRender::DestroyVideoRender(_vrm1);
    289     _vrm1 = NULL;
    290     _vrm1 = webrtc::VideoRender::CreateVideoRender(
    291         4561, _window1, false, _renderType);
    292     EXPECT_TRUE(_vrm1 != NULL);
    293     tbCapture.Disconnect(tbChannel.videoChannel);
    294 }
    295 
    296 void ViEAutoTest::ViERenderAPITest() {
    297   TbInterfaces ViE("ViERenderAPITest");
    298 
    299   TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    300   TbCaptureDevice tbCapture(ViE);
    301   tbCapture.ConnectTo(tbChannel.videoChannel);
    302   tbChannel.StartReceive();
    303   tbChannel.StartSend();
    304 
    305   EXPECT_EQ(0, ViE.render->AddRenderer(
    306       tbCapture.captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
    307   EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
    308   EXPECT_EQ(0, ViE.render->AddRenderer(
    309       tbChannel.videoChannel, _window2, 1, 0.0, 0.0, 1.0, 1.0));
    310   EXPECT_EQ(0, ViE.render->StartRender(tbChannel.videoChannel));
    311 
    312   // Test setting HW render delay.
    313   // Already started.
    314   EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 50));
    315   EXPECT_EQ(0, ViE.render->StopRender(tbChannel.videoChannel));
    316   // Invalid values.
    317   EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 9));
    318   EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel,
    319                                                    501));
    320   // Valid values.
    321   EXPECT_EQ(0, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 11));
    322   EXPECT_EQ(0, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 499));
    323 }
    324