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