blob: 7dc0dbf3254ea19d1c873fac1664d0c7561c471a [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
wu@webrtc.org9143f772012-02-08 00:14:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000011#include <assert.h>
12
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000013#include "webrtc/engine_configurations.h"
andrew@webrtc.org9841d922012-10-31 05:22:11 +000014#include "webrtc/modules/video_render/i_video_render.h"
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000015#include "webrtc/modules/video_render/include/video_render_defines.h"
16#include "webrtc/modules/video_render/incoming_video_stream.h"
17#include "webrtc/modules/video_render/video_render_impl.h"
18#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/trace.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +000021#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +000022
23#if defined (_WIN32)
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000024#include "webrtc/modules/video_render/windows/video_render_windows_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000025#define STANDARD_RENDERING kRenderWindows
26
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +000027// WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC
28// gets defined if WEBRTC_IOS is defined
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +000029#elif defined(WEBRTC_IOS) && 0
30// TODO(sjlee): land https://webrtc-codereview.appspot.com/1641004/
niklase@google.com470e71d2011-07-07 08:21:25 +000031#if defined(IPHONE_GLES_RENDERING)
32#define STANDARD_RENDERING kRenderiPhone
33#include "iPhone/video_render_iphone_impl.h"
34#endif
35
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +000036#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +000037#if defined(COCOA_RENDERING)
38#define STANDARD_RENDERING kRenderCocoa
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000039#include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000040#elif defined(CARBON_RENDERING)
41#define STANDARD_RENDERING kRenderCarbon
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000042#include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000043#endif
44
leozwang@google.com03bc96d2011-07-26 05:03:10 +000045#elif defined(WEBRTC_ANDROID)
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000046#include "webrtc/modules/video_render/android/video_render_android_impl.h"
47#include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h"
48#include "webrtc/modules/video_render/android/video_render_android_surface_view.h"
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +000049#define STANDARD_RENDERING kRenderAndroid
niklase@google.com470e71d2011-07-07 08:21:25 +000050
51#elif defined(WEBRTC_LINUX)
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000052#include "webrtc/modules/video_render/linux/video_render_linux_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000053#define STANDARD_RENDERING kRenderX11
54
55#else
56//Other platforms
57#endif
58
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +000059#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +000060
61// For external rendering
pbos@webrtc.org5aa3f1b2013-07-12 08:12:08 +000062#include "webrtc/modules/video_render/external/video_render_external_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000063#ifndef STANDARD_RENDERING
64#define STANDARD_RENDERING kRenderExternal
65#endif // STANDARD_RENDERING
66
67namespace webrtc {
68
69VideoRender*
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +000070VideoRender::CreateVideoRender(const int32_t id,
niklase@google.com470e71d2011-07-07 08:21:25 +000071 void* window,
72 const bool fullscreen,
73 const VideoRenderType videoRenderType/*=kRenderDefault*/)
74{
niklase@google.com470e71d2011-07-07 08:21:25 +000075 VideoRenderType resultVideoRenderType = videoRenderType;
76 if (videoRenderType == kRenderDefault)
77 {
78 resultVideoRenderType = STANDARD_RENDERING;
79 }
80 return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
81 fullscreen);
82}
83
84void VideoRender::DestroyVideoRender(
85 VideoRender* module)
86{
87 if (module)
88 {
niklase@google.com470e71d2011-07-07 08:21:25 +000089 delete module;
90 }
91}
92
niklase@google.com470e71d2011-07-07 08:21:25 +000093ModuleVideoRenderImpl::ModuleVideoRenderImpl(
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +000094 const int32_t id,
niklase@google.com470e71d2011-07-07 08:21:25 +000095 const VideoRenderType videoRenderType,
96 void* window,
97 const bool fullscreen) :
98 _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()),
wu@webrtc.org2259f852012-06-19 14:56:50 +000099 _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL),
100 _streamRenderMap(*(new MapWrapper()))
niklase@google.com470e71d2011-07-07 08:21:25 +0000101{
102
103 // Create platform specific renderer
104 switch (videoRenderType)
105 {
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000106#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
108#if defined(_WIN32)
109 case kRenderWindows:
110 {
111 VideoRenderWindowsImpl* ptrRenderer;
112 ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen);
113 if (ptrRenderer)
114 {
115 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
116 }
117 }
118 break;
119
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +0000120#elif defined(WEBRTC_IOS) && 0
121 // TODO(sjlee): land https://webrtc-codereview.appspot.com/1641004/
niklase@google.com470e71d2011-07-07 08:21:25 +0000122 case kRenderiPhone:
123 {
124 VideoRenderIPhoneImpl* ptrRenderer = new VideoRenderIPhoneImpl(_id, videoRenderType, window, _fullScreen);
125 if(ptrRenderer)
126 {
127 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
128 }
129 }
130 break;
131
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000132#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000133
134#if defined(COCOA_RENDERING)
135 case kRenderCocoa:
136 {
137 VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen);
138 if(ptrRenderer)
139 {
140 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
141 }
142 }
143
144 break;
145#elif defined(CARBON_RENDERING)
146 case kRenderCarbon:
147 {
148 VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen);
149 if(ptrRenderer)
150 {
151 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
152 }
153 }
154 break;
155#endif
156
leozwang@google.com03bc96d2011-07-26 05:03:10 +0000157#elif defined(WEBRTC_ANDROID)
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 case kRenderAndroid:
159 {
160 if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window))
161 {
162 AndroidNativeOpenGl2Renderer* ptrRenderer = NULL;
163 ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen);
164 if (ptrRenderer)
165 {
166 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
167 }
168 }
169 else
170 {
171 AndroidSurfaceViewRenderer* ptrRenderer = NULL;
172 ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen);
173 if (ptrRenderer)
174 {
175 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
176 }
177 }
178
179 }
180 break;
181#elif defined(WEBRTC_LINUX)
182 case kRenderX11:
183 {
184 VideoRenderLinuxImpl* ptrRenderer = NULL;
185 ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen);
186 if ( ptrRenderer )
187 {
188 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
189 }
190 }
191 break;
192
193#else
194 // Other platforms
195#endif
196
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000197#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000198 case kRenderExternal:
199 {
200 VideoRenderExternalImpl* ptrRenderer(NULL);
201 ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType,
202 window, _fullScreen);
203 if (ptrRenderer)
204 {
205 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
206 }
207 }
208 break;
209 default:
210 // Error...
211 break;
212 }
213 if (_ptrRenderer)
214 {
215 if (_ptrRenderer->Init() == -1)
216 {
217 }
218 }
219}
220
221ModuleVideoRenderImpl::~ModuleVideoRenderImpl()
222{
223 delete &_moduleCrit;
224
225 while (_streamRenderMap.Size() > 0)
226 {
227 MapItem* item = _streamRenderMap.First();
228 IncomingVideoStream* ptrIncomingStream =
229 static_cast<IncomingVideoStream*> (item->GetItem());
230 assert(ptrIncomingStream != NULL);
231 delete ptrIncomingStream;
232 _streamRenderMap.Erase(item);
233 }
234 delete &_streamRenderMap;
235
236 // Delete platform specific renderer
237 if (_ptrRenderer)
238 {
239 VideoRenderType videoRenderType = _ptrRenderer->RenderType();
240 switch (videoRenderType)
241 {
242 case kRenderExternal:
243 {
244 VideoRenderExternalImpl
245 * ptrRenderer =
246 reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer);
247 _ptrRenderer = NULL;
248 delete ptrRenderer;
249 }
250 break;
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000251#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000252
253#if defined(_WIN32)
254 case kRenderWindows:
255 {
256 VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer);
257 _ptrRenderer = NULL;
258 delete ptrRenderer;
259 }
260 break;
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000261#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
263#if defined(COCOA_RENDERING)
264 case kRenderCocoa:
265 {
266 VideoRenderMacCocoaImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCocoaImpl*> (_ptrRenderer);
267 _ptrRenderer = NULL;
268 delete ptrRenderer;
269 }
270 break;
271#elif defined(CARBON_RENDERING)
272 case kRenderCarbon:
273 {
274 VideoRenderMacCarbonImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCarbonImpl*> (_ptrRenderer);
275 _ptrRenderer = NULL;
276 delete ptrRenderer;
277 }
278 break;
279#endif
280
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +0000281#elif defined(WEBRTC_IOS) && 0
282 // TODO(sjlee): land https://webrtc-codereview.appspot.com/1641004/
niklase@google.com470e71d2011-07-07 08:21:25 +0000283 case kRenderiPhone:
284 break;
285
leozwang@google.com03bc96d2011-07-26 05:03:10 +0000286#elif defined(WEBRTC_ANDROID)
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 case kRenderAndroid:
288 {
289 VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer);
290 _ptrRenderer = NULL;
291 delete ptrRenderer;
292 }
293 break;
294
295#elif defined(WEBRTC_LINUX)
296 case kRenderX11:
297 {
298 VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer);
299 _ptrRenderer = NULL;
300 delete ptrRenderer;
301 }
302 break;
303#else
304 //other platforms
305#endif
306
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000307#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000308
309 default:
310 // Error...
311 break;
312 }
313 }
314}
315
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000316int32_t ModuleVideoRenderImpl::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +0000317{
niklase@google.com470e71d2011-07-07 08:21:25 +0000318
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000319 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000320
321 _id = id;
322
323 if (_ptrRenderer)
324 {
325 _ptrRenderer->ChangeUniqueId(_id);
326 }
327
328 return 0;
329}
330
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000331int32_t ModuleVideoRenderImpl::TimeUntilNextProcess()
niklase@google.com470e71d2011-07-07 08:21:25 +0000332{
333 // Not used
334 return 50;
335}
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000336int32_t ModuleVideoRenderImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +0000337{
338 // Not used
339 return 0;
340}
341
342void*
343ModuleVideoRenderImpl::Window()
344{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000345 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 return _ptrWindow;
347}
348
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000349int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
niklase@google.com470e71d2011-07-07 08:21:25 +0000350{
351
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000352 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000353
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000354#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000355
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000356#if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 _ptrRenderer = NULL;
358 delete _ptrRenderer;
359
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +0000360#if 0 // TODO(sjlee): land https://webrtc-codereview.appspot.com/1641004/
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 VideoRenderIPhoneImpl* ptrRenderer;
362 ptrRenderer = new VideoRenderIPhoneImpl(_id, kRenderiPhone, window, _fullScreen);
363 if (!ptrRenderer)
364 {
365 return -1;
366 }
367 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
368 return _ptrRenderer->ChangeWindow(window);
fischman@webrtc.orgc6d5b502013-07-18 02:02:07 +0000369#else
370 return -1;
371#endif
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000372#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000373
374 _ptrRenderer = NULL;
375 delete _ptrRenderer;
376
377#if defined(COCOA_RENDERING)
378 VideoRenderMacCocoaImpl* ptrRenderer;
379 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen);
380#elif defined(CARBON_RENDERING)
381 VideoRenderMacCarbonImpl* ptrRenderer;
382 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen);
383#endif
384 if (!ptrRenderer)
385 {
386 return -1;
387 }
388 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
389 return _ptrRenderer->ChangeWindow(window);
390
391#else
392 if (!_ptrRenderer)
393 {
394 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
395 "%s: No renderer", __FUNCTION__);
396 return -1;
397 }
398 return _ptrRenderer->ChangeWindow(window);
399
400#endif
401
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000402#else // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000403 return -1;
404#endif
405}
406
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000407int32_t ModuleVideoRenderImpl::Id()
niklase@google.com470e71d2011-07-07 08:21:25 +0000408{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000409 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 return _id;
411}
412
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000413uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(
414 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000415{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000416 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000417
418 MapItem* mapItem = _streamRenderMap.Find(streamId);
419 if (mapItem == NULL)
420 {
421 // This stream doesn't exist
422 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
423 "%s: stream doesn't exist", __FUNCTION__);
424 return 0;
425 }
426 IncomingVideoStream* incomingStream =
427 static_cast<IncomingVideoStream*> (mapItem->GetItem());
428 if (incomingStream == NULL)
429 {
430 // This should never happen
431 assert(false);
432 _streamRenderMap.Erase(mapItem);
433 return 0;
434 }
435 return incomingStream->IncomingRate();
436}
437
438VideoRenderCallback*
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000439ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId,
440 const uint32_t zOrder,
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 const float left,
442 const float top,
443 const float right,
444 const float bottom)
445{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000446 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000447
448 if (!_ptrRenderer)
449 {
450 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
451 "%s: No renderer", __FUNCTION__);
452 return NULL;
453 }
454
455 if (_streamRenderMap.Find(streamId) != NULL)
456 {
457 // The stream already exists...
458 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
459 "%s: stream already exists", __FUNCTION__);
460 return NULL;
461 }
462
niklase@google.com470e71d2011-07-07 08:21:25 +0000463 VideoRenderCallback* ptrRenderCallback =
464 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top,
465 right, bottom);
466 if (ptrRenderCallback == NULL)
467 {
468 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
469 "%s: Can't create incoming stream in renderer",
470 __FUNCTION__);
471 return NULL;
472 }
473
wu@webrtc.org9143f772012-02-08 00:14:25 +0000474 // Create platform independant code
475 IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(_id,
476 streamId);
477 if (ptrIncomingStream == NULL)
478 {
479 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
480 "%s: Can't create incoming stream", __FUNCTION__);
481 return NULL;
482 }
483
484
niklase@google.com470e71d2011-07-07 08:21:25 +0000485 if (ptrIncomingStream->SetRenderCallback(ptrRenderCallback) == -1)
486 {
487 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
488 "%s: Can't set render callback", __FUNCTION__);
489 delete ptrIncomingStream;
490 _ptrRenderer->DeleteIncomingRenderStream(streamId);
491 return NULL;
492 }
493
494 VideoRenderCallback* moduleCallback =
495 ptrIncomingStream->ModuleCallback();
496
497 // Store the stream
498 _streamRenderMap.Insert(streamId, ptrIncomingStream);
499
500 return moduleCallback;
501}
502
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000503int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
504 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000505{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000506 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507
508 if (!_ptrRenderer)
509 {
510 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
511 "%s: No renderer", __FUNCTION__);
512 return -1;
513 }
514
515 MapItem* mapItem = _streamRenderMap.Find(streamId);
516 if (!mapItem)
517 {
518 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
519 "%s: stream doesn't exist", __FUNCTION__);
520 return -1;
521 }
522
523 IncomingVideoStream* ptrIncomingStream =
524 static_cast<IncomingVideoStream*> (mapItem->GetItem());
525 delete ptrIncomingStream;
526 ptrIncomingStream = NULL;
527 _ptrRenderer->DeleteIncomingRenderStream(streamId);
528 _streamRenderMap.Erase(mapItem);
529
530 return 0;
531}
532
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000533int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
534 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000535 VideoRenderCallback* renderObject)
536{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000537 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000538
539 MapItem* mapItem = _streamRenderMap.Find(streamId);
540 if (!mapItem)
541 {
542 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
543 "%s: stream doesn't exist", __FUNCTION__);
544 return -1;
545 }
546
547 IncomingVideoStream* ptrIncomingStream =
548 static_cast<IncomingVideoStream*> (mapItem->GetItem());
wu@webrtc.org9143f772012-02-08 00:14:25 +0000549 if (!ptrIncomingStream) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
551 "%s: could not get stream", __FUNCTION__);
wu@webrtc.org9143f772012-02-08 00:14:25 +0000552 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
554 return ptrIncomingStream->SetExternalCallback(renderObject);
555}
556
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000557int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
558 const uint32_t streamId,
559 uint32_t& zOrder,
niklase@google.com470e71d2011-07-07 08:21:25 +0000560 float& left,
561 float& top,
562 float& right,
563 float& bottom) const
564{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000565 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000566
567 if (!_ptrRenderer)
568 {
569 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
570 "%s: No renderer", __FUNCTION__);
571 return -1;
572 }
573
574 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
575 left, top, right,
576 bottom);
577}
578
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000579uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000580{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000581 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000582
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000583 return (uint32_t) _streamRenderMap.Size();
niklase@google.com470e71d2011-07-07 08:21:25 +0000584}
585
586bool ModuleVideoRenderImpl::HasIncomingRenderStream(
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000587 const uint32_t streamId) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000588{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000589 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000590
591 bool hasStream = false;
592 if (_streamRenderMap.Find(streamId) != NULL)
593 {
594 hasStream = true;
595 }
596 return hasStream;
597}
598
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000599int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
600 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000601 VideoRenderCallback* callbackObj)
602{
603 return -1;
604}
605
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000606int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000607{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000608 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000609
610 if (!_ptrRenderer)
611 {
612 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
613 "%s: No renderer", __FUNCTION__);
614 return -1;
615 }
616
617 // Start the stream
618 MapItem* item = _streamRenderMap.Find(streamId);
619 if (item == NULL)
620 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000621 return -1;
622 }
623
624 IncomingVideoStream* incomingStream =
625 static_cast<IncomingVideoStream*> (item->GetItem());
626 if (incomingStream->Start() == -1)
627 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000628 return -1;
629 }
630
631 // Start the HW renderer
632 if (_ptrRenderer->StartRender() == -1)
633 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000634 return -1;
635 }
636 return 0;
637}
638
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000639int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000640{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000641 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000642
643 if (!_ptrRenderer)
644 {
645 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
646 "%s(%d): No renderer", __FUNCTION__, streamId);
647 return -1;
648 }
649
650 // Stop the incoming stream
651 MapItem* item = _streamRenderMap.Find(streamId);
652 if (item == NULL)
653 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000654 return -1;
655 }
656
657 IncomingVideoStream* incomingStream =
658 static_cast<IncomingVideoStream*> (item->GetItem());
659 if (incomingStream->Stop() == -1)
660 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000661 return -1;
662 }
663
664 return 0;
665}
666
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000667int32_t ModuleVideoRenderImpl::ResetRender()
niklase@google.com470e71d2011-07-07 08:21:25 +0000668{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000669 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000670
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000671 int32_t error = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000672
673 // Loop through all incoming streams and stop them
674 MapItem* item = _streamRenderMap.First();
675 while (item)
676 {
677 IncomingVideoStream* incomingStream =
678 static_cast<IncomingVideoStream*> (item->GetItem());
679 if (incomingStream->Reset() == -1)
680 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000681 error = -1;
682 }
683 item = _streamRenderMap.Next(item);
684 }
685 return error;
686}
687
688RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
689{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000690 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000691
692 if (_ptrRenderer == NULL)
693 {
694 return kVideoI420;
695 }
696
697 return _ptrRenderer->PerferedVideoType();
698}
699
700bool ModuleVideoRenderImpl::IsFullScreen()
701{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000702 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000703
704 if (!_ptrRenderer)
705 {
706 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
707 "%s: No renderer", __FUNCTION__);
708 return false;
709 }
710 return _ptrRenderer->FullScreen();
711}
712
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000713int32_t ModuleVideoRenderImpl::GetScreenResolution(
714 uint32_t& screenWidth,
715 uint32_t& screenHeight) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000716{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000717 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000718
719 if (!_ptrRenderer)
720 {
721 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
722 "%s: No renderer", __FUNCTION__);
723 return false;
724 }
725 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
726}
727
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000728uint32_t ModuleVideoRenderImpl::RenderFrameRate(
729 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000730{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000731 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000732
733 if (!_ptrRenderer)
734 {
735 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
736 "%s: No renderer", __FUNCTION__);
737 return false;
738 }
739 return _ptrRenderer->RenderFrameRate(streamId);
740}
741
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000742int32_t ModuleVideoRenderImpl::SetStreamCropping(
743 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000744 const float left,
745 const float top,
746 const float right,
747 const float bottom)
748{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000749 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000750
751 if (!_ptrRenderer)
752 {
753 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
754 "%s: No renderer", __FUNCTION__);
755 return false;
756 }
757 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
758}
759
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000760int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000761{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000762 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000763
764 if (!_ptrRenderer)
765 {
766 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
767 "%s: No renderer", __FUNCTION__);
768 return false;
769 }
770 return _ptrRenderer->SetTransparentBackground(enable);
771}
772
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000773int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000774{
775 return -1;
776}
777
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000778int32_t ModuleVideoRenderImpl::SetText(
779 const uint8_t textId,
780 const uint8_t* text,
781 const int32_t textLength,
782 const uint32_t textColorRef,
783 const uint32_t backgroundColorRef,
niklase@google.com470e71d2011-07-07 08:21:25 +0000784 const float left, const float top,
785 const float right,
786 const float bottom)
787{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000788 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
790 if (!_ptrRenderer)
791 {
792 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
793 "%s: No renderer", __FUNCTION__);
794 return -1;
795 }
796 return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
797 backgroundColorRef, left, top, right, bottom);
798}
799
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000800int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
801 const uint8_t pictureId,
802 const void* colorKey,
803 const float left,
804 const float top,
805 const float right,
806 const float bottom)
niklase@google.com470e71d2011-07-07 08:21:25 +0000807{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000808 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000809
810 if (!_ptrRenderer)
811 {
812 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
813 "%s: No renderer", __FUNCTION__);
814 return -1;
815 }
816 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
817 right, bottom);
818}
819
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000820int32_t ModuleVideoRenderImpl::GetLastRenderedFrame(
821 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000822 I420VideoFrame &frame) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000823{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000824 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000825
826 if (!_ptrRenderer)
827 {
828 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
829 "%s: No renderer", __FUNCTION__);
830 return -1;
831 }
832
833 MapItem *item = _streamRenderMap.Find(streamId);
834 if (item == NULL)
835 {
836 // This stream doesn't exist
837 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
838 "%s: stream doesn't exist", __FUNCTION__);
839 return 0;
840 }
841 IncomingVideoStream* incomingStream =
842 static_cast<IncomingVideoStream*> (item->GetItem());
843 if (incomingStream == NULL)
844 {
845 // This should never happen
846 assert(false);
847 _streamRenderMap.Erase(item);
848 return 0;
849 }
850 return incomingStream->GetLastRenderedFrame(frame);
851}
852
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000853int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
854 uint32_t stream_id, int32_t delay_ms) {
mflodman@webrtc.orgaeb37d32012-10-11 16:31:00 +0000855 CriticalSectionScoped cs(&_moduleCrit);
mflodman@webrtc.orgf4f21452012-09-28 11:27:35 +0000856
857 if (!_ptrRenderer) {
858 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
859 "%s: No renderer", __FUNCTION__);
860 return false;
861 }
862
863 MapItem *item = _streamRenderMap.Find(stream_id);
864 if (item == NULL) {
865 // This stream doesn't exist
866 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
867 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
868 delay_ms);
869 return -1;
870 }
871
872 IncomingVideoStream* incoming_stream =
873 static_cast<IncomingVideoStream*> (item->GetItem());
874 if (incoming_stream == NULL) {
875 // This should never happen
876 assert(false);
877 _streamRenderMap.Erase(item);
878 return 0;
879 }
880
881 return incoming_stream->SetExpectedRenderDelay(delay_ms);
882}
883
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000884int32_t ModuleVideoRenderImpl::ConfigureRenderer(
885 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000886 const unsigned int zOrder,
887 const float left,
888 const float top,
889 const float right,
890 const float bottom)
891{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000892 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000893
894 if (!_ptrRenderer)
895 {
896 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
897 "%s: No renderer", __FUNCTION__);
898 return false;
899 }
900 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
901 bottom);
902}
903
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000904int32_t ModuleVideoRenderImpl::SetStartImage(
905 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000906 const I420VideoFrame& videoFrame)
niklase@google.com470e71d2011-07-07 08:21:25 +0000907{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000908 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000909
910 if (!_ptrRenderer)
911 {
912 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
913 "%s: No renderer", __FUNCTION__);
914 return -1;
915 }
916
917 MapItem *item = _streamRenderMap.Find(streamId);
918 if (item == NULL)
919 {
920 // This stream doesn't exist
921 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
922 "%s: stream doesn't exist", __FUNCTION__);
923 return -1;
924 }
925 IncomingVideoStream* incomingStream =
926 static_cast<IncomingVideoStream*> (item->GetItem());
927 if (incomingStream == NULL)
928 {
929 // This should never happen
930 assert(false);
931 _streamRenderMap.Erase(item);
932 return 0;
933 }
934 return incomingStream->SetStartImage(videoFrame);
935
936}
937
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000938int32_t ModuleVideoRenderImpl::SetTimeoutImage(
939 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000940 const I420VideoFrame& videoFrame,
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000941 const uint32_t timeout)
niklase@google.com470e71d2011-07-07 08:21:25 +0000942{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000943 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000944
945 if (!_ptrRenderer)
946 {
947 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
948 "%s: No renderer", __FUNCTION__);
949 return -1;
950 }
951
952 MapItem *item = _streamRenderMap.Find(streamId);
953 if (item == NULL)
954 {
955 // This stream doesn't exist
956 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
957 "%s: stream doesn't exist", __FUNCTION__);
958 return -1;
959 }
960 IncomingVideoStream* incomingStream =
961 static_cast<IncomingVideoStream*> (item->GetItem());
962 if (incomingStream == NULL)
963 {
964 // This should never happen
965 assert(false);
966 _streamRenderMap.Erase(item);
967 return 0;
968 }
969 return incomingStream->SetTimeoutImage(videoFrame, timeout);
970}
971
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000972int32_t ModuleVideoRenderImpl::MirrorRenderStream(const int renderId,
973 const bool enable,
974 const bool mirrorXAxis,
975 const bool mirrorYAxis)
niklase@google.com470e71d2011-07-07 08:21:25 +0000976{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000977 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000978
979 if (!_ptrRenderer)
980 {
981 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
982 "%s: No renderer", __FUNCTION__);
983 return -1;
984 }
985
986 MapItem *item = _streamRenderMap.Find(renderId);
987 if (item == NULL)
988 {
989 // This stream doesn't exist
990 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
991 "%s: stream doesn't exist", __FUNCTION__);
992 return 0;
993 }
994 IncomingVideoStream* incomingStream =
995 static_cast<IncomingVideoStream*> (item->GetItem());
996 if (incomingStream == NULL)
997 {
998 // This should never happen
999 assert(false);
1000 _streamRenderMap.Erase(item);
1001 return 0;
1002 }
1003
1004 return incomingStream->EnableMirroring(enable, mirrorXAxis, mirrorYAxis);
1005}
1006
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001007} // namespace webrtc