Search code examples
javaandroidjava-native-interfaceyuvandroid-camera2

Process hosting the camera service has died unexpectedly


I have tried everything and I don't find a reason for why my Camera app is throwing me a dead service exception.

Here is the case. I'm using a HDR jni library, which I already check and it works fine, It's not a memory lead of native memory, and it's not a jni problem. So, the problem must to be in my code:

I'm just waiting to the CaptureResult to return me a AE_CONVERGED_STATE to check if the sensor already take the correct exposure and then I call my method:

    Log.performanceEnd("YUV capture");
        Log.d(TAG, "[onImageAvailable] YUV capture, mBurstCount: " + mBurstCount);
        Image image = imageReader.acquireNextImage();
        if (mBackgroundHandler != null) {
            mBackgroundHandler.post(new YuvCopy(image, mBurstCount));
        }
        mBurstCount++;

        if (mBurstState == BURST_STATE_HDR) {
            switch (mBurstCount) {
                case 1:
                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, HDR_EXPOSURE_COMPENSATION_VALUE_HIGH);
                    break;
                case 2:
                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, HDR_EXPOSURE_COMPENSATION_VALUE_LOW);
                    break;
                case 3:
                    //Restore exposure compensation value
                    mCaptureCallback = mPhotoCaptureCallback;
                    mSettingsManager.setExposureCompensation(mPreviewRequestBuilder);
                    mActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            onPictureCaptured();
                        }
                    });
                    unlockFocus();
                    break;
            }
            if (mBurstCount != 3) {
                updatePreviewSession();
            }
            //Finish HDR session
            if (mBurstCount < YUV_BURST_LIMIT) mHdrState = STATE_PICTURE_TAKEN;
        }

Here is my YUV method:

 /**
 * Transform YUV420 to NV21 readable frames
 */
private class YuvCopy implements Runnable {
    private final Image mImage;
    private final int mPictureIndex;

    public YuvCopy(Image image, int index) {
        mImage = image;
        mPictureIndex = index;
    }

    @Override
    public void run() {
        if (mImage != null) {
            if (mImage.getWidth() * mImage.getHeight() > 0) {
                Image.Plane[] planes = mImage.getPlanes();                   

                long startCopy = System.currentTimeMillis();

                int width = mImage.getWidth();
                int height = mImage.getHeight();
                int ySize = width * height;
                ByteBuffer yBuffer = mImage.getPlanes()[0].getBuffer();
                ByteBuffer uvBuffer = mImage.getPlanes()[1].getBuffer();
                ByteBuffer vuBuffer = mImage.getPlanes()[2].getBuffer();
                byte[] mData = new byte[ySize + (ySize / 2)];
                yBuffer.get(mData, 0, ySize);
                vuBuffer.get(mData, ySize, (ySize / 2) - 1);
                mData[mData.length - 1] = uvBuffer.get(uvBuffer.capacity() - 1);
                mImage.close();

                mHdrCaptureArray[mPictureIndex] = mData;

                Log.i(TAG, "[YuvCopy|run] Time to Copy data: " + (System.currentTimeMillis() - startCopy) + "ms");

                if (mPictureIndex == YUV_BURST_LIMIT - 1) {
                    startHdrProcessing();

                } else {
                    mImage.close();
                }

            }
        }
    }

I pick a total of three photos and then I call my merge method of my JNI library. I tried to comment all the jni code and it still happening, so I think that possibly the problem must to be here, in my YUV method or maybe in the Burst HDR call.

Finally here is my log error when it happends:

01-01 12:30:27.531 21945-21957/com.myCamera W/AudioSystem: AudioFlinger server died!
01-01 12:30:27.532 21945-22038/com.myCamera W/AudioSystem: AudioPolicyService server died!
1-01 12:30:27.903 21945-21978/com.myCamera I/CameraManagerGlobal: Connecting to camera service
01-01 12:30:27.903 21945-21978/com.myCamera E/CameraManagerGlobal: Camera service is unavailable
01-01 12:30:27.903 21945-21978/com.myCamera W/System.err: android.hardware.camera2.CameraAccessException: Camera service is currently unavailable
01-01 12:30:29.103 21945-21945/com.myCamera W/System.err: android.hardware.camera2.CameraAccessException: Process hosting the camera service has died unexpectedly

Sometimes it take just 2 photos, and sometimes 300, but in the end, it still happening. Also, a lot of times all my device is almost dead and anything work's really fine, so I need to reboot my phone.


Solution

  • Finally the problem was caused because I had a wrong configuration of my ImageReaders, depending of the Hardware level of the Phone, the camera can allow different types of imageReaders with different sizes for each one. For example, a INFO_SUPPORTED_HARDWARE_LEVEL == FULL doesn't support a JPEG image reader configurated to the max size of the device and another one with YUV format over the preview size in that moment. Anyway, sometimes it can work, and sometimes fail.

    If an application tries to create a session using a set of targets that exceed the limits described in the below tables, one of three possibilities may occur. First, the session may be successfully created and work normally. Second, the session may be successfully created, but the camera device won't meet the frame rate guarantees as described in getOutputMinFrameDuration(int, Size). Or third, if the output set cannot be used at all, session creation will fail entirely, with onConfigureFailed(CameraCaptureSession) being invoked.

    Quote from: https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html

    That means that my device can't have a YUV image reader configurated to 4608x3456 size when my JPEG imageReader is configurated to the same size too. It can only support my preview size(1920x1080). You can check all the possible configurations in this link.