Home | History | Annotate | Download | only in video_engine
      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 "webrtc/video_engine/vie_render_manager.h"
     12 
     13 #include "webrtc/engine_configurations.h"
     14 #include "webrtc/modules/video_render/include/video_render.h"
     15 #include "webrtc/modules/video_render/include/video_render_defines.h"
     16 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     17 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
     18 #include "webrtc/system_wrappers/interface/logging.h"
     19 #include "webrtc/video_engine/vie_defines.h"
     20 #include "webrtc/video_engine/vie_renderer.h"
     21 
     22 namespace webrtc {
     23 
     24 ViERenderManagerScoped::ViERenderManagerScoped(
     25     const ViERenderManager& vie_render_manager)
     26     : ViEManagerScopedBase(vie_render_manager) {
     27 }
     28 
     29 ViERenderer* ViERenderManagerScoped::Renderer(int32_t render_id) const {
     30   return static_cast<const ViERenderManager*>(vie_manager_)->ViERenderPtr(
     31            render_id);
     32 }
     33 
     34 ViERenderManager::ViERenderManager(int32_t engine_id)
     35     : list_cs_(CriticalSectionWrapper::CreateCriticalSection()),
     36       engine_id_(engine_id),
     37       use_external_render_module_(false) {
     38 }
     39 
     40 ViERenderManager::~ViERenderManager() {
     41   for (RendererMap::iterator it = stream_to_vie_renderer_.begin();
     42        it != stream_to_vie_renderer_.end();
     43        ++it) {
     44     // The renderer is deleted in RemoveRenderStream.
     45     RemoveRenderStream(it->first);
     46   }
     47 }
     48 
     49 int32_t ViERenderManager::RegisterVideoRenderModule(
     50     VideoRender* render_module) {
     51   // See if there is already a render module registered for the window that
     52   // the registrant render module is associated with.
     53   VideoRender* current_module = FindRenderModule(render_module->Window());
     54   if (current_module) {
     55     LOG_F(LS_ERROR) << "A render module is already registered for this window.";
     56     return -1;
     57   }
     58 
     59   // Register module.
     60   render_list_.push_back(render_module);
     61   use_external_render_module_ = true;
     62   return 0;
     63 }
     64 
     65 int32_t ViERenderManager::DeRegisterVideoRenderModule(
     66     VideoRender* render_module) {
     67   // Check if there are streams in the module.
     68   uint32_t n_streams = render_module->GetNumIncomingRenderStreams();
     69   if (n_streams != 0) {
     70     LOG(LS_ERROR) << "There are still " << n_streams
     71                   << "in this module, cannot de-register.";
     72     return -1;
     73   }
     74 
     75   for (RenderList::iterator iter = render_list_.begin();
     76        iter != render_list_.end(); ++iter) {
     77     if (render_module == *iter) {
     78       // We've found our renderer. Erase the render module from the map.
     79       render_list_.erase(iter);
     80       return 0;
     81     }
     82   }
     83 
     84   LOG(LS_ERROR) << "Module not registered.";
     85   return -1;
     86 }
     87 
     88 ViERenderer* ViERenderManager::AddRenderStream(const int32_t render_id,
     89                                                void* window,
     90                                                const uint32_t z_order,
     91                                                const float left,
     92                                                const float top,
     93                                                const float right,
     94                                                const float bottom) {
     95   CriticalSectionScoped cs(list_cs_.get());
     96 
     97   if (stream_to_vie_renderer_.find(render_id) !=
     98       stream_to_vie_renderer_.end()) {
     99     LOG(LS_ERROR) << "Render stream already exists";
    100     return NULL;
    101   }
    102 
    103   // Get the render module for this window.
    104   VideoRender* render_module = FindRenderModule(window);
    105   if (render_module == NULL) {
    106     // No render module for this window, create a new one.
    107     render_module = VideoRender::CreateVideoRender(ViEModuleId(engine_id_, -1),
    108                                                   window, false);
    109     if (!render_module)
    110       return NULL;
    111 
    112     render_list_.push_back(render_module);
    113   }
    114 
    115   ViERenderer* vie_renderer = ViERenderer::CreateViERenderer(render_id,
    116                                                              engine_id_,
    117                                                              *render_module,
    118                                                              *this, z_order,
    119                                                              left, top, right,
    120                                                              bottom);
    121   if (!vie_renderer)
    122     return NULL;
    123 
    124   stream_to_vie_renderer_[render_id] = vie_renderer;
    125   return vie_renderer;
    126 }
    127 
    128 int32_t ViERenderManager::RemoveRenderStream(
    129     const int32_t render_id) {
    130   // We need exclusive right to the items in the render manager to delete a
    131   // stream.
    132   ViEManagerWriteScoped scope(this);
    133   CriticalSectionScoped cs(list_cs_.get());
    134   RendererMap::iterator it = stream_to_vie_renderer_.find(render_id);
    135   if (it == stream_to_vie_renderer_.end()) {
    136     LOG(LS_ERROR) << "No renderer found for render_id: " << render_id;
    137     return 0;
    138   }
    139 
    140   // Get the render module pointer for this vie_render object.
    141   VideoRender& renderer = it->second->RenderModule();
    142 
    143   // Delete the vie_render.
    144   // This deletes the stream in the render module.
    145   delete it->second;
    146 
    147   // Remove from the stream map.
    148   stream_to_vie_renderer_.erase(it);
    149 
    150   // Check if there are other streams in the module.
    151   if (!use_external_render_module_ &&
    152       renderer.GetNumIncomingRenderStreams() == 0) {
    153     // Erase the render module from the map.
    154     for (RenderList::iterator iter = render_list_.begin();
    155          iter != render_list_.end(); ++iter) {
    156       if (&renderer == *iter) {
    157         // We've found our renderer.
    158         render_list_.erase(iter);
    159         break;
    160       }
    161     }
    162     // Destroy the module.
    163     VideoRender::DestroyVideoRender(&renderer);
    164   }
    165   return 0;
    166 }
    167 
    168 VideoRender* ViERenderManager::FindRenderModule(void* window) {
    169   for (RenderList::iterator iter = render_list_.begin();
    170        iter != render_list_.end(); ++iter) {
    171     if ((*iter)->Window() == window) {
    172       // We've found the render module.
    173       return *iter;
    174     }
    175   }
    176   return NULL;
    177 }
    178 
    179 ViERenderer* ViERenderManager::ViERenderPtr(int32_t render_id) const {
    180   RendererMap::const_iterator it = stream_to_vie_renderer_.find(render_id);
    181   if (it == stream_to_vie_renderer_.end())
    182     return NULL;
    183 
    184   return it->second;
    185 }
    186 
    187 }  // namespace webrtc
    188