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