Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1338)

Side by Side Diff: talk/app/webrtc/objc/avfoundationvideocapturer.mm

Issue 1416303003: Handle iOS devices with no rear-facing camera (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Check back camera in new Objective-C API Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698