Skip to content

Commit

Permalink
Merge pull request #864 from Redth/fix-ios-reset-config
Browse files Browse the repository at this point in the history
Reset AVCaptureDevice configurations on camera shutdown in iOS
  • Loading branch information
Redth committed Mar 14, 2020
2 parents 9e0dedd + 2195a09 commit 9a7e3bf
Showing 1 changed file with 89 additions and 33 deletions.
122 changes: 89 additions & 33 deletions ZXing.Net.Mobile/iOS/ZXingScannerView.ios.cs
Expand Up @@ -37,6 +37,7 @@ public ZXingScannerView(CGRect frame) : base(frame)
}

AVCaptureSession session;
AVCaptureDevice captureDevice = null;
AVCaptureVideoPreviewLayer previewLayer;
AVCaptureVideoDataOutput output;
OutputRecorder outputRecorder;
Expand All @@ -56,7 +57,9 @@ public ZXingScannerView(CGRect frame) : base(frame)

bool shouldRotatePreviewBuffer = false;

void Setup(CGRect frame)
AVConfigs captureDeviceOriginalConfig;

void Setup()
{
var started = DateTime.UtcNow;

Expand Down Expand Up @@ -91,7 +94,6 @@ void Setup(CGRect frame)
bool torch = false;
bool analyzing = true;


bool SetupCaptureSession()
{
var started = DateTime.UtcNow;
Expand All @@ -114,8 +116,6 @@ bool SetupCaptureSession()
};

// create a device input and attach it to the session
// var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
AVCaptureDevice captureDevice = null;
var devices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);
foreach (var device in devices)
{
Expand Down Expand Up @@ -273,9 +273,25 @@ bool SetupCaptureSession()

var perf5 = PerformanceCounter.Start();

NSError err = null;
if (captureDevice.LockForConfiguration(out err))
if (captureDevice.LockForConfiguration(out var err))
{
captureDeviceOriginalConfig = new AVConfigs
{
FocusMode = captureDevice.FocusMode,
ExposureMode = captureDevice.ExposureMode,
WhiteBalanceMode = captureDevice.WhiteBalanceMode,
AutoFocusRangeRestriction = captureDevice.AutoFocusRangeRestriction,
};

if (captureDevice.HasFlash)
captureDeviceOriginalConfig.FlashMode = captureDevice.FlashMode;
if (captureDevice.HasTorch)
captureDeviceOriginalConfig.TorchMode = captureDevice.TorchMode;
if (captureDevice.FocusPointOfInterestSupported)
captureDeviceOriginalConfig.FocusPointOfInterest = captureDevice.FocusPointOfInterest;
if (captureDevice.ExposurePointOfInterestSupported)
captureDeviceOriginalConfig.ExposurePointOfInterest = captureDevice.ExposurePointOfInterest;

if (ScanningOptions.DisableAutofocus)
{
captureDevice.FocusMode = AVCaptureFocusMode.Locked;
Expand All @@ -299,7 +315,9 @@ bool SetupCaptureSession()
captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.AutoWhiteBalance;

if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
{
captureDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near;
}

if (captureDevice.FocusPointOfInterestSupported)
captureDevice.FocusPointOfInterest = new PointF(0.5f, 0.5f);
Expand Down Expand Up @@ -489,7 +507,7 @@ public void StartScanning(Action<Result> scanResultHandler, MobileBarcodeScannin

var perf = PerformanceCounter.Start();

Setup(Frame);
Setup();

ScanningOptions = options ?? MobileBarcodeScanningOptions.Default;
resultCallback = scanResultHandler;
Expand All @@ -506,10 +524,11 @@ public void StartScanning(Action<Result> scanResultHandler, MobileBarcodeScannin
if (Runtime.Arch == Arch.SIMULATOR)
{
var simView = new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height));
simView.BackgroundColor = UIColor.LightGray;
simView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
InsertSubview(simView, 0);
InsertSubview(new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height))
{
BackgroundColor = UIColor.LightGray,
AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
}, 0);
}
});
Expand Down Expand Up @@ -540,6 +559,30 @@ public void StopScanning()
if (outputRecorder != null)
outputRecorder.CancelTokenSource.Cancel();

// Revert camera settings to original
if (captureDevice != null && captureDevice.LockForConfiguration(out var err))
{
captureDevice.FocusMode = captureDeviceOriginalConfig.FocusMode;
captureDevice.ExposureMode = captureDeviceOriginalConfig.ExposureMode;
captureDevice.WhiteBalanceMode = captureDeviceOriginalConfig.WhiteBalanceMode;

if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
captureDevice.AutoFocusRangeRestriction = captureDeviceOriginalConfig.AutoFocusRangeRestriction;

if (captureDevice.FocusPointOfInterestSupported)
captureDevice.FocusPointOfInterest = captureDeviceOriginalConfig.FocusPointOfInterest;

if (captureDevice.ExposurePointOfInterestSupported)
captureDevice.ExposurePointOfInterest = captureDeviceOriginalConfig.ExposurePointOfInterest;

if (captureDevice.HasFlash)
captureDevice.FlashMode = captureDeviceOriginalConfig.FlashMode;
if (captureDevice.HasTorch)
captureDevice.TorchMode = captureDeviceOriginalConfig.TorchMode;

captureDevice.UnlockForConfiguration();
}

//Try removing all existing outputs prior to closing the session
try
{
Expand Down Expand Up @@ -572,34 +615,35 @@ public void Torch(bool on)
{
try
{
NSError err;

var device = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);

if (device.HasTorch || device.HasFlash)
var device = captureDevice ?? AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
if (device != null && (device.HasTorch || device.HasFlash))
{
device.LockForConfiguration(out var err);

device.LockForConfiguration(out err);

if (on)
if (err != null)
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.On;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.On;
if (on)
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.On;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.On;
}
else
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.Off;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.Off;
}
}
else

try
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.Off;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.Off;
device.UnlockForConfiguration();
}

device.UnlockForConfiguration();
catch { }
}
device = null;


torch = on;
}
Expand Down Expand Up @@ -636,11 +680,23 @@ public bool HasTorch
if (hasTorch.HasValue)
return hasTorch.Value;

var device = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
var device = captureDevice ?? AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
hasTorch = device.HasFlash || device.HasTorch;
return hasTorch.Value;
}
}
#endregion
}

struct AVConfigs
{
public AVCaptureFocusMode FocusMode;
public AVCaptureExposureMode ExposureMode;
public AVCaptureWhiteBalanceMode WhiteBalanceMode;
public AVCaptureAutoFocusRangeRestriction AutoFocusRangeRestriction;
public CGPoint FocusPointOfInterest;
public CGPoint ExposurePointOfInterest;
public AVCaptureFlashMode FlashMode;
public AVCaptureTorchMode TorchMode;
}
}

0 comments on commit 9a7e3bf

Please sign in to comment.