使用setRepeatingRequest的Android Camera 2 API 1fps

时间:2017-10-14 19:36:17

标签: android camera android-camera android-camera2

我想使用Camera 2 API的setRepeatingRequest()模式拍摄1fps的照片。

我将CONTROL_AE_MODE设置为CONTROL_AE_MODE_OFF,将SENSOR_FRAME_DURATION设置为1。但是,我仍然可以使用以下代码获得20fps的非常高的帧速率。

我尝试将捕获请求模板从TEMPLATE_PREVIEW更改为TEMPLATE_STILL_CAPTURE而没有任何运气。如何使用setRepeatingRequest()实现1fps?

CaptureRequest.Builder requestBuilder
            = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
    requestBuilder.addTarget(imageReader.getSurface());
        cameraDevice.createCaptureSession(Collections.singletonList(imageReader.getSurface()),
            new CameraCaptureSession.StateCallback() {

                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    // The camera is already closed
                    if (cameraDevice == null) {
                        return;
                    }

                    captureSession = cameraCaptureSession;
                    try {
                        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
                        requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1L);

                        CameraCaptureSession.CaptureCallback captureCallback
                                = new CameraCaptureSession.CaptureCallback() {

                            @Override
                            public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                    @NonNull CaptureRequest request,
                                    @NonNull TotalCaptureResult result) {
                            }
                        };

                        captureSession.setRepeatingRequest(
                                requestBuilder.build(), captureCallback, callbackHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(
                        @NonNull CameraCaptureSession cameraCaptureSession) {
                }
            }, null);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

2 个答案:

答案 0 :(得分:1)

首先,根据the docs

,SENSOR_FRAME_DURATION中的单位为纳秒。

请尝试使用requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000000L);

此外,你可以使用CountDownTimer不那么优雅地做,并且每1秒拍一张照片。我知道这很糟糕,因为你每秒都在初始化所有相机的东西,但它是一个可行的解决方案。一个例子是:

new CountDownTimer(5000,1000){
    @Override
    public void onFinish() { (...) }

    @Override
    public void onTick(long millisUntilFinished) {
        // TODO take picture
    }
}.start();

另一个第三种解决方案是使用Camera.Parameters [setPreviewFpsRange](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFpsRange(int,int)),但它需要Camera API而不是Camera2。但这只是另一种可能性

答案 1 :(得分:1)

您对 onCaptureCompleted()的调用频率的控制是有限的。但是你可以完全控制你在回调中做的事情。

如果你的相机产生20 fps,你可以跳过19个回调并捕获第二十个。如果您不确定帧速率是否足够稳定,则可以为最后使用的图片保留时间戳(使用SystemClock.elapsedRealtime()),并忽略所有回调,直到一秒钟之后。如果你真的需要,你甚至可以使用sleep()来提高精确度。