1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <assert.h>
12
13 #include "webrtc/engine_configurations.h"
14 #include "webrtc/modules/video_render/i_video_render.h"
15 #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"
20
21 #ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
22
23 #if defined (_WIN32)
24 #include "webrtc/modules/video_render/windows/video_render_windows_impl.h"
25 #define STANDARD_RENDERING kRenderWindows
26
27 // WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC
28 // gets defined if WEBRTC_IOS is defined
29 #elif defined(WEBRTC_IOS)
30 #define STANDARD_RENDERING kRenderiOS
31 #include "ios/video_render_ios_impl.h"
32 #elif defined(WEBRTC_MAC)
33 #if defined(COCOA_RENDERING)
34 #define STANDARD_RENDERING kRenderCocoa
35 #include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h"
36 #elif defined(CARBON_RENDERING)
37 #define STANDARD_RENDERING kRenderCarbon
38 #include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h"
39 #endif
40
41 #elif defined(WEBRTC_ANDROID)
42 #include "webrtc/modules/video_render/android/video_render_android_impl.h"
43 #include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h"
44 #include "webrtc/modules/video_render/android/video_render_android_surface_view.h"
45 #define STANDARD_RENDERING kRenderAndroid
46
47 #elif defined(WEBRTC_LINUX)
48 #include "webrtc/modules/video_render/linux/video_render_linux_impl.h"
49 #define STANDARD_RENDERING kRenderX11
50
51 #else
52 //Other platforms
53 #endif
54
55 #endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
56
57 // For external rendering
58 #include "webrtc/modules/video_render/external/video_render_external_impl.h"
59 #ifndef STANDARD_RENDERING
60 #define STANDARD_RENDERING kRenderExternal
61 #endif // STANDARD_RENDERING
62
63 namespace webrtc {
64
65 VideoRender*
CreateVideoRender(const int32_t id,void * window,const bool fullscreen,const VideoRenderType videoRenderType)66 VideoRender::CreateVideoRender(const int32_t id,
67 void* window,
68 const bool fullscreen,
69 const VideoRenderType videoRenderType/*=kRenderDefault*/)
70 {
71 VideoRenderType resultVideoRenderType = videoRenderType;
72 if (videoRenderType == kRenderDefault)
73 {
74 resultVideoRenderType = STANDARD_RENDERING;
75 }
76 return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
77 fullscreen);
78 }
79
DestroyVideoRender(VideoRender * module)80 void VideoRender::DestroyVideoRender(
81 VideoRender* module)
82 {
83 if (module)
84 {
85 delete module;
86 }
87 }
88
ModuleVideoRenderImpl(const int32_t id,const VideoRenderType videoRenderType,void * window,const bool fullscreen)89 ModuleVideoRenderImpl::ModuleVideoRenderImpl(
90 const int32_t id,
91 const VideoRenderType videoRenderType,
92 void* window,
93 const bool fullscreen) :
94 _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()),
95 _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL)
96 {
97
98 // Create platform specific renderer
99 switch (videoRenderType)
100 {
101 #ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
102
103 #if defined(_WIN32)
104 case kRenderWindows:
105 {
106 VideoRenderWindowsImpl* ptrRenderer;
107 ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen);
108 if (ptrRenderer)
109 {
110 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
111 }
112 }
113 break;
114
115 #elif defined(WEBRTC_IOS)
116 case kRenderiOS:
117 {
118 VideoRenderIosImpl* ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
119 if(ptrRenderer)
120 {
121 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
122 }
123 }
124 break;
125
126 #elif defined(WEBRTC_MAC)
127
128 #if defined(COCOA_RENDERING)
129 case kRenderCocoa:
130 {
131 VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen);
132 if(ptrRenderer)
133 {
134 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
135 }
136 }
137
138 break;
139 #elif defined(CARBON_RENDERING)
140 case kRenderCarbon:
141 {
142 VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen);
143 if(ptrRenderer)
144 {
145 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
146 }
147 }
148 break;
149 #endif
150
151 #elif defined(WEBRTC_ANDROID)
152 case kRenderAndroid:
153 {
154 if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window))
155 {
156 AndroidNativeOpenGl2Renderer* ptrRenderer = NULL;
157 ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen);
158 if (ptrRenderer)
159 {
160 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
161 }
162 }
163 else
164 {
165 AndroidSurfaceViewRenderer* ptrRenderer = NULL;
166 ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen);
167 if (ptrRenderer)
168 {
169 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
170 }
171 }
172
173 }
174 break;
175 #elif defined(WEBRTC_LINUX)
176 case kRenderX11:
177 {
178 VideoRenderLinuxImpl* ptrRenderer = NULL;
179 ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen);
180 if ( ptrRenderer )
181 {
182 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
183 }
184 }
185 break;
186
187 #else
188 // Other platforms
189 #endif
190
191 #endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
192 case kRenderExternal:
193 {
194 VideoRenderExternalImpl* ptrRenderer(NULL);
195 ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType,
196 window, _fullScreen);
197 if (ptrRenderer)
198 {
199 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
200 }
201 }
202 break;
203 default:
204 // Error...
205 break;
206 }
207 if (_ptrRenderer)
208 {
209 if (_ptrRenderer->Init() == -1)
210 {
211 }
212 }
213 }
214
~ModuleVideoRenderImpl()215 ModuleVideoRenderImpl::~ModuleVideoRenderImpl()
216 {
217 delete &_moduleCrit;
218
219 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
220 it != _streamRenderMap.end();
221 ++it) {
222 delete it->second;
223 }
224
225 // Delete platform specific renderer
226 if (_ptrRenderer)
227 {
228 VideoRenderType videoRenderType = _ptrRenderer->RenderType();
229
230 switch (videoRenderType)
231 {
232 case kRenderExternal:
233 {
234 VideoRenderExternalImpl
235 * ptrRenderer =
236 reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer);
237 _ptrRenderer = NULL;
238 delete ptrRenderer;
239 }
240 break;
241 #ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
242
243 #if defined(_WIN32)
244 case kRenderWindows:
245 {
246 VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer);
247 _ptrRenderer = NULL;
248 delete ptrRenderer;
249 }
250 break;
251 #elif defined(WEBRTC_IOS)
252 case kRenderiOS:
253 {
254 VideoRenderIosImpl* ptrRenderer = reinterpret_cast<VideoRenderIosImpl*> (_ptrRenderer);
255 _ptrRenderer = NULL;
256 delete ptrRenderer;
257 }
258 break;
259 #elif defined(WEBRTC_MAC)
260
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
279 #elif defined(WEBRTC_ANDROID)
280 case kRenderAndroid:
281 {
282 VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer);
283 _ptrRenderer = NULL;
284 delete ptrRenderer;
285 }
286 break;
287
288 #elif defined(WEBRTC_LINUX)
289 case kRenderX11:
290 {
291 VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer);
292 _ptrRenderer = NULL;
293 delete ptrRenderer;
294 }
295 break;
296 #else
297 //other platforms
298 #endif
299
300 #endif // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
301
302 default:
303 // Error...
304 break;
305 }
306 }
307 }
308
ChangeUniqueId(const int32_t id)309 int32_t ModuleVideoRenderImpl::ChangeUniqueId(const int32_t id)
310 {
311
312 CriticalSectionScoped cs(&_moduleCrit);
313
314 _id = id;
315
316 if (_ptrRenderer)
317 {
318 _ptrRenderer->ChangeUniqueId(_id);
319 }
320
321 return 0;
322 }
323
TimeUntilNextProcess()324 int32_t ModuleVideoRenderImpl::TimeUntilNextProcess()
325 {
326 // Not used
327 return 50;
328 }
Process()329 int32_t ModuleVideoRenderImpl::Process()
330 {
331 // Not used
332 return 0;
333 }
334
335 void*
Window()336 ModuleVideoRenderImpl::Window()
337 {
338 CriticalSectionScoped cs(&_moduleCrit);
339 return _ptrWindow;
340 }
341
ChangeWindow(void * window)342 int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
343 {
344
345 CriticalSectionScoped cs(&_moduleCrit);
346
347 #ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
348
349 #if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC
350 _ptrRenderer = NULL;
351 delete _ptrRenderer;
352
353 VideoRenderIosImpl* ptrRenderer;
354 ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
355 if (!ptrRenderer)
356 {
357 return -1;
358 }
359 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
360 return _ptrRenderer->ChangeWindow(window);
361 #elif defined(WEBRTC_MAC)
362
363 _ptrRenderer = NULL;
364 delete _ptrRenderer;
365
366 #if defined(COCOA_RENDERING)
367 VideoRenderMacCocoaImpl* ptrRenderer;
368 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen);
369 #elif defined(CARBON_RENDERING)
370 VideoRenderMacCarbonImpl* ptrRenderer;
371 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen);
372 #endif
373 if (!ptrRenderer)
374 {
375 return -1;
376 }
377 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
378 return _ptrRenderer->ChangeWindow(window);
379
380 #else
381 if (!_ptrRenderer)
382 {
383 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
384 "%s: No renderer", __FUNCTION__);
385 return -1;
386 }
387 return _ptrRenderer->ChangeWindow(window);
388
389 #endif
390
391 #else // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
392 return -1;
393 #endif
394 }
395
Id()396 int32_t ModuleVideoRenderImpl::Id()
397 {
398 CriticalSectionScoped cs(&_moduleCrit);
399 return _id;
400 }
401
GetIncomingFrameRate(const uint32_t streamId)402 uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) {
403 CriticalSectionScoped cs(&_moduleCrit);
404
405 IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId);
406
407 if (it == _streamRenderMap.end()) {
408 // This stream doesn't exist
409 WEBRTC_TRACE(kTraceError,
410 kTraceVideoRenderer,
411 _id,
412 "%s: stream doesn't exist",
413 __FUNCTION__);
414 return 0;
415 }
416 assert(it->second != NULL);
417 return it->second->IncomingRate();
418 }
419
420 VideoRenderCallback*
AddIncomingRenderStream(const uint32_t streamId,const uint32_t zOrder,const float left,const float top,const float right,const float bottom)421 ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId,
422 const uint32_t zOrder,
423 const float left,
424 const float top,
425 const float right,
426 const float bottom)
427 {
428 CriticalSectionScoped cs(&_moduleCrit);
429
430 if (!_ptrRenderer)
431 {
432 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
433 "%s: No renderer", __FUNCTION__);
434 return NULL;
435 }
436
437 if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) {
438 // The stream already exists...
439 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
440 "%s: stream already exists", __FUNCTION__);
441 return NULL;
442 }
443
444 VideoRenderCallback* ptrRenderCallback =
445 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top,
446 right, bottom);
447 if (ptrRenderCallback == NULL)
448 {
449 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
450 "%s: Can't create incoming stream in renderer",
451 __FUNCTION__);
452 return NULL;
453 }
454
455 // Create platform independant code
456 IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(_id,
457 streamId);
458 if (ptrIncomingStream == NULL)
459 {
460 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
461 "%s: Can't create incoming stream", __FUNCTION__);
462 return NULL;
463 }
464
465
466 if (ptrIncomingStream->SetRenderCallback(ptrRenderCallback) == -1)
467 {
468 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
469 "%s: Can't set render callback", __FUNCTION__);
470 delete ptrIncomingStream;
471 _ptrRenderer->DeleteIncomingRenderStream(streamId);
472 return NULL;
473 }
474
475 VideoRenderCallback* moduleCallback =
476 ptrIncomingStream->ModuleCallback();
477
478 // Store the stream
479 _streamRenderMap[streamId] = ptrIncomingStream;
480
481 return moduleCallback;
482 }
483
DeleteIncomingRenderStream(const uint32_t streamId)484 int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
485 const uint32_t streamId)
486 {
487 CriticalSectionScoped cs(&_moduleCrit);
488
489 if (!_ptrRenderer)
490 {
491 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
492 "%s: No renderer", __FUNCTION__);
493 return -1;
494 }
495
496 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
497 if (item == _streamRenderMap.end())
498 {
499 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
500 "%s: stream doesn't exist", __FUNCTION__);
501 return -1;
502 }
503
504 delete item->second;
505
506 _ptrRenderer->DeleteIncomingRenderStream(streamId);
507
508 _streamRenderMap.erase(item);
509
510 return 0;
511 }
512
AddExternalRenderCallback(const uint32_t streamId,VideoRenderCallback * renderObject)513 int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
514 const uint32_t streamId,
515 VideoRenderCallback* renderObject) {
516 CriticalSectionScoped cs(&_moduleCrit);
517
518 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
519
520 if (item == _streamRenderMap.end())
521 {
522 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
523 "%s: stream doesn't exist", __FUNCTION__);
524 return -1;
525 }
526
527 if (item->second == NULL) {
528 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
529 "%s: could not get stream", __FUNCTION__);
530 return -1;
531 }
532 return item->second->SetExternalCallback(renderObject);
533 }
534
GetIncomingRenderStreamProperties(const uint32_t streamId,uint32_t & zOrder,float & left,float & top,float & right,float & bottom) const535 int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
536 const uint32_t streamId,
537 uint32_t& zOrder,
538 float& left,
539 float& top,
540 float& right,
541 float& bottom) const {
542 CriticalSectionScoped cs(&_moduleCrit);
543
544 if (!_ptrRenderer)
545 {
546 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
547 "%s: No renderer", __FUNCTION__);
548 return -1;
549 }
550
551 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
552 left, top, right,
553 bottom);
554 }
555
GetNumIncomingRenderStreams() const556 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
557 {
558 CriticalSectionScoped cs(&_moduleCrit);
559
560 return static_cast<uint32_t>(_streamRenderMap.size());
561 }
562
HasIncomingRenderStream(const uint32_t streamId) const563 bool ModuleVideoRenderImpl::HasIncomingRenderStream(
564 const uint32_t streamId) const {
565 CriticalSectionScoped cs(&_moduleCrit);
566
567 return _streamRenderMap.find(streamId) != _streamRenderMap.end();
568 }
569
RegisterRawFrameCallback(const uint32_t streamId,VideoRenderCallback * callbackObj)570 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
571 const uint32_t streamId,
572 VideoRenderCallback* callbackObj) {
573 return -1;
574 }
575
StartRender(const uint32_t streamId)576 int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
577 {
578 CriticalSectionScoped cs(&_moduleCrit);
579
580 if (!_ptrRenderer)
581 {
582 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
583 "%s: No renderer", __FUNCTION__);
584 return -1;
585 }
586
587 // Start the stream
588 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
589
590 if (item == _streamRenderMap.end())
591 {
592 return -1;
593 }
594
595 if (item->second->Start() == -1)
596 {
597 return -1;
598 }
599
600 // Start the HW renderer
601 if (_ptrRenderer->StartRender() == -1)
602 {
603 return -1;
604 }
605 return 0;
606 }
607
StopRender(const uint32_t streamId)608 int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
609 {
610 CriticalSectionScoped cs(&_moduleCrit);
611
612 if (!_ptrRenderer)
613 {
614 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
615 "%s(%d): No renderer", __FUNCTION__, streamId);
616 return -1;
617 }
618
619 // Stop the incoming stream
620 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
621
622 if (item == _streamRenderMap.end())
623 {
624 return -1;
625 }
626
627 if (item->second->Stop() == -1)
628 {
629 return -1;
630 }
631
632 return 0;
633 }
634
ResetRender()635 int32_t ModuleVideoRenderImpl::ResetRender()
636 {
637 CriticalSectionScoped cs(&_moduleCrit);
638
639 int32_t ret = 0;
640 // Loop through all incoming streams and reset them
641 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
642 it != _streamRenderMap.end();
643 ++it) {
644 if (it->second->Reset() == -1)
645 ret = -1;
646 }
647 return ret;
648 }
649
PreferredVideoType() const650 RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
651 {
652 CriticalSectionScoped cs(&_moduleCrit);
653
654 if (_ptrRenderer == NULL)
655 {
656 return kVideoI420;
657 }
658
659 return _ptrRenderer->PerferedVideoType();
660 }
661
IsFullScreen()662 bool ModuleVideoRenderImpl::IsFullScreen()
663 {
664 CriticalSectionScoped cs(&_moduleCrit);
665
666 if (!_ptrRenderer)
667 {
668 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
669 "%s: No renderer", __FUNCTION__);
670 return false;
671 }
672 return _ptrRenderer->FullScreen();
673 }
674
GetScreenResolution(uint32_t & screenWidth,uint32_t & screenHeight) const675 int32_t ModuleVideoRenderImpl::GetScreenResolution(
676 uint32_t& screenWidth,
677 uint32_t& screenHeight) const
678 {
679 CriticalSectionScoped cs(&_moduleCrit);
680
681 if (!_ptrRenderer)
682 {
683 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
684 "%s: No renderer", __FUNCTION__);
685 return false;
686 }
687 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
688 }
689
RenderFrameRate(const uint32_t streamId)690 uint32_t ModuleVideoRenderImpl::RenderFrameRate(
691 const uint32_t streamId)
692 {
693 CriticalSectionScoped cs(&_moduleCrit);
694
695 if (!_ptrRenderer)
696 {
697 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
698 "%s: No renderer", __FUNCTION__);
699 return false;
700 }
701 return _ptrRenderer->RenderFrameRate(streamId);
702 }
703
SetStreamCropping(const uint32_t streamId,const float left,const float top,const float right,const float bottom)704 int32_t ModuleVideoRenderImpl::SetStreamCropping(
705 const uint32_t streamId,
706 const float left,
707 const float top,
708 const float right,
709 const float bottom)
710 {
711 CriticalSectionScoped cs(&_moduleCrit);
712
713 if (!_ptrRenderer)
714 {
715 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
716 "%s: No renderer", __FUNCTION__);
717 return false;
718 }
719 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
720 }
721
SetTransparentBackground(const bool enable)722 int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
723 {
724 CriticalSectionScoped cs(&_moduleCrit);
725
726 if (!_ptrRenderer)
727 {
728 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
729 "%s: No renderer", __FUNCTION__);
730 return false;
731 }
732 return _ptrRenderer->SetTransparentBackground(enable);
733 }
734
FullScreenRender(void * window,const bool enable)735 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
736 {
737 return -1;
738 }
739
SetText(const uint8_t textId,const uint8_t * text,const int32_t textLength,const uint32_t textColorRef,const uint32_t backgroundColorRef,const float left,const float top,const float right,const float bottom)740 int32_t ModuleVideoRenderImpl::SetText(
741 const uint8_t textId,
742 const uint8_t* text,
743 const int32_t textLength,
744 const uint32_t textColorRef,
745 const uint32_t backgroundColorRef,
746 const float left, const float top,
747 const float right,
748 const float bottom)
749 {
750 CriticalSectionScoped cs(&_moduleCrit);
751
752 if (!_ptrRenderer)
753 {
754 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
755 "%s: No renderer", __FUNCTION__);
756 return -1;
757 }
758 return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
759 backgroundColorRef, left, top, right, bottom);
760 }
761
SetBitmap(const void * bitMap,const uint8_t pictureId,const void * colorKey,const float left,const float top,const float right,const float bottom)762 int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
763 const uint8_t pictureId,
764 const void* colorKey,
765 const float left,
766 const float top,
767 const float right,
768 const float bottom)
769 {
770 CriticalSectionScoped cs(&_moduleCrit);
771
772 if (!_ptrRenderer)
773 {
774 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
775 "%s: No renderer", __FUNCTION__);
776 return -1;
777 }
778 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
779 right, bottom);
780 }
781
GetLastRenderedFrame(const uint32_t streamId,I420VideoFrame & frame) const782 int32_t ModuleVideoRenderImpl::GetLastRenderedFrame(
783 const uint32_t streamId,
784 I420VideoFrame &frame) const
785 {
786 CriticalSectionScoped cs(&_moduleCrit);
787
788 if (!_ptrRenderer)
789 {
790 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
791 "%s: No renderer", __FUNCTION__);
792 return -1;
793 }
794
795 IncomingVideoStreamMap::const_iterator item =
796 _streamRenderMap.find(streamId);
797 if (item == _streamRenderMap.end())
798 {
799 // This stream doesn't exist
800 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
801 "%s: stream doesn't exist", __FUNCTION__);
802 return 0;
803 }
804
805 assert(item->second != NULL);
806 return item->second->GetLastRenderedFrame(frame);
807 }
808
SetExpectedRenderDelay(uint32_t stream_id,int32_t delay_ms)809 int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
810 uint32_t stream_id, int32_t delay_ms) {
811 CriticalSectionScoped cs(&_moduleCrit);
812
813 if (!_ptrRenderer) {
814 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
815 "%s: No renderer", __FUNCTION__);
816 return false;
817 }
818
819 IncomingVideoStreamMap::const_iterator item =
820 _streamRenderMap.find(stream_id);
821 if (item == _streamRenderMap.end()) {
822 // This stream doesn't exist
823 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
824 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
825 delay_ms);
826 return -1;
827 }
828
829 assert(item->second != NULL);
830 return item->second->SetExpectedRenderDelay(delay_ms);
831 }
832
ConfigureRenderer(const uint32_t streamId,const unsigned int zOrder,const float left,const float top,const float right,const float bottom)833 int32_t ModuleVideoRenderImpl::ConfigureRenderer(
834 const uint32_t streamId,
835 const unsigned int zOrder,
836 const float left,
837 const float top,
838 const float right,
839 const float bottom)
840 {
841 CriticalSectionScoped cs(&_moduleCrit);
842
843 if (!_ptrRenderer)
844 {
845 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
846 "%s: No renderer", __FUNCTION__);
847 return false;
848 }
849 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
850 bottom);
851 }
852
SetStartImage(const uint32_t streamId,const I420VideoFrame & videoFrame)853 int32_t ModuleVideoRenderImpl::SetStartImage(
854 const uint32_t streamId,
855 const I420VideoFrame& videoFrame)
856 {
857 CriticalSectionScoped cs(&_moduleCrit);
858
859 if (!_ptrRenderer)
860 {
861 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
862 "%s: No renderer", __FUNCTION__);
863 return -1;
864 }
865
866 IncomingVideoStreamMap::const_iterator item =
867 _streamRenderMap.find(streamId);
868 if (item == _streamRenderMap.end())
869 {
870 // This stream doesn't exist
871 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
872 "%s: stream doesn't exist", __FUNCTION__);
873 return -1;
874 }
875 assert (item->second != NULL);
876 return item->second->SetStartImage(videoFrame);
877
878 }
879
SetTimeoutImage(const uint32_t streamId,const I420VideoFrame & videoFrame,const uint32_t timeout)880 int32_t ModuleVideoRenderImpl::SetTimeoutImage(
881 const uint32_t streamId,
882 const I420VideoFrame& videoFrame,
883 const uint32_t timeout)
884 {
885 CriticalSectionScoped cs(&_moduleCrit);
886
887 if (!_ptrRenderer)
888 {
889 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
890 "%s: No renderer", __FUNCTION__);
891 return -1;
892 }
893
894 IncomingVideoStreamMap::const_iterator item =
895 _streamRenderMap.find(streamId);
896 if (item == _streamRenderMap.end())
897 {
898 // This stream doesn't exist
899 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
900 "%s: stream doesn't exist", __FUNCTION__);
901 return -1;
902 }
903 assert(item->second != NULL);
904 return item->second->SetTimeoutImage(videoFrame, timeout);
905 }
906
MirrorRenderStream(const int renderId,const bool enable,const bool mirrorXAxis,const bool mirrorYAxis)907 int32_t ModuleVideoRenderImpl::MirrorRenderStream(const int renderId,
908 const bool enable,
909 const bool mirrorXAxis,
910 const bool mirrorYAxis)
911 {
912 CriticalSectionScoped cs(&_moduleCrit);
913
914 if (!_ptrRenderer)
915 {
916 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
917 "%s: No renderer", __FUNCTION__);
918 return -1;
919 }
920
921 IncomingVideoStreamMap::const_iterator item =
922 _streamRenderMap.find(renderId);
923 if (item == _streamRenderMap.end())
924 {
925 // This stream doesn't exist
926 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
927 "%s: stream doesn't exist", __FUNCTION__);
928 return 0;
929 }
930 assert(item->second != NULL);
931
932 return item->second->EnableMirroring(enable, mirrorXAxis, mirrorYAxis);
933 }
934
935 } // namespace webrtc
936