blob: cce26ba92113bcc54cde8ee8dfe879493d6a10ce [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
11#include "video_render_impl.h"
12#include "engine_configurations.h"
13#include "critical_section_wrapper.h"
14#include "video_render_defines.h"
15#include "trace.h"
16#include "incoming_video_stream.h"
andrew@webrtc.org9841d922012-10-31 05:22:11 +000017#include "webrtc/modules/video_render/i_video_render.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000018
19#include <cassert>
20
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)
24#include "windows/video_render_windows_impl.h"
25#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
29#elif defined(WEBRTC_IOS)
niklase@google.com470e71d2011-07-07 08:21:25 +000030#if defined(IPHONE_GLES_RENDERING)
31#define STANDARD_RENDERING kRenderiPhone
32#include "iPhone/video_render_iphone_impl.h"
33#endif
34
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +000035#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +000036#if defined(COCOA_RENDERING)
37#define STANDARD_RENDERING kRenderCocoa
38#include "mac/video_render_mac_cocoa_impl.h"
39#elif defined(CARBON_RENDERING)
40#define STANDARD_RENDERING kRenderCarbon
41#include "mac/video_render_mac_carbon_impl.h"
42#endif
43
leozwang@google.com03bc96d2011-07-26 05:03:10 +000044#elif defined(WEBRTC_ANDROID)
leozwang@webrtc.orgac9fd8a2012-03-19 21:09:42 +000045#include "android/video_render_android_impl.h"
46#include "android/video_render_android_surface_view.h"
47#include "android/video_render_android_native_opengl2.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000048#define STANDARD_RENDERING kRenderAndroid
49
50#elif defined(WEBRTC_LINUX)
51#include "linux/video_render_linux_impl.h"
52#define STANDARD_RENDERING kRenderX11
53
54#else
55//Other platforms
56#endif
57
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +000058#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +000059
60// For external rendering
61#include "external/video_render_external_impl.h"
62#ifndef STANDARD_RENDERING
63#define STANDARD_RENDERING kRenderExternal
64#endif // STANDARD_RENDERING
65
66namespace webrtc {
67
68VideoRender*
69VideoRender::CreateVideoRender(const WebRtc_Word32 id,
70 void* window,
71 const bool fullscreen,
72 const VideoRenderType videoRenderType/*=kRenderDefault*/)
73{
niklase@google.com470e71d2011-07-07 08:21:25 +000074 VideoRenderType resultVideoRenderType = videoRenderType;
75 if (videoRenderType == kRenderDefault)
76 {
77 resultVideoRenderType = STANDARD_RENDERING;
78 }
79 return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
80 fullscreen);
81}
82
83void VideoRender::DestroyVideoRender(
84 VideoRender* module)
85{
86 if (module)
87 {
niklase@google.com470e71d2011-07-07 08:21:25 +000088 delete module;
89 }
90}
91
niklase@google.com470e71d2011-07-07 08:21:25 +000092ModuleVideoRenderImpl::ModuleVideoRenderImpl(
93 const WebRtc_Word32 id,
94 const VideoRenderType videoRenderType,
95 void* window,
96 const bool fullscreen) :
97 _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()),
wu@webrtc.org2259f852012-06-19 14:56:50 +000098 _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL),
99 _streamRenderMap(*(new MapWrapper()))
niklase@google.com470e71d2011-07-07 08:21:25 +0000100{
101
102 // Create platform specific renderer
103 switch (videoRenderType)
104 {
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000105#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000106
107#if defined(_WIN32)
108 case kRenderWindows:
109 {
110 VideoRenderWindowsImpl* ptrRenderer;
111 ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen);
112 if (ptrRenderer)
113 {
114 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
115 }
116 }
117 break;
118
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000119#elif defined(WEBRTC_IOS)
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 case kRenderiPhone:
121 {
122 VideoRenderIPhoneImpl* ptrRenderer = new VideoRenderIPhoneImpl(_id, videoRenderType, window, _fullScreen);
123 if(ptrRenderer)
124 {
125 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
126 }
127 }
128 break;
129
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000130#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000131
132#if defined(COCOA_RENDERING)
133 case kRenderCocoa:
134 {
135 VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen);
136 if(ptrRenderer)
137 {
138 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
139 }
140 }
141
142 break;
143#elif defined(CARBON_RENDERING)
144 case kRenderCarbon:
145 {
146 VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen);
147 if(ptrRenderer)
148 {
149 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
150 }
151 }
152 break;
153#endif
154
leozwang@google.com03bc96d2011-07-26 05:03:10 +0000155#elif defined(WEBRTC_ANDROID)
niklase@google.com470e71d2011-07-07 08:21:25 +0000156 case kRenderAndroid:
157 {
158 if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window))
159 {
160 AndroidNativeOpenGl2Renderer* ptrRenderer = NULL;
161 ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen);
162 if (ptrRenderer)
163 {
164 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
165 }
166 }
167 else
168 {
169 AndroidSurfaceViewRenderer* ptrRenderer = NULL;
170 ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen);
171 if (ptrRenderer)
172 {
173 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
174 }
175 }
176
177 }
178 break;
179#elif defined(WEBRTC_LINUX)
180 case kRenderX11:
181 {
182 VideoRenderLinuxImpl* ptrRenderer = NULL;
183 ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen);
184 if ( ptrRenderer )
185 {
186 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
187 }
188 }
189 break;
190
191#else
192 // Other platforms
193#endif
194
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000195#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000196 case kRenderExternal:
197 {
198 VideoRenderExternalImpl* ptrRenderer(NULL);
199 ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType,
200 window, _fullScreen);
201 if (ptrRenderer)
202 {
203 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
204 }
205 }
206 break;
207 default:
208 // Error...
209 break;
210 }
211 if (_ptrRenderer)
212 {
213 if (_ptrRenderer->Init() == -1)
214 {
215 }
216 }
217}
218
219ModuleVideoRenderImpl::~ModuleVideoRenderImpl()
220{
221 delete &_moduleCrit;
222
223 while (_streamRenderMap.Size() > 0)
224 {
225 MapItem* item = _streamRenderMap.First();
226 IncomingVideoStream* ptrIncomingStream =
227 static_cast<IncomingVideoStream*> (item->GetItem());
228 assert(ptrIncomingStream != NULL);
229 delete ptrIncomingStream;
230 _streamRenderMap.Erase(item);
231 }
232 delete &_streamRenderMap;
233
234 // Delete platform specific renderer
235 if (_ptrRenderer)
236 {
237 VideoRenderType videoRenderType = _ptrRenderer->RenderType();
238 switch (videoRenderType)
239 {
240 case kRenderExternal:
241 {
242 VideoRenderExternalImpl
243 * ptrRenderer =
244 reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer);
245 _ptrRenderer = NULL;
246 delete ptrRenderer;
247 }
248 break;
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000249#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000250
251#if defined(_WIN32)
252 case kRenderWindows:
253 {
254 VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer);
255 _ptrRenderer = NULL;
256 delete ptrRenderer;
257 }
258 break;
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000259#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000260
261#if defined(COCOA_RENDERING)
262 case kRenderCocoa:
263 {
264 VideoRenderMacCocoaImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCocoaImpl*> (_ptrRenderer);
265 _ptrRenderer = NULL;
266 delete ptrRenderer;
267 }
268 break;
269#elif defined(CARBON_RENDERING)
270 case kRenderCarbon:
271 {
272 VideoRenderMacCarbonImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCarbonImpl*> (_ptrRenderer);
273 _ptrRenderer = NULL;
274 delete ptrRenderer;
275 }
276 break;
277#endif
278
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000279#elif defined(WEBRTC_IOS)
niklase@google.com470e71d2011-07-07 08:21:25 +0000280 case kRenderiPhone:
281 break;
282
leozwang@google.com03bc96d2011-07-26 05:03:10 +0000283#elif defined(WEBRTC_ANDROID)
niklase@google.com470e71d2011-07-07 08:21:25 +0000284 case kRenderAndroid:
285 {
286 VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer);
287 _ptrRenderer = NULL;
288 delete ptrRenderer;
289 }
290 break;
291
292#elif defined(WEBRTC_LINUX)
293 case kRenderX11:
294 {
295 VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer);
296 _ptrRenderer = NULL;
297 delete ptrRenderer;
298 }
299 break;
300#else
301 //other platforms
302#endif
303
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000304#endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000305
306 default:
307 // Error...
308 break;
309 }
310 }
311}
312
niklase@google.com470e71d2011-07-07 08:21:25 +0000313WebRtc_Word32 ModuleVideoRenderImpl::ChangeUniqueId(const WebRtc_Word32 id)
314{
niklase@google.com470e71d2011-07-07 08:21:25 +0000315
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000316 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000317
318 _id = id;
319
320 if (_ptrRenderer)
321 {
322 _ptrRenderer->ChangeUniqueId(_id);
323 }
324
325 return 0;
326}
327
328WebRtc_Word32 ModuleVideoRenderImpl::TimeUntilNextProcess()
329{
330 // Not used
331 return 50;
332}
333WebRtc_Word32 ModuleVideoRenderImpl::Process()
334{
335 // Not used
336 return 0;
337}
338
339void*
340ModuleVideoRenderImpl::Window()
341{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000342 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 return _ptrWindow;
344}
345
346WebRtc_Word32 ModuleVideoRenderImpl::ChangeWindow(void* window)
347{
348
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000349 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000350
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000351#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000352
sjlee@webrtc.org414fa7f2012-09-11 17:25:46 +0000353#if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 _ptrRenderer = NULL;
355 delete _ptrRenderer;
356
357 VideoRenderIPhoneImpl* ptrRenderer;
358 ptrRenderer = new VideoRenderIPhoneImpl(_id, kRenderiPhone, window, _fullScreen);
359 if (!ptrRenderer)
360 {
361 return -1;
362 }
363 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
364 return _ptrRenderer->ChangeWindow(window);
365
andrew@webrtc.orgf3b65db2012-09-06 18:17:00 +0000366#elif defined(WEBRTC_MAC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000367
368 _ptrRenderer = NULL;
369 delete _ptrRenderer;
370
371#if defined(COCOA_RENDERING)
372 VideoRenderMacCocoaImpl* ptrRenderer;
373 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen);
374#elif defined(CARBON_RENDERING)
375 VideoRenderMacCarbonImpl* ptrRenderer;
376 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen);
377#endif
378 if (!ptrRenderer)
379 {
380 return -1;
381 }
382 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
383 return _ptrRenderer->ChangeWindow(window);
384
385#else
386 if (!_ptrRenderer)
387 {
388 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
389 "%s: No renderer", __FUNCTION__);
390 return -1;
391 }
392 return _ptrRenderer->ChangeWindow(window);
393
394#endif
395
wu@webrtc.orgf3f2f6a2011-10-19 18:42:17 +0000396#else // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
niklase@google.com470e71d2011-07-07 08:21:25 +0000397 return -1;
398#endif
399}
400
401WebRtc_Word32 ModuleVideoRenderImpl::Id()
402{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000403 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000404 return _id;
405}
406
407WebRtc_UWord32 ModuleVideoRenderImpl::GetIncomingFrameRate(
408 const WebRtc_UWord32 streamId)
409{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000410 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000411
412 MapItem* mapItem = _streamRenderMap.Find(streamId);
413 if (mapItem == NULL)
414 {
415 // This stream doesn't exist
416 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
417 "%s: stream doesn't exist", __FUNCTION__);
418 return 0;
419 }
420 IncomingVideoStream* incomingStream =
421 static_cast<IncomingVideoStream*> (mapItem->GetItem());
422 if (incomingStream == NULL)
423 {
424 // This should never happen
425 assert(false);
426 _streamRenderMap.Erase(mapItem);
427 return 0;
428 }
429 return incomingStream->IncomingRate();
430}
431
432VideoRenderCallback*
433ModuleVideoRenderImpl::AddIncomingRenderStream(const WebRtc_UWord32 streamId,
434 const WebRtc_UWord32 zOrder,
435 const float left,
436 const float top,
437 const float right,
438 const float bottom)
439{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000440 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000441
442 if (!_ptrRenderer)
443 {
444 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
445 "%s: No renderer", __FUNCTION__);
446 return NULL;
447 }
448
449 if (_streamRenderMap.Find(streamId) != NULL)
450 {
451 // The stream already exists...
452 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
453 "%s: stream already exists", __FUNCTION__);
454 return NULL;
455 }
456
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 VideoRenderCallback* ptrRenderCallback =
458 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top,
459 right, bottom);
460 if (ptrRenderCallback == NULL)
461 {
462 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
463 "%s: Can't create incoming stream in renderer",
464 __FUNCTION__);
465 return NULL;
466 }
467
wu@webrtc.org9143f772012-02-08 00:14:25 +0000468 // Create platform independant code
469 IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(_id,
470 streamId);
471 if (ptrIncomingStream == NULL)
472 {
473 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
474 "%s: Can't create incoming stream", __FUNCTION__);
475 return NULL;
476 }
477
478
niklase@google.com470e71d2011-07-07 08:21:25 +0000479 if (ptrIncomingStream->SetRenderCallback(ptrRenderCallback) == -1)
480 {
481 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
482 "%s: Can't set render callback", __FUNCTION__);
483 delete ptrIncomingStream;
484 _ptrRenderer->DeleteIncomingRenderStream(streamId);
485 return NULL;
486 }
487
488 VideoRenderCallback* moduleCallback =
489 ptrIncomingStream->ModuleCallback();
490
491 // Store the stream
492 _streamRenderMap.Insert(streamId, ptrIncomingStream);
493
494 return moduleCallback;
495}
496
497WebRtc_Word32 ModuleVideoRenderImpl::DeleteIncomingRenderStream(
498 const WebRtc_UWord32 streamId)
499{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000500 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000501
502 if (!_ptrRenderer)
503 {
504 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
505 "%s: No renderer", __FUNCTION__);
506 return -1;
507 }
508
509 MapItem* mapItem = _streamRenderMap.Find(streamId);
510 if (!mapItem)
511 {
512 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
513 "%s: stream doesn't exist", __FUNCTION__);
514 return -1;
515 }
516
517 IncomingVideoStream* ptrIncomingStream =
518 static_cast<IncomingVideoStream*> (mapItem->GetItem());
519 delete ptrIncomingStream;
520 ptrIncomingStream = NULL;
521 _ptrRenderer->DeleteIncomingRenderStream(streamId);
522 _streamRenderMap.Erase(mapItem);
523
524 return 0;
525}
526
527WebRtc_Word32 ModuleVideoRenderImpl::AddExternalRenderCallback(
528 const WebRtc_UWord32 streamId,
529 VideoRenderCallback* renderObject)
530{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000531 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000532
533 MapItem* mapItem = _streamRenderMap.Find(streamId);
534 if (!mapItem)
535 {
536 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
537 "%s: stream doesn't exist", __FUNCTION__);
538 return -1;
539 }
540
541 IncomingVideoStream* ptrIncomingStream =
542 static_cast<IncomingVideoStream*> (mapItem->GetItem());
wu@webrtc.org9143f772012-02-08 00:14:25 +0000543 if (!ptrIncomingStream) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000544 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
545 "%s: could not get stream", __FUNCTION__);
wu@webrtc.org9143f772012-02-08 00:14:25 +0000546 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 }
548 return ptrIncomingStream->SetExternalCallback(renderObject);
549}
550
551WebRtc_Word32 ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
552 const WebRtc_UWord32 streamId,
553 WebRtc_UWord32& zOrder,
554 float& left,
555 float& top,
556 float& right,
557 float& bottom) const
558{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000559 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000560
561 if (!_ptrRenderer)
562 {
563 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
564 "%s: No renderer", __FUNCTION__);
565 return -1;
566 }
567
568 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
569 left, top, right,
570 bottom);
571}
572
573WebRtc_UWord32 ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
574{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000575 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576
577 return (WebRtc_UWord32) _streamRenderMap.Size();
578}
579
580bool ModuleVideoRenderImpl::HasIncomingRenderStream(
581 const WebRtc_UWord32 streamId) const
582{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000583 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000584
585 bool hasStream = false;
586 if (_streamRenderMap.Find(streamId) != NULL)
587 {
588 hasStream = true;
589 }
590 return hasStream;
591}
592
593WebRtc_Word32 ModuleVideoRenderImpl::RegisterRawFrameCallback(
594 const WebRtc_UWord32 streamId,
595 VideoRenderCallback* callbackObj)
596{
597 return -1;
598}
599
600WebRtc_Word32 ModuleVideoRenderImpl::StartRender(const WebRtc_UWord32 streamId)
601{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000602 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
604 if (!_ptrRenderer)
605 {
606 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
607 "%s: No renderer", __FUNCTION__);
608 return -1;
609 }
610
611 // Start the stream
612 MapItem* item = _streamRenderMap.Find(streamId);
613 if (item == NULL)
614 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000615 return -1;
616 }
617
618 IncomingVideoStream* incomingStream =
619 static_cast<IncomingVideoStream*> (item->GetItem());
620 if (incomingStream->Start() == -1)
621 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000622 return -1;
623 }
624
625 // Start the HW renderer
626 if (_ptrRenderer->StartRender() == -1)
627 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000628 return -1;
629 }
630 return 0;
631}
632
633WebRtc_Word32 ModuleVideoRenderImpl::StopRender(const WebRtc_UWord32 streamId)
634{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000635 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000636
637 if (!_ptrRenderer)
638 {
639 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
640 "%s(%d): No renderer", __FUNCTION__, streamId);
641 return -1;
642 }
643
644 // Stop the incoming stream
645 MapItem* item = _streamRenderMap.Find(streamId);
646 if (item == NULL)
647 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000648 return -1;
649 }
650
651 IncomingVideoStream* incomingStream =
652 static_cast<IncomingVideoStream*> (item->GetItem());
653 if (incomingStream->Stop() == -1)
654 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000655 return -1;
656 }
657
658 return 0;
659}
660
661WebRtc_Word32 ModuleVideoRenderImpl::ResetRender()
662{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000663 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000664
665 WebRtc_Word32 error = 0;
666
667 // Loop through all incoming streams and stop them
668 MapItem* item = _streamRenderMap.First();
669 while (item)
670 {
671 IncomingVideoStream* incomingStream =
672 static_cast<IncomingVideoStream*> (item->GetItem());
673 if (incomingStream->Reset() == -1)
674 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000675 error = -1;
676 }
677 item = _streamRenderMap.Next(item);
678 }
679 return error;
680}
681
682RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
683{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000684 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000685
686 if (_ptrRenderer == NULL)
687 {
688 return kVideoI420;
689 }
690
691 return _ptrRenderer->PerferedVideoType();
692}
693
694bool ModuleVideoRenderImpl::IsFullScreen()
695{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000696 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000697
698 if (!_ptrRenderer)
699 {
700 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
701 "%s: No renderer", __FUNCTION__);
702 return false;
703 }
704 return _ptrRenderer->FullScreen();
705}
706
707WebRtc_Word32 ModuleVideoRenderImpl::GetScreenResolution(
708 WebRtc_UWord32& screenWidth,
709 WebRtc_UWord32& screenHeight) const
710{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000711 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000712
713 if (!_ptrRenderer)
714 {
715 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
716 "%s: No renderer", __FUNCTION__);
717 return false;
718 }
719 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
720}
721
722WebRtc_UWord32 ModuleVideoRenderImpl::RenderFrameRate(
723 const WebRtc_UWord32 streamId)
724{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000725 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000726
727 if (!_ptrRenderer)
728 {
729 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
730 "%s: No renderer", __FUNCTION__);
731 return false;
732 }
733 return _ptrRenderer->RenderFrameRate(streamId);
734}
735
736WebRtc_Word32 ModuleVideoRenderImpl::SetStreamCropping(
737 const WebRtc_UWord32 streamId,
738 const float left,
739 const float top,
740 const float right,
741 const float bottom)
742{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000743 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000744
745 if (!_ptrRenderer)
746 {
747 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
748 "%s: No renderer", __FUNCTION__);
749 return false;
750 }
751 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
752}
753
754WebRtc_Word32 ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
755{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000756 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000757
758 if (!_ptrRenderer)
759 {
760 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
761 "%s: No renderer", __FUNCTION__);
762 return false;
763 }
764 return _ptrRenderer->SetTransparentBackground(enable);
765}
766
767WebRtc_Word32 ModuleVideoRenderImpl::FullScreenRender(void* window,
768 const bool enable)
769{
770 return -1;
771}
772
773WebRtc_Word32 ModuleVideoRenderImpl::SetText(
774 const WebRtc_UWord8 textId,
775 const WebRtc_UWord8* text,
776 const WebRtc_Word32 textLength,
777 const WebRtc_UWord32 textColorRef,
778 const WebRtc_UWord32 backgroundColorRef,
779 const float left, const float top,
780 const float right,
781 const float bottom)
782{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000783 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000784
785 if (!_ptrRenderer)
786 {
787 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
788 "%s: No renderer", __FUNCTION__);
789 return -1;
790 }
791 return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
792 backgroundColorRef, left, top, right, bottom);
793}
794
795WebRtc_Word32 ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
796 const WebRtc_UWord8 pictureId,
797 const void* colorKey,
798 const float left,
799 const float top,
800 const float right,
801 const float bottom)
802{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000803 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000804
805 if (!_ptrRenderer)
806 {
807 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
808 "%s: No renderer", __FUNCTION__);
809 return -1;
810 }
811 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
812 right, bottom);
813}
814
815WebRtc_Word32 ModuleVideoRenderImpl::GetLastRenderedFrame(
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000816 const WebRtc_UWord32 streamId,
817 I420VideoFrame &frame) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000818{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000819 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000820
821 if (!_ptrRenderer)
822 {
823 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
824 "%s: No renderer", __FUNCTION__);
825 return -1;
826 }
827
828 MapItem *item = _streamRenderMap.Find(streamId);
829 if (item == NULL)
830 {
831 // This stream doesn't exist
832 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
833 "%s: stream doesn't exist", __FUNCTION__);
834 return 0;
835 }
836 IncomingVideoStream* incomingStream =
837 static_cast<IncomingVideoStream*> (item->GetItem());
838 if (incomingStream == NULL)
839 {
840 // This should never happen
841 assert(false);
842 _streamRenderMap.Erase(item);
843 return 0;
844 }
845 return incomingStream->GetLastRenderedFrame(frame);
846}
847
mflodman@webrtc.orgf4f21452012-09-28 11:27:35 +0000848WebRtc_Word32 ModuleVideoRenderImpl::SetExpectedRenderDelay(
849 WebRtc_UWord32 stream_id, WebRtc_Word32 delay_ms) {
mflodman@webrtc.orgaeb37d32012-10-11 16:31:00 +0000850 CriticalSectionScoped cs(&_moduleCrit);
mflodman@webrtc.orgf4f21452012-09-28 11:27:35 +0000851
852 if (!_ptrRenderer) {
853 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
854 "%s: No renderer", __FUNCTION__);
855 return false;
856 }
857
858 MapItem *item = _streamRenderMap.Find(stream_id);
859 if (item == NULL) {
860 // This stream doesn't exist
861 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
862 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
863 delay_ms);
864 return -1;
865 }
866
867 IncomingVideoStream* incoming_stream =
868 static_cast<IncomingVideoStream*> (item->GetItem());
869 if (incoming_stream == NULL) {
870 // This should never happen
871 assert(false);
872 _streamRenderMap.Erase(item);
873 return 0;
874 }
875
876 return incoming_stream->SetExpectedRenderDelay(delay_ms);
877}
878
niklase@google.com470e71d2011-07-07 08:21:25 +0000879WebRtc_Word32 ModuleVideoRenderImpl::ConfigureRenderer(
880 const WebRtc_UWord32 streamId,
881 const unsigned int zOrder,
882 const float left,
883 const float top,
884 const float right,
885 const float bottom)
886{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000887 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000888
889 if (!_ptrRenderer)
890 {
891 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
892 "%s: No renderer", __FUNCTION__);
893 return false;
894 }
895 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
896 bottom);
897}
898
899WebRtc_Word32 ModuleVideoRenderImpl::SetStartImage(
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000900 const WebRtc_UWord32 streamId,
901 const I420VideoFrame& videoFrame)
niklase@google.com470e71d2011-07-07 08:21:25 +0000902{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000903 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000904
905 if (!_ptrRenderer)
906 {
907 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
908 "%s: No renderer", __FUNCTION__);
909 return -1;
910 }
911
912 MapItem *item = _streamRenderMap.Find(streamId);
913 if (item == NULL)
914 {
915 // This stream doesn't exist
916 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
917 "%s: stream doesn't exist", __FUNCTION__);
918 return -1;
919 }
920 IncomingVideoStream* incomingStream =
921 static_cast<IncomingVideoStream*> (item->GetItem());
922 if (incomingStream == NULL)
923 {
924 // This should never happen
925 assert(false);
926 _streamRenderMap.Erase(item);
927 return 0;
928 }
929 return incomingStream->SetStartImage(videoFrame);
930
931}
932
933WebRtc_Word32 ModuleVideoRenderImpl::SetTimeoutImage(
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000934 const WebRtc_UWord32 streamId,
935 const I420VideoFrame& videoFrame,
936 const WebRtc_UWord32 timeout)
niklase@google.com470e71d2011-07-07 08:21:25 +0000937{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000938 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000939
940 if (!_ptrRenderer)
941 {
942 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
943 "%s: No renderer", __FUNCTION__);
944 return -1;
945 }
946
947 MapItem *item = _streamRenderMap.Find(streamId);
948 if (item == NULL)
949 {
950 // This stream doesn't exist
951 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
952 "%s: stream doesn't exist", __FUNCTION__);
953 return -1;
954 }
955 IncomingVideoStream* incomingStream =
956 static_cast<IncomingVideoStream*> (item->GetItem());
957 if (incomingStream == NULL)
958 {
959 // This should never happen
960 assert(false);
961 _streamRenderMap.Erase(item);
962 return 0;
963 }
964 return incomingStream->SetTimeoutImage(videoFrame, timeout);
965}
966
967WebRtc_Word32 ModuleVideoRenderImpl::MirrorRenderStream(const int renderId,
968 const bool enable,
969 const bool mirrorXAxis,
970 const bool mirrorYAxis)
971{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000972 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000973
974 if (!_ptrRenderer)
975 {
976 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
977 "%s: No renderer", __FUNCTION__);
978 return -1;
979 }
980
981 MapItem *item = _streamRenderMap.Find(renderId);
982 if (item == NULL)
983 {
984 // This stream doesn't exist
985 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
986 "%s: stream doesn't exist", __FUNCTION__);
987 return 0;
988 }
989 IncomingVideoStream* incomingStream =
990 static_cast<IncomingVideoStream*> (item->GetItem());
991 if (incomingStream == NULL)
992 {
993 // This should never happen
994 assert(false);
995 _streamRenderMap.Erase(item);
996 return 0;
997 }
998
999 return incomingStream->EnableMirroring(enable, mirrorXAxis, mirrorYAxis);
1000}
1001
1002} //namespace webrtc