垃圾邮件 W/ImageReader_JNI:无法获取缓冲区项,很可能客户端试图获取超过 maxImages 个缓冲区

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

我在使用 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.

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

这是我从图片中提取的代码 reader:

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 数量只是延迟了以后仍然发生的崩溃。

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

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

根据 MLKit 开发人员指南中的最佳实践: “如果您使用相机或相机 2 API,请限制对检测器的调用。如果在检测器 运行 时有新的视频帧可用,请丢弃该帧。请参阅 VisionProcessorBase class 在快速入门示例应用程序中作为示例。"

https://developers.google.com/ml-kit/vision/object-detection/android