Home | History | Annotate | Download | only in video_engine
      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 
     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 
     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 
     58 ViECaptureImpl::ViECaptureImpl(ViESharedData* shared_data)
     59     : shared_data_(shared_data) {}
     60 
     61 ViECaptureImpl::~ViECaptureImpl() {}
     62 
     63 int ViECaptureImpl::NumberOfCaptureDevices() {
     64   return  shared_data_->input_manager()->NumberOfCaptureDevices();
     65 }
     66 
     67 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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