java Android camera2 捕捉连拍太慢
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29265126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android camera2 capture burst is too slow
提问by acheroncaptain
I am trying to modify the android-Camera2Basic code to capture a burst of pictures. However, I can't get the delay between pictures any faster than 200-300ms on my Nexus 5, running L 5.0.1.
我正在尝试修改 android-Camera2Basic 代码以捕捉连拍图片。但是,在运行 L 5.0.1 的 Nexus 5 上,图片之间的延迟无法超过 200-300 毫秒。
I've tried a bunch of things, but this is the most basic. This is the only part of the Camera2Basic code that I've modified. My preview TextureView is only 50x50dp, but that shouldn't matter, right?
我已经尝试了很多东西,但这是最基本的。这是我修改过的 Camera2Basic 代码的唯一部分。我的预览 TextureView 只有 50x50dp,但这应该无关紧要,对吧?
For what it's worth, this code only has delays around 50-100ms on my Nexus 6, with L 5.1.
对于它的价值,这段代码在我的 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();
}
};
回答by rcsumner
The issue you are running into is an artifact of the image output format you have requested. The JPEG encoding process puts a large stall time on the camera pipeline, so there is a lot of downtime between when one exposure ends and the next begins while this encoding happens.
您遇到的问题是您请求的图像输出格式的工件。JPEG 编码过程在相机流水线上放置了很长的停顿时间,因此在进行此编码时,在一次曝光结束和下一次曝光开始之间存在大量停机时间。
The 30fps rate that is quoted can be achieved by setting the output image format on the ImageReader
as YUV, since that is a more "native" output for the camera. This would be the way to store the images as they are captured, and then you would have to do JPEG encoding afterwards, separate of the camera's inline processing.
引用的 30fps 速率可以通过将输出图像格式设置ImageReader
为 YUV 来实现,因为这是相机更“本机”的输出。这将是在捕获图像时存储图像的方式,然后您必须在之后进行 JPEG 编码,与相机的内联处理分开。
For example, on the Nexus 5 the output stall time for JPEG
encoding is 243ms, which you have been observing. For YUV_420_888
output, it is 0ms. Likewise, because of their large size, RAW_SENSOR
encoding introduces a stall time of 200ms.
例如,在 Nexus 5 上,JPEG
编码的输出停顿时间是 243 毫秒,这是您一直观察到的。对于YUV_420_888
输出,它是 0ms。同样,由于它们的尺寸很大,RAW_SENSOR
编码引入了 200 毫秒的停顿时间。
Note also that even if you remove the stall time obstacle by choosing a "faster" format, there is still a minimum frame time, depending on the output image size. But for a Nexus 5's full resolution output, this is 33ms, which is what you were expecting.
另请注意,即使您通过选择“更快”格式来消除停顿时间障碍,仍然存在最小帧时间,具体取决于输出图像大小。但是对于 Nexus 5 的全分辨率输出,这是 33 毫秒,这正是您所期望的。
The relevant information is in the camera metadata's StreamConfigurationMap
object, here. Check out the getOutputStallDuration(int format, Size size)
and getOutputMinFrameDuration(int format, Size size)
methods for confirmation.
相关信息在相机元数据的StreamConfigurationMap
对象中,这里。查看确认方法getOutputStallDuration(int format, Size size)
和getOutputMinFrameDuration(int format, Size size)
方法。
回答by Maxim Metelskiy
Try to set following capture request parameters
尝试设置以下捕获请求参数
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);
I am not sure about how fast info comes into CameraCaptureSession.CaptureCallback. It's not have image data, and it could be called before or after ImageReader.OnImageAvailableListener. Try to measure time between ImageReader.OnImageAvailableListener calls. And don't forget to read images and release them, because new images are not available if buffer is filled and images not released. For example:
我不确定信息进入 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);
回答by iheanyi
Based on this PcMag article: http://www.pcmag.com/article2/0,2817,2428017,00.aspThe Nexus 5 burst mode lets you take 3 pictures per second. So getting much less than 333ms between photos is highly unlikely.
基于此 PcMag 文章:http://www.pcmag.com/article2/0,2817,2428017,00.asp Nexus 5 连拍模式可让您每秒拍摄 3 张照片。因此,照片之间的间隔极不可能远小于 333 毫秒。
Do you have a source for information that suggests the Nexus 5 burst should be faster?
您是否有信息来源表明 Nexus 5 爆发应该更快?