【问题标题】:Spamming W/ImageReader_JNI: Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers垃圾邮件 W/ImageReader_JNI:无法获取缓冲区项,很可能客户端试图获取超过 maxImages 缓冲区
【发布时间】:2021-01-22 18:15:06
【问题描述】:

我在使用 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 数量只会延迟稍后仍会发生的崩溃。

【问题讨论】:

    标签: android kotlin android-camera2 google-mlkit


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      根据 MLKit 开发者指南中的最佳实践: “如果您使用 Camera 或 camera2 API,请限制对检测器的调用。如果在检测器运行时有新的视频帧可用,请丢弃该帧。请参阅快速入门示例应用程序中的 VisionProcessorBase 类以获取示例。”

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

      【讨论】:

      • 感谢您的回答!我将创建一个类变量“isProcessing”,当它为假时我运行它,否则我只是关闭图像。
      猜你喜欢
      • 2016-07-25
      • 2012-09-17
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多