blob: 507e05ae35df88010bfa678e64eac0cc3f9dd6ab [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
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
pbos@webrtc.org281cff82013-05-17 13:44:48 +000011#include "webrtc/video_engine/vie_render_impl.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000012
pbos@webrtc.org281cff82013-05-17 13:44:48 +000013#include "webrtc/engine_configurations.h"
andrew@webrtc.org07e96da2012-10-31 05:22:11 +000014#include "webrtc/modules/video_render/include/video_render.h"
15#include "webrtc/modules/video_render/include/video_render_defines.h"
pbos@webrtc.org281cff82013-05-17 13:44:48 +000016#include "webrtc/system_wrappers/interface/trace.h"
17#include "webrtc/video_engine/include/vie_errors.h"
18#include "webrtc/video_engine/vie_capturer.h"
19#include "webrtc/video_engine/vie_channel.h"
20#include "webrtc/video_engine/vie_channel_manager.h"
21#include "webrtc/video_engine/vie_defines.h"
22#include "webrtc/video_engine/vie_frame_provider_base.h"
23#include "webrtc/video_engine/vie_impl.h"
24#include "webrtc/video_engine/vie_input_manager.h"
25#include "webrtc/video_engine/vie_render_manager.h"
26#include "webrtc/video_engine/vie_renderer.h"
27#include "webrtc/video_engine/vie_shared_data.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000028
29namespace webrtc {
30
31ViERender* ViERender::GetInterface(VideoEngine* video_engine) {
32#ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
33 if (!video_engine) {
34 return NULL;
35 }
andrew@webrtc.org7ab72682013-05-09 02:12:07 +000036 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000037 ViERenderImpl* vie_render_impl = vie_impl;
38 // Increase ref count.
39 (*vie_render_impl)++;
40 return vie_render_impl;
41#else
42 return NULL;
43#endif
44}
45
46int ViERenderImpl::Release() {
47 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
48 "ViERender::Release()");
49 // Decrease ref count
50 (*this)--;
pbos@webrtc.org67879bc2013-04-09 13:41:51 +000051 int32_t ref_count = GetCount();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000052 if (ref_count < 0) {
53 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
54 "ViERender release too many times");
55 return -1;
56 }
57 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
58 "ViERender reference count: %d", ref_count);
59 return ref_count;
60}
61
62ViERenderImpl::ViERenderImpl(ViESharedData* shared_data)
63 : shared_data_(shared_data) {
64 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
65 "ViERenderImpl::ViERenderImpl() Ctor");
66}
67
68ViERenderImpl::~ViERenderImpl() {
69 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
70 "ViERenderImpl::~ViERenderImpl() Dtor");
71}
72
73int ViERenderImpl::RegisterVideoRenderModule(
74 VideoRender& render_module) {
75 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
76 "%s (&render_module: %p)", __FUNCTION__, &render_module);
77 if (shared_data_->render_manager()->RegisterVideoRenderModule(
78 &render_module) != 0) {
79 shared_data_->SetLastError(kViERenderUnknownError);
80 return -1;
81 }
82 return 0;
83}
84
85int ViERenderImpl::DeRegisterVideoRenderModule(
86 VideoRender& render_module) {
87 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
88 "%s (&render_module: %p)", __FUNCTION__, &render_module);
89 if (shared_data_->render_manager()->DeRegisterVideoRenderModule(
90 &render_module) != 0) {
91 // Error logging is done in ViERenderManager::DeRegisterVideoRenderModule.
92 shared_data_->SetLastError(kViERenderUnknownError);
93 return -1;
94 }
95 return 0;
96}
97
98int ViERenderImpl::AddRenderer(const int render_id, void* window,
99 const unsigned int z_order, const float left,
100 const float top, const float right,
101 const float bottom) {
102 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
103 "%s (render_id: %d, window: 0x%p, z_order: %u, left: %f, "
104 "top: %f, right: %f, bottom: %f)",
105 __FUNCTION__, render_id, window, z_order, left, top, right,
106 bottom);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000107 {
108 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
109 if (rs.Renderer(render_id)) {
110 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
111 "%s - Renderer already exist %d.", __FUNCTION__,
112 render_id);
113 shared_data_->SetLastError(kViERenderAlreadyExists);
114 return -1;
115 }
116 }
117 if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
118 // This is a channel.
119 ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
120 ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
121 if (!frame_provider) {
122 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
123 "%s: FrameProvider id %d doesn't exist", __FUNCTION__,
124 render_id);
125 shared_data_->SetLastError(kViERenderInvalidRenderId);
126 return -1;
127 }
128 ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
129 render_id, window, z_order, left, top, right, bottom);
130 if (!renderer) {
131 shared_data_->SetLastError(kViERenderUnknownError);
132 return -1;
133 }
134 return frame_provider->RegisterFrameCallback(render_id, renderer);
135 } else {
136 // Camera or file.
137 ViEInputManagerScoped is(*(shared_data_->input_manager()));
138 ViEFrameProviderBase* frame_provider = is.FrameProvider(render_id);
139 if (!frame_provider) {
140 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
141 "%s: FrameProvider id %d doesn't exist", __FUNCTION__,
142 render_id);
143 shared_data_->SetLastError(kViERenderInvalidRenderId);
144 return -1;
145 }
146 ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
147 render_id, window, z_order, left, top, right, bottom);
148 if (!renderer) {
149 shared_data_->SetLastError(kViERenderUnknownError);
150 return -1;
151 }
152 return frame_provider->RegisterFrameCallback(render_id, renderer);
153 }
154}
155
156int ViERenderImpl::RemoveRenderer(const int render_id) {
157 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
158 "%s(render_id: %d)", __FUNCTION__, render_id);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000159 ViERenderer* renderer = NULL;
160 {
161 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
162 renderer = rs.Renderer(render_id);
163 if (!renderer) {
164 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
165 ViEId(shared_data_->instance_id()),
166 "%s No render exist with render_id: %d", __FUNCTION__,
167 render_id);
168 shared_data_->SetLastError(kViERenderInvalidRenderId);
169 return -1;
170 }
171 // Leave the scope lock since we don't want to lock two managers
172 // simultanousely.
173 }
174 if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
175 // This is a channel.
176 ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
177 ViEChannel* channel = cm.Channel(render_id);
178 if (!channel) {
179 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
180 ViEId(shared_data_->instance_id()),
181 "%s: no channel with id %d exists ", __FUNCTION__,
182 render_id);
183 shared_data_->SetLastError(kViERenderInvalidRenderId);
184 return -1;
185 }
186 channel->DeregisterFrameCallback(renderer);
187 } else {
188 // Provider owned by inputmanager, i.e. file or capture device.
189 ViEInputManagerScoped is(*(shared_data_->input_manager()));
190 ViEFrameProviderBase* provider = is.FrameProvider(render_id);
191 if (!provider) {
192 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
193 ViEId(shared_data_->instance_id()),
194 "%s: no provider with id %d exists ", __FUNCTION__,
195 render_id);
196 shared_data_->SetLastError(kViERenderInvalidRenderId);
197 return -1;
198 }
199 provider->DeregisterFrameCallback(renderer);
200 }
201 if (shared_data_->render_manager()->RemoveRenderStream(render_id) != 0) {
202 shared_data_->SetLastError(kViERenderUnknownError);
203 return -1;
204 }
205 return 0;
206}
207
208int ViERenderImpl::StartRender(const int render_id) {
209 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
210 ViEId(shared_data_->instance_id(), render_id),
211 "%s(channel: %d)", __FUNCTION__, render_id);
212 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
213 ViERenderer* renderer = rs.Renderer(render_id);
214 if (!renderer) {
215 WEBRTC_TRACE(kTraceError, kTraceVideo,
216 ViEId(shared_data_->instance_id(), render_id),
217 "%s: No renderer with render Id %d exist.", __FUNCTION__,
218 render_id);
219 shared_data_->SetLastError(kViERenderInvalidRenderId);
220 return -1;
221 }
222 if (renderer->StartRender() != 0) {
223 shared_data_->SetLastError(kViERenderUnknownError);
224 return -1;
225 }
226 return 0;
227}
228
229int ViERenderImpl::StopRender(const int render_id) {
230 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
231 ViEId(shared_data_->instance_id(), render_id),
232 "%s(channel: %d)", __FUNCTION__, render_id);
233 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
234 ViERenderer* renderer = rs.Renderer(render_id);
235 if (!renderer) {
236 WEBRTC_TRACE(kTraceError, kTraceVideo,
237 ViEId(shared_data_->instance_id(), render_id),
238 "%s: No renderer with render_id %d exist.", __FUNCTION__,
239 render_id);
240 shared_data_->SetLastError(kViERenderInvalidRenderId);
241 return -1;
242 }
243 if (renderer->StopRender() != 0) {
244 shared_data_->SetLastError(kViERenderUnknownError);
245 return -1;
246 }
247 return 0;
248}
249
250int ViERenderImpl::SetExpectedRenderDelay(int render_id, int render_delay) {
251 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
252 ViEId(shared_data_->instance_id(), render_id),
253 "%s(channel: %d)", __FUNCTION__, render_id);
254 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
255 ViERenderer* renderer = rs.Renderer(render_id);
256 if (!renderer) {
257 WEBRTC_TRACE(kTraceError, kTraceVideo,
258 ViEId(shared_data_->instance_id(), render_id),
259 "%s: No renderer with render_id %d exist.", __FUNCTION__,
260 render_id);
261 shared_data_->SetLastError(kViERenderInvalidRenderId);
262 return -1;
263 }
264 if (renderer->SetExpectedRenderDelay(render_delay) != 0) {
265 shared_data_->SetLastError(kViERenderUnknownError);
266 return -1;
267 }
268 return 0;
269}
270
271int ViERenderImpl::ConfigureRender(int render_id, const unsigned int z_order,
272 const float left, const float top,
273 const float right, const float bottom) {
274 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
275 ViEId(shared_data_->instance_id(), render_id),
276 "%s(channel: %d)", __FUNCTION__, render_id);
277 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
278 ViERenderer* renderer = rs.Renderer(render_id);
279 if (!renderer) {
280 WEBRTC_TRACE(kTraceError, kTraceVideo,
281 ViEId(shared_data_->instance_id(), render_id),
282 "%s: No renderer with render_id %d exist.", __FUNCTION__,
283 render_id);
284 shared_data_->SetLastError(kViERenderInvalidRenderId);
285 return -1;
286 }
287
288 if (renderer->ConfigureRenderer(z_order, left, top, right, bottom) != 0) {
289 shared_data_->SetLastError(kViERenderUnknownError);
290 return -1;
291 }
292 return 0;
293}
294
295int ViERenderImpl::MirrorRenderStream(const int render_id, const bool enable,
296 const bool mirror_xaxis,
297 const bool mirror_yaxis) {
298 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
299 ViERenderer* renderer = rs.Renderer(render_id);
300 if (!renderer) {
301 WEBRTC_TRACE(kTraceError, kTraceVideo,
302 ViEId(shared_data_->instance_id(), render_id),
303 "%s: No renderer with render_id %d exist.", __FUNCTION__,
304 render_id);
305 shared_data_->SetLastError(kViERenderInvalidRenderId);
306 return -1;
307 }
308 if (renderer->EnableMirroring(render_id, enable, mirror_xaxis, mirror_yaxis)
309 != 0) {
310 shared_data_->SetLastError(kViERenderUnknownError);
311 return -1;
312 }
313 return 0;
314}
315
316int ViERenderImpl::AddRenderer(const int render_id,
317 RawVideoType video_input_format,
318 ExternalRenderer* external_renderer) {
319 // Check if the client requested a format that we can convert the frames to.
320 if (video_input_format != kVideoI420 &&
321 video_input_format != kVideoYV12 &&
322 video_input_format != kVideoYUY2 &&
323 video_input_format != kVideoUYVY &&
324 video_input_format != kVideoARGB &&
325 video_input_format != kVideoRGB24 &&
326 video_input_format != kVideoRGB565 &&
327 video_input_format != kVideoARGB4444 &&
328 video_input_format != kVideoARGB1555) {
329 WEBRTC_TRACE(kTraceError, kTraceVideo,
330 ViEId(shared_data_->instance_id(), render_id),
331 "%s: Unsupported video frame format requested",
332 __FUNCTION__, render_id);
333 shared_data_->SetLastError(kViERenderInvalidFrameFormat);
334 return -1;
335 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000336 {
337 // Verify the renderer doesn't exist.
338 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
339 if (rs.Renderer(render_id)) {
340 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
341 "%s - Renderer already exist %d.", __FUNCTION__,
342 render_id);
343 shared_data_->SetLastError(kViERenderAlreadyExists);
344 return -1;
345 }
346 }
347 if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
348 // This is a channel.
349 ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
350 ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
351 if (!frame_provider) {
352 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
353 "%s: FrameProvider id %d doesn't exist", __FUNCTION__,
354 render_id);
355 shared_data_->SetLastError(kViERenderInvalidRenderId);
356 return -1;
357 }
358 ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
359 render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
360 if (!renderer) {
361 shared_data_->SetLastError(kViERenderUnknownError);
362 return -1;
363 }
364 if (renderer->SetExternalRenderer(render_id, video_input_format,
365 external_renderer) == -1) {
366 shared_data_->SetLastError(kViERenderUnknownError);
367 return -1;
368 }
369
370 return frame_provider->RegisterFrameCallback(render_id, renderer);
371 } else {
372 // Camera or file.
373 ViEInputManagerScoped is(*(shared_data_->input_manager()));
374 ViEFrameProviderBase* frame_provider = is.FrameProvider(render_id);
375 if (!frame_provider) {
376 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
377 "%s: FrameProvider id %d doesn't exist", __FUNCTION__,
378 render_id);
379 shared_data_->SetLastError(kViERenderInvalidRenderId);
380 return -1;
381 }
382 ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
383 render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
384 if (!renderer) {
385 shared_data_->SetLastError(kViERenderUnknownError);
386 return -1;
387 }
388 if (renderer->SetExternalRenderer(render_id, video_input_format,
389 external_renderer) == -1) {
390 shared_data_->SetLastError(kViERenderUnknownError);
391 return -1;
392 }
393 return frame_provider->RegisterFrameCallback(render_id, renderer);
394 }
395}
396
397} // namespace webrtc