device_info.mm (5790B)
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 "device_info.h" 20 #include "device_info_objc.h" 21 #include "modules/video_capture/video_capture_impl.h" 22 #include "mozilla/StaticPrefs_media.h" 23 #include "objc_video_capture/device_info_avfoundation.h" 24 #include "rtc_base/logging.h" 25 26 using namespace mozilla; 27 using namespace webrtc; 28 using namespace videocapturemodule; 29 30 MOZ_RUNINIT static NSArray* camera_presets = @[ 31 AVCaptureSessionPreset352x288, AVCaptureSessionPreset640x480, 32 AVCaptureSessionPreset1280x720 33 ]; 34 35 #define IOS_UNSUPPORTED() \ 36 RTC_LOG(LS_ERROR) << __FUNCTION__ \ 37 << " is not supported on the iOS platform."; \ 38 return -1; 39 40 VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() { 41 if (StaticPrefs::media_getusermedia_camera_macavf_enabled_AtStartup()) { 42 return new DeviceInfoAvFoundation(); 43 } 44 return new DeviceInfoIos(); 45 } 46 47 DeviceInfoIos::DeviceInfoIos() { this->Init(); } 48 49 DeviceInfoIos::~DeviceInfoIos() { [_captureInfo registerOwner:nil]; } 50 51 int32_t DeviceInfoIos::Init() { 52 _captureInfo = [[DeviceInfoIosObjC alloc] init]; 53 [_captureInfo registerOwner:this]; 54 55 // Fill in all device capabilities. 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 int error = this->GetDeviceName(i, deviceNameUTF8, 256, deviceId, 256); 74 if (error) { 75 return error; 76 } 77 std::string deviceIdCopy(deviceId); 78 std::pair<std::string, VideoCaptureCapabilities> mapPair = 79 std::pair<std::string, VideoCaptureCapabilities>(deviceIdCopy, 80 capabilityVector); 81 _capabilitiesMap.insert(mapPair); 82 } 83 84 return 0; 85 } 86 87 uint32_t DeviceInfoIos::NumberOfDevices() { 88 return [DeviceInfoIosObjC captureDeviceCount]; 89 } 90 91 int32_t DeviceInfoIos::GetDeviceName( 92 uint32_t deviceNumber, char* deviceNameUTF8, uint32_t deviceNameUTF8Length, 93 char* deviceUniqueIdUTF8, uint32_t deviceUniqueIdUTF8Length, 94 char* productUniqueIdUTF8, uint32_t productUniqueIdUTF8Length, pid_t* pid, 95 bool* deviceIsPlaceholder) { 96 if (deviceNumber >= NumberOfDevices()) { 97 return -1; 98 } 99 100 NSString* deviceName = [DeviceInfoIosObjC deviceNameForIndex:deviceNumber]; 101 102 NSString* deviceUniqueId = 103 [DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber]; 104 105 strncpy(deviceNameUTF8, [deviceName UTF8String], deviceNameUTF8Length); 106 deviceNameUTF8[deviceNameUTF8Length - 1] = '\0'; 107 108 strncpy(deviceUniqueIdUTF8, deviceUniqueId.UTF8String, 109 deviceUniqueIdUTF8Length); 110 deviceUniqueIdUTF8[deviceUniqueIdUTF8Length - 1] = '\0'; 111 112 if (productUniqueIdUTF8) { 113 productUniqueIdUTF8[0] = '\0'; 114 } 115 116 return 0; 117 } 118 119 int32_t DeviceInfoIos::NumberOfCapabilities(const char* deviceUniqueIdUTF8) { 120 int32_t numberOfCapabilities = 0; 121 std::string deviceUniqueId(deviceUniqueIdUTF8); 122 std::map<std::string, VideoCaptureCapabilities>::iterator it = 123 _capabilitiesMap.find(deviceUniqueId); 124 125 if (it != _capabilitiesMap.end()) { 126 numberOfCapabilities = it->second.size(); 127 } 128 return numberOfCapabilities; 129 } 130 131 int32_t DeviceInfoIos::GetCapability(const char* deviceUniqueIdUTF8, 132 const uint32_t deviceCapabilityNumber, 133 VideoCaptureCapability& capability) { 134 std::string deviceUniqueId(deviceUniqueIdUTF8); 135 std::map<std::string, VideoCaptureCapabilities>::iterator it = 136 _capabilitiesMap.find(deviceUniqueId); 137 138 if (it != _capabilitiesMap.end()) { 139 VideoCaptureCapabilities deviceCapabilities = it->second; 140 141 if (deviceCapabilityNumber < deviceCapabilities.size()) { 142 VideoCaptureCapability cap; 143 cap = deviceCapabilities[deviceCapabilityNumber]; 144 capability = cap; 145 return 0; 146 } 147 } 148 149 return -1; 150 } 151 152 int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox( 153 const char* deviceUniqueIdUTF8, const char* dialogTitleUTF8, 154 void* parentWindow, uint32_t positionX, uint32_t positionY) { 155 IOS_UNSUPPORTED(); 156 } 157 158 int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8, 159 VideoRotation& orientation) { 160 if (strcmp(deviceUniqueIdUTF8, "Front Camera") == 0) { 161 orientation = kVideoRotation_0; 162 } else { 163 orientation = kVideoRotation_90; 164 } 165 return orientation; 166 } 167 168 int32_t DeviceInfoIos::CreateCapabilityMap(const char* deviceUniqueIdUTF8) { 169 std::string deviceName(deviceUniqueIdUTF8); 170 std::map<std::string, std::vector<VideoCaptureCapability>>::iterator it = 171 _capabilitiesMap.find(deviceName); 172 VideoCaptureCapabilities deviceCapabilities; 173 if (it != _capabilitiesMap.end()) { 174 _captureCapabilities = it->second; 175 return 0; 176 } 177 178 return -1; 179 }