Source-SCCamera/ManagedCapturer/SCManagedCaptureDeviceDefau...

94 lines
3.5 KiB
Objective-C

//
// SCManagedCaptureDeviceDefaultZoomHandler.m
// Snapchat
//
// Created by Yu-Kuan Lai on 4/12/17.
// Copyright © 2017 Snapchat, Inc. All rights reserved.
//
#import "SCManagedCaptureDeviceDefaultZoomHandler_Private.h"
#import "SCCaptureResource.h"
#import "SCManagedCaptureDevice+SCManagedCapturer.h"
#import "SCManagedCapturer.h"
#import "SCManagedCapturerLogging.h"
#import "SCManagedCapturerStateBuilder.h"
#import "SCMetalUtils.h"
#import <SCFoundation/SCAssertWrapper.h>
#import <SCFoundation/SCQueuePerformer.h>
#import <SCFoundation/SCThreadHelpers.h>
#import <SCFoundation/SCTraceODPCompatible.h>
@implementation SCManagedCaptureDeviceDefaultZoomHandler
- (instancetype)initWithCaptureResource:(SCCaptureResource *)captureResource
{
self = [super init];
if (self) {
_captureResource = captureResource;
}
return self;
}
- (void)setZoomFactor:(CGFloat)zoomFactor forDevice:(SCManagedCaptureDevice *)device immediately:(BOOL)immediately
{
[self _setZoomFactor:zoomFactor forManagedCaptureDevice:device];
}
- (void)softwareZoomWithDevice:(SCManagedCaptureDevice *)device
{
SCTraceODPCompatibleStart(2);
SCAssert([_captureResource.queuePerformer isCurrentPerformer] ||
[[SCQueuePerformer mainQueuePerformer] isCurrentPerformer],
@"");
SCAssert(device.softwareZoom, @"Only do software zoom for software zoom device");
SC_GUARD_ELSE_RETURN(!SCDeviceSupportsMetal());
float zoomFactor = device.zoomFactor;
SCLogCapturerInfo(@"Adjusting software zoom factor to: %f", zoomFactor);
AVCaptureVideoPreviewLayer *videoPreviewLayer = _captureResource.videoPreviewLayer;
[[SCQueuePerformer mainQueuePerformer] perform:^{
[CATransaction begin];
[CATransaction setDisableActions:YES];
// I end up need to change its superlayer transform to get the zoom effect
videoPreviewLayer.superlayer.affineTransform = CGAffineTransformMakeScale(zoomFactor, zoomFactor);
[CATransaction commit];
}];
}
- (void)_setZoomFactor:(CGFloat)zoomFactor forManagedCaptureDevice:(SCManagedCaptureDevice *)device
{
SCTraceODPCompatibleStart(2);
[_captureResource.queuePerformer perform:^{
SCTraceStart();
if (device) {
SCLogCapturerInfo(@"Set zoom factor: %f -> %f", _captureResource.state.zoomFactor, zoomFactor);
[device setZoomFactor:zoomFactor];
BOOL zoomFactorChanged = NO;
// If the device is our current device, send the notification, update the
// state.
if (device.isConnected && device == _captureResource.device) {
if (device.softwareZoom) {
[self softwareZoomWithDevice:device];
}
_captureResource.state = [[[SCManagedCapturerStateBuilder
withManagedCapturerState:_captureResource.state] setZoomFactor:zoomFactor] build];
zoomFactorChanged = YES;
}
SCManagedCapturerState *state = [_captureResource.state copy];
runOnMainThreadAsynchronously(^{
if (zoomFactorChanged) {
[_captureResource.announcer managedCapturer:[SCManagedCapturer sharedInstance]
didChangeState:state];
[_captureResource.announcer managedCapturer:[SCManagedCapturer sharedInstance]
didChangeZoomFactor:state];
}
});
}
}];
}
@end