1

With the code snippet below fails to create a CaptureRequest for a preview with fixed focal length. The image displayed in the preview is always focussed at infinity even though the report from the TotalCaptureRequest says otherwise.

Here is the code snippet:

mPreviewBuilder = mCameraDevice.createCaptureRequest(SCameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder.set(SCaptureRequest.LENS_FOCUS_DISTANCE, 9.5f);
mPreviewBuilder.set(SCaptureRequest.CONTROL_AF_MODE, SCaptureRequest.CONTROL_AF_MODE_OFF);

My device is a Samsung Galaxy S7 which reports the following properties for the back camera: [code]CamId: 0 LensFace: BACK HwdSupportLevel: FULL SensorOrientation: 90 LensCalibration: CALIBRATED LensMinFocusDist: 10.0[/code]

Here is my log captured during the onCaptureComplete()

 callback: AF_STATE: 0 Lens Focus Distance: 9.555555 LENS_STATE: 0 HAS FOCUS RANGE: true Focus Range Min: 9.762765, Max: 9.348346

I have tried this with the plain-old Android Camera2 API as well as with the Samsung SDK (found here: http://developer.samsung.com/galaxy/camera)

Samsung's own camera app as well as Camera FV-5 support this functionality without any issue.

How do I get this to work?

Adding Some More Code For Context

/**
 * Start the camera preview.
 */
private void startPreview() {
    if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
        return;
    }
    try {
        closePreviewSession();
        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        mPreviewBuilder = mCameraDevice.createCaptureRequest(SCameraDevice.TEMPLATE_PREVIEW);
        //mPreviewBuilder.set(SCaptureRequest.CONTROL_CAPTURE_INTENT, SCaptureRequest.CONTROL_CAPTURE_INTENT_MANUAL);
        //mPreviewBuilder.set(SCaptureRequest.CONTROL_MODE, SCaptureRequest.CONTROL_MODE_OFF);
        mPreviewBuilder.set(SCaptureRequest.CONTROL_AF_MODE, SCaptureRequest.CONTROL_AF_MODE_OFF);
        mPreviewBuilder.set(SCaptureRequest.CONTROL_AE_MODE, SCaptureRequest.CONTROL_AE_MODE_ON);
        mPreviewBuilder.set(SCaptureRequest.LENS_FOCUS_DISTANCE, 9.5f);

        Surface previewSurface = new Surface(texture);
        mPreviewBuilder.addTarget(previewSurface);

        mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new SCameraCaptureSession.StateCallback() {

            @Override
            public void onConfigured(SCameraCaptureSession cameraCaptureSession) {
                mPreviewSession = cameraCaptureSession;
                updatePreview();
            }

            @Override
            public void onConfigureFailed(SCameraCaptureSession cameraCaptureSession) {
                Toast.makeText(getApplicationContext(),"Failed", Toast.LENGTH_SHORT).show();
            }
        }, mBackgroundHandler);


    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}


/**
 * Update the camera preview. {@link #startPreview()} needs to be called in advance.
 */
private void updatePreview() {
    if (null == mCameraDevice) {
        return;
    }
    try {
        setUpCaptureRequestBuilder(mPreviewBuilder);
        HandlerThread thread = new HandlerThread("CameraPreview");
        thread.start();
        mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallBack, mBackgroundHandler);
        Log.i(TAG, "New Session values, control mode " + mPreviewBuilder.get(SCaptureRequest.CONTROL_MODE) +
                ", AF mode: " + mPreviewBuilder.get(SCaptureRequest.CONTROL_AF_MODE) +
                ", Focus value; " + +mPreviewBuilder.get(SCaptureRequest.LENS_FOCUS_DISTANCE));
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}
unshul
  • 269
  • 3
  • 16

1 Answers1

0

Did you added a surface to your mPreviewBuilder?

 Surface surface = new Surface(texture);
 //Add surfaces
 mPreviewBuilder.addTarget(surface);
 surfaces.add(surface);

Second, set your AF_MODE to off before set the LENS_FOCUS_DISTANCE, and finally update your sesion with a setRepeatingRequest over your CaptureSesion. With that it must work.

 mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(),
                callback, mHandler);

Check the values of your CaptureRequest with a Log to check that everything is right and you are not overlapping something over your AF:

 Log.i(TAG, "New Session values, control mode " + mPreviewRequestBuilder.get(CaptureRequest.CONTROL_MODE) +
            ", AF mode: " + mPreviewRequestBuilder.get(CaptureRequest.CONTROL_AF_MODE) +
            ", Focus value; " + +mPreviewRequestBuilder.get(CaptureRequest.LENS_FOCUS_DISTANCE));
Francisco Durdin Garcia
  • 12,540
  • 9
  • 53
  • 95
  • @Durdins Still does not work. Here are the values from the log: New Session values, control mode 1, AF mode: 0, Focus value; 9.5 – unshul Sep 20 '16 at 15:08
  • that means that your captureRequest have the right values. Are you updating your preview? Do a new setRepeatingRequest over your CaptureSession after set the new values and it should update the preview with the new request builder values – Francisco Durdin Garcia Sep 20 '16 at 15:22
  • @Durdins: I think I am setting up the request and the preview as you suggest (I have updated my original post with some more context) but the focus value still does not seem to have an effect on the preview. – unshul Sep 20 '16 at 15:38
  • add this: mPreviewBuilder.set(SCaptureRequest.CONTROL_MODE, SCaptureRequest.CONTROL_MODE_OFF); – Francisco Durdin Garcia Sep 20 '16 at 15:43
  • If that doesn't work I just suggest you to move the control of the builder to other place. As long as i can see, your preview is correctly correct(but you dont have any imageReader attached) and idk why is not working. Im checking my code and everything is fine and it works. AF off, AE doesnt matter and control_mode is on, but i remember that i have problems with that, thats why i told you to put CONTROL_MODE_OFF. Try it and let's see if we can fix it ;) – Francisco Durdin Garcia Sep 20 '16 at 15:51
  • @Durdins Thanks ... When I set CONTROL_MODE to CONTROL_MODE_OFF the image is very dark, only very bright light sources show up in the image. Once again, the focus distance value does not seem to have an effect as the image is blurry at close distances. Are you using a Samsung Galaxy phone? – unshul Sep 20 '16 at 16:09
  • Im using a BQ, not a Samsung Galaxy, but the api 2 may work in the 2 sdks in the same way. Preview is dark cause control Mode off disable auto exposure and auto focua value. Which means that your preview have a default ISO and Time exposure. – Francisco Durdin Garcia Sep 20 '16 at 16:18
  • If your preview is dark means that rhe capture builder is setting the values. Are you sure that your Focus value is not set? 9'5f its pretty near the hyperfocal. So maybe you dont see any difference. Try ti move the Focus from 0 (infinite) to Max in a New seekbar where you set Focus value and update the preview and check if you see any difference – Francisco Durdin Garcia Sep 20 '16 at 16:21
  • @Durdin: Actually the focus_distance is measured in diopters, i.e. 1/focal_length . For the camera in question, the minimum "focus_distance" is 10, so I am pretty close to the minimum. https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INFO_FOCUS_DISTANCE_CALIBRATION – unshul Sep 21 '16 at 01:23
  • If the minimum is 10 u are pretty near the Focus near the infinite. Im not an expert in photography :P. It depends of the phone. Try with a lower value, or just open me a chat whenever you can and we Will try to find a solution – Francisco Durdin Garcia Sep 21 '16 at 06:18