Camera analysis only entering to analyze method in ImageAnalysis.Analyzer only once, in Xiaomi Mi a20 Lite

Issue

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()
                    }
        }
    }

Solution

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.

Answered By – Facundo Farall

Leave a Comment