我已经尝试了所有方法,但我找不到为什么我的相机应用程序给我抛出一个死服务异常的原因。
情况是这样的。我正在使用 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 方法中,或者可能在突发 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 张照片,但最终,它仍然会发生。此外,很多时候我的所有设备几乎都没电了,任何工作都很好,所以我需要重新启动手机。
最后,由于我的ImageReader配置错误,根据手机的硬件级别,相机可以允许不同类型的imageReader,每个图像阅读器具有不同的尺寸。例如,一个INFO_SUPPORTED_HARDWARE_LEVEL == FULL
不支持配置为设备最大大小的 JPEG 图像阅读器,而另一个在当时的预览大小上具有 YUV 格式的图像读取器。无论如何,有时它可以工作,有时可以失败。
如果应用程序尝试使用一组超出下表中所述限制的目标创建会话,则可能会出现以下三种可能性之一。首先,会话可能已成功创建并正常工作。其次,会话可能已成功创建,但相机设备不满足 getOutputMinFrameDuration(int, Size) 中所述的帧速率保证。第三,如果输出集根本无法使用,会话创建将完全失败,并调用onConfigureFailed(CameraCaptureSession)。
引用自: https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html
这意味着当我的 JPEG 图像阅读器也配置为相同大小时,我的设备无法将 YUV 图像阅读器配置为 4608x3456 大小。它只能支持我的预览尺寸(1920x1080)。您可以在此链接中检查所有可能的配置。