From d2590519a2847e0f3ecc81d7647a68bb161bfb57 Mon Sep 17 00:00:00 2001 From: afriscic Date: Sun, 12 Jan 2025 17:08:27 +0100 Subject: [PATCH] 2.1.4 --- .../BarcodeScanning.Native.Maui.csproj | 6 +- .../Platform/MaciOS/BarcodeView.cs | 32 +++-- .../Platform/MaciOS/CameraManager.cs | 112 +++++++++--------- 3 files changed, 87 insertions(+), 63 deletions(-) diff --git a/BarcodeScanning.Native.Maui/BarcodeScanning.Native.Maui.csproj b/BarcodeScanning.Native.Maui/BarcodeScanning.Native.Maui.csproj index f14f3d5..8fed4b0 100644 --- a/BarcodeScanning.Native.Maui/BarcodeScanning.Native.Maui.csproj +++ b/BarcodeScanning.Native.Maui/BarcodeScanning.Native.Maui.csproj @@ -10,7 +10,7 @@ true true enable - 2.1.3 + 2.1.4 Alen Friščić MIT README.md @@ -51,8 +51,8 @@ - - + + diff --git a/BarcodeScanning.Native.Maui/Platform/MaciOS/BarcodeView.cs b/BarcodeScanning.Native.Maui/Platform/MaciOS/BarcodeView.cs index 6540239..cc25d64 100644 --- a/BarcodeScanning.Native.Maui/Platform/MaciOS/BarcodeView.cs +++ b/BarcodeScanning.Native.Maui/Platform/MaciOS/BarcodeView.cs @@ -32,15 +32,33 @@ public override void LayoutSubviews() _previewLayer.Frame = layer.Bounds; var connection = _previewLayer.Connection; - if (connection is not null && connection.SupportsVideoOrientation) + if (connection is not null) { - connection.VideoOrientation = this.Window?.WindowScene?.InterfaceOrientation switch + /*if (OperatingSystem.IsIOSVersionAtLeast(17)) { - UIInterfaceOrientation.LandscapeLeft => AVCaptureVideoOrientation.LandscapeLeft, - UIInterfaceOrientation.LandscapeRight => AVCaptureVideoOrientation.LandscapeRight, - UIInterfaceOrientation.PortraitUpsideDown => AVCaptureVideoOrientation.PortraitUpsideDown, - _ => AVCaptureVideoOrientation.Portrait - }; + var angle = this.Window?.WindowScene?.InterfaceOrientation switch + { + UIInterfaceOrientation.LandscapeLeft => 0, + UIInterfaceOrientation.LandscapeRight => 180, + UIInterfaceOrientation.PortraitUpsideDown => 270, + _ => 90 + }; + if (connection.IsVideoRotationAngleSupported(angle)) + connection.VideoRotationAngle = angle; + } + else + {*/ + if (connection.SupportsVideoOrientation) + { + connection.VideoOrientation = this.Window?.WindowScene?.InterfaceOrientation switch + { + UIInterfaceOrientation.LandscapeLeft => AVCaptureVideoOrientation.LandscapeLeft, + UIInterfaceOrientation.LandscapeRight => AVCaptureVideoOrientation.LandscapeRight, + UIInterfaceOrientation.PortraitUpsideDown => AVCaptureVideoOrientation.PortraitUpsideDown, + _ => AVCaptureVideoOrientation.Portrait + }; + } + //} } } } diff --git a/BarcodeScanning.Native.Maui/Platform/MaciOS/CameraManager.cs b/BarcodeScanning.Native.Maui/Platform/MaciOS/CameraManager.cs index d1680b7..91d13ff 100644 --- a/BarcodeScanning.Native.Maui/Platform/MaciOS/CameraManager.cs +++ b/BarcodeScanning.Native.Maui/Platform/MaciOS/CameraManager.cs @@ -75,29 +75,25 @@ internal CameraManager(CameraView cameraView) internal void Start() { if (_captureSession is not null) - { - if (_captureSession.Running) - _dispatchQueue.DispatchAsync(_captureSession.StopRunning); - + { UpdateCamera(); - UpdateResolution(); - if (!_captureSession.Outputs.Contains(_videoDataOutput) && _captureSession.CanAddOutput(_videoDataOutput)) - { - _dispatchQueue.DispatchAsync(() => - { - _captureSession.BeginConfiguration(); - _captureSession.AddOutput(_videoDataOutput); - _captureSession.CommitConfiguration(); - }); - } + _dispatchQueue.DispatchBarrierAsync(() => + { + if (_captureSession.Running) + _captureSession.StopRunning(); - _dispatchQueue.DispatchAsync(() => - { _captureSession.StartRunning(); if (_videoDataOutput is not null) { + if (!_captureSession.Outputs.Contains(_videoDataOutput) && _captureSession.CanAddOutput(_videoDataOutput)) + { + _captureSession.BeginConfiguration(); + _captureSession.AddOutput(_videoDataOutput); + _captureSession.CommitConfiguration(); + } + _videoDataOutput.SetSampleBufferDelegate(null, null); _videoDataOutput.SetSampleBufferDelegate(_barcodeAnalyzer, DispatchQueue.DefaultGlobalQueue); } @@ -117,7 +113,7 @@ internal void Stop() DeviceLock(() => _captureDevice.TorchMode = AVCaptureTorchMode.Off); if (_captureSession.Running) - _dispatchQueue.DispatchAsync(_captureSession.StopRunning); + _dispatchQueue.DispatchBarrierAsync(_captureSession.StopRunning); } } @@ -139,46 +135,52 @@ internal void UpdateCamera() { if (_captureSession is not null) { - _dispatchQueue.DispatchAsync(() => + AVCaptureDevice? newDevice = null; + if (_cameraView?.CameraFacing == CameraFacing.Front) { - _captureSession.BeginConfiguration(); + newDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Front); + } + else + { + newDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInTripleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); + newDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInDualWideCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); + newDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInDualCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); + newDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); + } + newDevice ??= AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video); - if (_captureInput is not null) + if (_captureDevice != newDevice) + { + _dispatchQueue.DispatchBarrierAsync(() => { - if (_captureSession.Inputs.Contains(_captureInput)) - _captureSession.RemoveInput(_captureInput); + _captureSession.BeginConfiguration(); - _captureInput.Dispose(); - } + if (_captureInput is not null) + { + if (_captureSession.Inputs.Contains(_captureInput)) + _captureSession.RemoveInput(_captureInput); - _captureDevice?.Dispose(); - if (_cameraView?.CameraFacing == CameraFacing.Front) - { - _captureDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Front); - } - else - { - _captureDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInTripleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); - _captureDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInDualWideCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); - _captureDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInDualCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); - _captureDevice ??= AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaTypes.Video, AVCaptureDevicePosition.Back); - } - _captureDevice ??= AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video); - - if (_captureDevice is not null) - { - _captureInput = new AVCaptureDeviceInput(_captureDevice, out _); + _captureInput.Dispose(); + } - if (_captureSession.CanAddInput(_captureInput)) - _captureSession.AddInput(_captureInput); - } - - _captureSession.SessionPreset = Methods.GetBestSupportedPreset(_captureSession, _cameraView?.CaptureQuality ?? CaptureQuality.Medium); - _captureSession.CommitConfiguration(); + _captureDevice?.Dispose(); + _captureDevice = newDevice; + + if (_captureDevice is not null) + { + _captureInput = new AVCaptureDeviceInput(_captureDevice, out _); + + if (_captureInput is not null && _captureSession.CanAddInput(_captureInput)) + _captureSession.AddInput(_captureInput); + } + + _captureSession.SessionPreset = Methods.GetBestSupportedPreset(_captureSession, _cameraView?.CaptureQuality ?? CaptureQuality.Medium); + _captureSession.CommitConfiguration(); - UpdateZoomFactor(); - ResetFocus(); - }); + UpdateZoomFactor(); + ResetFocus(); + }); + } } } @@ -194,7 +196,7 @@ internal void UpdateResolution() { if (_captureSession is not null) { - _dispatchQueue.DispatchAsync(() => + _dispatchQueue.DispatchBarrierAsync(() => { _captureSession.BeginConfiguration(); _captureSession.SessionPreset = Methods.GetBestSupportedPreset(_captureSession, _cameraView?.CaptureQuality ?? CaptureQuality.Medium); @@ -255,7 +257,7 @@ internal void UpdateZoomFactor() private void DeviceLock(Action action) { - DispatchQueue.MainQueue.DispatchAsync(() => + DispatchQueue.MainQueue.DispatchBarrierAsync(() => { if (_captureDevice?.LockForConfiguration(out _) ?? false) { @@ -314,7 +316,11 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - Stop(); + if (_captureDevice is not null && _captureDevice.TorchActive) + DeviceLock(() => _captureDevice.TorchMode = AVCaptureTorchMode.Off); + + if (_captureSession?.Running ?? false) + _dispatchQueue?.DispatchBarrierSync(_captureSession.StopRunning); if (_subjectAreaChangedNotificaion is not null) NSNotificationCenter.DefaultCenter.RemoveObserver(_subjectAreaChangedNotificaion);