Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash - IllegalStateException: maxImages (16) has already been acquired (SharedCamera) #1637

Open
DanPetras opened this issue Jan 29, 2024 · 5 comments
Labels

Comments

@DanPetras
Copy link

SPECIFIC ISSUE ENCOUNTERED

Crash from Crashlytics

VERSIONS USED

  • Android Studio: Android Studio Hedgehog | 2023.1.1 Patch 1
  • ARCore SDK for Android: 1.41.0
  • Device manufacturer, model, and O/S: Google Pixel 6 Pro, Pixel 7, Pixel 7a, Motorola - Moto G72, Vivo X90 Pro+, Oppo - PFZM10, Oneplus, Xiaomi; Android 12, 13, 14
  • Google Play Services for AR (ARCore): Unknown

STEPS TO REPRODUCE THE ISSUE

Fatal Exception: java.lang.IllegalStateException: maxImages (16) has already been acquired, call #close before acquiring more.
       at android.media.ImageReader.acquireNextImage(ImageReader.java:661)
       at android.media.ImageReader.acquireLatestImage(ImageReader.java:541)
       at com.google.ar.core.SharedCamera.lambda$setDummyOnImageAvailableListener$0(SharedCamera.java:1)
       at com.google.ar.core.SharedCamera.a(SharedCamera.java)
       at com.google.ar.core.ap.onImageAvailable(ap.java)
       at android.media.ImageReader$1.run(ImageReader.java:947)
       at android.os.Handler.handleCallback(Handler.java:958)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:205)
       at android.os.Looper.loop(Looper.java:294)
       at android.os.HandlerThread.run(HandlerThread.java:67)

WORKAROUNDS (IF ANY)

The exception can't be caught as the call is made on another thread inside the AR core lib.

ADDITIONAL COMMENTS

The app is using AR core with the shared camera feature.
The Crashlytics is reporting Device state 100% In background

@DanPetras DanPetras added the bug label Jan 29, 2024
@15kingben
Copy link

setDummyOnImageAvailableListener should not retain any images, so this is probably an issue that the acquired images are not being released from somewhere else. Are all images, either ARCore frames or images acquired from the SharedCamera, being promptly closed?

@DanPetras
Copy link
Author

We are rendering the camera preview with com.google.ar.core.Session.setCameraTextureName(OpenGL TEXTURE_EXTERNAL_OES texture name) and not calling com.google.ar.core.Frame.acquireCameraImage() at all.
We use separate android.hardware.camera2.CameraCaptureSession with separate android.media.ImageReader and closing images acquired this way as soon as possible (after converting and encoding to file).
I don't see how this affects the setDummyOnImageAvailableListener but I just might not know, can you elaborate?
Can be images acquired from setDummyOnImageAvailableListener accessed by any other means from app code that I don't know of? Thanks.

@15kingben
Copy link

This is triggered by Session.pause(), and simply puts OnImageAvailableListener to ARCore's image readers to avoid buffer starvation which does:

Image image = reader.acquireLatestImage();
if (image != null) {
  image.close();
}

So those images are not being used anywhere. However, acquireLatestImage could fail if the app has already acquired and failed to release 16 other images.

@DanPetras
Copy link
Author

How can the app acquire images from the same ImageReader that setDummyOnImageAvailableListener is using?
I'm not aware that we do such thing.

From what you wrote, it seems that the ImageReader buffer is already full when setDummyOnImageAvailableListener is called. Is the app causing this (the filled buffer) or ARCore itself?

We are using com.google.ar.core.Config.updateMode = Config.UpdateMode.LATEST_CAMERA_IMAGE (if that changes anything).

@DanPetras
Copy link
Author

I checked it several times already and I'm sure I'm closing all the images obtained by com.google.ar.core.Frame.acquireCameraImage().

Like this:

frame.acquireCameraImage().use { /* convert image to bitmap */ }

The only other images I acquire are from my own android.media.ImageReader which has maxImages set to 5, so there is no chance that I could acquire 16 images from that. I'm also pretty sure that all of those images are closed too.

Is there something else that could be acquiring those 16 images before we call com.google.ar.core.Session.pause()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants