avenger
avenger

Reputation: 141

Android Camera 2 API 1fps using setRepeatingRequest

I want to take 1fps still captures using Camera 2 API's setRepeatingRequest() mode.

I set the CONTROL_AE_MODE to CONTROL_AE_MODE_OFF and SENSOR_FRAME_DURATION to 1. However I still receive a very high frame rate of 20fps with the below code.

I tried changing the capture request template from TEMPLATE_PREVIEW to TEMPLATE_STILL_CAPTURE without any luck. How do I achieve 1fps using setRepeatingRequest()?

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

Upvotes: 5

Views: 2469

Answers (2)

Alex Cohn
Alex Cohn

Reputation: 57163

Your control over how often will onCaptureCompleted() be invoked is limited. But you have full control over what you do in that callback.

If your camera produces 20 fps, you can skip 19 callbacks and capture the twentieth. If you are not sure that the frame rate is stable enough, you can keep the timestamp (using SystemClock.elapsedRealtime()) for the last picture you used, and ignore all callbacks until one second after that. You can even play with sleep() to improve precision if you really need it.

Upvotes: 0

webo80
webo80

Reputation: 3393

First of all, the unit in SENSOR_FRAME_DURATION is in nanoseconds, according to the docs

So try with requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000000L);

In addition, you can do it less elegantly using a CountDownTimer, and taking a photo each 1 sec. I know this is bad, because you are initializing all the camera stuff each seconds, but it's a solution that just works. An example would be:

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

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

Another third solution would be using Camera.Parameters [setPreviewFpsRange](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFpsRange(int, int)), but it would require Camera API instead of Camera2. But it's just another possibility

Upvotes: 1

Related Questions