Skip to content

Commit

Permalink
Fix camera rotation (#92)
Browse files Browse the repository at this point in the history
Use UIInterfaceOrientation instead of UIDeviceOrientation for RTCVideoFrame's rotation
  • Loading branch information
hiroshihorie authored and cloudwebrtc committed Sep 14, 2023
1 parent f12f8d9 commit 28e2021
Showing 1 changed file with 29 additions and 26 deletions.
55 changes: 29 additions & 26 deletions sdk/objc/components/capturer/RTCCameraVideoCapturer.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ @implementation RTC_OBJC_TYPE (RTCCameraVideoCapturer) {
FourCharCode _outputPixelFormat;
RTCVideoRotation _rotation;
#if TARGET_OS_IPHONE
UIDeviceOrientation _orientation;
UIInterfaceOrientation _orientation;
BOOL _generatingOrientationNotifications;
#endif
}
Expand Down Expand Up @@ -75,7 +75,7 @@ - (instancetype)initWithDelegate:(__weak id<RTC_OBJC_TYPE(RTCVideoCapturerDelega
}
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
#if TARGET_OS_IPHONE
_orientation = UIDeviceOrientationPortrait;
_orientation = UIInterfaceOrientationPortrait;
_rotation = RTCVideoRotation_90;
[center addObserver:self
selector:@selector(deviceOrientationDidChange:)
Expand Down Expand Up @@ -166,6 +166,8 @@ - (void)startCaptureWithDevice:(AVCaptureDevice *)device
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
self->_generatingOrientationNotifications = YES;
}
// Must be called on main
[self updateOrientation];
});
#endif

Expand All @@ -183,7 +185,6 @@ - (void)startCaptureWithDevice:(AVCaptureDevice *)device
return;
}
[self reconfigureCaptureSessionInput];
[self updateOrientation];
[self updateDeviceCaptureFormat:format fps:fps];
[self updateVideoDataOutputPixelFormat:format];
[self.captureSession startRunning];
Expand Down Expand Up @@ -226,10 +227,7 @@ - (void)stopCaptureWithCompletionHandler:(nullable void (^)(void))completionHand

#if TARGET_OS_IPHONE
- (void)deviceOrientationDidChange:(NSNotification *)notification {
[RTC_OBJC_TYPE(RTCDispatcher) dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
block:^{
[self updateOrientation];
}];
[self updateOrientation];
}
#endif

Expand Down Expand Up @@ -265,22 +263,20 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput
usingFrontCamera = AVCaptureDevicePositionFront == deviceInput.device.position;
}
switch (_orientation) {
case UIDeviceOrientationPortrait:
case UIInterfaceOrientationPortrait:
_rotation = RTCVideoRotation_90;
break;
case UIDeviceOrientationPortraitUpsideDown:
case UIInterfaceOrientationPortraitUpsideDown:
_rotation = RTCVideoRotation_270;
break;
case UIDeviceOrientationLandscapeLeft:
_rotation = usingFrontCamera ? RTCVideoRotation_180 : RTCVideoRotation_0;
break;
case UIDeviceOrientationLandscapeRight:
case UIInterfaceOrientationLandscapeLeft:
_rotation = usingFrontCamera ? RTCVideoRotation_0 : RTCVideoRotation_180;
break;
case UIDeviceOrientationFaceUp:
case UIDeviceOrientationFaceDown:
case UIDeviceOrientationUnknown:
// Ignore.
case UIInterfaceOrientationLandscapeRight:
_rotation = usingFrontCamera ? RTCVideoRotation_180 : RTCVideoRotation_0;
break;
case UIInterfaceOrientationUnknown:
_rotation = RTCVideoRotation_0;
break;
}
#else
Expand Down Expand Up @@ -495,8 +491,8 @@ - (void)updateDeviceCaptureFormat:(AVCaptureDeviceFormat *)format fps:(NSInteger
@"updateDeviceCaptureFormat must be called on the capture queue.");
@try {
_currentDevice.activeFormat = format;
if(![NSStringFromClass([_currentDevice class]) isEqualToString:@"AVCaptureDALDevice"]) {
_currentDevice.activeVideoMinFrameDuration = CMTimeMake(1, fps);
if (![NSStringFromClass([_currentDevice class]) isEqualToString:@"AVCaptureDALDevice"]) {
_currentDevice.activeVideoMinFrameDuration = CMTimeMake(1, fps);
}
} @catch (NSException *exception) {
RTCLogError(@"Failed to set active format!\n User info:%@", exception.userInfo);
Expand All @@ -508,8 +504,8 @@ - (void)reconfigureCaptureSessionInput {
NSAssert([RTC_OBJC_TYPE(RTCDispatcher) isOnQueueForType:RTCDispatcherTypeCaptureSession],
@"reconfigureCaptureSessionInput must be called on the capture queue.");
NSError *error = nil;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:_currentDevice error:&error];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:_currentDevice
error:&error];
if (!input) {
RTCLogError(@"Failed to create front camera input: %@", error.localizedDescription);
return;
Expand All @@ -526,12 +522,19 @@ - (void)reconfigureCaptureSessionInput {
[_captureSession commitConfiguration];
}

- (void)updateOrientation {
NSAssert([RTC_OBJC_TYPE(RTCDispatcher) isOnQueueForType:RTCDispatcherTypeCaptureSession],
@"updateOrientation must be called on the capture queue.");
#if TARGET_OS_IPHONE
_orientation = [UIDevice currentDevice].orientation;
#endif
- (void)updateOrientation {
NSAssert([RTC_OBJC_TYPE(RTCDispatcher) isOnQueueForType:RTCDispatcherTypeMain],
@"statusBarOrientation must be called on the main queue.");
// statusBarOrientation must be called on the main queue
UIInterfaceOrientation newOrientation = [UIApplication sharedApplication].statusBarOrientation;

[RTC_OBJC_TYPE(RTCDispatcher) dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
block:^{
// Must be called on the capture queue
self->_orientation = newOrientation;
}];
}
#endif

@end

0 comments on commit 28e2021

Please sign in to comment.