Home | History | Annotate | Download | only in video_render
      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/common_video/include/incoming_video_stream.h"
     14 #include "webrtc/engine_configurations.h"
     15 #include "webrtc/modules/video_render/i_video_render.h"
     16 #include "webrtc/modules/video_render/video_render_defines.h"
     17 #include "webrtc/modules/video_render/video_render_impl.h"
     18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     19 #include "webrtc/system_wrappers/include/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*
     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 
     76 void VideoRender::DestroyVideoRender(
     77                                                          VideoRender* module)
     78 {
     79     if (module)
     80     {
     81         delete module;
     82     }
     83 }
     84 
     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 
    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 
    297 int64_t ModuleVideoRenderImpl::TimeUntilNextProcess()
    298 {
    299     // Not used
    300     return 50;
    301 }
    302 int32_t ModuleVideoRenderImpl::Process()
    303 {
    304     // Not used
    305     return 0;
    306 }
    307 
    308 void*
    309 ModuleVideoRenderImpl::Window()
    310 {
    311     CriticalSectionScoped cs(&_moduleCrit);
    312     return _ptrWindow;
    313 }
    314 
    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 
    363 int32_t ModuleVideoRenderImpl::Id()
    364 {
    365     CriticalSectionScoped cs(&_moduleCrit);
    366     return _id;
    367 }
    368 
    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*
    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 =
    424         new IncomingVideoStream(streamId, false);
    425     ptrIncomingStream->SetRenderCallback(ptrRenderCallback);
    426     VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback();
    427 
    428     // Store the stream
    429     _streamRenderMap[streamId] = ptrIncomingStream;
    430 
    431     return moduleCallback;
    432 }
    433 
    434 int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
    435                                                                 const uint32_t streamId)
    436 {
    437     CriticalSectionScoped cs(&_moduleCrit);
    438 
    439     if (!_ptrRenderer)
    440     {
    441         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    442                      "%s: No renderer", __FUNCTION__);
    443         return -1;
    444     }
    445 
    446     IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
    447     if (item == _streamRenderMap.end())
    448     {
    449         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    450                      "%s: stream doesn't exist", __FUNCTION__);
    451         return -1;
    452     }
    453 
    454     delete item->second;
    455 
    456     _ptrRenderer->DeleteIncomingRenderStream(streamId);
    457 
    458     _streamRenderMap.erase(item);
    459 
    460     return 0;
    461 }
    462 
    463 int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
    464     const uint32_t streamId,
    465     VideoRenderCallback* renderObject) {
    466     CriticalSectionScoped cs(&_moduleCrit);
    467 
    468     IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
    469 
    470     if (item == _streamRenderMap.end())
    471     {
    472         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    473                      "%s: stream doesn't exist", __FUNCTION__);
    474         return -1;
    475     }
    476 
    477     if (item->second == NULL) {
    478         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    479                      "%s: could not get stream", __FUNCTION__);
    480         return -1;
    481     }
    482     item->second->SetExternalCallback(renderObject);
    483     return 0;
    484 }
    485 
    486 int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
    487     const uint32_t streamId,
    488     uint32_t& zOrder,
    489     float& left,
    490     float& top,
    491     float& right,
    492     float& bottom) const {
    493     CriticalSectionScoped cs(&_moduleCrit);
    494 
    495     if (!_ptrRenderer)
    496     {
    497         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    498                      "%s: No renderer", __FUNCTION__);
    499         return -1;
    500     }
    501 
    502     return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
    503                                                            left, top, right,
    504                                                            bottom);
    505 }
    506 
    507 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
    508 {
    509     CriticalSectionScoped cs(&_moduleCrit);
    510 
    511     return static_cast<uint32_t>(_streamRenderMap.size());
    512 }
    513 
    514 bool ModuleVideoRenderImpl::HasIncomingRenderStream(
    515     const uint32_t streamId) const {
    516   CriticalSectionScoped cs(&_moduleCrit);
    517 
    518   return _streamRenderMap.find(streamId) != _streamRenderMap.end();
    519 }
    520 
    521 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
    522     const uint32_t streamId,
    523     VideoRenderCallback* callbackObj) {
    524   return -1;
    525 }
    526 
    527 int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
    528 {
    529     CriticalSectionScoped cs(&_moduleCrit);
    530 
    531     if (!_ptrRenderer)
    532     {
    533         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    534                      "%s: No renderer", __FUNCTION__);
    535         return -1;
    536     }
    537 
    538     // Start the stream
    539     IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
    540 
    541     if (item == _streamRenderMap.end())
    542     {
    543         return -1;
    544     }
    545 
    546     if (item->second->Start() == -1)
    547     {
    548         return -1;
    549     }
    550 
    551     // Start the HW renderer
    552     if (_ptrRenderer->StartRender() == -1)
    553     {
    554         return -1;
    555     }
    556     return 0;
    557 }
    558 
    559 int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
    560 {
    561     CriticalSectionScoped cs(&_moduleCrit);
    562 
    563     if (!_ptrRenderer)
    564     {
    565         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    566                      "%s(%d): No renderer", __FUNCTION__, streamId);
    567         return -1;
    568     }
    569 
    570     // Stop the incoming stream
    571     IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
    572 
    573     if (item == _streamRenderMap.end())
    574     {
    575         return -1;
    576     }
    577 
    578     if (item->second->Stop() == -1)
    579     {
    580         return -1;
    581     }
    582 
    583     return 0;
    584 }
    585 
    586 int32_t ModuleVideoRenderImpl::ResetRender()
    587 {
    588     CriticalSectionScoped cs(&_moduleCrit);
    589 
    590     int32_t ret = 0;
    591     // Loop through all incoming streams and reset them
    592     for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
    593          it != _streamRenderMap.end();
    594          ++it) {
    595       if (it->second->Reset() == -1)
    596         ret = -1;
    597     }
    598     return ret;
    599 }
    600 
    601 RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
    602 {
    603     CriticalSectionScoped cs(&_moduleCrit);
    604 
    605     if (_ptrRenderer == NULL)
    606     {
    607         return kVideoI420;
    608     }
    609 
    610     return _ptrRenderer->PerferedVideoType();
    611 }
    612 
    613 bool ModuleVideoRenderImpl::IsFullScreen()
    614 {
    615     CriticalSectionScoped cs(&_moduleCrit);
    616 
    617     if (!_ptrRenderer)
    618     {
    619         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    620                      "%s: No renderer", __FUNCTION__);
    621         return false;
    622     }
    623     return _ptrRenderer->FullScreen();
    624 }
    625 
    626 int32_t ModuleVideoRenderImpl::GetScreenResolution(
    627                                                          uint32_t& screenWidth,
    628                                                          uint32_t& screenHeight) const
    629 {
    630     CriticalSectionScoped cs(&_moduleCrit);
    631 
    632     if (!_ptrRenderer)
    633     {
    634         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    635                      "%s: No renderer", __FUNCTION__);
    636         return false;
    637     }
    638     return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
    639 }
    640 
    641 uint32_t ModuleVideoRenderImpl::RenderFrameRate(
    642                                                       const uint32_t streamId)
    643 {
    644     CriticalSectionScoped cs(&_moduleCrit);
    645 
    646     if (!_ptrRenderer)
    647     {
    648         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    649                      "%s: No renderer", __FUNCTION__);
    650         return false;
    651     }
    652     return _ptrRenderer->RenderFrameRate(streamId);
    653 }
    654 
    655 int32_t ModuleVideoRenderImpl::SetStreamCropping(
    656                                                        const uint32_t streamId,
    657                                                        const float left,
    658                                                        const float top,
    659                                                        const float right,
    660                                                        const float bottom)
    661 {
    662     CriticalSectionScoped cs(&_moduleCrit);
    663 
    664     if (!_ptrRenderer)
    665     {
    666         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    667                      "%s: No renderer", __FUNCTION__);
    668         return false;
    669     }
    670     return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
    671 }
    672 
    673 int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
    674 {
    675     CriticalSectionScoped cs(&_moduleCrit);
    676 
    677     if (!_ptrRenderer)
    678     {
    679         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    680                      "%s: No renderer", __FUNCTION__);
    681         return false;
    682     }
    683     return _ptrRenderer->SetTransparentBackground(enable);
    684 }
    685 
    686 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
    687 {
    688     return -1;
    689 }
    690 
    691 int32_t ModuleVideoRenderImpl::SetText(
    692                                              const uint8_t textId,
    693                                              const uint8_t* text,
    694                                              const int32_t textLength,
    695                                              const uint32_t textColorRef,
    696                                              const uint32_t backgroundColorRef,
    697                                              const float left, const float top,
    698                                              const float right,
    699                                              const float bottom)
    700 {
    701     CriticalSectionScoped cs(&_moduleCrit);
    702 
    703     if (!_ptrRenderer)
    704     {
    705         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    706                      "%s: No renderer", __FUNCTION__);
    707         return -1;
    708     }
    709     return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
    710                                  backgroundColorRef, left, top, right, bottom);
    711 }
    712 
    713 int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
    714                                          const uint8_t pictureId,
    715                                          const void* colorKey,
    716                                          const float left,
    717                                          const float top,
    718                                          const float right,
    719                                          const float bottom)
    720 {
    721     CriticalSectionScoped cs(&_moduleCrit);
    722 
    723     if (!_ptrRenderer)
    724     {
    725         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    726                      "%s: No renderer", __FUNCTION__);
    727         return -1;
    728     }
    729     return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
    730                                    right, bottom);
    731 }
    732 
    733 int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
    734     uint32_t stream_id, int32_t delay_ms) {
    735   CriticalSectionScoped cs(&_moduleCrit);
    736 
    737   if (!_ptrRenderer) {
    738     WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    739                  "%s: No renderer", __FUNCTION__);
    740     return false;
    741   }
    742 
    743   IncomingVideoStreamMap::const_iterator item =
    744       _streamRenderMap.find(stream_id);
    745   if (item == _streamRenderMap.end()) {
    746     // This stream doesn't exist
    747     WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    748                  "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
    749                  delay_ms);
    750     return -1;
    751   }
    752 
    753   assert(item->second != NULL);
    754   return item->second->SetExpectedRenderDelay(delay_ms);
    755 }
    756 
    757 int32_t ModuleVideoRenderImpl::ConfigureRenderer(
    758                                                        const uint32_t streamId,
    759                                                        const unsigned int zOrder,
    760                                                        const float left,
    761                                                        const float top,
    762                                                        const float right,
    763                                                        const float bottom)
    764 {
    765     CriticalSectionScoped cs(&_moduleCrit);
    766 
    767     if (!_ptrRenderer)
    768     {
    769         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    770                      "%s: No renderer", __FUNCTION__);
    771         return false;
    772     }
    773     return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
    774                                            bottom);
    775 }
    776 
    777 int32_t ModuleVideoRenderImpl::SetStartImage(const uint32_t streamId,
    778                                              const VideoFrame& videoFrame) {
    779     CriticalSectionScoped cs(&_moduleCrit);
    780 
    781     if (!_ptrRenderer)
    782     {
    783         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    784                      "%s: No renderer", __FUNCTION__);
    785         return -1;
    786     }
    787 
    788     IncomingVideoStreamMap::const_iterator item =
    789         _streamRenderMap.find(streamId);
    790     if (item == _streamRenderMap.end())
    791     {
    792         // This stream doesn't exist
    793         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    794                      "%s: stream doesn't exist", __FUNCTION__);
    795         return -1;
    796     }
    797     assert (item->second != NULL);
    798     return item->second->SetStartImage(videoFrame);
    799 
    800 }
    801 
    802 int32_t ModuleVideoRenderImpl::SetTimeoutImage(const uint32_t streamId,
    803                                                const VideoFrame& videoFrame,
    804                                                const uint32_t timeout) {
    805     CriticalSectionScoped cs(&_moduleCrit);
    806 
    807     if (!_ptrRenderer)
    808     {
    809         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    810                      "%s: No renderer", __FUNCTION__);
    811         return -1;
    812     }
    813 
    814     IncomingVideoStreamMap::const_iterator item =
    815         _streamRenderMap.find(streamId);
    816     if (item == _streamRenderMap.end())
    817     {
    818         // This stream doesn't exist
    819         WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    820                      "%s: stream doesn't exist", __FUNCTION__);
    821         return -1;
    822     }
    823     assert(item->second != NULL);
    824     return item->second->SetTimeoutImage(videoFrame, timeout);
    825 }
    826 
    827 }  // namespace webrtc
    828