diff --git a/submodules/Camera/Sources/Camera.swift b/submodules/Camera/Sources/Camera.swift index 2ae5f15f10..f180045b7c 100644 --- a/submodules/Camera/Sources/Camera.swift +++ b/submodules/Camera/Sources/Camera.swift @@ -65,7 +65,7 @@ final class CameraDeviceContext { self.device.configureDeviceFormat(maxDimensions: self.preferredMaxDimensions, maxFramerate: self.preferredMaxFrameRate) self.output.configureVideoStabilization() - self.device.resetZoom() + self.device.resetZoom(neutral: self.exclusive || !self.additional) } func invalidate() { @@ -77,7 +77,11 @@ final class CameraDeviceContext { } private var preferredMaxDimensions: CMVideoDimensions { - return CMVideoDimensions(width: 1920, height: 1080) + if self.additional { + return CMVideoDimensions(width: 1920, height: 1440) + } else { + return CMVideoDimensions(width: 1920, height: 1080) + } } private var preferredMaxFrameRate: Double { diff --git a/submodules/Camera/Sources/CameraDevice.swift b/submodules/Camera/Sources/CameraDevice.swift index b6a8ff112e..02fcbd06ec 100644 --- a/submodules/Camera/Sources/CameraDevice.swift +++ b/submodules/Camera/Sources/CameraDevice.swift @@ -44,7 +44,14 @@ final class CameraDevice { selectedDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera, .builtInTelephotoCamera], mediaType: .video, position: position).devices.first } } else { - selectedDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera, .builtInTelephotoCamera], mediaType: .video, position: position).devices.first + if #available(iOS 11.1, *), dual, case .front = position { + if let trueDepthDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTrueDepthCamera], mediaType: .video, position: position).devices.first { + selectedDevice = trueDepthDevice + } + } + if selectedDevice == nil { + selectedDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera, .builtInTelephotoCamera], mediaType: .video, position: position).devices.first + } } self.videoDevice = selectedDevice @@ -245,12 +252,12 @@ final class CameraDevice { } } - func resetZoom() { + func resetZoom(neutral: Bool = true) { guard let device = self.videoDevice else { return } self.transaction(device) { device in - device.videoZoomFactor = device.neutralZoomFactor + device.videoZoomFactor = neutral ? device.neutralZoomFactor : device.minAvailableVideoZoomFactor } } } diff --git a/submodules/Camera/Sources/CameraPreviewView.swift b/submodules/Camera/Sources/CameraPreviewView.swift index 68ecdd4f8d..e08915b971 100644 --- a/submodules/Camera/Sources/CameraPreviewView.swift +++ b/submodules/Camera/Sources/CameraPreviewView.swift @@ -48,7 +48,7 @@ public class CameraSimplePreviewView: UIView { public init(frame: CGRect, main: Bool) { super.init(frame: frame) - self.videoPreviewLayer.videoGravity = .resizeAspectFill + self.videoPreviewLayer.videoGravity = main ? .resizeAspectFill : .resizeAspect self.placeholderView.contentMode = .scaleAspectFill self.addSubview(self.placeholderView) diff --git a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift index eecfa3a371..20c96b41d4 100644 --- a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift +++ b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift @@ -1912,8 +1912,7 @@ public class CameraScreen: ViewController { } let additionalPreviewInnerSize = previewFrame.size.aspectFilled(CGSize(width: circleSide, height: circleSide)) - let additionalPreviewInnerFrame = CGRect(origin: CGPoint(x: 0.0, y: floorToScreenPixels((circleSide - additionalPreviewInnerSize.height) / 2.0)), size: additionalPreviewInnerSize) - + let additionalPreviewFrame = CGRect(origin: CGPoint(x: origin.x - circleSide / 2.0, y: origin.y - circleSide / 2.0), size: CGSize(width: circleSide, height: circleSide)) transition.setPosition(view: self.additionalPreviewContainerView, position: additionalPreviewFrame.center) @@ -1931,16 +1930,23 @@ public class CameraScreen: ViewController { } } + var mainPreviewInnerSize = previewFrame.size + let mainPreviewView: CameraSimplePreviewView let additionalPreviewView: CameraSimplePreviewView if self.cameraPosition == .front && self.isDualCamEnabled { mainPreviewView = self.additionalPreviewView additionalPreviewView = self.mainPreviewView + + mainPreviewInnerSize = CGSize(width: floorToScreenPixels(mainPreviewInnerSize.height / 3.0 * 4.0), height: mainPreviewInnerSize.height) } else { mainPreviewView = self.mainPreviewView additionalPreviewView = self.additionalPreviewView } + let mainPreviewInnerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - mainPreviewInnerSize.width) / 2.0), y: floorToScreenPixels((previewSize.height - mainPreviewInnerSize.height) / 2.0)), size: mainPreviewInnerSize) + let additionalPreviewInnerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((circleSide - additionalPreviewInnerSize.width) / 2.0), y: floorToScreenPixels((circleSide - additionalPreviewInnerSize.height) / 2.0)), size: additionalPreviewInnerSize) + if mainPreviewView.superview != self.mainPreviewContainerView { self.mainPreviewContainerView.insertSubview(mainPreviewView, at: 0) } @@ -1948,7 +1954,7 @@ public class CameraScreen: ViewController { self.additionalPreviewContainerView.insertSubview(additionalPreviewView, at: 0) } - mainPreviewView.frame = CGRect(origin: .zero, size: previewFrame.size) + mainPreviewView.frame = mainPreviewInnerFrame additionalPreviewView.frame = additionalPreviewInnerFrame self.previewFrameLeftDimView.isHidden = !isTablet diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/VideoTextureSource.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/VideoTextureSource.swift index 3763e91861..1d30ce287c 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/VideoTextureSource.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/VideoTextureSource.swift @@ -514,7 +514,7 @@ final class VideoInputScalePass: RenderPass { func update(values: MediaEditorValues) { if let position = values.additionalVideoPosition, let scale = values.additionalVideoScale, let rotation = values.additionalVideoRotation { - self.additionalPosition = VideoInputScalePass.VideoPosition(position: position, size: CGSize(width: 1080.0 / 4.0, height: 1920.0 / 4.0), scale: scale, rotation: rotation) + self.additionalPosition = VideoInputScalePass.VideoPosition(position: position, size: CGSize(width: 1080.0 / 4.0, height: 1440.0 / 4.0), scale: scale, rotation: rotation) } if !values.additionalVideoPositionChanges.isEmpty { self.videoPositionChanges = values.additionalVideoPositionChanges @@ -530,7 +530,7 @@ final class VideoInputScalePass: RenderPass { private var additionalPosition = VideoPosition( position: CGPoint(x: 1080 / 2.0, y: 1920.0 / 2.0), - size: CGSize(width: 1080.0, height: 1920.0), + size: CGSize(width: 1440.0, height: 1920.0), scale: 0.5, rotation: 0.0 ) @@ -550,7 +550,6 @@ final class VideoInputScalePass: RenderPass { let scale: CGFloat let rotation: CGFloat - func mixed(with other: VideoPosition, fraction: CGFloat) -> VideoPosition { let position = CGPoint( x: self.position.x + (other.position.x - self.position.x) * fraction, @@ -589,6 +588,10 @@ final class VideoInputScalePass: RenderPass { var foregroundTexture = additionalInput var foregroundTextureRotation = self.additionalTextureRotation + var mainPosition = self.mainPosition + var additionalPosition = self.additionalPosition + var disappearingPosition = self.mainPosition + var transitionFraction = 1.0 if let additionalInput { var previousChange: VideoPositionChange? @@ -606,8 +609,13 @@ final class VideoInputScalePass: RenderPass { backgroundTexture = additionalInput backgroundTextureRotation = self.additionalTextureRotation + mainPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation) + additionalPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: 1080.0 / 4.0, height: 1920.0 / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation) + foregroundTexture = mainInput foregroundTextureRotation = self.mainTextureRotation + } else { + disappearingPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation) } if previousChange.timestamp > 0.0 && timestamp < previousChange.timestamp + transitionDuration { transitionFraction = (timestamp - previousChange.timestamp) / transitionDuration @@ -615,22 +623,23 @@ final class VideoInputScalePass: RenderPass { } } - var backgroundVideoState = VideoState(texture: backgroundTexture, textureRotation: backgroundTextureRotation, position: self.mainPosition, roundness: 0.0, alpha: 1.0) + var backgroundVideoState = VideoState(texture: backgroundTexture, textureRotation: backgroundTextureRotation, position: mainPosition, roundness: 0.0, alpha: 1.0) var foregroundVideoState: VideoState? var disappearingVideoState: VideoState? if let foregroundTexture { - var foregroundPosition = self.additionalPosition + var foregroundPosition = additionalPosition var foregroundAlpha: Float = 1.0 if transitionFraction < 1.0 { let springFraction = lookupSpringValue(transitionFraction) - let appearingPosition = VideoPosition(position: self.additionalPosition.position, size: self.additionalPosition.size, scale: 0.01, rotation: self.additionalPosition.rotation) + let appearingPosition = VideoPosition(position: additionalPosition.position, size: additionalPosition.size, scale: 0.01, rotation: self.additionalPosition.rotation) + let backgroundInitialPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: mainPosition.size.width / 4.0, height: mainPosition.size.height / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation) - foregroundPosition = appearingPosition.mixed(with: self.additionalPosition, fraction: springFraction) + foregroundPosition = appearingPosition.mixed(with: additionalPosition, fraction: springFraction) - disappearingVideoState = VideoState(texture: foregroundTexture, textureRotation: foregroundTextureRotation, position: self.mainPosition, roundness: 0.0, alpha: 1.0) - backgroundVideoState = VideoState(texture: backgroundTexture, textureRotation: backgroundTextureRotation, position: self.additionalPosition.mixed(with: self.mainPosition, fraction: springFraction), roundness: Float(1.0 - springFraction), alpha: 1.0) + disappearingVideoState = VideoState(texture: foregroundTexture, textureRotation: foregroundTextureRotation, position: disappearingPosition, roundness: 0.0, alpha: 1.0) + backgroundVideoState = VideoState(texture: backgroundTexture, textureRotation: backgroundTextureRotation, position: backgroundInitialPosition.mixed(with: mainPosition, fraction: springFraction), roundness: Float(1.0 - springFraction), alpha: 1.0) foregroundAlpha = min(1.0, max(0.0, Float(transitionFraction) * 2.5)) }