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/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*
     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 
     80 void VideoRender::DestroyVideoRender(
     81                                                          VideoRender* module)
     82 {
     83     if (module)
     84     {
     85         delete module;
     86     }
     87 }
     88 
     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 
    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 
    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 
    324 int32_t ModuleVideoRenderImpl::TimeUntilNextProcess()
    325 {
    326     // Not used
    327     return 50;
    328 }
    329 int32_t ModuleVideoRenderImpl::Process()
    330 {
    331     // Not used
    332     return 0;
    333 }
    334 
    335 void*
    336 ModuleVideoRenderImpl::Window()
    337 {
    338     CriticalSectionScoped cs(&_moduleCrit);
    339     return _ptrWindow;
    340 }
    341 
    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 
    396 int32_t ModuleVideoRenderImpl::Id()
    397 {
    398     CriticalSectionScoped cs(&_moduleCrit);
    399     return _id;
    400 }
    401 
    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*
    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 
    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 
    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 
    535 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 
    556 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
    557 {
    558     CriticalSectionScoped cs(&_moduleCrit);
    559 
    560     return static_cast<uint32_t>(_streamRenderMap.size());
    561 }
    562 
    563 bool ModuleVideoRenderImpl::HasIncomingRenderStream(
    564     const uint32_t streamId) const {
    565   CriticalSectionScoped cs(&_moduleCrit);
    566 
    567   return _streamRenderMap.find(streamId) != _streamRenderMap.end();
    568 }
    569 
    570 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
    571     const uint32_t streamId,
    572     VideoRenderCallback* callbackObj) {
    573   return -1;
    574 }
    575 
    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 
    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 
    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 
    650 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 
    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 
    675 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 
    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 
    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 
    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 
    735 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
    736 {
    737     return -1;
    738 }
    739 
    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 
    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 
    782 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 
    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 
    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 
    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 
    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 
    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