Java 基于camera2 API的应用程序由于图像读取器表面而在某些设备中崩溃
我有一个神秘的安卓问题(至少在我看来)。我的应用程序通过camera2 api库管理设备的摄像头。在我的例子中,我有两个曲面,其中一个来自图像读取器对象。接下来,我定义捕获会话并将这些曲面设置为目标。正如您在下面的代码中所看到的,在这种情况下,我遵循典型的工作流:Java 基于camera2 API的应用程序由于图像读取器表面而在某些设备中崩溃,java,android,android-camera,android-camera2,Java,Android,Android Camera,Android Camera2,我有一个神秘的安卓问题(至少在我看来)。我的应用程序通过camera2 api库管理设备的摄像头。在我的例子中,我有两个曲面,其中一个来自图像读取器对象。接下来,我定义捕获会话并将这些曲面设置为目标。正如您在下面的代码中所看到的,在这种情况下,我遵循典型的工作流: // Create ImageReader Surface int max = 2; mReader = ImageReader.newInstance(mWidth, mHeight,
// Create ImageReader Surface
int max = 2;
mReader = ImageReader.newInstance(mWidth, mHeight, ImageFormat.YV12, max);
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader mReader) {
Image image = null;
image = mReader.acquireLatestImage();
if (image == null) {
return;
}
byte[] bytes = convertYUV420ToNV21(image);
nativeVideoFrame(bytes);
image.close();
}
};
if (OPENGL_SOURCE==2){
nativeVideoInit(mWidth, mHeight, 0, false);
}
mReader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
// Create Texture Surface
texture = createTexture();
mSurfaceTexture = new SurfaceTexture(texture);
mSurfaceTexture.setOnFrameAvailableListener(this);
mSurfaceTexture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
mSurface = new Surface(mSurfaceTexture);
//Attach surfaces to CaptureRequest
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(mReader.getSurface());
outputSurfaces.add(mSurface);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(mSurface);
captureRequestBuilder.addTarget(mReader.getSurface());
//Define the capture request
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
//创建ImageReader曲面
int max=2;
mReader=ImageReader.newInstance(mWidth,mHeight,ImageFormat.YV12,max);
ImageReader.OnImageAvailableListener readerListener=新建ImageReader.OnImageAvailableListener(){
@凌驾
公共图像可用(图像阅读器mReader){
图像=空;
image=mReader.acquiredlatestimage();
if(image==null){
返回;
}
byte[]bytes=convertYUV420ToNV21(图像);
本地视频帧(字节);
image.close();
}
};
如果(OPENGL_源代码==2){
nativeVideoInit(mWidth,mHeight,0,false);
}
mReader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
//创建纹理曲面
纹理=createTexture();
mSurfaceTexture=新的表面纹理(纹理);
mSurfaceTexture.setOnFrameAvailableListener(此);
mSurfaceTexture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
mSurface=新曲面(mSurfaceTexture);
//将曲面附加到CaptureRequest
List outputSurfaces=新的ArrayList(2);
add(mReader.getSurface());
outputSurfaces.add(mSurface);
captureRequestBuilder=cameraDevice.createCaptureRequest(cameraDevice.TEMPLATE\u预览);
captureRequestBuilder.addTarget(mSurface);
addTarget(mReader.getSurface());
//定义捕获请求
cameraDevice.createCaptureSession(outputSurfaces,新的CameraCaptureSession.StateCallback(){
@凌驾
未配置公共void(@NonNull CameraCaptureSession CameraCaptureSession){
//摄像机已经关上了
如果(null==cameraDevice){
返回;
}
//当会话准备就绪时,我们开始显示预览。
cameraCaptureSessions=cameraCaptureSession;
updatePreview();
}
@凌驾
已配置公用void onconfig(@NonNull CameraCaptureSession CameraCaptureSession){
Toast.makeText(MainActivity.this,“配置更改”,Toast.LENGTH_SHORT.show();
}
},空);
}捕获(CameraAccessE异常){
e、 printStackTrace();
}
问题是,在我的平板电脑Samsung TAB A上运行此代码没有任何问题。但是,当在我的Nexus 5X或我朋友的Samsung S6上尝试时,应用程序突然崩溃,抛出以下错误:
08-23 11:28:51.772:E/AndroidRuntime(20315):致命异常:主
08-23 11:28:51.772:E/AndroidRuntime(20315):进程:com.example.opengltest,PID:20315
08-23 11:28:51.772:E/AndroidRuntime(20315):java.lang.IllegalArgumentException:传递给摄影机服务的参数不正确
08-23 11:28:51.772:E/AndroidRuntime(20315):在android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:114)
做一些测试,我发现问题来自图像阅读器表面。如果我从捕获会话的设置中去掉这个表面,代码将无缝运行
为什么这只发生在我的Nexus 5x或三星S6上,而不发生在我的平板电脑上?我怎样才能修好它
谢谢
JM如果查看整个系统日志,则摄像头服务应具有 更详细的行说明了输出曲面集不好的原因 然而,YV12并不是一种保证支持的格式,所以它可能就是这样。有些设备支持,有些不支持 唯一保证所有设备都支持的YUV格式是
如果您想在可能的情况下使用YV12,在尝试使用之前,您需要检查列表以查看是否列出了它。但是,在许多设备上,您仍然需要回到YUV_420_888,因此直接支持该功能而不支持其他功能是最简单的。如果查看整个系统日志,相机服务应该有一个 更详细的行说明了输出曲面集不好的原因 然而,YV12并不是一种保证支持的格式,所以它可能就是这样。有些设备支持,有些不支持 唯一保证所有设备都支持的YUV格式是
如果您想在可能的情况下使用YV12,在尝试使用之前,您需要检查列表以查看是否列出了它。但在许多设备上,您仍然需要回到YUV_420_888,因此,直接支持它而不支持其他功能是最简单的。这正是您所说的。那些设备不支持YV12格式,这正是你所说的。这些设备不支持YV12格式