我已尝试过所有内容,但我找不到为什么我的相机应用程序会让我失去服务异常的原因。
情况就是这样。我正在使用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张,但最后还是会发生。此外,很多时候我的设备几乎已经死了,任何工作都很好,所以我需要重新启动手机。
答案 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中检查所有可能的配置。