Search code examples
androidandroid-cameraxxiaomi

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


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.