The analysis works fine in every other Android phone I've tried (Huawei Mate 20 Pro, Samsung S8, Samsung J7 and Samsung S10+), but not in the Xiaomi Mi a20 Lite. It only enters once the the analyze
function and then in the Logcat throws:
E/ImageAnalysisAnalyzer: Failed to acquire image.
java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more.
I've built the analyser like this, because we want it to bring a new frame only when the one in the queue has been processed:
val imageAnalysis = builder
.setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER)
.setImageQueueDepth(1)
.build()
In the analyze
function we make sure to close the image
, but the error comes up nonetheless in this particular Xiaomi device:
@SuppressLint("UnsafeOptInUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image
if (mediaImage != null) {
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
val scanner = BarcodeScanning.getClient(options)
scanner.process(image)
.addOnSuccessListener { barcodes: List<Barcode?> ->
if (barcodes.isNotEmpty()) {
EventBus.getDefault().post(OnRetrievedSuccess(barcodes))
}
image.mediaImage?.close()
imageProxy.close()
}
.addOnFailureListener {
EventBus.getDefault().post(OnRetrievedFailure())
image.mediaImage?.close()
imageProxy.close()
}
}
}
The problem was solved changing the image strategy when building:
val imageAnalysis = builder
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setImageQueueDepth(1)
.build()
Seemed more reasonable to process one frame and then ask another, but with this strategy it worked fine in every phone.