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_capture_impl.h"
12
13 #include <map>
14
15 #include "webrtc/system_wrappers/interface/logging.h"
16 #include "webrtc/video_engine/include/vie_errors.h"
17 #include "webrtc/video_engine/vie_capturer.h"
18 #include "webrtc/video_engine/vie_channel.h"
19 #include "webrtc/video_engine/vie_channel_manager.h"
20 #include "webrtc/video_engine/vie_defines.h"
21 #include "webrtc/video_engine/vie_encoder.h"
22 #include "webrtc/video_engine/vie_impl.h"
23 #include "webrtc/video_engine/vie_input_manager.h"
24 #include "webrtc/video_engine/vie_shared_data.h"
25
26 namespace webrtc {
27
28 class CpuOveruseObserver;
29
GetInterface(VideoEngine * video_engine)30 ViECapture* ViECapture::GetInterface(VideoEngine* video_engine) {
31 #ifdef WEBRTC_VIDEO_ENGINE_CAPTURE_API
32 if (!video_engine) {
33 return NULL;
34 }
35 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
36 ViECaptureImpl* vie_capture_impl = vie_impl;
37 // Increase ref count.
38 (*vie_capture_impl)++;
39 return vie_capture_impl;
40 #else
41 return NULL;
42 #endif
43 }
44
Release()45 int ViECaptureImpl::Release() {
46 // Decrease ref count
47 (*this)--;
48
49 int32_t ref_count = GetCount();
50 if (ref_count < 0) {
51 LOG(LS_WARNING) << "ViECapture released too many times.";
52 shared_data_->SetLastError(kViEAPIDoesNotExist);
53 return -1;
54 }
55 return ref_count;
56 }
57
ViECaptureImpl(ViESharedData * shared_data)58 ViECaptureImpl::ViECaptureImpl(ViESharedData* shared_data)
59 : shared_data_(shared_data) {}
60
~ViECaptureImpl()61 ViECaptureImpl::~ViECaptureImpl() {}
62
NumberOfCaptureDevices()63 int ViECaptureImpl::NumberOfCaptureDevices() {
64 return shared_data_->input_manager()->NumberOfCaptureDevices();
65 }
66
67
GetCaptureDevice(unsigned int list_number,char * device_nameUTF8,unsigned int device_nameUTF8Length,char * unique_idUTF8,unsigned int unique_idUTF8Length,pid_t * pid)68 int ViECaptureImpl::GetCaptureDevice(unsigned int list_number,
69 char* device_nameUTF8,
70 unsigned int device_nameUTF8Length,
71 char* unique_idUTF8,
72 unsigned int unique_idUTF8Length,
73 pid_t* pid) {
74 return shared_data_->input_manager()->GetDeviceName(
75 list_number,
76 device_nameUTF8, device_nameUTF8Length,
77 unique_idUTF8, unique_idUTF8Length, pid);
78 }
79
AllocateCaptureDevice(const char * unique_idUTF8,const unsigned int unique_idUTF8Length,int & capture_id)80 int ViECaptureImpl::AllocateCaptureDevice(
81 const char* unique_idUTF8,
82 const unsigned int unique_idUTF8Length,
83 int& capture_id) {
84 LOG(LS_INFO) << "AllocateCaptureDevice " << unique_idUTF8;
85 const int32_t result =
86 shared_data_->input_manager()->CreateCaptureDevice(
87 unique_idUTF8,
88 static_cast<const uint32_t>(unique_idUTF8Length),
89 capture_id);
90 if (result != 0) {
91 shared_data_->SetLastError(result);
92 return -1;
93 }
94 return 0;
95 }
96
AllocateExternalCaptureDevice(int & capture_id,ViEExternalCapture * & external_capture)97 int ViECaptureImpl::AllocateExternalCaptureDevice(
98 int& capture_id, ViEExternalCapture*& external_capture) {
99 const int32_t result =
100 shared_data_->input_manager()->CreateExternalCaptureDevice(
101 external_capture, capture_id);
102
103 if (result != 0) {
104 shared_data_->SetLastError(result);
105 return -1;
106 }
107 LOG(LS_INFO) << "External capture device allocated: " << capture_id;
108 return 0;
109 }
110
AllocateCaptureDevice(VideoCaptureModule & capture_module,int & capture_id)111 int ViECaptureImpl::AllocateCaptureDevice(
112 VideoCaptureModule& capture_module, int& capture_id) { // NOLINT
113 int32_t result = shared_data_->input_manager()->CreateCaptureDevice(
114 &capture_module, capture_id);
115 if (result != 0) {
116 shared_data_->SetLastError(result);
117 return -1;
118 }
119 LOG(LS_INFO) << "External capture device, by module, allocated: "
120 << capture_id;
121 return 0;
122 }
123
124
ReleaseCaptureDevice(const int capture_id)125 int ViECaptureImpl::ReleaseCaptureDevice(const int capture_id) {
126 LOG(LS_INFO) << "ReleaseCaptureDevice " << capture_id;
127 {
128 ViEInputManagerScoped is((*(shared_data_->input_manager())));
129 ViECapturer* vie_capture = is.Capture(capture_id);
130 if (!vie_capture) {
131 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
132 return -1;
133 }
134 }
135 return shared_data_->input_manager()->DestroyCaptureDevice(capture_id);
136 }
137
ConnectCaptureDevice(const int capture_id,const int video_channel)138 int ViECaptureImpl::ConnectCaptureDevice(const int capture_id,
139 const int video_channel) {
140 LOG(LS_INFO) << "Connect capture id " << capture_id
141 << " to channel " << video_channel;
142
143 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
144 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
145 if (!vie_encoder) {
146 LOG(LS_ERROR) << "Channel doesn't exist.";
147 shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
148 return -1;
149 }
150 if (vie_encoder->Owner() != video_channel) {
151 LOG(LS_ERROR) << "Can't connect capture device to a receive device.";
152 shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
153 return -1;
154 }
155
156 ViEInputManagerScoped is(*(shared_data_->input_manager()));
157 ViECapturer* vie_capture = is.Capture(capture_id);
158 if (!vie_capture) {
159 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
160 return -1;
161 }
162 // Check if the encoder already has a connected frame provider
163 if (is.FrameProvider(vie_encoder) != NULL) {
164 LOG(LS_ERROR) << "Channel already connected to capture device.";
165 shared_data_->SetLastError(kViECaptureDeviceAlreadyConnected);
166 return -1;
167 }
168 if (vie_capture->RegisterFrameCallback(video_channel, vie_encoder) != 0) {
169 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
170 return -1;
171 }
172 std::map<int, CpuOveruseObserver*>::iterator it =
173 shared_data_->overuse_observers()->find(video_channel);
174 if (it != shared_data_->overuse_observers()->end()) {
175 vie_capture->RegisterCpuOveruseObserver(it->second);
176 }
177 return 0;
178 }
179
180
DisconnectCaptureDevice(const int video_channel)181 int ViECaptureImpl::DisconnectCaptureDevice(const int video_channel) {
182 LOG(LS_INFO) << "DisconnectCaptureDevice " << video_channel;
183
184 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
185 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
186 if (!vie_encoder) {
187 LOG(LS_ERROR) << "Channel doesn't exist.";
188 shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
189 return -1;
190 }
191
192 ViEInputManagerScoped is(*(shared_data_->input_manager()));
193 ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
194 if (!frame_provider) {
195 shared_data_->SetLastError(kViECaptureDeviceNotConnected);
196 return -1;
197 }
198 if (frame_provider->Id() < kViECaptureIdBase ||
199 frame_provider->Id() > kViECaptureIdMax) {
200 shared_data_->SetLastError(kViECaptureDeviceNotConnected);
201 return -1;
202 }
203
204 ViECapturer* vie_capture = is.Capture(frame_provider->Id());
205 assert(vie_capture);
206 vie_capture->RegisterCpuOveruseObserver(NULL);
207 if (frame_provider->DeregisterFrameCallback(vie_encoder) != 0) {
208 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
209 return -1;
210 }
211
212 return 0;
213 }
214
StartCapture(const int capture_id,const CaptureCapability & capture_capability)215 int ViECaptureImpl::StartCapture(const int capture_id,
216 const CaptureCapability& capture_capability) {
217 LOG(LS_INFO) << "StartCapture " << capture_id;
218
219 ViEInputManagerScoped is(*(shared_data_->input_manager()));
220 ViECapturer* vie_capture = is.Capture(capture_id);
221 if (!vie_capture) {
222 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
223 return -1;
224 }
225 if (vie_capture->Started()) {
226 shared_data_->SetLastError(kViECaptureDeviceAlreadyStarted);
227 return -1;
228 }
229 if (vie_capture->Start(capture_capability) != 0) {
230 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
231 return -1;
232 }
233 return 0;
234 }
235
StopCapture(const int capture_id)236 int ViECaptureImpl::StopCapture(const int capture_id) {
237 LOG(LS_INFO) << "StopCapture " << capture_id;
238
239 ViEInputManagerScoped is(*(shared_data_->input_manager()));
240 ViECapturer* vie_capture = is.Capture(capture_id);
241 if (!vie_capture) {
242 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
243 return -1;
244 }
245 if (!vie_capture->Started()) {
246 shared_data_->SetLastError(kViECaptureDeviceNotStarted);
247 return 0;
248 }
249 if (vie_capture->Stop() != 0) {
250 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
251 return -1;
252 }
253 return 0;
254 }
255
SetVideoRotation(const int capture_id,const VideoRotation rotation)256 int ViECaptureImpl::SetVideoRotation(const int capture_id,
257 const VideoRotation rotation) {
258 LOG(LS_INFO) << "SetRotateCaptureFrames for " << capture_id << ", rotation "
259 << static_cast<int>(rotation);
260
261 ViEInputManagerScoped is(*(shared_data_->input_manager()));
262 ViECapturer* vie_capture = is.Capture(capture_id);
263 if (!vie_capture) {
264 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
265 return -1;
266 }
267 if (vie_capture->SetVideoRotation(rotation) != 0) {
268 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
269 return -1;
270 }
271 return 0;
272 }
273
SetCaptureDelay(const int capture_id,const unsigned int capture_delay_ms)274 int ViECaptureImpl::SetCaptureDelay(const int capture_id,
275 const unsigned int capture_delay_ms) {
276 LOG(LS_INFO) << "SetCaptureDelay " << capture_delay_ms
277 << ", for device " << capture_id;
278
279 ViEInputManagerScoped is(*(shared_data_->input_manager()));
280 ViECapturer* vie_capture = is.Capture(capture_id);
281 if (!vie_capture) {
282 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
283 return -1;
284 }
285
286 if (vie_capture->SetCaptureDelay(capture_delay_ms) != 0) {
287 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
288 return -1;
289 }
290 return 0;
291 }
292
NumberOfCapabilities(const char * unique_idUTF8,const unsigned int unique_idUTF8Length)293 int ViECaptureImpl::NumberOfCapabilities(
294 const char* unique_idUTF8,
295 const unsigned int unique_idUTF8Length) {
296
297 return shared_data_->input_manager()->NumberOfCaptureCapabilities(
298 unique_idUTF8);
299 }
300
301
GetCaptureCapability(const char * unique_idUTF8,const unsigned int unique_idUTF8Length,const unsigned int capability_number,CaptureCapability & capability)302 int ViECaptureImpl::GetCaptureCapability(const char* unique_idUTF8,
303 const unsigned int unique_idUTF8Length,
304 const unsigned int capability_number,
305 CaptureCapability& capability) {
306
307 if (shared_data_->input_manager()->GetCaptureCapability(
308 unique_idUTF8, capability_number, capability) != 0) {
309 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
310 return -1;
311 }
312 return 0;
313 }
314
ShowCaptureSettingsDialogBox(const char * unique_idUTF8,const unsigned int unique_idUTF8Length,const char * dialog_title,void * parent_window,const unsigned int x,const unsigned int y)315 int ViECaptureImpl::ShowCaptureSettingsDialogBox(
316 const char* unique_idUTF8,
317 const unsigned int unique_idUTF8Length,
318 const char* dialog_title,
319 void* parent_window,
320 const unsigned int x,
321 const unsigned int y) {
322 return shared_data_->input_manager()->DisplayCaptureSettingsDialogBox(
323 unique_idUTF8, dialog_title,
324 parent_window, x, y);
325 }
326
GetOrientation(const char * unique_idUTF8,VideoRotation & orientation)327 int ViECaptureImpl::GetOrientation(const char* unique_idUTF8,
328 VideoRotation& orientation) {
329 if (shared_data_->input_manager()->GetOrientation(
330 unique_idUTF8,
331 orientation) != 0) {
332 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
333 return -1;
334 }
335 return 0;
336 }
337
338
EnableBrightnessAlarm(const int capture_id,const bool enable)339 int ViECaptureImpl::EnableBrightnessAlarm(const int capture_id,
340 const bool enable) {
341 LOG(LS_INFO) << "EnableBrightnessAlarm for device " << capture_id
342 << ", status " << enable;
343 ViEInputManagerScoped is(*(shared_data_->input_manager()));
344 ViECapturer* vie_capture = is.Capture(capture_id);
345 if (!vie_capture) {
346 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
347 return -1;
348 }
349 if (vie_capture->EnableBrightnessAlarm(enable) != 0) {
350 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
351 return -1;
352 }
353 return 0;
354 }
355
RegisterObserver(const int capture_id,ViECaptureObserver & observer)356 int ViECaptureImpl::RegisterObserver(const int capture_id,
357 ViECaptureObserver& observer) {
358 LOG(LS_INFO) << "Register capture observer " << capture_id;
359 ViEInputManagerScoped is(*(shared_data_->input_manager()));
360 ViECapturer* vie_capture = is.Capture(capture_id);
361 if (!vie_capture) {
362 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
363 return -1;
364 }
365 if (vie_capture->IsObserverRegistered()) {
366 LOG_F(LS_ERROR) << "Observer already registered.";
367 shared_data_->SetLastError(kViECaptureObserverAlreadyRegistered);
368 return -1;
369 }
370 if (vie_capture->RegisterObserver(&observer) != 0) {
371 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
372 return -1;
373 }
374 return 0;
375 }
376
RegisterInputObserver(ViEInputObserver * observer)377 int ViECaptureImpl::RegisterInputObserver(ViEInputObserver* observer) {
378 if (shared_data_->input_manager()->RegisterObserver(observer) != 0) {
379 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
380 return -1;
381 }
382 return 0;
383 }
384
DeregisterObserver(const int capture_id)385 int ViECaptureImpl::DeregisterObserver(const int capture_id) {
386 ViEInputManagerScoped is(*(shared_data_->input_manager()));
387 ViECapturer* vie_capture = is.Capture(capture_id);
388 if (!vie_capture) {
389 shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
390 return -1;
391 }
392 if (!vie_capture->IsObserverRegistered()) {
393 shared_data_->SetLastError(kViECaptureDeviceObserverNotRegistered);
394 return -1;
395 }
396
397 if (vie_capture->DeRegisterObserver() != 0) {
398 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
399 return -1;
400 }
401 return 0;
402 }
403
DeregisterInputObserver()404 int ViECaptureImpl::DeregisterInputObserver() {
405 if (shared_data_->input_manager()->DeRegisterObserver() != 0) {
406 shared_data_->SetLastError(kViECaptureDeviceUnknownError);
407 return -1;
408 }
409 return 0;
410 }
411
412 } // namespace webrtc
413