1/*
2 *  Copyright (c) 2011 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_image_process_impl.h"
12
13#include "webrtc/system_wrappers/interface/logging.h"
14#include "webrtc/video_engine/include/vie_errors.h"
15#include "webrtc/video_engine/vie_capturer.h"
16#include "webrtc/video_engine/vie_channel.h"
17#include "webrtc/video_engine/vie_channel_manager.h"
18#include "webrtc/video_engine/vie_defines.h"
19#include "webrtc/video_engine/vie_encoder.h"
20#include "webrtc/video_engine/vie_impl.h"
21#include "webrtc/video_engine/vie_input_manager.h"
22#include "webrtc/video_engine/vie_shared_data.h"
23
24namespace webrtc {
25
26ViEImageProcess* ViEImageProcess::GetInterface(VideoEngine* video_engine) {
27#ifdef WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
28  if (!video_engine) {
29    return NULL;
30  }
31  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
32  ViEImageProcessImpl* vie_image_process_impl = vie_impl;
33  // Increase ref count.
34  (*vie_image_process_impl)++;
35  return vie_image_process_impl;
36#else
37  return NULL;
38#endif
39}
40
41int ViEImageProcessImpl::Release() {
42  // Decrease ref count.
43  (*this)--;
44
45  int32_t ref_count = GetCount();
46  if (ref_count < 0) {
47    LOG(LS_ERROR) << "ViEImageProcess release too many times";
48    shared_data_->SetLastError(kViEAPIDoesNotExist);
49    return -1;
50  }
51  return ref_count;
52}
53
54ViEImageProcessImpl::ViEImageProcessImpl(ViESharedData* shared_data)
55    : shared_data_(shared_data) {}
56
57ViEImageProcessImpl::~ViEImageProcessImpl() {}
58
59int ViEImageProcessImpl::RegisterCaptureEffectFilter(
60  const int capture_id,
61  ViEEffectFilter& capture_filter) {
62  LOG_F(LS_INFO) << "capture_id: " << capture_id;
63  ViEInputManagerScoped is(*(shared_data_->input_manager()));
64  ViECapturer* vie_capture = is.Capture(capture_id);
65  if (!vie_capture) {
66    shared_data_->SetLastError(kViEImageProcessInvalidCaptureId);
67    return -1;
68  }
69  if (vie_capture->RegisterEffectFilter(&capture_filter) != 0) {
70    shared_data_->SetLastError(kViEImageProcessFilterExists);
71    return -1;
72  }
73  return 0;
74}
75
76int ViEImageProcessImpl::DeregisterCaptureEffectFilter(const int capture_id) {
77  LOG_F(LS_INFO) << "capture_id: " << capture_id;
78
79  ViEInputManagerScoped is(*(shared_data_->input_manager()));
80  ViECapturer* vie_capture = is.Capture(capture_id);
81  if (!vie_capture) {
82    shared_data_->SetLastError(kViEImageProcessInvalidCaptureId);
83    return -1;
84  }
85  if (vie_capture->RegisterEffectFilter(NULL) != 0) {
86    shared_data_->SetLastError(kViEImageProcessFilterDoesNotExist);
87    return -1;
88  }
89  return 0;
90}
91
92int ViEImageProcessImpl::RegisterSendEffectFilter(
93    const int video_channel,
94    ViEEffectFilter& send_filter) {
95  LOG_F(LS_INFO) << "video_channel: " << video_channel;
96
97  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
98  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
99  if (vie_encoder == NULL) {
100    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
101    return -1;
102  }
103
104  if (vie_encoder->RegisterEffectFilter(&send_filter) != 0) {
105    shared_data_->SetLastError(kViEImageProcessFilterExists);
106    return -1;
107  }
108  return 0;
109}
110
111int ViEImageProcessImpl::DeregisterSendEffectFilter(const int video_channel) {
112  LOG_F(LS_INFO) << "video_channel: " << video_channel;
113
114  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
115  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
116  if (vie_encoder == NULL) {
117    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
118    return -1;
119  }
120  if (vie_encoder->RegisterEffectFilter(NULL) != 0) {
121    shared_data_->SetLastError(kViEImageProcessFilterDoesNotExist);
122    return -1;
123  }
124  return 0;
125}
126
127int ViEImageProcessImpl::RegisterRenderEffectFilter(
128  const int video_channel,
129  ViEEffectFilter& render_filter) {
130  LOG_F(LS_INFO) << "video_channel: " << video_channel;
131
132  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
133  ViEChannel* vie_channel = cs.Channel(video_channel);
134  if (!vie_channel) {
135    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
136    return -1;
137  }
138  if (vie_channel->RegisterEffectFilter(&render_filter) != 0) {
139    shared_data_->SetLastError(kViEImageProcessFilterExists);
140    return -1;
141  }
142  return 0;
143}
144
145int ViEImageProcessImpl::DeregisterRenderEffectFilter(const int video_channel) {
146  LOG_F(LS_INFO) << "video_channel: " << video_channel;
147
148  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
149  ViEChannel* vie_channel = cs.Channel(video_channel);
150  if (!vie_channel) {
151    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
152    return -1;
153  }
154
155  if (vie_channel->RegisterEffectFilter(NULL) != 0) {
156    shared_data_->SetLastError(kViEImageProcessFilterDoesNotExist);
157    return -1;
158  }
159  return 0;
160}
161
162int ViEImageProcessImpl::EnableDeflickering(const int capture_id,
163                                            const bool enable) {
164  LOG_F(LS_INFO) << "capture_id: " << capture_id
165                 << " enable: " << (enable ? "on" : "off");
166
167  ViEInputManagerScoped is(*(shared_data_->input_manager()));
168  ViECapturer* vie_capture = is.Capture(capture_id);
169  if (!vie_capture) {
170    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
171    return -1;
172  }
173
174  if (vie_capture->EnableDeflickering(enable) != 0) {
175    if (enable) {
176      shared_data_->SetLastError(kViEImageProcessAlreadyEnabled);
177    } else {
178      shared_data_->SetLastError(kViEImageProcessAlreadyDisabled);
179    }
180    return -1;
181  }
182  return 0;
183}
184
185int ViEImageProcessImpl::EnableDenoising(const int capture_id,
186                                         const bool enable) {
187  LOG_F(LS_INFO) << "capture_id: " << capture_id
188                 << " enable: " << (enable ? "on" : "off");
189
190  ViEInputManagerScoped is(*(shared_data_->input_manager()));
191  ViECapturer* vie_capture = is.Capture(capture_id);
192  if (!vie_capture) {
193    shared_data_->SetLastError(kViEImageProcessInvalidCaptureId);
194    return -1;
195  }
196
197  if (vie_capture->EnableDenoising(enable) != 0) {
198    if (enable) {
199      shared_data_->SetLastError(kViEImageProcessAlreadyEnabled);
200    } else {
201      shared_data_->SetLastError(kViEImageProcessAlreadyDisabled);
202    }
203    return -1;
204  }
205  return 0;
206}
207
208int ViEImageProcessImpl::EnableColorEnhancement(const int video_channel,
209                                                const bool enable) {
210  LOG_F(LS_INFO) << "video_channel: " << video_channel
211                 << " enable: " << (enable ? "on" : "off");
212
213  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
214  ViEChannel* vie_channel = cs.Channel(video_channel);
215  if (!vie_channel) {
216    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
217    return -1;
218  }
219  if (vie_channel->EnableColorEnhancement(enable) != 0) {
220    if (enable) {
221      shared_data_->SetLastError(kViEImageProcessAlreadyEnabled);
222    } else {
223      shared_data_->SetLastError(kViEImageProcessAlreadyDisabled);
224    }
225    return -1;
226  }
227  return 0;
228}
229
230void ViEImageProcessImpl::RegisterPreEncodeCallback(
231    int video_channel,
232    I420FrameCallback* pre_encode_callback) {
233  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
234  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
235  vie_encoder->RegisterPreEncodeCallback(pre_encode_callback);
236}
237
238void ViEImageProcessImpl::DeRegisterPreEncodeCallback(int video_channel) {
239  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
240  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
241  assert(vie_encoder != NULL);
242  vie_encoder->DeRegisterPreEncodeCallback();
243}
244
245void ViEImageProcessImpl::RegisterPostEncodeImageCallback(
246    int video_channel,
247    EncodedImageCallback* post_encode_callback) {
248  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
249  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
250  assert(vie_encoder != NULL);
251  vie_encoder->RegisterPostEncodeImageCallback(post_encode_callback);
252}
253
254void ViEImageProcessImpl::DeRegisterPostEncodeCallback(int video_channel) {
255  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
256  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
257  assert(vie_encoder != NULL);
258  vie_encoder->DeRegisterPostEncodeImageCallback();
259}
260
261void ViEImageProcessImpl::RegisterPreDecodeImageCallback(
262    int video_channel,
263    EncodedImageCallback* pre_decode_callback) {
264  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
265  ViEChannel* channel = cs.Channel(video_channel);
266  channel->RegisterPreDecodeImageCallback(pre_decode_callback);
267}
268
269void ViEImageProcessImpl::DeRegisterPreDecodeCallback(int video_channel) {
270  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
271  ViEChannel* channel = cs.Channel(video_channel);
272  channel->RegisterPreDecodeImageCallback(NULL);
273}
274
275void ViEImageProcessImpl::RegisterPreRenderCallback(
276    int video_channel,
277    I420FrameCallback* pre_render_callback) {
278  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
279  ViEChannel* vie_channel = cs.Channel(video_channel);
280  assert(vie_channel != NULL);
281  vie_channel->RegisterPreRenderCallback(pre_render_callback);
282}
283
284void ViEImageProcessImpl::DeRegisterPreRenderCallback(int video_channel) {
285  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
286  ViEChannel* vie_channel = cs.Channel(video_channel);
287  assert(vie_channel != NULL);
288  vie_channel->RegisterPreRenderCallback(NULL);
289}
290
291}  // namespace webrtc
292