Camera2 Session 不支持 MediaCodec 的持久输入表面?
MediaCodec's Persistent Input Surface unsupported by Camera2 Session?
我正在编写一个 Android 应用程序,它支持保存 RAW/JPEG 并同时录制视频。我在创建 CameraCaptureSession
时尝试传递 4 个表面:预览、由 MediaCodec#createPersistentInputSurface
创建的 2x ImageSaver
和 1x PersistentInputSurface
。通过使用持久输入表面,我打算避免 2 次捕获之间的中断。
创建会话时失败:
W/CameraDevice-JV-0: Stream configuration failed due to: endConfigure:380: Camera 0: Unsupported set of inputs/outputs provided
Session 0: Failed to create capture session; configuration failed
我试过去掉所有其他表面,只留下PersistentInputSurface
,仍然失败。
@Override
public void onResume() {
super.onResume();
//Some other setups...
if (persistentRecorderSurface == null) {
persistentRecorderSurface = MediaCodec.createPersistentInputSurface();
}
startBackgroundThread();
startCamera();
if (mPreviewView.isAvailable()) {
configureTransform(mPreviewView.getWidth(), mPreviewView.getHeight());
} else {
mPreviewView.setSurfaceTextureListener(mSurfaceTextureListener);
}
if (mOrientationListener != null && mOrientationListener.canDetectOrientation()) {
mOrientationListener.enable();
}
}
private void createCameraPreviewSessionLocked() {
try {
SurfaceTexture texture = mPreviewView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
mPreviewRequestBuilder = mBackCameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mBackCameraDevice.createCaptureSession(Arrays.asList(
surface,
mJpegImageReader.get().getSurface(),
mRAWImageReader.get().getSurface(),
persistentRecorderSurface
), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
synchronized (mCameraStateLock) {
if (mBackCameraDevice == null) {
return;
}
try {
setup3AControlsLocked(mPreviewRequestBuilder);
session.setRepeatingRequest(mPreviewRequestBuilder.build(),
mPreCaptureCallback, mBackgroundHandler);
mState = CameraStates.PREVIEW;
} catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
return;
}
mSession = session;
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
showToast("Failed to configure camera.");
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
查看错误行之前的系统日志行以进行确认会很有帮助,但最有可能的是:
您需要实际将 persistentRecorderSurface 绑定到 MediaRecorder or MediaCodec,并在创建相机捕获会话之前对其调用 prepare()。
否则,持久表面的另一端实际上什么也没有,相机无法判断需要什么分辨率或其他设置。
另请注意,根据相机支持的硬件级别和功能,您可以从相机获得的并发输出数量是有限的。目前没有要求设备必须支持您的输出组合(预览、记录、JPEG、RAW),不幸的是,所以很可能许多或所有设备仍然会给您一个错误。
我正在编写一个 Android 应用程序,它支持保存 RAW/JPEG 并同时录制视频。我在创建 CameraCaptureSession
时尝试传递 4 个表面:预览、由 MediaCodec#createPersistentInputSurface
创建的 2x ImageSaver
和 1x PersistentInputSurface
。通过使用持久输入表面,我打算避免 2 次捕获之间的中断。
创建会话时失败:
W/CameraDevice-JV-0: Stream configuration failed due to: endConfigure:380: Camera 0: Unsupported set of inputs/outputs provided
Session 0: Failed to create capture session; configuration failed
我试过去掉所有其他表面,只留下PersistentInputSurface
,仍然失败。
@Override
public void onResume() {
super.onResume();
//Some other setups...
if (persistentRecorderSurface == null) {
persistentRecorderSurface = MediaCodec.createPersistentInputSurface();
}
startBackgroundThread();
startCamera();
if (mPreviewView.isAvailable()) {
configureTransform(mPreviewView.getWidth(), mPreviewView.getHeight());
} else {
mPreviewView.setSurfaceTextureListener(mSurfaceTextureListener);
}
if (mOrientationListener != null && mOrientationListener.canDetectOrientation()) {
mOrientationListener.enable();
}
}
private void createCameraPreviewSessionLocked() {
try {
SurfaceTexture texture = mPreviewView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
mPreviewRequestBuilder = mBackCameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mBackCameraDevice.createCaptureSession(Arrays.asList(
surface,
mJpegImageReader.get().getSurface(),
mRAWImageReader.get().getSurface(),
persistentRecorderSurface
), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
synchronized (mCameraStateLock) {
if (mBackCameraDevice == null) {
return;
}
try {
setup3AControlsLocked(mPreviewRequestBuilder);
session.setRepeatingRequest(mPreviewRequestBuilder.build(),
mPreCaptureCallback, mBackgroundHandler);
mState = CameraStates.PREVIEW;
} catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
return;
}
mSession = session;
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
showToast("Failed to configure camera.");
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
查看错误行之前的系统日志行以进行确认会很有帮助,但最有可能的是:
您需要实际将 persistentRecorderSurface 绑定到 MediaRecorder or MediaCodec,并在创建相机捕获会话之前对其调用 prepare()。
否则,持久表面的另一端实际上什么也没有,相机无法判断需要什么分辨率或其他设置。
另请注意,根据相机支持的硬件级别和功能,您可以从相机获得的并发输出数量是有限的。目前没有要求设备必须支持您的输出组合(预览、记录、JPEG、RAW),不幸的是,所以很可能许多或所有设备仍然会给您一个错误。