OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 // This class used to capture frames using AVFoundation APIs on iOS. It is meant | 46 // This class used to capture frames using AVFoundation APIs on iOS. It is meant |
47 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this | 47 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this |
48 // because other webrtc objects own cricket::VideoCapturer, which is not | 48 // because other webrtc objects own cricket::VideoCapturer, which is not |
49 // ref counted. To prevent bad behavior we do not expose this class directly. | 49 // ref counted. To prevent bad behavior we do not expose this class directly. |
50 @interface RTCAVFoundationVideoCapturerInternal : NSObject | 50 @interface RTCAVFoundationVideoCapturerInternal : NSObject |
51 <AVCaptureVideoDataOutputSampleBufferDelegate> | 51 <AVCaptureVideoDataOutputSampleBufferDelegate> |
52 | 52 |
53 @property(nonatomic, readonly) AVCaptureSession* captureSession; | 53 @property(nonatomic, readonly) AVCaptureSession* captureSession; |
54 @property(nonatomic, readonly) BOOL isRunning; | 54 @property(nonatomic, readonly) BOOL isRunning; |
55 @property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO. | 55 @property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO. |
56 @property(nonatomic, readonly) BOOL canUseBackCamera; | |
tkchin_webrtc
2016/03/14 18:16:59
nit: move above useBackCamera
hjon
2016/03/14 18:31:44
Done.
| |
56 | 57 |
57 // We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it | 58 // We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it |
58 // when we receive frames. This is safe because this object should be owned by | 59 // when we receive frames. This is safe because this object should be owned by |
59 // it. | 60 // it. |
60 - (instancetype)initWithCapturer:(webrtc::AVFoundationVideoCapturer*)capturer; | 61 - (instancetype)initWithCapturer:(webrtc::AVFoundationVideoCapturer*)capturer; |
61 - (void)startCaptureAsync; | 62 - (void)startCaptureAsync; |
62 - (void)stopCaptureAsync; | 63 - (void)stopCaptureAsync; |
63 | 64 |
64 @end | 65 @end |
65 | 66 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 } | 99 } |
99 return self; | 100 return self; |
100 } | 101 } |
101 | 102 |
102 - (void)dealloc { | 103 - (void)dealloc { |
103 [self stopCaptureAsync]; | 104 [self stopCaptureAsync]; |
104 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 105 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
105 _capturer = nullptr; | 106 _capturer = nullptr; |
106 } | 107 } |
107 | 108 |
109 - (BOOL)canUseBackCamera { | |
110 return _backDeviceInput != nil; | |
111 } | |
112 | |
108 - (void)setUseBackCamera:(BOOL)useBackCamera { | 113 - (void)setUseBackCamera:(BOOL)useBackCamera { |
109 if (_useBackCamera == useBackCamera) { | 114 if (_useBackCamera == useBackCamera) { |
110 return; | 115 return; |
111 } | 116 } |
117 if (!self.canUseBackCamera) { | |
118 NSLog(@"No rear-facing camera exists or it cannot be used; not switching."); | |
tkchin_webrtc
2016/03/14 18:16:59
import webrtc/base/RTCLogging and use RTCLog
here
hjon
2016/03/14 18:31:44
Done.
| |
119 return; | |
120 } | |
112 _useBackCamera = useBackCamera; | 121 _useBackCamera = useBackCamera; |
113 [self updateSessionInput]; | 122 [self updateSessionInput]; |
114 } | 123 } |
115 | 124 |
116 - (void)startCaptureAsync { | 125 - (void)startCaptureAsync { |
117 if (_isRunning) { | 126 if (_isRunning) { |
118 return; | 127 return; |
119 } | 128 } |
120 _orientationHasChanged = NO; | 129 _orientationHasChanged = NO; |
121 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; | 130 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 AVCaptureDevice* backCaptureDevice = nil; | 205 AVCaptureDevice* backCaptureDevice = nil; |
197 for (AVCaptureDevice* captureDevice in | 206 for (AVCaptureDevice* captureDevice in |
198 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { | 207 [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { |
199 if (captureDevice.position == AVCaptureDevicePositionBack) { | 208 if (captureDevice.position == AVCaptureDevicePositionBack) { |
200 backCaptureDevice = captureDevice; | 209 backCaptureDevice = captureDevice; |
201 } | 210 } |
202 if (captureDevice.position == AVCaptureDevicePositionFront) { | 211 if (captureDevice.position == AVCaptureDevicePositionFront) { |
203 frontCaptureDevice = captureDevice; | 212 frontCaptureDevice = captureDevice; |
204 } | 213 } |
205 } | 214 } |
206 if (!frontCaptureDevice || !backCaptureDevice) { | 215 if (!frontCaptureDevice) { |
207 NSLog(@"Failed to get capture devices."); | 216 NSLog(@"Failed to get front capture device."); |
208 return NO; | 217 return NO; |
209 } | 218 } |
219 if (!backCaptureDevice) { | |
220 NSLog(@"Failed to get back capture device"); | |
221 // Don't return NO here because devices exist (16GB 5th generation iPod | |
222 // Touch) that don't have a rear-facing camera. | |
223 } | |
210 | 224 |
211 // Set up the session inputs. | 225 // Set up the session inputs. |
212 NSError* error = nil; | 226 NSError* error = nil; |
213 _frontDeviceInput = | 227 _frontDeviceInput = |
214 [AVCaptureDeviceInput deviceInputWithDevice:frontCaptureDevice | 228 [AVCaptureDeviceInput deviceInputWithDevice:frontCaptureDevice |
215 error:&error]; | 229 error:&error]; |
216 if (!_frontDeviceInput) { | 230 if (!_frontDeviceInput) { |
217 NSLog(@"Failed to get capture device input: %@", | 231 NSLog(@"Failed to get capture device input: %@", |
218 error.localizedDescription); | 232 error.localizedDescription); |
219 return NO; | 233 return NO; |
220 } | 234 } |
221 _backDeviceInput = | 235 if (backCaptureDevice) { |
222 [AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice | 236 _backDeviceInput = |
223 error:&error]; | 237 [AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice |
224 if (!_backDeviceInput) { | 238 error:&error]; |
225 NSLog(@"Failed to get capture device input: %@", | 239 if (error) { |
226 error.localizedDescription); | 240 NSLog(@"Failed to get capture device input: %@", |
227 return NO; | 241 error.localizedDescription); |
242 _backDeviceInput = nil; | |
243 error = nil; | |
tkchin_webrtc
2016/03/14 18:16:59
nil out error before _backDeviceInput = [AVCap.. i
hjon
2016/03/14 18:31:44
Done.
| |
244 } | |
228 } | 245 } |
229 | 246 |
230 // Add the inputs. | 247 // Add the inputs. |
231 if (![_captureSession canAddInput:_frontDeviceInput] || | 248 if (![_captureSession canAddInput:_frontDeviceInput] || |
232 ![_captureSession canAddInput:_backDeviceInput]) { | 249 (_backDeviceInput && ![_captureSession canAddInput:_backDeviceInput])) { |
233 NSLog(@"Session does not support capture inputs."); | 250 NSLog(@"Session does not support capture inputs."); |
234 return NO; | 251 return NO; |
235 } | 252 } |
236 [self updateSessionInput]; | 253 [self updateSessionInput]; |
237 | 254 |
238 return YES; | 255 return YES; |
239 } | 256 } |
240 | 257 |
241 - (void)deviceOrientationDidChange:(NSNotification*)notification { | 258 - (void)deviceOrientationDidChange:(NSNotification*)notification { |
242 _orientationHasChanged = YES; | 259 _orientationHasChanged = YES; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 } | 363 } |
347 | 364 |
348 bool AVFoundationVideoCapturer::IsRunning() { | 365 bool AVFoundationVideoCapturer::IsRunning() { |
349 return _capturer.isRunning; | 366 return _capturer.isRunning; |
350 } | 367 } |
351 | 368 |
352 AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() { | 369 AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() { |
353 return _capturer.captureSession; | 370 return _capturer.captureSession; |
354 } | 371 } |
355 | 372 |
373 bool AVFoundationVideoCapturer::CanUseBackCamera() const { | |
374 return _capturer.canUseBackCamera; | |
375 } | |
376 | |
356 void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) { | 377 void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) { |
357 _capturer.useBackCamera = useBackCamera; | 378 _capturer.useBackCamera = useBackCamera; |
358 } | 379 } |
359 | 380 |
360 bool AVFoundationVideoCapturer::GetUseBackCamera() const { | 381 bool AVFoundationVideoCapturer::GetUseBackCamera() const { |
361 return _capturer.useBackCamera; | 382 return _capturer.useBackCamera; |
362 } | 383 } |
363 | 384 |
364 void AVFoundationVideoCapturer::CaptureSampleBuffer( | 385 void AVFoundationVideoCapturer::CaptureSampleBuffer( |
365 CMSampleBufferRef sampleBuffer) { | 386 CMSampleBufferRef sampleBuffer) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 | 449 |
429 void AVFoundationVideoCapturer::SignalFrameCapturedOnStartThread( | 450 void AVFoundationVideoCapturer::SignalFrameCapturedOnStartThread( |
430 const cricket::CapturedFrame* frame) { | 451 const cricket::CapturedFrame* frame) { |
431 RTC_DCHECK(_startThread->IsCurrent()); | 452 RTC_DCHECK(_startThread->IsCurrent()); |
432 // This will call a superclass method that will perform the frame conversion | 453 // This will call a superclass method that will perform the frame conversion |
433 // to I420. | 454 // to I420. |
434 SignalFrameCaptured(this, frame); | 455 SignalFrameCaptured(this, frame); |
435 } | 456 } |
436 | 457 |
437 } // namespace webrtc | 458 } // namespace webrtc |
OLD | NEW |