Home | History | Annotate | Download | only in ios
      1 /*
      2  *  Copyright (c) 2013 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 #if !defined(__has_feature) || !__has_feature(objc_arc)
     12 #error "This file requires ARC support."
     13 #endif
     14 
     15 #include <AVFoundation/AVFoundation.h>
     16 
     17 #include <string>
     18 
     19 #include "webrtc/modules/video_capture/ios/device_info_ios.h"
     20 #include "webrtc/modules/video_capture/ios/device_info_ios_objc.h"
     21 #include "webrtc/modules/video_capture/video_capture_impl.h"
     22 #include "webrtc/system_wrappers/include/trace.h"
     23 
     24 using namespace webrtc;
     25 using namespace videocapturemodule;
     26 
     27 static NSArray *camera_presets = @[AVCaptureSessionPreset352x288,
     28                                    AVCaptureSessionPreset640x480,
     29                                    AVCaptureSessionPreset1280x720,
     30                                    AVCaptureSessionPreset1920x1080];
     31 
     32 
     33 #define IOS_UNSUPPORTED()                                  \
     34   WEBRTC_TRACE(kTraceError,                                \
     35                kTraceVideoCapture,                         \
     36                _id,                                        \
     37                "%s is not supported on the iOS platform.", \
     38                __FUNCTION__);                              \
     39   return -1;
     40 
     41 VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo(
     42     const int32_t device_id) {
     43   return new DeviceInfoIos(device_id);
     44 }
     45 
     46 DeviceInfoIos::DeviceInfoIos(const int32_t device_id)
     47     : DeviceInfoImpl(device_id) {
     48   this->Init();
     49 }
     50 
     51 DeviceInfoIos::~DeviceInfoIos() {}
     52 
     53 int32_t DeviceInfoIos::Init() {
     54   // Fill in all device capabilities.
     55 
     56   int deviceCount = [DeviceInfoIosObjC captureDeviceCount];
     57 
     58   for (int i = 0; i < deviceCount; i++) {
     59     AVCaptureDevice *avDevice = [DeviceInfoIosObjC captureDeviceForIndex:i];
     60     VideoCaptureCapabilities capabilityVector;
     61 
     62     for (NSString *preset in camera_presets) {
     63       BOOL support = [avDevice supportsAVCaptureSessionPreset:preset];
     64       if (support) {
     65         VideoCaptureCapability capability =
     66             [DeviceInfoIosObjC capabilityForPreset:preset];
     67         capabilityVector.push_back(capability);
     68       }
     69     }
     70 
     71     char deviceNameUTF8[256];
     72     char deviceId[256];
     73     this->GetDeviceName(i, deviceNameUTF8, 256, deviceId, 256);
     74     std::string deviceIdCopy(deviceId);
     75     std::pair<std::string, VideoCaptureCapabilities> mapPair =
     76         std::pair<std::string, VideoCaptureCapabilities>
     77             (deviceIdCopy, capabilityVector);
     78     _capabilitiesMap.insert(mapPair);
     79   }
     80 
     81   return 0;
     82 }
     83 
     84 uint32_t DeviceInfoIos::NumberOfDevices() {
     85   return [DeviceInfoIosObjC captureDeviceCount];
     86 }
     87 
     88 int32_t DeviceInfoIos::GetDeviceName(uint32_t deviceNumber,
     89                                      char* deviceNameUTF8,
     90                                      uint32_t deviceNameUTF8Length,
     91                                      char* deviceUniqueIdUTF8,
     92                                      uint32_t deviceUniqueIdUTF8Length,
     93                                      char* productUniqueIdUTF8,
     94                                      uint32_t productUniqueIdUTF8Length) {
     95   NSString* deviceName = [DeviceInfoIosObjC deviceNameForIndex:deviceNumber];
     96 
     97   NSString* deviceUniqueId =
     98       [DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber];
     99 
    100   strncpy(deviceNameUTF8, [deviceName UTF8String], deviceNameUTF8Length);
    101   deviceNameUTF8[deviceNameUTF8Length - 1] = '\0';
    102 
    103   strncpy(deviceUniqueIdUTF8,
    104           [deviceUniqueId UTF8String],
    105           deviceUniqueIdUTF8Length);
    106   deviceUniqueIdUTF8[deviceUniqueIdUTF8Length - 1] = '\0';
    107 
    108   if (productUniqueIdUTF8) {
    109     productUniqueIdUTF8[0] = '\0';
    110   }
    111 
    112   return 0;
    113 }
    114 
    115 int32_t DeviceInfoIos::NumberOfCapabilities(const char* deviceUniqueIdUTF8) {
    116   int32_t numberOfCapabilities = 0;
    117   std::string deviceUniqueId(deviceUniqueIdUTF8);
    118   std::map<std::string, VideoCaptureCapabilities>::iterator it =
    119       _capabilitiesMap.find(deviceUniqueId);
    120 
    121   if (it != _capabilitiesMap.end()) {
    122     numberOfCapabilities = it->second.size();
    123   }
    124   return numberOfCapabilities;
    125 }
    126 
    127 int32_t DeviceInfoIos::GetCapability(const char* deviceUniqueIdUTF8,
    128                                      const uint32_t deviceCapabilityNumber,
    129                                      VideoCaptureCapability& capability) {
    130   std::string deviceUniqueId(deviceUniqueIdUTF8);
    131   std::map<std::string, VideoCaptureCapabilities>::iterator it =
    132       _capabilitiesMap.find(deviceUniqueId);
    133 
    134   if (it != _capabilitiesMap.end()) {
    135     VideoCaptureCapabilities deviceCapabilities = it->second;
    136 
    137     if (deviceCapabilityNumber < deviceCapabilities.size()) {
    138       VideoCaptureCapability cap;
    139       cap = deviceCapabilities[deviceCapabilityNumber];
    140       capability = cap;
    141       return 0;
    142     }
    143   }
    144 
    145   return -1;
    146 }
    147 
    148 int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox(
    149     const char* deviceUniqueIdUTF8,
    150     const char* dialogTitleUTF8,
    151     void* parentWindow,
    152     uint32_t positionX,
    153     uint32_t positionY) {
    154   IOS_UNSUPPORTED();
    155 }
    156 
    157 int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8,
    158                                       VideoRotation& orientation) {
    159   if (strcmp(deviceUniqueIdUTF8, "Front Camera") == 0) {
    160     orientation = kVideoRotation_0;
    161   } else {
    162     orientation = kVideoRotation_90;
    163   }
    164   return orientation;
    165 }
    166 
    167 int32_t DeviceInfoIos::CreateCapabilityMap(const char* deviceUniqueIdUTF8) {
    168   std::string deviceName(deviceUniqueIdUTF8);
    169   std::map<std::string, std::vector<VideoCaptureCapability>>::iterator it =
    170       _capabilitiesMap.find(deviceName);
    171   VideoCaptureCapabilities deviceCapabilities;
    172   if (it != _capabilitiesMap.end()) {
    173     _captureCapabilities = it->second;
    174     return 0;
    175   }
    176 
    177   return -1;
    178 }
    179