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