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:
ViEAutoTestExternalRenderer()46 ViEAutoTestExternalRenderer() :
47 _width(0),
48 _height(0)
49 {
50 }
FrameSizeChange(unsigned int width,unsigned int height,unsigned int numberOfStreams)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
DeliverFrame(unsigned char * buffer,int bufferSize,uint32_t time_stamp,int64_t ntp_time_ms,int64_t render_time,void *)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
IsTextureSupported()73 virtual bool IsTextureSupported() { return false; }
74
75 public:
~ViEAutoTestExternalRenderer()76 virtual ~ViEAutoTestExternalRenderer()
77 {
78 }
79 private:
80 int _width, _height;
81 };
82
ViERenderStandardTest()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
ViERenderExtendedTest()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
ViERenderAPITest()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