device_info_objc.mm (5013B)
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 #import <AVFoundation/AVFoundation.h> 16 17 #import "device_info_objc.h" 18 19 @implementation DeviceInfoIosObjC 20 21 - (id)init { 22 self = [super init]; 23 if (nil != self) { 24 _lock = [[NSLock alloc] init]; 25 } 26 return self; 27 } 28 29 - (void)dealloc { 30 } 31 32 - (void)registerOwner:(webrtc::VideoCaptureModule::DeviceInfo*)owner { 33 [_lock lock]; 34 if (!_owner && owner) { 35 [self configureObservers]; 36 } else if (_owner && !owner) { 37 NSNotificationCenter* notificationCenter = 38 [NSNotificationCenter defaultCenter]; 39 for (id observer in _observers) { 40 [notificationCenter removeObserver:observer]; 41 } 42 _observers = nil; 43 } 44 _owner = owner; 45 [_lock unlock]; 46 } 47 48 + (int)captureDeviceCount { 49 int cnt = 0; 50 @try { 51 for (AVCaptureDevice* device in 52 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { 53 if ([device isSuspended]) { 54 continue; 55 } 56 cnt++; 57 } 58 } @catch (NSException* exception) { 59 cnt = 0; 60 } 61 return cnt; 62 } 63 64 + (AVCaptureDevice*)captureDeviceForIndex:(int)index { 65 int cnt = 0; 66 @try { 67 for (AVCaptureDevice* device in 68 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { 69 if ([device isSuspended]) { 70 continue; 71 } 72 if (cnt == index) { 73 return device; 74 } 75 cnt++; 76 } 77 } @catch (NSException* exception) { 78 cnt = 0; 79 } 80 81 return nil; 82 } 83 84 + (AVCaptureDevice*)captureDeviceForUniqueId:(NSString*)uniqueId { 85 for (AVCaptureDevice* device in 86 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { 87 if ([device isSuspended]) { 88 continue; 89 } 90 if ([uniqueId isEqual:device.uniqueID]) { 91 return device; 92 } 93 } 94 95 return nil; 96 } 97 98 + (NSString*)deviceNameForIndex:(int)index { 99 return [DeviceInfoIosObjC captureDeviceForIndex:index].localizedName; 100 } 101 102 + (NSString*)deviceUniqueIdForIndex:(int)index { 103 return [DeviceInfoIosObjC captureDeviceForIndex:index].uniqueID; 104 } 105 106 + (NSString*)deviceNameForUniqueId:(NSString*)uniqueId { 107 return [[AVCaptureDevice deviceWithUniqueID:uniqueId] localizedName]; 108 } 109 110 + (webrtc::VideoCaptureCapability)capabilityForPreset:(NSString*)preset { 111 webrtc::VideoCaptureCapability capability; 112 113 // TODO(tkchin): Maybe query AVCaptureDevice for supported formats, and 114 // then get the dimensions / frame rate from each supported format 115 if ([preset isEqualToString:AVCaptureSessionPreset352x288]) { 116 capability.width = 352; 117 capability.height = 288; 118 capability.maxFPS = 30; 119 capability.videoType = webrtc::VideoType::kNV12; 120 capability.interlaced = false; 121 } else if ([preset isEqualToString:AVCaptureSessionPreset640x480]) { 122 capability.width = 640; 123 capability.height = 480; 124 capability.maxFPS = 30; 125 capability.videoType = webrtc::VideoType::kNV12; 126 capability.interlaced = false; 127 } else if ([preset isEqualToString:AVCaptureSessionPreset1280x720]) { 128 capability.width = 1280; 129 capability.height = 720; 130 capability.maxFPS = 30; 131 capability.videoType = webrtc::VideoType::kNV12; 132 capability.interlaced = false; 133 } 134 135 return capability; 136 } 137 138 - (void)configureObservers { 139 // register device connected / disconnected event 140 NSNotificationCenter* notificationCenter = 141 [NSNotificationCenter defaultCenter]; 142 143 id deviceWasConnectedObserver = [notificationCenter 144 addObserverForName:AVCaptureDeviceWasConnectedNotification 145 object:nil 146 queue:[NSOperationQueue mainQueue] 147 usingBlock:^(NSNotification* note) { 148 [_lock lock]; 149 AVCaptureDevice* device = [note object]; 150 BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo]; 151 if (isVideoDevice && _owner) _owner->DeviceChange(); 152 [_lock unlock]; 153 }]; 154 155 id deviceWasDisconnectedObserver = [notificationCenter 156 addObserverForName:AVCaptureDeviceWasDisconnectedNotification 157 object:nil 158 queue:[NSOperationQueue mainQueue] 159 usingBlock:^(NSNotification* note) { 160 [_lock lock]; 161 AVCaptureDevice* device = [note object]; 162 BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo]; 163 if (isVideoDevice && _owner) _owner->DeviceChange(); 164 [_lock unlock]; 165 }]; 166 167 _observers = 168 [[NSArray alloc] initWithObjects:deviceWasConnectedObserver, 169 deviceWasDisconnectedObserver, nil]; 170 } 171 172 @end