OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 // This class used to capture frames using AVFoundation APIs on iOS. It is meant | 29 // This class used to capture frames using AVFoundation APIs on iOS. It is meant |
30 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this | 30 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this |
31 // because other webrtc objects own cricket::VideoCapturer, which is not | 31 // because other webrtc objects own cricket::VideoCapturer, which is not |
32 // ref counted. To prevent bad behavior we do not expose this class directly. | 32 // ref counted. To prevent bad behavior we do not expose this class directly. |
33 @interface RTCAVFoundationVideoCapturerInternal : NSObject | 33 @interface RTCAVFoundationVideoCapturerInternal : NSObject |
34 <AVCaptureVideoDataOutputSampleBufferDelegate> | 34 <AVCaptureVideoDataOutputSampleBufferDelegate> |
35 | 35 |
36 @property(nonatomic, readonly) AVCaptureSession *captureSession; | 36 @property(nonatomic, readonly) AVCaptureSession *captureSession; |
37 @property(nonatomic, readonly) BOOL isRunning; | 37 @property(nonatomic, readonly) BOOL isRunning; |
38 @property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO. | 38 @property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO. |
| 39 @property(nonatomic, readonly) BOOL canUseBackCamera; |
39 | 40 |
40 // We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it | 41 // We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it |
41 // when we receive frames. This is safe because this object should be owned by | 42 // when we receive frames. This is safe because this object should be owned by |
42 // it. | 43 // it. |
43 - (instancetype)initWithCapturer:(webrtc::AVFoundationVideoCapturer *)capturer; | 44 - (instancetype)initWithCapturer:(webrtc::AVFoundationVideoCapturer *)capturer; |
44 - (void)startCaptureAsync; | 45 - (void)startCaptureAsync; |
45 - (void)stopCaptureAsync; | 46 - (void)stopCaptureAsync; |
46 | 47 |
47 @end | 48 @end |
48 | 49 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 } | 82 } |
82 return self; | 83 return self; |
83 } | 84 } |
84 | 85 |
85 - (void)dealloc { | 86 - (void)dealloc { |
86 [self stopCaptureAsync]; | 87 [self stopCaptureAsync]; |
87 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 88 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
88 _capturer = nullptr; | 89 _capturer = nullptr; |
89 } | 90 } |
90 | 91 |
| 92 - (BOOL)canUseBackCamera { |
| 93 return _backDeviceInput != nil; |
| 94 } |
| 95 |
91 - (void)setUseBackCamera:(BOOL)useBackCamera { | 96 - (void)setUseBackCamera:(BOOL)useBackCamera { |
92 if (_useBackCamera == useBackCamera) { | 97 if (_useBackCamera == useBackCamera) { |
93 return; | 98 return; |
94 } | 99 } |
| 100 if (!self.canUseBackCamera) { |
| 101 NSLog(@"No rear-facing camera exists or it cannot be used; not switching."); |
| 102 return; |
| 103 } |
95 _useBackCamera = useBackCamera; | 104 _useBackCamera = useBackCamera; |
96 [self updateSessionInput]; | 105 [self updateSessionInput]; |
97 } | 106 } |
98 | 107 |
99 - (void)startCaptureAsync { | 108 - (void)startCaptureAsync { |
100 if (_isRunning) { | 109 if (_isRunning) { |
101 return; | 110 return; |
102 } | 111 } |
103 _orientationHasChanged = NO; | 112 _orientationHasChanged = NO; |
104 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; | 113 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 AVCaptureDevice *backCaptureDevice = nil; | 188 AVCaptureDevice *backCaptureDevice = nil; |
180 for (AVCaptureDevice *captureDevice in | 189 for (AVCaptureDevice *captureDevice in |
181 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { | 190 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { |
182 if (captureDevice.position == AVCaptureDevicePositionBack) { | 191 if (captureDevice.position == AVCaptureDevicePositionBack) { |
183 backCaptureDevice = captureDevice; | 192 backCaptureDevice = captureDevice; |
184 } | 193 } |
185 if (captureDevice.position == AVCaptureDevicePositionFront) { | 194 if (captureDevice.position == AVCaptureDevicePositionFront) { |
186 frontCaptureDevice = captureDevice; | 195 frontCaptureDevice = captureDevice; |
187 } | 196 } |
188 } | 197 } |
189 if (!frontCaptureDevice || !backCaptureDevice) { | 198 if (!frontCaptureDevice) { |
190 NSLog(@"Failed to get capture devices."); | 199 NSLog(@"Failed to get front capture device."); |
191 return NO; | 200 return NO; |
192 } | 201 } |
| 202 if (!backCaptureDevice) { |
| 203 NSLog(@"Failed to get back capture device"); |
| 204 // Don't return NO here because devices exist (16GB 5th generation iPod |
| 205 // Touch) that don't have a rear-facing camera. |
| 206 } |
193 | 207 |
194 // Set up the session inputs. | 208 // Set up the session inputs. |
195 NSError *error = nil; | 209 NSError *error = nil; |
196 _frontDeviceInput = | 210 _frontDeviceInput = |
197 [AVCaptureDeviceInput deviceInputWithDevice:frontCaptureDevice | 211 [AVCaptureDeviceInput deviceInputWithDevice:frontCaptureDevice |
198 error:&error]; | 212 error:&error]; |
199 if (!_frontDeviceInput) { | 213 if (!_frontDeviceInput) { |
200 NSLog(@"Failed to get capture device input: %@", | 214 NSLog(@"Failed to get capture device input: %@", |
201 error.localizedDescription); | 215 error.localizedDescription); |
202 return NO; | 216 return NO; |
203 } | 217 } |
204 _backDeviceInput = | 218 if (backCaptureDevice) { |
205 [AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice | 219 _backDeviceInput = |
206 error:&error]; | 220 [AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice |
207 if (!_backDeviceInput) { | 221 error:&error]; |
208 NSLog(@"Failed to get capture device input: %@", | 222 if (error) { |
209 error.localizedDescription); | 223 NSLog(@"Failed to get capture device input: %@", |
210 return NO; | 224 error.localizedDescription); |
| 225 _backDeviceInput = nil; |
| 226 error = nil; |
| 227 } |
211 } | 228 } |
212 | 229 |
213 // Add the inputs. | 230 // Add the inputs. |
214 if (![_captureSession canAddInput:_frontDeviceInput] || | 231 if (![_captureSession canAddInput:_frontDeviceInput] || |
215 ![_captureSession canAddInput:_backDeviceInput]) { | 232 (_backDeviceInput && ![_captureSession canAddInput:_backDeviceInput])) { |
216 NSLog(@"Session does not support capture inputs."); | 233 NSLog(@"Session does not support capture inputs."); |
217 return NO; | 234 return NO; |
218 } | 235 } |
219 [self updateSessionInput]; | 236 [self updateSessionInput]; |
220 | 237 |
221 return YES; | 238 return YES; |
222 } | 239 } |
223 | 240 |
224 - (void)deviceOrientationDidChange:(NSNotification *)notification { | 241 - (void)deviceOrientationDidChange:(NSNotification *)notification { |
225 _orientationHasChanged = YES; | 242 _orientationHasChanged = YES; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 } | 346 } |
330 | 347 |
331 bool AVFoundationVideoCapturer::IsRunning() { | 348 bool AVFoundationVideoCapturer::IsRunning() { |
332 return _capturer.isRunning; | 349 return _capturer.isRunning; |
333 } | 350 } |
334 | 351 |
335 AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() { | 352 AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() { |
336 return _capturer.captureSession; | 353 return _capturer.captureSession; |
337 } | 354 } |
338 | 355 |
| 356 bool AVFoundationVideoCapturer::CanUseBackCamera() const { |
| 357 return _capturer.canUseBackCamera; |
| 358 } |
| 359 |
339 void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) { | 360 void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) { |
340 _capturer.useBackCamera = useBackCamera; | 361 _capturer.useBackCamera = useBackCamera; |
341 } | 362 } |
342 | 363 |
343 bool AVFoundationVideoCapturer::GetUseBackCamera() const { | 364 bool AVFoundationVideoCapturer::GetUseBackCamera() const { |
344 return _capturer.useBackCamera; | 365 return _capturer.useBackCamera; |
345 } | 366 } |
346 | 367 |
347 void AVFoundationVideoCapturer::CaptureSampleBuffer( | 368 void AVFoundationVideoCapturer::CaptureSampleBuffer( |
348 CMSampleBufferRef sampleBuffer) { | 369 CMSampleBufferRef sampleBuffer) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 432 |
412 void AVFoundationVideoCapturer::SignalFrameCapturedOnStartThread( | 433 void AVFoundationVideoCapturer::SignalFrameCapturedOnStartThread( |
413 const cricket::CapturedFrame *frame) { | 434 const cricket::CapturedFrame *frame) { |
414 RTC_DCHECK(_startThread->IsCurrent()); | 435 RTC_DCHECK(_startThread->IsCurrent()); |
415 // This will call a superclass method that will perform the frame conversion | 436 // This will call a superclass method that will perform the frame conversion |
416 // to I420. | 437 // to I420. |
417 SignalFrameCaptured(this, frame); | 438 SignalFrameCaptured(this, frame); |
418 } | 439 } |
419 | 440 |
420 } // namespace webrtc | 441 } // namespace webrtc |
OLD | NEW |