Jørgen P. Tjernø

iOS: Respect detectionTimeout

- Respect `detectionTimeout` on iOS devices, instead of arbitrarily
  waiting 10 frames
- Don't start a second scan until the first one is done, to keep memory
  usage more fixed if the device is slow
@@ -27,6 +27,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -27,6 +27,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
27 27
28 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates 28 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates
29 29
  30 + var timeoutSeconds: Double = 0
  31 +
30 32
31 // var analyzeMode: Int = 0 33 // var analyzeMode: Int = 0
32 var analyzing: Bool = false 34 var analyzing: Bool = false
@@ -90,8 +92,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -90,8 +92,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
90 return Unmanaged<CVPixelBuffer>.passRetained(latestBuffer) 92 return Unmanaged<CVPixelBuffer>.passRetained(latestBuffer)
91 } 93 }
92 94
93 - var i = 0  
94 - 95 + var nextScanTime = 0.0
  96 + var imagesCurrentlyBeingProcessed = 0
95 97
96 // Gets called when a new image is added to the buffer 98 // Gets called when a new image is added to the buffer
97 public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { 99 public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
@@ -106,14 +108,18 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -106,14 +108,18 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
106 latestBuffer = imageBuffer 108 latestBuffer = imageBuffer
107 registry.textureFrameAvailable(textureId) 109 registry.textureFrameAvailable(textureId)
108 110
109 - if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && i > 10 || detectionSpeed == DetectionSpeed.unrestricted) {  
110 - i = 0 111 + let currentTime = Date.now.timeIntervalSince1970
  112 + let eligibleForScan = currentTime > nextScanTime && imagesCurrentlyBeingProcessed == 0;
  113 + if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) {
  114 + nextScanTime = currentTime + timeoutSeconds
  115 + imagesCurrentlyBeingProcessed += 1
111 let imageRequestHandler = VNImageRequestHandler( 116 let imageRequestHandler = VNImageRequestHandler(
112 cvPixelBuffer: latestBuffer, 117 cvPixelBuffer: latestBuffer,
113 orientation: .right) 118 orientation: .right)
114 119
115 do { 120 do {
116 try imageRequestHandler.perform([VNDetectBarcodesRequest { (request, error) in 121 try imageRequestHandler.perform([VNDetectBarcodesRequest { (request, error) in
  122 + imagesCurrentlyBeingProcessed -= 1
117 if error == nil { 123 if error == nil {
118 if let results = request.results as? [VNBarcodeObservation] { 124 if let results = request.results as? [VNBarcodeObservation] {
119 for barcode in results { 125 for barcode in results {
@@ -142,8 +148,6 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -142,8 +148,6 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
142 } catch { 148 } catch {
143 print(error) 149 print(error)
144 } 150 }
145 - } else {  
146 - i+=1  
147 } 151 }
148 } 152 }
149 153
@@ -220,7 +224,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -220,7 +224,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
220 let torch: Bool = argReader.bool(key: "torch") ?? false 224 let torch: Bool = argReader.bool(key: "torch") ?? false
221 let facing: Int = argReader.int(key: "facing") ?? 1 225 let facing: Int = argReader.int(key: "facing") ?? 1
222 let speed: Int = (call.arguments as! Dictionary<String, Any?>)["speed"] as? Int ?? 0 226 let speed: Int = (call.arguments as! Dictionary<String, Any?>)["speed"] as? Int ?? 0
  227 + let timeoutMs: Int = (call.arguments as! Dictionary<String, Any?>)["timeout"] as? Int ?? 0
223 228
  229 + timeoutSeconds = timeoutMs * 1000.0
224 detectionSpeed = DetectionSpeed(rawValue: speed)! 230 detectionSpeed = DetectionSpeed(rawValue: speed)!
225 231
226 // Set the camera to use 232 // Set the camera to use