托管相机服务的流程意外死亡

时间:2016-07-13 13:15:49

标签: java android java-native-interface yuv android-camera2

我已尝试过所有内容,但我找不到为什么我的相机应用程序会让我失去服务异常的原因。

情况就是这样。我正在使用HDR jni库,我已经检查过它并且工作正常,它不是本机内存的内存引导,并且它不是jni问题。所以,问题必须出在我的代码中:

我只是等待CaptureResult给我一个AE_CONVERGED_STATE来检查传感器是否已经接受正确的曝光,然后我调用我的方法:

    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;
        }

这是我的YUV方法:

 /**
 * 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();
                }

            }
        }
    }

我总共挑选了三张照片然后调用了我的JNI库的合并方法。我试图评论所有的jni代码并且它仍然在发生,所以我认为可能问题必须在这里,在我的YUV方法中或者在Burst HDR调用中。

最后这是发生时的日志错误:

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

有时它只需要2张照片,有时只需要300张,但最后还是会发生。此外,很多时候我的设备几乎已经死了,任何工作都很好,所以我需要重新启动手机。

1 个答案:

答案 0 :(得分:1)

最后问题是因为我的ImageReader配置错误,根据手机的硬件级别,相机可以允许每种不同尺寸的不同类型的图像阅读器。 例如,INFO_SUPPORTED_HARDWARE_LEVEL == FULL不支持配置为设备最大尺寸的JPEG图像阅读器,另一个支持YUV格式的JPEG图像阅读器。无论如何,有时它可以工作,有时会失败。

  

如果应用程序尝试使用超出下表中所述限制的一组目标创建会话,则可能会出现三种可能性之一。首先,可以成功创建会话并正常工作。其次,可以成功创建会话,但是相机设备不符合getOutputMinFrameDuration(int,Size)中描述的帧速率保证。或者第三,如果根本无法使用输出集,则会调用onConfigureFailed(CameraCaptureSession),会话创建将完全失败。

引自:https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html

这意味着当我的JPEG imageReader配置为相同大小时,我的设备无法将YUV图像阅读器配置为4608x3456大小。它只能支持我的预览尺寸(1920x1080)。您可以在此link中检查所有可能的配置。