Merge commit '367836362a6ec47f840041928c3ff8d0c269c3fb'

This commit is contained in:
Ali 2021-07-25 21:36:42 +02:00
commit b09f60cadd
14 changed files with 202 additions and 42 deletions

View File

@ -83,6 +83,11 @@ typedef enum
@property (nonatomic, readonly) bool isZoomAvailable;
@property (nonatomic, assign) CGFloat zoomLevel;
@property (nonatomic, readonly) CGFloat minZoomLevel;
@property (nonatomic, readonly) CGFloat maxZoomLevel;
@property (nonatomic, readonly) bool hasUltrawideCamera;
@property (nonatomic, readonly) bool hasTelephotoCamera;
@property (nonatomic, assign) bool disableResultMirroring;

View File

@ -24,6 +24,11 @@
@property (nonatomic, readonly) bool isZoomAvailable;
@property (nonatomic, assign) CGFloat zoomLevel;
@property (nonatomic, readonly) CGFloat minZoomLevel;
@property (nonatomic, readonly) CGFloat maxZoomLevel;
@property (nonatomic, readonly) bool hasUltrawideCamera;
@property (nonatomic, readonly) bool hasTelephotoCamera;
@property (nonatomic, readonly) CGPoint focusPoint;

View File

@ -49,6 +49,7 @@
@property (nonatomic, copy) void(^focusPointChanged)(CGPoint point);
@property (nonatomic, copy) void(^expositionChanged)(CGFloat value);
@property (nonatomic, copy) void(^zoomChanged)(CGFloat level);
@property (nonatomic, copy) void(^shutterPressed)(bool fromHardwareButton);
@property (nonatomic, copy) void(^shutterReleased)(bool fromHardwareButton);
@ -61,7 +62,7 @@
@property (nonatomic, assign) CGRect previewViewFrame;
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar;
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera;
- (void)setDocumentFrameHidden:(bool)hidden;
- (void)setCameraMode:(PGCameraMode)mode;

View File

@ -25,6 +25,8 @@
- (void)setHidden:(bool)hidden animated:(bool)animated;
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera;
@end

View File

@ -705,11 +705,27 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
#pragma mark - Zoom
- (bool)hasUltrawideCamera {
return self.captureSession.hasUltrawideCamera;
}
- (bool)hasTelephotoCamera {
return self.captureSession.hasTelephotoCamera;
}
- (bool)isZoomAvailable
{
return self.captureSession.isZoomAvailable;
}
- (CGFloat)minZoomLevel {
return self.captureSession.minZoomLevel;
}
- (CGFloat)maxZoomLevel {
return self.captureSession.maxZoomLevel;
}
- (CGFloat)zoomLevel
{
return self.captureSession.zoomLevel;
@ -717,8 +733,6 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)setZoomLevel:(CGFloat)zoomLevel
{
zoomLevel = MAX(0.0f, MIN(1.0f, zoomLevel));
[[PGCamera cameraQueue] dispatch:^
{
if (self.disabled)

View File

@ -139,6 +139,8 @@ const NSInteger PGCameraFrameRate = 30;
TGLegacyLog(@"ERROR: camera can't add still image output");
}
[self resetZoom];
AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
videoOutput.alwaysDiscardsLateVideoFrames = true;
videoOutput.videoSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) };
@ -234,8 +236,7 @@ const NSInteger PGCameraFrameRate = 30;
[self commitConfiguration];
[self resetFocusPoint];
self.zoomLevel = 0.0f;
[self resetZoom];
}
- (void)resetFlashMode
@ -292,6 +293,8 @@ const NSInteger PGCameraFrameRate = 30;
[self _enableLowLightBoost];
[self _enableVideoStabilization];
[self resetZoom];
[self commitConfiguration];
if (mode == PGCameraModePhotoScan) {
@ -444,9 +447,22 @@ const NSInteger PGCameraFrameRate = 30;
#pragma mark - Zoom
- (CGFloat)_maximumZoomFactor
{
return MIN(5.0f, self.videoDevice.activeFormat.videoMaxZoomFactor);
- (bool)hasUltrawideCamera {
if (iosMajorVersion() >= 13.0) {
if (self.videoDevice.isVirtualDevice && self.videoDevice.constituentDevices.firstObject.deviceType == AVCaptureDeviceTypeBuiltInUltraWideCamera) {
return true;
}
}
return false;
}
- (bool)hasTelephotoCamera {
if (iosMajorVersion() >= 13.0) {
if (self.videoDevice.isVirtualDevice && self.videoDevice.constituentDevices.lastObject.deviceType == AVCaptureDeviceTypeBuiltInTelephotoCamera) {
return true;
}
}
return false;
}
- (CGFloat)zoomLevel
@ -454,7 +470,52 @@ const NSInteger PGCameraFrameRate = 30;
if (![self.videoDevice respondsToSelector:@selector(videoZoomFactor)])
return 1.0f;
return (self.videoDevice.videoZoomFactor - 1.0f) / ([self _maximumZoomFactor] - 1.0f);
if (iosMajorVersion() >= 13.0 && self.videoDevice.isVirtualDevice) {
CGFloat backingLevel = self.videoDevice.videoZoomFactor;
CGFloat realLevel = backingLevel;
NSArray *marks = self.videoDevice.virtualDeviceSwitchOverVideoZoomFactors;
if (marks.count == 2) {
CGFloat firstMark = [marks.firstObject floatValue];
CGFloat secondMark = [marks.lastObject floatValue];
if (backingLevel < firstMark) {
realLevel = 0.5 + 0.5 * (backingLevel - 1.0) / (firstMark - 1.0);
} else if (backingLevel < secondMark) {
realLevel = 1.0 + 1.0 * (backingLevel - firstMark) / (secondMark - firstMark);
} else {
realLevel = 2.0 + 6.0 * (backingLevel - secondMark) / (self.maxZoomLevel - secondMark);
}
} else if (marks.count == 1) {
CGFloat mark = [marks.firstObject floatValue];
if (backingLevel < mark) {
realLevel = 1.0 + 1.0 * (backingLevel - 1.0) / (mark - 1.0);
} else {
realLevel = 2.0 + 6.0 * (backingLevel - mark) / (self.maxZoomLevel - mark);
}
}
return realLevel;
}
return self.videoDevice.videoZoomFactor;
}
- (CGFloat)minZoomLevel {
if (iosMajorVersion() >= 13.0) {
if (self.videoDevice.isVirtualDevice && self.videoDevice.constituentDevices.firstObject.deviceType == AVCaptureDeviceTypeBuiltInUltraWideCamera) {
return 0.5;
}
}
return 1.0;
}
- (CGFloat)maxZoomLevel {
return MIN(16.0f, self.videoDevice.activeFormat.videoMaxZoomFactor);
}
- (void)resetZoom {
[self setZoomLevel:1.0];
}
- (void)setZoomLevel:(CGFloat)zoomLevel
@ -469,7 +530,31 @@ const NSInteger PGCameraFrameRate = 30;
if (strongSelf == nil)
return;
device.videoZoomFactor = MAX(1.0f, MIN([strongSelf _maximumZoomFactor], 1.0f + ([strongSelf _maximumZoomFactor] - 1.0f) * zoomLevel));
CGFloat level = zoomLevel;
CGFloat backingLevel = 1.0;
if (iosMajorVersion() >= 13.0 && device.isVirtualDevice) {
NSArray *marks = device.virtualDeviceSwitchOverVideoZoomFactors;
if (marks.count == 2) {
CGFloat firstMark = [marks.firstObject floatValue];
CGFloat secondMark = [marks.lastObject floatValue];
if (level < 1.0) {
level = MAX(0.5, level);
backingLevel = 1.0 + ((level - 0.5) / 0.5) * (firstMark - 1.0);
} else if (zoomLevel < 2.0) {
backingLevel = firstMark + ((level - 1.0) / 1.0) * (secondMark - firstMark);
} else {
backingLevel = secondMark + ((level - 2.0) / 6.0) * (self.maxZoomLevel - secondMark);
}
} else if (marks.count == 1) {
CGFloat mark = [marks.firstObject floatValue];
if (zoomLevel < 2.0) {
backingLevel = 1.0 + ((level - 1.0) / 1.0) * (mark - 1.0);
} else {
backingLevel = mark + ((level - 2.0) / 6.0) * (self.maxZoomLevel - mark);
}
}
}
device.videoZoomFactor = MAX(1.0, MIN([strongSelf maxZoomLevel], backingLevel));
}];
}
@ -700,16 +785,13 @@ const NSInteger PGCameraFrameRate = 30;
+ (AVCaptureDevice *)_deviceWithPosition:(AVCaptureDevicePosition)position
{
if (iosMajorVersion() >= 10 && position == AVCaptureDevicePositionBack) {
AVCaptureDevice *device = nil;
if (iosMajorVersion() >= 13) {
device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInTripleCamera mediaType:AVMediaTypeVideo position:position];
}
if (iosMajorVersion() >= 13 && position != AVCaptureDevicePositionFront) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInTripleCamera mediaType:AVMediaTypeVideo position:position];
if (device == nil) {
device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInDualCamera mediaType:AVMediaTypeVideo position:position];
}
if (device != nil) {
return device;
return device;
}
}

View File

@ -302,12 +302,12 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
_interfaceView = [[TGCameraMainPhoneView alloc] initWithFrame:screenBounds avatar:_intent == TGCameraControllerAvatarIntent];
_interfaceView = [[TGCameraMainPhoneView alloc] initWithFrame:screenBounds avatar:_intent == TGCameraControllerAvatarIntent hasUltrawideCamera:_camera.hasUltrawideCamera hasTelephotoCamera:_camera.hasTelephotoCamera];
[_interfaceView setInterfaceOrientation:interfaceOrientation animated:false];
}
else
{
_interfaceView = [[TGCameraMainTabletView alloc] initWithFrame:screenBounds avatar:_intent == TGCameraControllerAvatarIntent];
_interfaceView = [[TGCameraMainTabletView alloc] initWithFrame:screenBounds avatar:_intent == TGCameraControllerAvatarIntent hasUltrawideCamera:_camera.hasUltrawideCamera hasTelephotoCamera:_camera.hasTelephotoCamera];
[_interfaceView setInterfaceOrientation:interfaceOrientation animated:false];
CGSize referenceSize = [self referenceViewSizeForOrientation:interfaceOrientation];
@ -378,6 +378,15 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
[strongSelf->_camera setFlashMode:mode];
};
_interfaceView.zoomChanged = ^(CGFloat level)
{
__strong TGCameraController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[strongSelf->_camera setZoomLevel:level];
};
_interfaceView.shutterPressed = ^(bool fromHardwareButton)
{
__strong TGCameraController *strongSelf = weakSelf;
@ -555,8 +564,6 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
}
else
{
strongSelf->_camera.zoomLevel = 0.0f;
[strongSelf->_camera captureNextFrameCompletion:^(UIImage *image)
{
if (commitBlock != nil)
@ -2514,8 +2521,11 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
{
case UIGestureRecognizerStateChanged:
{
CGFloat delta = (gestureRecognizer.scale - 1.0f) / 1.5f;
CGFloat value = MAX(0.0f, MIN(1.0f, _camera.zoomLevel + delta));
CGFloat delta = (gestureRecognizer.scale - 1.0f) * 1.25;
if (_camera.zoomLevel > 2.0) {
delta *= 2.0;
}
CGFloat value = MAX(_camera.minZoomLevel, MIN(_camera.maxZoomLevel, _camera.zoomLevel + delta));
[_camera setZoomLevel:value];
[_interfaceView setZoomLevel:value displayNeeded:true];

View File

@ -67,10 +67,7 @@
TGCameraFlashActiveView *_flashActiveView;
TGCameraFlipButton *_topFlipButton;
TGCameraZoomModeView *_zoomModeView;
TGCameraZoomWheelView *_zoomWheelView;
bool _hasResults;
CGFloat _topPanelOffset;
@ -103,7 +100,7 @@
@synthesize cancelPressed;
@synthesize actionHandle = _actionHandle;
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera
{
self = [super initWithFrame:frame];
if (self != nil)
@ -287,7 +284,7 @@
};
// [self addSubview:_zoomView];
_zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43)];
_zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera];
_zoomModeView.zoomChanged = ^(CGFloat zoomLevel, bool done) {
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
if (strongSelf == nil)
@ -303,6 +300,9 @@
[strongSelf->_zoomModeView setHidden:false animated:true];
[strongSelf->_zoomWheelView setHidden:true animated:true];
}
if (strongSelf.zoomChanged != nil)
strongSelf.zoomChanged(zoomLevel);
};
[_zoomModeView setZoomLevel:1.0];
[self addSubview:_zoomModeView];

View File

@ -42,7 +42,7 @@ const CGFloat TGCameraTabletPanelViewWidth = 102.0f;
@synthesize shutterReleased;
@synthesize cancelPressed;
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar
- (instancetype)initWithFrame:(CGRect)frame avatar:(bool)avatar hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera
{
self = [super initWithFrame:frame];
if (self != nil)

View File

@ -182,7 +182,7 @@
- (void)setZoomLevel:(CGFloat)zoomLevel displayNeeded:(bool)displayNeeded
{
[_zoomView setZoomLevel:zoomLevel displayNeeded:displayNeeded];
[_zoomModeView setZoomLevel:zoomLevel];
[_zoomModeView setZoomLevel:zoomLevel animated:true];
}
- (void)zoomChangingEnded

View File

@ -228,6 +228,9 @@
@interface TGCameraZoomModeView ()
{
UIView *_backgroundView;
bool _hasUltrawideCamera;
bool _hasTelephotoCamera;
TGCameraZoomModeItemView *_leftItem;
TGCameraZoomModeItemView *_centerItem;
@ -237,11 +240,14 @@
@implementation TGCameraZoomModeView
- (instancetype)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera
{
self = [super initWithFrame:frame];
if (self != nil)
{
{
_hasUltrawideCamera = hasUltrawideCamera;
_hasTelephotoCamera = hasTelephotoCamera;
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.15];
_backgroundView.layer.cornerRadius = self.bounds.size.height / 2.0;
@ -256,12 +262,16 @@
[_rightItem addTarget:self action:@selector(rightPressed) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_backgroundView];
[self addSubview:_leftItem];
if (hasUltrawideCamera) {
[self addSubview:_leftItem];
}
[self addSubview:_centerItem];
[self addSubview:_rightItem];
if (hasTelephotoCamera) {
[self addSubview:_rightItem];
}
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
[self addGestureRecognizer:gestureRecognizer];
// [self addGestureRecognizer:gestureRecognizer];
}
return self;
}
@ -318,15 +328,23 @@
{
_zoomLevel = zoomLevel;
if (zoomLevel < 1.0) {
[_leftItem setValue:[NSString stringWithFormat:@"%.1fx", zoomLevel] selected:true animated:animated];
NSString *value = [NSString stringWithFormat:@"%.1fx", zoomLevel];
if ([value isEqual:@"1.0x"]) {
value = @"0.9x";
}
[_leftItem setValue:value selected:true animated:animated];
[_centerItem setValue:@"1" selected:false animated:animated];
[_rightItem setValue:@"2" selected:false animated:animated];
} else if (zoomLevel < 2.0) {
[_leftItem setValue:@"0.5" selected:false animated:animated];
if ((zoomLevel - 1.0) < FLT_EPSILON) {
if ((zoomLevel - 1.0) < 0.1) {
[_centerItem setValue:@"1x" selected:true animated:animated];
} else {
[_centerItem setValue:[NSString stringWithFormat:@"%.1fx", zoomLevel] selected:true animated:animated];
NSString *value = [NSString stringWithFormat:@"%.1fx", zoomLevel];
if ([value isEqual:@"1.0x"]) {
value = @"1x";
}
[_centerItem setValue:value selected:true animated:animated];
}
[_rightItem setValue:@"2" selected:false animated:animated];
} else {
@ -334,8 +352,8 @@
[_centerItem setValue:@"1" selected:false animated:animated];
CGFloat near = round(zoomLevel);
if (ABS(zoomLevel - near) < FLT_EPSILON) {
[_rightItem setValue:[NSString stringWithFormat:@"%d", (int)zoomLevel] selected:true animated:animated];
if (ABS(zoomLevel - near) < 0.1) {
[_rightItem setValue:[NSString stringWithFormat:@"%dx", (int)zoomLevel] selected:true animated:animated];
} else {
[_rightItem setValue:[NSString stringWithFormat:@"%.1fx", zoomLevel] selected:true animated:animated];
}
@ -375,8 +393,12 @@
- (void)layoutSubviews
{
if (_leftItem.isHidden) {
if (_rightItem.superview == nil) {
_backgroundView.frame = CGRectMake(43, 0, 43, 43);
} else if (_leftItem.superview == nil) {
_backgroundView.frame = CGRectMake(21 + TGScreenPixel, 0, 86, 43);
_centerItem.frame = CGRectMake(21 + TGScreenPixel, 0, 43, 43);
_rightItem.frame = CGRectMake(21 + TGScreenPixel + 43, 0, 43, 43);
} else {
_leftItem.frame = CGRectMake(0, 0, 43, 43.0);
_centerItem.frame = CGRectMake(43, 0, 43, 43.0);

View File

@ -17,6 +17,7 @@
@property (nonatomic, readonly) bool isZoomAvailable;
@property (nonatomic, assign) CGFloat zoomLevel;
- (void)cancelZoom;
- (instancetype)initWithDelegate:(id<TGVideoCameraPipelineDelegate>)delegate position:(AVCaptureDevicePosition)position callbackQueue:(dispatch_queue_t)queue liveUploadInterface:(id<TGLiveUploadInterface>)liveUploadInterface;

View File

@ -894,6 +894,20 @@ static CGFloat angleOffsetFromPortraitOrientationToOrientation(AVCaptureVideoOri
}];
}
- (void)cancelZoom {
__weak TGVideoCameraPipeline *weakSelf = self;
[[TGVideoCameraPipeline cameraQueue] dispatch:^
{
__strong TGVideoCameraPipeline *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[self _reconfigureDevice:_videoDevice withBlock:^(AVCaptureDevice *device) {
[device rampToVideoZoomFactor:1.0 withRate:8.0];
}];
}];
}
- (bool)isZoomAvailable
{
return [TGVideoCameraPipeline _isZoomAvailableForDevice:_videoDevice];

View File

@ -450,6 +450,10 @@ typedef enum
gestureRecognizer.scale = 1.0f;
}
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
[_capturePipeline cancelZoom];
break;
default:
break;
}