安卓相机2拍摄连拍速度太慢

我正在尝试修改android-Camera2Basic代码以捕获一连串的图片。但是,在我的Nexus 5上运行L 5.0.1,我无法将图片之间的延迟速度快于200-300ms。

我尝试过很多东西,但这是最基本的。这是我修改的Camera2Basic代码的唯一部分。我的预览纹理视图只有50x50dp,但这并不重要,对吧?

值得一提的是,此代码在我的Nexus 6上只有大约50-100ms的延迟,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();
    }
};

答案 1

您遇到的问题是您请求的图像输出格式的工件。JPEG编码过程在相机管道上放置了很长的停顿时间,因此在进行此编码时,在一次曝光结束和下一次曝光开始之间有很多停机时间。

引用的30fps速率可以通过在YUV上设置输出图像格式来实现,因为这是相机的更“原生”输出。这将是在捕获图像时存储图像的方法,然后您必须进行JPEG编码,与相机的内联处理分开。ImageReader

例如,在Nexus 5上,编码的输出停顿时间为243ms,您一直在观察。对于输出,它是0ms。同样,由于它们的尺寸很大,编码引入了200ms的停顿时间。JPEGYUV_420_888RAW_SENSOR

另请注意,即使您通过选择“更快”格式来消除失速时间障碍,仍然存在一个最小帧时间,具体取决于输出图像大小。但对于Nexus 5的全分辨率输出,这是33ms,这是你所期望的。

相关信息位于相机元数据的对象中,请点击此处。查看 和 确认方法。StreamConfigurationMapgetOutputStallDuration(int format, Size size)getOutputMinFrameDuration(int format, Size size)


答案 2

尝试设置以下捕获请求参数

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);

推荐