首页 > 解决方案 > 垃圾邮件 W/ImageReader_JNI:无法获取缓冲区项,很可能客户端试图获取超过 maxImages 缓冲区

问题描述

我在使用 Camera2 API 和 Google MLKit 时遇到了问题。目前,我尝试做的只是在检测到面部时记录一条消息。但我有这个问题:

它在控制台上发送垃圾邮件:

W/ImageReader_JNI: Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers

然后使我的应用程序崩溃:

java.lang.IllegalStateException: maxImages (2) has already been acquired, call #close before acquiring more.

但正如谷歌对 CameraX 的建议(我使用 Camera2,但我必须做同样的事情),我在 addOnCompleteListener 中关闭了使用 image.close() 获得的图像。

这是我来自图像阅读器的代码:

val imageReader = ImageReader.newInstance(rotatedPreviewWidth, rotatedPreviewHeight,
    ImageFormat.YUV_420_888, 2)

    imageReader.setOnImageAvailableListener({
        it.acquireLatestImage()?.let { image ->

            val mlImage = InputImage.fromMediaImage(image, getRotationCompensation(cameraDevice.id, getInstance(), true))


            val result = detector.process(mlImage)
                 .addOnSuccessListener {faces ->
                     if (faces.size > 0)
                         Log.d("photo", "Face found!")
                     else
                         Log.d("photo", "No face have been found")
                     }
                     .addOnFailureListener { e ->
                         Log.d("photo", "Error: $e")
                     }
                     .addOnCompleteListener {
                         image.close()
                     }
                 }
             }, Handler { true })

我认为正在发生的是:

由于 google 的处理可能很慢,所以在调用 acquireLatestImage() 获取新图像之前不会调用 addOnCompleteListener。

但我不知道如何防止这种情况:(,有人知道吗?或者我对这个问题的假设是错误的?

而且为了防止崩溃,我将 maxImages 增加到 4,现在它只是在发送垃圾邮件“W/ImageReader_JNI:无法获取缓冲区项,很可能客户端试图获取超过 maxImages 缓冲区”一段时间(然后停止) 但没有崩溃。

但我认为这种解决方案是一种隐藏问题而不是解决问题的方法。

编辑:增加 maxImages 数量只会延迟稍后仍然发生的崩溃。

标签: androidkotlinandroid-camera2google-mlkit

解决方案


image.close 方法真的被调用了吗?您很可能需要同时获取几个缓冲区,但如果 4 个还不够,您可能在扫描完成时没有释放它们。但也许处理速度很慢,您需要更多的缓冲区才能并行使用。

请注意,如果处理无法跟上帧速率,您可能需要手动丢帧以确保不会阻塞帧流。


推荐阅读