[SOLVED] CameraDevice::takeStillPicture() stuck on Status::pendingExposurePrecapture

Hi Android gurus,

I’m using CameraDevice::takeStillPicture() to capture images from the phone camera(s). On my ominous Google Pixel 3XL this sometimes just never triggers the callback when called. So I turned on camera logging to see where it fails and it seems that sometimes, the StillPictureTaker state gets stuck on State::pendingFocusLock or State::pendingExposurePrecapture.

When it fails on pendingExposurePrecapture this is what happens:

                    case State::pendingExposurePrecapture:
                    {
                        JUCE_CAMERA_LOG ("Still picture capture, updateState(), State::pendingExposurePrecapture...");

                        auto controlAeStateIntValue = getControlAEState (captureResult);
                        static constexpr int controlAeStateFlashRequired = 4;
                        static constexpr int controlAeStatePrecapture = 5;
                        JUCE_CAMERA_LOG ("controlAeStateIntValue: " + String(controlAeStateIntValue));
                        if (controlAeStateIntValue == -1 || controlAeStateIntValue == controlAeStateFlashRequired
                                                         || controlAeStateIntValue == controlAeStatePrecapture)
                        {
                            currentState = State::pendingExposurePostPrecapture;
                        }

                        break;
                    }

The controlAeStateIntValue is set to 5 when that happens, which means currentState is updated to pendingExposurePostPrecapture, but then nothing else happens and it just stops there.

Any ideas what could be going on here? The problem can only be remedied by restarting the camera device… either it works after starting the camera, or it doesn’t, it never works and then stops…

If anyone encounters problems with this, don’t make this mistake:

For iOS I was managing the lifetime of the CameraDevice in a

static inline std::unique_ptr<CameraDevice> currentCamera;

I’m doing this, so it doesn’t block when I destroy a component that holds a camera device. (And manage the deletion manually…). On Android this results in undefined behaviour. Making this a non-static class member on Android instead did the trick and also on Android the Camera Device doesn’t block when closing, so problem solved