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