blob: a6cff878e192e2cbfaa52e97b4cb6c723e989341 [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*
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +000069VideoRender::CreateVideoRender(const int32_t id,
niklase@google.com470e71d2011-07-07 08:21:25 +000070 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(
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +000093 const int32_t id,
niklase@google.com470e71d2011-07-07 08:21:25 +000094 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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000313int32_t ModuleVideoRenderImpl::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +0000314{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000328int32_t ModuleVideoRenderImpl::TimeUntilNextProcess()
niklase@google.com470e71d2011-07-07 08:21:25 +0000329{
330 // Not used
331 return 50;
332}
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000333int32_t ModuleVideoRenderImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +0000334{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000346int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
niklase@google.com470e71d2011-07-07 08:21:25 +0000347{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000401int32_t ModuleVideoRenderImpl::Id()
niklase@google.com470e71d2011-07-07 08:21:25 +0000402{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000407uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(
408 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000409{
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*
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000433ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId,
434 const uint32_t zOrder,
niklase@google.com470e71d2011-07-07 08:21:25 +0000435 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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000497int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
498 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000499{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000527int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
528 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000551int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
552 const uint32_t streamId,
553 uint32_t& zOrder,
niklase@google.com470e71d2011-07-07 08:21:25 +0000554 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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000573uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000574{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000575 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000577 return (uint32_t) _streamRenderMap.Size();
niklase@google.com470e71d2011-07-07 08:21:25 +0000578}
579
580bool ModuleVideoRenderImpl::HasIncomingRenderStream(
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000581 const uint32_t streamId) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000582{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000593int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
594 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000595 VideoRenderCallback* callbackObj)
596{
597 return -1;
598}
599
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000600int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000601{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000633int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000634{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000661int32_t ModuleVideoRenderImpl::ResetRender()
niklase@google.com470e71d2011-07-07 08:21:25 +0000662{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000663 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000664
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000665 int32_t error = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000666
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000707int32_t ModuleVideoRenderImpl::GetScreenResolution(
708 uint32_t& screenWidth,
709 uint32_t& screenHeight) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000710{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000722uint32_t ModuleVideoRenderImpl::RenderFrameRate(
723 const uint32_t streamId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000724{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000736int32_t ModuleVideoRenderImpl::SetStreamCropping(
737 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000738 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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000754int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000755{
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
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000767int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000768{
769 return -1;
770}
771
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000772int32_t ModuleVideoRenderImpl::SetText(
773 const uint8_t textId,
774 const uint8_t* text,
775 const int32_t textLength,
776 const uint32_t textColorRef,
777 const uint32_t backgroundColorRef,
niklase@google.com470e71d2011-07-07 08:21:25 +0000778 const float left, const float top,
779 const float right,
780 const float bottom)
781{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000782 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000783
784 if (!_ptrRenderer)
785 {
786 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
787 "%s: No renderer", __FUNCTION__);
788 return -1;
789 }
790 return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
791 backgroundColorRef, left, top, right, bottom);
792}
793
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000794int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
795 const uint8_t pictureId,
796 const void* colorKey,
797 const float left,
798 const float top,
799 const float right,
800 const float bottom)
niklase@google.com470e71d2011-07-07 08:21:25 +0000801{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000802 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
804 if (!_ptrRenderer)
805 {
806 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
807 "%s: No renderer", __FUNCTION__);
808 return -1;
809 }
810 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
811 right, bottom);
812}
813
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000814int32_t ModuleVideoRenderImpl::GetLastRenderedFrame(
815 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000816 I420VideoFrame &frame) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000817{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000818 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000819
820 if (!_ptrRenderer)
821 {
822 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
823 "%s: No renderer", __FUNCTION__);
824 return -1;
825 }
826
827 MapItem *item = _streamRenderMap.Find(streamId);
828 if (item == NULL)
829 {
830 // This stream doesn't exist
831 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
832 "%s: stream doesn't exist", __FUNCTION__);
833 return 0;
834 }
835 IncomingVideoStream* incomingStream =
836 static_cast<IncomingVideoStream*> (item->GetItem());
837 if (incomingStream == NULL)
838 {
839 // This should never happen
840 assert(false);
841 _streamRenderMap.Erase(item);
842 return 0;
843 }
844 return incomingStream->GetLastRenderedFrame(frame);
845}
846
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000847int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
848 uint32_t stream_id, int32_t delay_ms) {
mflodman@webrtc.orgaeb37d32012-10-11 16:31:00 +0000849 CriticalSectionScoped cs(&_moduleCrit);
mflodman@webrtc.orgf4f21452012-09-28 11:27:35 +0000850
851 if (!_ptrRenderer) {
852 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
853 "%s: No renderer", __FUNCTION__);
854 return false;
855 }
856
857 MapItem *item = _streamRenderMap.Find(stream_id);
858 if (item == NULL) {
859 // This stream doesn't exist
860 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
861 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
862 delay_ms);
863 return -1;
864 }
865
866 IncomingVideoStream* incoming_stream =
867 static_cast<IncomingVideoStream*> (item->GetItem());
868 if (incoming_stream == NULL) {
869 // This should never happen
870 assert(false);
871 _streamRenderMap.Erase(item);
872 return 0;
873 }
874
875 return incoming_stream->SetExpectedRenderDelay(delay_ms);
876}
877
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000878int32_t ModuleVideoRenderImpl::ConfigureRenderer(
879 const uint32_t streamId,
niklase@google.com470e71d2011-07-07 08:21:25 +0000880 const unsigned int zOrder,
881 const float left,
882 const float top,
883 const float right,
884 const float bottom)
885{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000886 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000887
888 if (!_ptrRenderer)
889 {
890 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
891 "%s: No renderer", __FUNCTION__);
892 return false;
893 }
894 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
895 bottom);
896}
897
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000898int32_t ModuleVideoRenderImpl::SetStartImage(
899 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000900 const I420VideoFrame& videoFrame)
niklase@google.com470e71d2011-07-07 08:21:25 +0000901{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000902 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000903
904 if (!_ptrRenderer)
905 {
906 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
907 "%s: No renderer", __FUNCTION__);
908 return -1;
909 }
910
911 MapItem *item = _streamRenderMap.Find(streamId);
912 if (item == NULL)
913 {
914 // This stream doesn't exist
915 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
916 "%s: stream doesn't exist", __FUNCTION__);
917 return -1;
918 }
919 IncomingVideoStream* incomingStream =
920 static_cast<IncomingVideoStream*> (item->GetItem());
921 if (incomingStream == NULL)
922 {
923 // This should never happen
924 assert(false);
925 _streamRenderMap.Erase(item);
926 return 0;
927 }
928 return incomingStream->SetStartImage(videoFrame);
929
930}
931
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000932int32_t ModuleVideoRenderImpl::SetTimeoutImage(
933 const uint32_t streamId,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000934 const I420VideoFrame& videoFrame,
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000935 const uint32_t timeout)
niklase@google.com470e71d2011-07-07 08:21:25 +0000936{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000937 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000938
939 if (!_ptrRenderer)
940 {
941 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
942 "%s: No renderer", __FUNCTION__);
943 return -1;
944 }
945
946 MapItem *item = _streamRenderMap.Find(streamId);
947 if (item == NULL)
948 {
949 // This stream doesn't exist
950 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
951 "%s: stream doesn't exist", __FUNCTION__);
952 return -1;
953 }
954 IncomingVideoStream* incomingStream =
955 static_cast<IncomingVideoStream*> (item->GetItem());
956 if (incomingStream == NULL)
957 {
958 // This should never happen
959 assert(false);
960 _streamRenderMap.Erase(item);
961 return 0;
962 }
963 return incomingStream->SetTimeoutImage(videoFrame, timeout);
964}
965
pbos@webrtc.orgddf94e72013-04-10 08:09:04 +0000966int32_t ModuleVideoRenderImpl::MirrorRenderStream(const int renderId,
967 const bool enable,
968 const bool mirrorXAxis,
969 const bool mirrorYAxis)
niklase@google.com470e71d2011-07-07 08:21:25 +0000970{
mflodman@webrtc.org0e703f42012-03-06 12:02:20 +0000971 CriticalSectionScoped cs(&_moduleCrit);
niklase@google.com470e71d2011-07-07 08:21:25 +0000972
973 if (!_ptrRenderer)
974 {
975 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
976 "%s: No renderer", __FUNCTION__);
977 return -1;
978 }
979
980 MapItem *item = _streamRenderMap.Find(renderId);
981 if (item == NULL)
982 {
983 // This stream doesn't exist
984 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
985 "%s: stream doesn't exist", __FUNCTION__);
986 return 0;
987 }
988 IncomingVideoStream* incomingStream =
989 static_cast<IncomingVideoStream*> (item->GetItem());
990 if (incomingStream == NULL)
991 {
992 // This should never happen
993 assert(false);
994 _streamRenderMap.Erase(item);
995 return 0;
996 }
997
998 return incomingStream->EnableMirroring(enable, mirrorXAxis, mirrorYAxis);
999}
1000
1001} //namespace webrtc