2014 snapchat source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.5 KiB

  1. //
  2. // SCManagedCaptureDeviceDefaultZoomHandler.m
  3. // Snapchat
  4. //
  5. // Created by Yu-Kuan Lai on 4/12/17.
  6. // Copyright © 2017 Snapchat, Inc. All rights reserved.
  7. //
  8. #import "SCManagedCaptureDeviceDefaultZoomHandler_Private.h"
  9. #import "SCCaptureResource.h"
  10. #import "SCManagedCaptureDevice+SCManagedCapturer.h"
  11. #import "SCManagedCapturer.h"
  12. #import "SCManagedCapturerLogging.h"
  13. #import "SCManagedCapturerStateBuilder.h"
  14. #import "SCMetalUtils.h"
  15. #import <SCFoundation/SCAssertWrapper.h>
  16. #import <SCFoundation/SCQueuePerformer.h>
  17. #import <SCFoundation/SCThreadHelpers.h>
  18. #import <SCFoundation/SCTraceODPCompatible.h>
  19. @implementation SCManagedCaptureDeviceDefaultZoomHandler
  20. - (instancetype)initWithCaptureResource:(SCCaptureResource *)captureResource
  21. {
  22. self = [super init];
  23. if (self) {
  24. _captureResource = captureResource;
  25. }
  26. return self;
  27. }
  28. - (void)setZoomFactor:(CGFloat)zoomFactor forDevice:(SCManagedCaptureDevice *)device immediately:(BOOL)immediately
  29. {
  30. [self _setZoomFactor:zoomFactor forManagedCaptureDevice:device];
  31. }
  32. - (void)softwareZoomWithDevice:(SCManagedCaptureDevice *)device
  33. {
  34. SCTraceODPCompatibleStart(2);
  35. SCAssert([_captureResource.queuePerformer isCurrentPerformer] ||
  36. [[SCQueuePerformer mainQueuePerformer] isCurrentPerformer],
  37. @"");
  38. SCAssert(device.softwareZoom, @"Only do software zoom for software zoom device");
  39. SC_GUARD_ELSE_RETURN(!SCDeviceSupportsMetal());
  40. float zoomFactor = device.zoomFactor;
  41. SCLogCapturerInfo(@"Adjusting software zoom factor to: %f", zoomFactor);
  42. AVCaptureVideoPreviewLayer *videoPreviewLayer = _captureResource.videoPreviewLayer;
  43. [[SCQueuePerformer mainQueuePerformer] perform:^{
  44. [CATransaction begin];
  45. [CATransaction setDisableActions:YES];
  46. // I end up need to change its superlayer transform to get the zoom effect
  47. videoPreviewLayer.superlayer.affineTransform = CGAffineTransformMakeScale(zoomFactor, zoomFactor);
  48. [CATransaction commit];
  49. }];
  50. }
  51. - (void)_setZoomFactor:(CGFloat)zoomFactor forManagedCaptureDevice:(SCManagedCaptureDevice *)device
  52. {
  53. SCTraceODPCompatibleStart(2);
  54. [_captureResource.queuePerformer perform:^{
  55. SCTraceStart();
  56. if (device) {
  57. SCLogCapturerInfo(@"Set zoom factor: %f -> %f", _captureResource.state.zoomFactor, zoomFactor);
  58. [device setZoomFactor:zoomFactor];
  59. BOOL zoomFactorChanged = NO;
  60. // If the device is our current device, send the notification, update the
  61. // state.
  62. if (device.isConnected && device == _captureResource.device) {
  63. if (device.softwareZoom) {
  64. [self softwareZoomWithDevice:device];
  65. }
  66. _captureResource.state = [[[SCManagedCapturerStateBuilder
  67. withManagedCapturerState:_captureResource.state] setZoomFactor:zoomFactor] build];
  68. zoomFactorChanged = YES;
  69. }
  70. SCManagedCapturerState *state = [_captureResource.state copy];
  71. runOnMainThreadAsynchronously(^{
  72. if (zoomFactorChanged) {
  73. [_captureResource.announcer managedCapturer:[SCManagedCapturer sharedInstance]
  74. didChangeState:state];
  75. [_captureResource.announcer managedCapturer:[SCManagedCapturer sharedInstance]
  76. didChangeZoomFactor:state];
  77. }
  78. });
  79. }
  80. }];
  81. }
  82. @end