• 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 "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 
ViERenderManagerScoped(const ViERenderManager & vie_render_manager)24 ViERenderManagerScoped::ViERenderManagerScoped(
25     const ViERenderManager& vie_render_manager)
26     : ViEManagerScopedBase(vie_render_manager) {
27 }
28 
Renderer(int32_t render_id) const29 ViERenderer* ViERenderManagerScoped::Renderer(int32_t render_id) const {
30   return static_cast<const ViERenderManager*>(vie_manager_)->ViERenderPtr(
31            render_id);
32 }
33 
ViERenderManager(int32_t engine_id)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 
~ViERenderManager()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 
RegisterVideoRenderModule(VideoRender * render_module)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 
DeRegisterVideoRenderModule(VideoRender * render_module)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 
AddRenderStream(const int32_t render_id,void * window,const uint32_t z_order,const float left,const float top,const float right,const float bottom)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 
RemoveRenderStream(const int32_t render_id)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 
FindRenderModule(void * window)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 
ViERenderPtr(int32_t render_id) const179 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