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