/* * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #if !defined(__has_feature) || !__has_feature(objc_arc) # error "This file requires ARC support." #endif #include #include #include "device_info.h" #include "device_info_objc.h" #include "modules/video_capture/video_capture_impl.h" #include "mozilla/StaticPrefs_media.h" #include "objc_video_capture/device_info_avfoundation.h" #include "rtc_base/logging.h" using namespace mozilla; using namespace webrtc; using namespace videocapturemodule; static NSArray* camera_presets = @[ AVCaptureSessionPreset352x288, AVCaptureSessionPreset640x480, AVCaptureSessionPreset1280x720 ]; #define IOS_UNSUPPORTED() \ RTC_LOG(LS_ERROR) << __FUNCTION__ << " is not supported on the iOS platform."; \ return -1; VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() { if (StaticPrefs::media_getusermedia_camera_macavf_enabled_AtStartup()) { return new DeviceInfoAvFoundation(); } return new DeviceInfoIos(); } DeviceInfoIos::DeviceInfoIos() { this->Init(); } DeviceInfoIos::~DeviceInfoIos() { [_captureInfo registerOwner:nil]; } int32_t DeviceInfoIos::Init() { _captureInfo = [[DeviceInfoIosObjC alloc] init]; [_captureInfo registerOwner:this]; // Fill in all device capabilities. int deviceCount = [DeviceInfoIosObjC captureDeviceCount]; for (int i = 0; i < deviceCount; i++) { AVCaptureDevice* avDevice = [DeviceInfoIosObjC captureDeviceForIndex:i]; VideoCaptureCapabilities capabilityVector; for (NSString* preset in camera_presets) { BOOL support = [avDevice supportsAVCaptureSessionPreset:preset]; if (support) { VideoCaptureCapability capability = [DeviceInfoIosObjC capabilityForPreset:preset]; capabilityVector.push_back(capability); } } char deviceNameUTF8[256]; char deviceId[256]; int error = this->GetDeviceName(i, deviceNameUTF8, 256, deviceId, 256); if (error) { return error; } std::string deviceIdCopy(deviceId); std::pair mapPair = std::pair(deviceIdCopy, capabilityVector); _capabilitiesMap.insert(mapPair); } return 0; } uint32_t DeviceInfoIos::NumberOfDevices() { return [DeviceInfoIosObjC captureDeviceCount]; } int32_t DeviceInfoIos::GetDeviceName(uint32_t deviceNumber, char* deviceNameUTF8, uint32_t deviceNameUTF8Length, char* deviceUniqueIdUTF8, uint32_t deviceUniqueIdUTF8Length, char* productUniqueIdUTF8, uint32_t productUniqueIdUTF8Length, pid_t* pid) { if (deviceNumber >= NumberOfDevices()) { return -1; } NSString* deviceName = [DeviceInfoIosObjC deviceNameForIndex:deviceNumber]; NSString* deviceUniqueId = [DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber]; strncpy(deviceNameUTF8, [deviceName UTF8String], deviceNameUTF8Length); deviceNameUTF8[deviceNameUTF8Length - 1] = '\0'; strncpy(deviceUniqueIdUTF8, deviceUniqueId.UTF8String, deviceUniqueIdUTF8Length); deviceUniqueIdUTF8[deviceUniqueIdUTF8Length - 1] = '\0'; if (productUniqueIdUTF8) { productUniqueIdUTF8[0] = '\0'; } return 0; } int32_t DeviceInfoIos::NumberOfCapabilities(const char* deviceUniqueIdUTF8) { int32_t numberOfCapabilities = 0; std::string deviceUniqueId(deviceUniqueIdUTF8); std::map::iterator it = _capabilitiesMap.find(deviceUniqueId); if (it != _capabilitiesMap.end()) { numberOfCapabilities = it->second.size(); } return numberOfCapabilities; } int32_t DeviceInfoIos::GetCapability(const char* deviceUniqueIdUTF8, const uint32_t deviceCapabilityNumber, VideoCaptureCapability& capability) { std::string deviceUniqueId(deviceUniqueIdUTF8); std::map::iterator it = _capabilitiesMap.find(deviceUniqueId); if (it != _capabilitiesMap.end()) { VideoCaptureCapabilities deviceCapabilities = it->second; if (deviceCapabilityNumber < deviceCapabilities.size()) { VideoCaptureCapability cap; cap = deviceCapabilities[deviceCapabilityNumber]; capability = cap; return 0; } } return -1; } int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox(const char* deviceUniqueIdUTF8, const char* dialogTitleUTF8, void* parentWindow, uint32_t positionX, uint32_t positionY) { IOS_UNSUPPORTED(); } int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8, VideoRotation& orientation) { if (strcmp(deviceUniqueIdUTF8, "Front Camera") == 0) { orientation = kVideoRotation_0; } else { orientation = kVideoRotation_90; } return orientation; } int32_t DeviceInfoIos::CreateCapabilityMap(const char* deviceUniqueIdUTF8) { std::string deviceName(deviceUniqueIdUTF8); std::map>::iterator it = _capabilitiesMap.find(deviceName); VideoCaptureCapabilities deviceCapabilities; if (it != _capabilitiesMap.end()) { _captureCapabilities = it->second; return 0; } return -1; }