1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_render_impl.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/engine_configurations.h"
1407e96da4b4ae3ba9e722128fc650f6b10ff663f5andrew@webrtc.org#include "webrtc/modules/video_render/include/video_render.h"
1507e96da4b4ae3ba9e722128fc650f6b10ff663f5andrew@webrtc.org#include "webrtc/modules/video_render/include/video_render_defines.h"
163468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
17281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_errors.h"
18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_capturer.h"
19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel.h"
20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel_manager.h"
21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_defines.h"
22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_frame_provider_base.h"
23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_impl.h"
24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_input_manager.h"
25281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_render_manager.h"
26281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_renderer.h"
27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_shared_data.h"
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViERender* ViERender::GetInterface(VideoEngine* video_engine) {
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!video_engine) {
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
367ab726855f2ceb9ff6365e3240668d58f45e6761andrew@webrtc.org  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderImpl* vie_render_impl = vie_impl;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Increase ref count.
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*vie_render_impl)++;
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_render_impl;
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::Release() {
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Decrease ref count
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*this)--;
4967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t ref_count = GetCount();
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ref_count < 0) {
513468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org    LOG(LS_ERROR) << "ViERender release too many times";
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ref_count;
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViERenderImpl::ViERenderImpl(ViESharedData* shared_data)
583468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org    : shared_data_(shared_data) {}
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
603468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.orgViERenderImpl::~ViERenderImpl() {}
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::RegisterVideoRenderModule(
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoRender& render_module) {
643468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO);
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_->render_manager()->RegisterVideoRenderModule(
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      &render_module) != 0) {
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::DeRegisterVideoRenderModule(
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoRender& render_module) {
753468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO);
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_->render_manager()->DeRegisterVideoRenderModule(
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      &render_module) != 0) {
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Error logging is done in ViERenderManager::DeRegisterVideoRenderModule.
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::AddRenderer(const int render_id, void* window,
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const unsigned int z_order, const float left,
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const float top, const float right,
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const float bottom) {
893468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id << " z_order: " << z_order
903468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                 << " left: " << left << " top: " << top << " right: " << right
913468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                 << " bottom: " << bottom;
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderManagerScoped rs(*(shared_data_->render_manager()));
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (rs.Renderer(render_id)) {
953468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org      LOG(LS_ERROR) << "Renderer for render_id: " << render_id
963468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                    << " already exists.";
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderAlreadyExists);
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This is a channel.
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!frame_provider) {
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        render_id, window, z_order, left, top, right, bottom);
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!renderer) {
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return frame_provider->RegisterFrameCallback(render_id, renderer);
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else {
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Camera or file.
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEInputManagerScoped is(*(shared_data_->input_manager()));
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEFrameProviderBase* frame_provider = is.FrameProvider(render_id);
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!frame_provider) {
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        render_id, window, z_order, left, top, right, bottom);
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!renderer) {
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return frame_provider->RegisterFrameCallback(render_id, renderer);
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::RemoveRenderer(const int render_id) {
1353468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = NULL;
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderManagerScoped rs(*(shared_data_->render_manager()));
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    renderer = rs.Renderer(render_id);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!renderer) {
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Leave the scope lock since we don't want to lock two managers
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // simultanousely.
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This is a channel.
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannel* channel = cm.Channel(render_id);
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!channel) {
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    channel->DeregisterFrameCallback(renderer);
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else {
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Provider owned by inputmanager, i.e. file or capture device.
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEInputManagerScoped is(*(shared_data_->input_manager()));
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEFrameProviderBase* provider = is.FrameProvider(render_id);
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!provider) {
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    provider->DeregisterFrameCallback(renderer);
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_->render_manager()->RemoveRenderStream(render_id) != 0) {
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::StartRender(const int render_id) {
1743468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id;
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = rs.Renderer(render_id);
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!renderer) {
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (renderer->StartRender() != 0) {
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::StopRender(const int render_id) {
1893468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id;
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = rs.Renderer(render_id);
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!renderer) {
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (renderer->StopRender() != 0) {
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::SetExpectedRenderDelay(int render_id, int render_delay) {
2043468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id
2053468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                 << " render_delay: " << render_delay;
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = rs.Renderer(render_id);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!renderer) {
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (renderer->SetExpectedRenderDelay(render_delay) != 0) {
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::ConfigureRender(int render_id, const unsigned int z_order,
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   const float left, const float top,
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   const float right, const float bottom) {
2223468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org  LOG_F(LS_INFO) << "render_id: " << render_id << " z_order: " << z_order
2233468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                 << " left: " << left << " top: " << top << " right: " << right
2243468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org                 << " bottom: " << bottom;
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = rs.Renderer(render_id);
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!renderer) {
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (renderer->ConfigureRenderer(z_order, left, top, right, bottom) != 0) {
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::MirrorRenderStream(const int render_id, const bool enable,
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      const bool mirror_xaxis,
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      const bool mirror_yaxis) {
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViERenderer* renderer = rs.Renderer(render_id);
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!renderer) {
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (renderer->EnableMirroring(render_id, enable, mirror_xaxis, mirror_yaxis)
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      != 0) {
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViERenderImpl::AddRenderer(const int render_id,
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               RawVideoType video_input_format,
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               ExternalRenderer* external_renderer) {
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check if the client requested a format that we can convert the frames to.
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_input_format != kVideoI420 &&
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoYV12 &&
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoYUY2 &&
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoUYVY &&
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoARGB &&
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoRGB24 &&
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoRGB565 &&
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoARGB4444 &&
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_input_format != kVideoARGB1555) {
2693468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org    LOG(LS_ERROR) << "Unsupported video frame format requested.";
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViERenderInvalidFrameFormat);
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Verify the renderer doesn't exist.
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderManagerScoped rs(*(shared_data_->render_manager()));
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (rs.Renderer(render_id)) {
2773468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org      LOG_F(LS_ERROR) << "Renderer already exists for render_id: " << render_id;
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderAlreadyExists);
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (render_id >= kViEChannelIdBase && render_id <= kViEChannelIdMax) {
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This is a channel.
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!frame_provider) {
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!renderer) {
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (renderer->SetExternalRenderer(render_id, video_input_format,
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      external_renderer) == -1) {
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return frame_provider->RegisterFrameCallback(render_id, renderer);
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else {
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Camera or file.
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEInputManagerScoped is(*(shared_data_->input_manager()));
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEFrameProviderBase* frame_provider = is.FrameProvider(render_id);
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!frame_provider) {
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderInvalidRenderId);
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!renderer) {
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (renderer->SetExternalRenderer(render_id, video_input_format,
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      external_renderer) == -1) {
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViERenderUnknownError);
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return frame_provider->RegisterFrameCallback(render_id, renderer);
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3263051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.orgint ViERenderImpl::AddRenderCallback(int render_id,
3273051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org                                     VideoRenderCallback* callback) {
3283051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  if (render_id < kViEChannelIdBase || render_id > kViEChannelIdMax)
3293051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    return -1;
3303051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  // This is a channel.
3313051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
3323051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
3333051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  if (!frame_provider) {
3343051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    shared_data_->SetLastError(kViERenderInvalidRenderId);
3353051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    return -1;
3363051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  }
3373051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
3383051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org      render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
3393051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  if (!renderer) {
3403051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
3413051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    return -1;
3423051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  }
3433051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  if (renderer->SetVideoRenderCallback(render_id, callback) != 0) {
3443051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    shared_data_->SetLastError(kViERenderUnknownError);
3453051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org    return -1;
3463051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  }
3473051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org
3483051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org  return frame_provider->RegisterFrameCallback(render_id, renderer);
3493051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org}
3503051951c0e66a04914085e9fa0d28c6564642ba9pbos@webrtc.org
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
352