• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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