Android camera2 连拍速度太慢
Android camera2 capture burst is too slow
我正在尝试修改 android-Camera2Basic 代码以捕捉连拍照片。但是,在我的 Nexus 5 运行 L 5.0.1.
上,我的图片之间的延迟不能超过 200-300 毫秒
我已经尝试了很多东西,但这是最基本的。这是我修改的 Camera2Basic 代码的唯一部分。我的预览 TextureView 只有 50x50dp,但这应该没关系吧?
对于它的价值,这段代码在我的 Nexus 6 上只有大约 50-100 毫秒的延迟,L 5.1。
private void captureStillPicture() {
try {
List<CaptureRequest> captureList = new ArrayList<CaptureRequest>();
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
for (int i=0;i<10;i++) {
captureList.add(mPreviewRequestBuilder.build());
}
mCaptureSession.stopRepeating();
mCaptureSession.captureBurst(captureList, cameraCaptureCallback, null);
mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
CameraCaptureSession.CaptureCallback cameraCaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
Log.d("camera","saved");
mPictureCounter++;
if (mPictureCounter >= 10)
unlockFocus();
}
};
尝试设置以下抓包请求参数
requestBuilder = camDevice
.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
requestBuilder.set(CaptureRequest.EDGE_MODE,
CaptureRequest.EDGE_MODE_OFF);
requestBuilder.set(
CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON);
requestBuilder.set(
CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_OFF);
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
我不确定信息进入 CameraCaptureSession.CaptureCallback 的速度有多快。它没有图像数据,可以在ImageReader.OnImageAvailableListener之前或之后调用。
尝试测量 ImageReader.OnImageAvailableListener 次调用之间的时间。
并且不要忘记读取图像并释放它们,因为如果缓冲区已满且未释放图像,则新图像不可用。例如:
private class imageAvailableListener implements
ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader ir) {
Log.i(TAG, "Time = " + System.currentTimeMillis());
Image im = ir.acquireNextImage();
im.close();
}
}
ImageReader mImageReader = ImageReader.newInstance(imageReaderWidth,
imageReaderHeight, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(
new imageAvailableListener(), null);
您 运行 遇到的问题是您请求的图像输出格式的伪影。 JPEG 编码过程会在相机流水线中放置大量停滞时间,因此在进行此编码时,在一次曝光结束和下一次曝光开始之间存在大量停机时间。
所引用的 30fps 速率可以通过将 ImageReader
上的输出图像格式设置为 YUV 来实现,因为这是相机的更多 "native" 输出。这将是在捕获图像时存储图像的方式,然后您必须在之后进行 JPEG 编码,与相机的内联处理分开。
例如,在 Nexus 5 上,JPEG
编码的输出停顿时间为 243 毫秒,您一直在观察。对于 YUV_420_888
输出,它是 0ms。同样,由于它们的尺寸较大,RAW_SENSOR
编码引入了 200 毫秒的停顿时间。
另请注意,即使您通过选择 "faster" 格式消除了延迟时间障碍,仍然存在最小帧时间,具体取决于输出图像大小。但是对于 Nexus 5 的全分辨率输出,这是 33 毫秒,这是您所期望的。
相关信息在相机元数据的 StreamConfigurationMap
对象中,here。查看 getOutputStallDuration(int format, Size size)
和 getOutputMinFrameDuration(int format, Size size)
方法进行确认。
我正在尝试修改 android-Camera2Basic 代码以捕捉连拍照片。但是,在我的 Nexus 5 运行 L 5.0.1.
上,我的图片之间的延迟不能超过 200-300 毫秒我已经尝试了很多东西,但这是最基本的。这是我修改的 Camera2Basic 代码的唯一部分。我的预览 TextureView 只有 50x50dp,但这应该没关系吧?
对于它的价值,这段代码在我的 Nexus 6 上只有大约 50-100 毫秒的延迟,L 5.1。
private void captureStillPicture() {
try {
List<CaptureRequest> captureList = new ArrayList<CaptureRequest>();
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
for (int i=0;i<10;i++) {
captureList.add(mPreviewRequestBuilder.build());
}
mCaptureSession.stopRepeating();
mCaptureSession.captureBurst(captureList, cameraCaptureCallback, null);
mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
CameraCaptureSession.CaptureCallback cameraCaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
Log.d("camera","saved");
mPictureCounter++;
if (mPictureCounter >= 10)
unlockFocus();
}
};
尝试设置以下抓包请求参数
requestBuilder = camDevice
.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
requestBuilder.set(CaptureRequest.EDGE_MODE,
CaptureRequest.EDGE_MODE_OFF);
requestBuilder.set(
CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON);
requestBuilder.set(
CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_OFF);
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
我不确定信息进入 CameraCaptureSession.CaptureCallback 的速度有多快。它没有图像数据,可以在ImageReader.OnImageAvailableListener之前或之后调用。 尝试测量 ImageReader.OnImageAvailableListener 次调用之间的时间。 并且不要忘记读取图像并释放它们,因为如果缓冲区已满且未释放图像,则新图像不可用。例如:
private class imageAvailableListener implements
ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader ir) {
Log.i(TAG, "Time = " + System.currentTimeMillis());
Image im = ir.acquireNextImage();
im.close();
}
}
ImageReader mImageReader = ImageReader.newInstance(imageReaderWidth,
imageReaderHeight, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(
new imageAvailableListener(), null);
您 运行 遇到的问题是您请求的图像输出格式的伪影。 JPEG 编码过程会在相机流水线中放置大量停滞时间,因此在进行此编码时,在一次曝光结束和下一次曝光开始之间存在大量停机时间。
所引用的 30fps 速率可以通过将 ImageReader
上的输出图像格式设置为 YUV 来实现,因为这是相机的更多 "native" 输出。这将是在捕获图像时存储图像的方式,然后您必须在之后进行 JPEG 编码,与相机的内联处理分开。
例如,在 Nexus 5 上,JPEG
编码的输出停顿时间为 243 毫秒,您一直在观察。对于 YUV_420_888
输出,它是 0ms。同样,由于它们的尺寸较大,RAW_SENSOR
编码引入了 200 毫秒的停顿时间。
另请注意,即使您通过选择 "faster" 格式消除了延迟时间障碍,仍然存在最小帧时间,具体取决于输出图像大小。但是对于 Nexus 5 的全分辨率输出,这是 33 毫秒,这是您所期望的。
相关信息在相机元数据的 StreamConfigurationMap
对象中,here。查看 getOutputStallDuration(int format, Size size)
和 getOutputMinFrameDuration(int format, Size size)
方法进行确认。