• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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   return shared_data_->input_manager()->GetDeviceName(
74       list_number,
75       device_nameUTF8, device_nameUTF8Length,
76       unique_idUTF8, unique_idUTF8Length);
77 }
78 
AllocateCaptureDevice(const char * unique_idUTF8,const unsigned int unique_idUTF8Length,int & capture_id)79 int ViECaptureImpl::AllocateCaptureDevice(
80   const char* unique_idUTF8,
81   const unsigned int unique_idUTF8Length,
82   int& capture_id) {
83   LOG(LS_INFO) << "AllocateCaptureDevice " << unique_idUTF8;
84   const int32_t result =
85       shared_data_->input_manager()->CreateCaptureDevice(
86           unique_idUTF8,
87           static_cast<const uint32_t>(unique_idUTF8Length),
88           capture_id);
89   if (result != 0) {
90     shared_data_->SetLastError(result);
91     return -1;
92   }
93   return 0;
94 }
95 
AllocateExternalCaptureDevice(int & capture_id,ViEExternalCapture * & external_capture)96 int ViECaptureImpl::AllocateExternalCaptureDevice(
97   int& capture_id, ViEExternalCapture*& external_capture) {
98   const int32_t result =
99       shared_data_->input_manager()->CreateExternalCaptureDevice(
100           external_capture, capture_id);
101 
102   if (result != 0) {
103     shared_data_->SetLastError(result);
104     return -1;
105   }
106   LOG(LS_INFO) << "External capture device allocated: " << capture_id;
107   return 0;
108 }
109 
AllocateCaptureDevice(VideoCaptureModule & capture_module,int & capture_id)110 int ViECaptureImpl::AllocateCaptureDevice(
111     VideoCaptureModule& capture_module, int& capture_id) {  // NOLINT
112   int32_t result = shared_data_->input_manager()->CreateCaptureDevice(
113       &capture_module, capture_id);
114   if (result != 0) {
115     shared_data_->SetLastError(result);
116     return -1;
117   }
118   LOG(LS_INFO) << "External capture device, by module, allocated: "
119                << capture_id;
120   return 0;
121 }
122 
123 
ReleaseCaptureDevice(const int capture_id)124 int ViECaptureImpl::ReleaseCaptureDevice(const int capture_id) {
125   LOG(LS_INFO) << "ReleaseCaptureDevice " << capture_id;
126   {
127     ViEInputManagerScoped is((*(shared_data_->input_manager())));
128     ViECapturer* vie_capture = is.Capture(capture_id);
129     if (!vie_capture) {
130       shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
131       return -1;
132     }
133   }
134   return shared_data_->input_manager()->DestroyCaptureDevice(capture_id);
135 }
136 
ConnectCaptureDevice(const int capture_id,const int video_channel)137 int ViECaptureImpl::ConnectCaptureDevice(const int capture_id,
138                                          const int video_channel) {
139   LOG(LS_INFO) << "Connect capture id " << capture_id
140                << " to channel " << video_channel;
141 
142   ViEInputManagerScoped is(*(shared_data_->input_manager()));
143   ViECapturer* vie_capture = is.Capture(capture_id);
144   if (!vie_capture) {
145     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
146     return -1;
147   }
148 
149   ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
150   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
151   if (!vie_encoder) {
152     LOG(LS_ERROR) << "Channel doesn't exist.";
153     shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
154     return -1;
155   }
156   if (vie_encoder->Owner() != video_channel) {
157     LOG(LS_ERROR) << "Can't connect capture device to a receive device.";
158     shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
159     return -1;
160   }
161   //  Check if the encoder already has a connected frame provider
162   if (is.FrameProvider(vie_encoder) != NULL) {
163     LOG(LS_ERROR) << "Channel already connected to capture device.";
164     shared_data_->SetLastError(kViECaptureDeviceAlreadyConnected);
165     return -1;
166   }
167   if (vie_capture->RegisterFrameCallback(video_channel, vie_encoder) != 0) {
168     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
169     return -1;
170   }
171   std::map<int, CpuOveruseObserver*>::iterator it =
172       shared_data_->overuse_observers()->find(video_channel);
173   if (it != shared_data_->overuse_observers()->end()) {
174     vie_capture->RegisterCpuOveruseObserver(it->second);
175   }
176   return 0;
177 }
178 
179 
DisconnectCaptureDevice(const int video_channel)180 int ViECaptureImpl::DisconnectCaptureDevice(const int video_channel) {
181   LOG(LS_INFO) << "DisconnectCaptureDevice " << video_channel;
182 
183   ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
184   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
185   if (!vie_encoder) {
186     LOG(LS_ERROR) << "Channel doesn't exist.";
187     shared_data_->SetLastError(kViECaptureDeviceInvalidChannelId);
188     return -1;
189   }
190 
191   ViEInputManagerScoped is(*(shared_data_->input_manager()));
192   ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
193   if (!frame_provider) {
194     shared_data_->SetLastError(kViECaptureDeviceNotConnected);
195     return -1;
196   }
197   if (frame_provider->Id() < kViECaptureIdBase ||
198       frame_provider->Id() > kViECaptureIdMax) {
199     shared_data_->SetLastError(kViECaptureDeviceNotConnected);
200     return -1;
201   }
202 
203   ViECapturer* vie_capture = is.Capture(frame_provider->Id());
204   assert(vie_capture);
205   vie_capture->RegisterCpuOveruseObserver(NULL);
206   if (frame_provider->DeregisterFrameCallback(vie_encoder) != 0) {
207     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
208     return -1;
209   }
210 
211   return 0;
212 }
213 
StartCapture(const int capture_id,const CaptureCapability & capture_capability)214 int ViECaptureImpl::StartCapture(const int capture_id,
215                                  const CaptureCapability& capture_capability) {
216   LOG(LS_INFO) << "StartCapture " << capture_id;
217 
218   ViEInputManagerScoped is(*(shared_data_->input_manager()));
219   ViECapturer* vie_capture = is.Capture(capture_id);
220   if (!vie_capture) {
221     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
222     return -1;
223   }
224   if (vie_capture->Started()) {
225     shared_data_->SetLastError(kViECaptureDeviceAlreadyStarted);
226     return -1;
227   }
228   if (vie_capture->Start(capture_capability) != 0) {
229     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
230     return -1;
231   }
232   return 0;
233 }
234 
StopCapture(const int capture_id)235 int ViECaptureImpl::StopCapture(const int capture_id) {
236   LOG(LS_INFO) << "StopCapture " << capture_id;
237 
238   ViEInputManagerScoped is(*(shared_data_->input_manager()));
239   ViECapturer* vie_capture = is.Capture(capture_id);
240   if (!vie_capture) {
241     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
242     return -1;
243   }
244   if (!vie_capture->Started()) {
245     shared_data_->SetLastError(kViECaptureDeviceNotStarted);
246     return 0;
247   }
248   if (vie_capture->Stop() != 0) {
249     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
250     return -1;
251   }
252   return 0;
253 }
254 
SetRotateCapturedFrames(const int capture_id,const RotateCapturedFrame rotation)255 int ViECaptureImpl::SetRotateCapturedFrames(
256     const int capture_id,
257     const RotateCapturedFrame rotation) {
258   int i_rotation = -1;
259   switch (rotation) {
260     case RotateCapturedFrame_0:
261       i_rotation = 0;
262       break;
263     case RotateCapturedFrame_90:
264       i_rotation = 90;
265       break;
266     case RotateCapturedFrame_180:
267       i_rotation = 180;
268       break;
269     case RotateCapturedFrame_270:
270       i_rotation = 270;
271       break;
272   }
273   LOG(LS_INFO) << "SetRotateCaptureFrames for " << capture_id
274                << ", rotation " << i_rotation;
275 
276   ViEInputManagerScoped is(*(shared_data_->input_manager()));
277   ViECapturer* vie_capture = is.Capture(capture_id);
278   if (!vie_capture) {
279     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
280     return -1;
281   }
282   if (vie_capture->SetRotateCapturedFrames(rotation) != 0) {
283     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
284     return -1;
285   }
286   return 0;
287 }
288 
SetCaptureDelay(const int capture_id,const unsigned int capture_delay_ms)289 int ViECaptureImpl::SetCaptureDelay(const int capture_id,
290                                     const unsigned int capture_delay_ms) {
291   LOG(LS_INFO) << "SetCaptureDelay " << capture_delay_ms
292                << ", for device " << capture_id;
293 
294   ViEInputManagerScoped is(*(shared_data_->input_manager()));
295   ViECapturer* vie_capture = is.Capture(capture_id);
296   if (!vie_capture) {
297     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
298     return -1;
299   }
300 
301   if (vie_capture->SetCaptureDelay(capture_delay_ms) != 0) {
302     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
303     return -1;
304   }
305   return 0;
306 }
307 
NumberOfCapabilities(const char * unique_idUTF8,const unsigned int unique_idUTF8Length)308 int ViECaptureImpl::NumberOfCapabilities(
309     const char* unique_idUTF8,
310     const unsigned int unique_idUTF8Length) {
311 
312 #if defined(WEBRTC_MAC)
313   // TODO(mflodman) Move to capture module!
314   // QTKit framework handles all capabilities and capture settings
315   // automatically (mandatory).
316   // Thus this function cannot be supported on the Mac platform.
317   shared_data_->SetLastError(kViECaptureDeviceMacQtkitNotSupported);
318   LOG_F(LS_ERROR) << "API not supported on Mac OS X.";
319   return -1;
320 #endif
321   return shared_data_->input_manager()->NumberOfCaptureCapabilities(
322       unique_idUTF8);
323 }
324 
325 
GetCaptureCapability(const char * unique_idUTF8,const unsigned int unique_idUTF8Length,const unsigned int capability_number,CaptureCapability & capability)326 int ViECaptureImpl::GetCaptureCapability(const char* unique_idUTF8,
327                                          const unsigned int unique_idUTF8Length,
328                                          const unsigned int capability_number,
329                                          CaptureCapability& capability) {
330 
331 #if defined(WEBRTC_MAC)
332   // TODO(mflodman) Move to capture module!
333   // QTKit framework handles all capabilities and capture settings
334   // automatically (mandatory).
335   // Thus this function cannot be supported on the Mac platform.
336   LOG_F(LS_ERROR) << "API not supported on Mac OS X.";
337   shared_data_->SetLastError(kViECaptureDeviceMacQtkitNotSupported);
338   return -1;
339 #endif
340   if (shared_data_->input_manager()->GetCaptureCapability(
341           unique_idUTF8, capability_number, capability) != 0) {
342     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
343     return -1;
344   }
345   return 0;
346 }
347 
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)348 int ViECaptureImpl::ShowCaptureSettingsDialogBox(
349     const char* unique_idUTF8,
350     const unsigned int unique_idUTF8Length,
351     const char* dialog_title,
352     void* parent_window,
353     const unsigned int x,
354     const unsigned int y) {
355 #if defined(WEBRTC_MAC)
356   // TODO(mflodman) Move to capture module
357   // QTKit framework handles all capabilities and capture settings
358   // automatically (mandatory).
359   // Thus this function cannot be supported on the Mac platform.
360   shared_data_->SetLastError(kViECaptureDeviceMacQtkitNotSupported);
361   LOG_F(LS_ERROR) << "API not supported on Mac OS X.";
362   return -1;
363 #endif
364   return shared_data_->input_manager()->DisplayCaptureSettingsDialogBox(
365            unique_idUTF8, dialog_title,
366            parent_window, x, y);
367 }
368 
GetOrientation(const char * unique_idUTF8,RotateCapturedFrame & orientation)369 int ViECaptureImpl::GetOrientation(const char* unique_idUTF8,
370                                    RotateCapturedFrame& orientation) {
371   if (shared_data_->input_manager()->GetOrientation(
372       unique_idUTF8,
373       orientation) != 0) {
374     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
375     return -1;
376   }
377   return 0;
378 }
379 
380 
EnableBrightnessAlarm(const int capture_id,const bool enable)381 int ViECaptureImpl::EnableBrightnessAlarm(const int capture_id,
382                                           const bool enable) {
383   LOG(LS_INFO) << "EnableBrightnessAlarm for device " << capture_id
384                << ", status " << enable;
385   ViEInputManagerScoped is(*(shared_data_->input_manager()));
386   ViECapturer* vie_capture = is.Capture(capture_id);
387   if (!vie_capture) {
388     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
389     return -1;
390   }
391   if (vie_capture->EnableBrightnessAlarm(enable) != 0) {
392     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
393     return -1;
394   }
395   return 0;
396 }
397 
RegisterObserver(const int capture_id,ViECaptureObserver & observer)398 int ViECaptureImpl::RegisterObserver(const int capture_id,
399                                      ViECaptureObserver& observer) {
400   LOG(LS_INFO) << "Register capture observer " << capture_id;
401   ViEInputManagerScoped is(*(shared_data_->input_manager()));
402   ViECapturer* vie_capture = is.Capture(capture_id);
403   if (!vie_capture) {
404     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
405     return -1;
406   }
407   if (vie_capture->IsObserverRegistered()) {
408     LOG_F(LS_ERROR) << "Observer already registered.";
409     shared_data_->SetLastError(kViECaptureObserverAlreadyRegistered);
410     return -1;
411   }
412   if (vie_capture->RegisterObserver(&observer) != 0) {
413     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
414     return -1;
415   }
416   return 0;
417 }
418 
DeregisterObserver(const int capture_id)419 int ViECaptureImpl::DeregisterObserver(const int capture_id) {
420   ViEInputManagerScoped is(*(shared_data_->input_manager()));
421   ViECapturer* vie_capture = is.Capture(capture_id);
422   if (!vie_capture) {
423     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
424     return -1;
425   }
426   if (!vie_capture->IsObserverRegistered()) {
427     shared_data_->SetLastError(kViECaptureDeviceObserverNotRegistered);
428     return -1;
429   }
430 
431   if (vie_capture->DeRegisterObserver() != 0) {
432     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
433     return -1;
434   }
435   return 0;
436 }
437 
438 }  // namespace webrtc
439