Handle iOS devices with no rear-facing camera
Devices exist (specifically the 16GB 5th generation iPod Touch) that do not have a rear-facing camera. This CL: - Adjusts RTCAVFoundationVideoCapturerInternal so initialization doesn't fail because a rear-facing camera doesn't exist, but still logs a warning - Provides a check for whether or not a rear-facing camera can be used (useful for toggling UI elements) - Turns an attempt to switch to the rear-facing camera into a no-op with a warning. BUG= Review URL: https://codereview.webrtc.org/1416303003 Cr-Commit-Position: refs/heads/master@{#11992}
This commit is contained in:
parent
e5d5e51a82
commit
a1cf366ea9
@ -46,6 +46,10 @@
|
||||
return [super initWithMediaSource:source];
|
||||
}
|
||||
|
||||
- (BOOL)canUseBackCamera {
|
||||
return self.capturer->CanUseBackCamera();
|
||||
}
|
||||
|
||||
- (BOOL)useBackCamera {
|
||||
return self.capturer->GetUseBackCamera();
|
||||
}
|
||||
|
||||
@ -56,6 +56,10 @@ class AVFoundationVideoCapturer : public cricket::VideoCapturer {
|
||||
// Returns the active capture session.
|
||||
AVCaptureSession* GetCaptureSession();
|
||||
|
||||
// Returns whether the rear-facing camera can be used.
|
||||
// e.g. It can't be used because it doesn't exist.
|
||||
bool CanUseBackCamera() const;
|
||||
|
||||
// Switches the camera being used (either front or back).
|
||||
void SetUseBackCamera(bool useBackCamera);
|
||||
bool GetUseBackCamera() const;
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "webrtc/base/objc/RTCDispatcher.h"
|
||||
#import "webrtc/base/objc/RTCLogging.h"
|
||||
|
||||
// TODO(tkchin): support other formats.
|
||||
static NSString* const kDefaultPreset = AVCaptureSessionPreset640x480;
|
||||
@ -52,6 +53,7 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
|
||||
@property(nonatomic, readonly) AVCaptureSession* captureSession;
|
||||
@property(nonatomic, readonly) BOOL isRunning;
|
||||
@property(nonatomic, readonly) BOOL canUseBackCamera;
|
||||
@property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO.
|
||||
|
||||
// We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it
|
||||
@ -105,10 +107,19 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
_capturer = nullptr;
|
||||
}
|
||||
|
||||
- (BOOL)canUseBackCamera {
|
||||
return _backDeviceInput != nil;
|
||||
}
|
||||
|
||||
- (void)setUseBackCamera:(BOOL)useBackCamera {
|
||||
if (_useBackCamera == useBackCamera) {
|
||||
return;
|
||||
}
|
||||
if (!self.canUseBackCamera) {
|
||||
RTCLog(@"No rear-facing camera exists or it cannot be used;"
|
||||
"not switching.");
|
||||
return;
|
||||
}
|
||||
_useBackCamera = useBackCamera;
|
||||
[self updateSessionInput];
|
||||
}
|
||||
@ -203,10 +214,15 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
frontCaptureDevice = captureDevice;
|
||||
}
|
||||
}
|
||||
if (!frontCaptureDevice || !backCaptureDevice) {
|
||||
NSLog(@"Failed to get capture devices.");
|
||||
if (!frontCaptureDevice) {
|
||||
RTCLog(@"Failed to get front capture device.");
|
||||
return NO;
|
||||
}
|
||||
if (!backCaptureDevice) {
|
||||
RTCLog(@"Failed to get back capture device");
|
||||
// Don't return NO here because devices exist (16GB 5th generation iPod
|
||||
// Touch) that don't have a rear-facing camera.
|
||||
}
|
||||
|
||||
// Set up the session inputs.
|
||||
NSError* error = nil;
|
||||
@ -218,18 +234,21 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
error.localizedDescription);
|
||||
return NO;
|
||||
}
|
||||
_backDeviceInput =
|
||||
[AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice
|
||||
error:&error];
|
||||
if (!_backDeviceInput) {
|
||||
NSLog(@"Failed to get capture device input: %@",
|
||||
error.localizedDescription);
|
||||
return NO;
|
||||
if (backCaptureDevice) {
|
||||
error = nil;
|
||||
_backDeviceInput =
|
||||
[AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice
|
||||
error:&error];
|
||||
if (error) {
|
||||
RTCLog(@"Failed to get capture device input: %@",
|
||||
error.localizedDescription);
|
||||
_backDeviceInput = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the inputs.
|
||||
if (![_captureSession canAddInput:_frontDeviceInput] ||
|
||||
![_captureSession canAddInput:_backDeviceInput]) {
|
||||
(_backDeviceInput && ![_captureSession canAddInput:_backDeviceInput])) {
|
||||
NSLog(@"Session does not support capture inputs.");
|
||||
return NO;
|
||||
}
|
||||
@ -353,6 +372,10 @@ AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() {
|
||||
return _capturer.captureSession;
|
||||
}
|
||||
|
||||
bool AVFoundationVideoCapturer::CanUseBackCamera() const {
|
||||
return _capturer.canUseBackCamera;
|
||||
}
|
||||
|
||||
void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) {
|
||||
_capturer.useBackCamera = useBackCamera;
|
||||
}
|
||||
|
||||
@ -41,6 +41,8 @@
|
||||
- (instancetype)initWithFactory:(RTCPeerConnectionFactory*)factory
|
||||
constraints:(RTCMediaConstraints*)constraints;
|
||||
|
||||
// Returns whether rear-facing camera is available for use.
|
||||
@property(nonatomic, readonly) BOOL canUseBackCamera;
|
||||
// Switches the camera being used (either front or back).
|
||||
@property(nonatomic, assign) BOOL useBackCamera;
|
||||
// Returns the active capture session.
|
||||
|
||||
@ -28,6 +28,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
|
||||
constraints:(nullable RTCMediaConstraints *)constraints;
|
||||
|
||||
/** Returns whether rear-facing camera is available for use. */
|
||||
@property(nonatomic, readonly) BOOL canUseBackCamera;
|
||||
|
||||
/** Switches the camera being used (either front or back). */
|
||||
@property(nonatomic, assign) BOOL useBackCamera;
|
||||
|
||||
|
||||
@ -27,6 +27,10 @@
|
||||
return [super initWithNativeVideoSource:source];
|
||||
}
|
||||
|
||||
- (BOOL)canUseBackCamera {
|
||||
return self.capturer->CanUseBackCamera();
|
||||
}
|
||||
|
||||
- (BOOL)useBackCamera {
|
||||
return self.capturer->GetUseBackCamera();
|
||||
}
|
||||
|
||||
@ -40,6 +40,12 @@ class AVFoundationVideoCapturer : public cricket::VideoCapturer {
|
||||
/** Returns the active capture session. */
|
||||
AVCaptureSession* GetCaptureSession();
|
||||
|
||||
/**
|
||||
* Returns whether the rear-facing camera can be used.
|
||||
* e.g. It can't be used because it doesn't exist.
|
||||
*/
|
||||
bool CanUseBackCamera() const;
|
||||
|
||||
/** Switches the camera being used (either front or back). */
|
||||
void SetUseBackCamera(bool useBackCamera);
|
||||
bool GetUseBackCamera() const;
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "webrtc/base/objc/RTCDispatcher.h"
|
||||
#import "webrtc/base/objc/RTCLogging.h"
|
||||
|
||||
// TODO(tkchin): support other formats.
|
||||
static NSString* const kDefaultPreset = AVCaptureSessionPreset640x480;
|
||||
@ -35,6 +36,7 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
|
||||
@property(nonatomic, readonly) AVCaptureSession *captureSession;
|
||||
@property(nonatomic, readonly) BOOL isRunning;
|
||||
@property(nonatomic, readonly) BOOL canUseBackCamera;
|
||||
@property(nonatomic, assign) BOOL useBackCamera; // Defaults to NO.
|
||||
|
||||
// We keep a pointer back to AVFoundationVideoCapturer to make callbacks on it
|
||||
@ -88,10 +90,19 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
_capturer = nullptr;
|
||||
}
|
||||
|
||||
- (BOOL)canUseBackCamera {
|
||||
return _backDeviceInput != nil;
|
||||
}
|
||||
|
||||
- (void)setUseBackCamera:(BOOL)useBackCamera {
|
||||
if (_useBackCamera == useBackCamera) {
|
||||
return;
|
||||
}
|
||||
if (!self.canUseBackCamera) {
|
||||
RTCLog(@"No rear-facing camera exists or it cannot be used;"
|
||||
"not switching.");
|
||||
return;
|
||||
}
|
||||
_useBackCamera = useBackCamera;
|
||||
[self updateSessionInput];
|
||||
}
|
||||
@ -186,10 +197,15 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
frontCaptureDevice = captureDevice;
|
||||
}
|
||||
}
|
||||
if (!frontCaptureDevice || !backCaptureDevice) {
|
||||
NSLog(@"Failed to get capture devices.");
|
||||
if (!frontCaptureDevice) {
|
||||
RTCLog(@"Failed to get front capture device.");
|
||||
return NO;
|
||||
}
|
||||
if (!backCaptureDevice) {
|
||||
RTCLog(@"Failed to get back capture device");
|
||||
// Don't return NO here because devices exist (16GB 5th generation iPod
|
||||
// Touch) that don't have a rear-facing camera.
|
||||
}
|
||||
|
||||
// Set up the session inputs.
|
||||
NSError *error = nil;
|
||||
@ -201,18 +217,21 @@ static cricket::VideoFormat const kDefaultFormat =
|
||||
error.localizedDescription);
|
||||
return NO;
|
||||
}
|
||||
_backDeviceInput =
|
||||
[AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice
|
||||
error:&error];
|
||||
if (!_backDeviceInput) {
|
||||
NSLog(@"Failed to get capture device input: %@",
|
||||
error.localizedDescription);
|
||||
return NO;
|
||||
if (backCaptureDevice) {
|
||||
error = nil;
|
||||
_backDeviceInput =
|
||||
[AVCaptureDeviceInput deviceInputWithDevice:backCaptureDevice
|
||||
error:&error];
|
||||
if (error) {
|
||||
RTCLog(@"Failed to get capture device input: %@",
|
||||
error.localizedDescription);
|
||||
_backDeviceInput = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the inputs.
|
||||
if (![_captureSession canAddInput:_frontDeviceInput] ||
|
||||
![_captureSession canAddInput:_backDeviceInput]) {
|
||||
(_backDeviceInput && ![_captureSession canAddInput:_backDeviceInput])) {
|
||||
NSLog(@"Session does not support capture inputs.");
|
||||
return NO;
|
||||
}
|
||||
@ -336,6 +355,10 @@ AVCaptureSession* AVFoundationVideoCapturer::GetCaptureSession() {
|
||||
return _capturer.captureSession;
|
||||
}
|
||||
|
||||
bool AVFoundationVideoCapturer::CanUseBackCamera() const {
|
||||
return _capturer.canUseBackCamera;
|
||||
}
|
||||
|
||||
void AVFoundationVideoCapturer::SetUseBackCamera(bool useBackCamera) {
|
||||
_capturer.useBackCamera = useBackCamera;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user