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::EnableColorEnhancement(const int video_channel,
186                                                const bool enable) {
187  LOG_F(LS_INFO) << "video_channel: " << video_channel
188                 << " enable: " << (enable ? "on" : "off");
189
190  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
191  ViEChannel* vie_channel = cs.Channel(video_channel);
192  if (!vie_channel) {
193    shared_data_->SetLastError(kViEImageProcessInvalidChannelId);
194    return -1;
195  }
196  if (vie_channel->EnableColorEnhancement(enable) != 0) {
197    if (enable) {
198      shared_data_->SetLastError(kViEImageProcessAlreadyEnabled);
199    } else {
200      shared_data_->SetLastError(kViEImageProcessAlreadyDisabled);
201    }
202    return -1;
203  }
204  return 0;
205}
206
207void ViEImageProcessImpl::RegisterPreEncodeCallback(
208    int video_channel,
209    I420FrameCallback* pre_encode_callback) {
210  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
211  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
212  vie_encoder->RegisterPreEncodeCallback(pre_encode_callback);
213}
214
215void ViEImageProcessImpl::DeRegisterPreEncodeCallback(int video_channel) {
216  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
217  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
218  assert(vie_encoder != NULL);
219  vie_encoder->DeRegisterPreEncodeCallback();
220}
221
222void ViEImageProcessImpl::RegisterPostEncodeImageCallback(
223    int video_channel,
224    EncodedImageCallback* post_encode_callback) {
225  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
226  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
227  assert(vie_encoder != NULL);
228  vie_encoder->RegisterPostEncodeImageCallback(post_encode_callback);
229}
230
231void ViEImageProcessImpl::DeRegisterPostEncodeCallback(int video_channel) {
232  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
233  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
234  assert(vie_encoder != NULL);
235  vie_encoder->DeRegisterPostEncodeImageCallback();
236}
237
238void ViEImageProcessImpl::RegisterPreDecodeImageCallback(
239    int video_channel,
240    EncodedImageCallback* pre_decode_callback) {
241  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
242  ViEChannel* channel = cs.Channel(video_channel);
243  channel->RegisterPreDecodeImageCallback(pre_decode_callback);
244}
245
246void ViEImageProcessImpl::DeRegisterPreDecodeCallback(int video_channel) {
247  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
248  ViEChannel* channel = cs.Channel(video_channel);
249  channel->RegisterPreDecodeImageCallback(NULL);
250}
251
252void ViEImageProcessImpl::RegisterPreRenderCallback(
253    int video_channel,
254    I420FrameCallback* pre_render_callback) {
255  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
256  ViEChannel* vie_channel = cs.Channel(video_channel);
257  assert(vie_channel != NULL);
258  vie_channel->RegisterPreRenderCallback(pre_render_callback);
259}
260
261void ViEImageProcessImpl::DeRegisterPreRenderCallback(int video_channel) {
262  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
263  ViEChannel* vie_channel = cs.Channel(video_channel);
264  assert(vie_channel != NULL);
265  vie_channel->RegisterPreRenderCallback(NULL);
266}
267
268}  // namespace webrtc
269