Example usage for android.hardware.camera2 CaptureRequest CONTROL_AF_REGIONS

List of usage examples for android.hardware.camera2 CaptureRequest CONTROL_AF_REGIONS

Introduction

In this page you can find the example usage for android.hardware.camera2 CaptureRequest CONTROL_AF_REGIONS.

Prototype

Key CONTROL_AF_REGIONS

To view the source code for android.hardware.camera2 CaptureRequest CONTROL_AF_REGIONS.

Click Source Link

Document

List of metering areas to use for auto-focus.

Not available if CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf is 0.

Usage

From source file:com.dastanapps.camera2.view.Cam2AutoFitTextureView.java

@Nullable
private Boolean touchTofocus2(MotionEvent event) {
    MotionEvent motionEvent = event;//from  ww  w . j a va  2s . c o  m
    final int actionMasked = motionEvent.getActionMasked();
    if (actionMasked != MotionEvent.ACTION_DOWN) {
        return false;
    }
    if (mManualFocusEngaged) {
        Log.d(TAG, "Manual focus already engaged");
        return true;
    }

    final Rect sensorArraySize = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);

    //TODO: here I just flip x,y, but this needs to correspond with the sensor orientation (via SENSOR_ORIENTATION)
    final int y = (int) ((motionEvent.getX() / (float) getWidth()) * (float) sensorArraySize.height());
    final int x = (int) ((motionEvent.getY() / (float) getHeight()) * (float) sensorArraySize.width());
    final int halfTouchWidth = 150; //(int)motionEvent.getTouchMajor(); //TODO: this doesn't represent actual touch size in pixel. Values range in [3, 10]...
    final int halfTouchHeight = 150; //(int)motionEvent.getTouchMinor();
    MeteringRectangle focusAreaTouch = new MeteringRectangle(Math.max(x - halfTouchWidth, 0),
            Math.max(y - halfTouchHeight, 0), halfTouchWidth * 2, halfTouchHeight * 2,
            MeteringRectangle.METERING_WEIGHT_MAX - 1);

    CameraCaptureSession.CaptureCallback captureCallbackHandler = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);
            mManualFocusEngaged = false;

            if (request.getTag() == "FOCUS_TAG") {
                //the focus trigger is complete -
                //resume repeating (preview surface will get frames), clear AF trigger
                mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);
                try {
                    mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
                CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
            Log.e(TAG, "Manual AF failure: " + failure);
            mManualFocusEngaged = false;
        }
    };

    //first stop the existing repeating request
    try {
        mPreviewSession.stopRepeating();
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }

    //cancel any existing AF trigger (repeated touches, etc.)
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
    try {
        mPreviewSession.capture(mPreviewBuilder.build(), captureCallbackHandler, null);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }

    //Now add a new AF trigger with focus region
    if (isMeteringAreaAFSupported()) {
        mPreviewBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[] { focusAreaTouch });
    }
    mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
    mPreviewBuilder.setTag("FOCUS_TAG"); //we'll capture this later for resuming the preview

    //            //then we ask for a single request (not repeating!)
    //            mPreviewSession.capture(mPreviewBuilder.build(), captureCallbackHandler, mBackgroundHandler);
    return null;
}

From source file:com.dastanapps.camera2.view.Cam2AutoFitTextureView.java

protected void touchToFocus(MotionEvent event) {
    //first stop the existing repeating request
    try {// w  w w .j a  va 2  s . co m
        mPreviewSession.stopRepeating();
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    Rect rect = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
    Log.i(TAG, "SENSOR_INFO_ACTIVE_ARRAY_SIZE,,,,,,,,rect.left--->" + rect.left + ",,,rect.top--->" + rect.top
            + ",,,,rect.right--->" + rect.right + ",,,,rect.bottom---->" + rect.bottom);
    Size size = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
    Log.i(TAG, "mCameraCharacteristics,,,,size.getWidth()--->" + size.getWidth() + ",,,size.getHeight()--->"
            + size.getHeight());
    int areaSize = 200;
    int right = rect.right;
    int bottom = rect.bottom;
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    int ll, rr;
    Rect newRect;
    int centerX = (int) event.getX();
    int centerY = (int) event.getY();
    ll = ((centerX * right) - areaSize) / viewWidth;
    rr = ((centerY * bottom) - areaSize) / viewHeight;
    int focusLeft = clamp(ll, 0, right);
    int focusBottom = clamp(rr, 0, bottom);
    Log.i(TAG, "focusLeft--->" + focusLeft + ",,,focusTop--->" + focusBottom + ",,,focusRight--->"
            + (focusLeft + areaSize) + ",,,focusBottom--->" + (focusBottom + areaSize));
    newRect = new Rect(focusLeft, focusBottom, focusLeft + areaSize, focusBottom + areaSize);
    MeteringRectangle meteringRectangle = new MeteringRectangle(newRect, 500);
    MeteringRectangle[] meteringRectangleArr = { meteringRectangle };
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meteringRectangleArr);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
    mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
}

From source file:com.obviousengine.android.focus.ZslFocusCamera.java

private void addRegionsToCaptureRequestBuilder(CaptureRequest.Builder builder) {
    builder.set(CaptureRequest.CONTROL_AE_REGIONS, aERegions);
    builder.set(CaptureRequest.CONTROL_AF_REGIONS, aFRegions);
    builder.set(CaptureRequest.SCALER_CROP_REGION, cropRegion);
}

From source file:com.android.camera.one.v2.OneCameraZslImpl.java

private void addRegionsToCaptureRequestBuilder(CaptureRequest.Builder builder) {
    builder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions);
    builder.set(CaptureRequest.CONTROL_AF_REGIONS, mAFRegions);
    builder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion);
}

From source file:com.android.camera2.its.ItsService.java

private void do3A(JSONObject params) throws ItsException {
    try {//from   ww  w. j a va 2  s. com
        // Start a 3A action, and wait for it to converge.
        // Get the converged values for each "A", and package into JSON result for caller.

        // 3A happens on full-res frames.
        Size sizes[] = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
        int widths[] = new int[1];
        int heights[] = new int[1];
        int formats[] = new int[1];
        widths[0] = sizes[0].getWidth();
        heights[0] = sizes[0].getHeight();
        formats[0] = ImageFormat.YUV_420_888;
        int width = widths[0];
        int height = heights[0];

        prepareCaptureReader(widths, heights, formats, 1);
        List<Surface> outputSurfaces = new ArrayList<Surface>(1);
        outputSurfaces.add(mCaptureReaders[0].getSurface());
        BlockingSessionCallback sessionListener = new BlockingSessionCallback();
        mCamera.createCaptureSession(outputSurfaces, sessionListener, mCameraHandler);
        mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);

        // Add a listener that just recycles buffers; they aren't saved anywhere.
        ImageReader.OnImageAvailableListener readerListener = createAvailableListenerDropper(mCaptureCallback);
        mCaptureReaders[0].setOnImageAvailableListener(readerListener, mSaveHandlers[0]);

        // Get the user-specified regions for AE, AWB, AF.
        // Note that the user specifies normalized [x,y,w,h], which is converted below
        // to an [x0,y0,x1,y1] region in sensor coords. The capture request region
        // also has a fifth "weight" element: [x0,y0,x1,y1,w].
        MeteringRectangle[] regionAE = new MeteringRectangle[] {
                new MeteringRectangle(0, 0, width, height, 1) };
        MeteringRectangle[] regionAF = new MeteringRectangle[] {
                new MeteringRectangle(0, 0, width, height, 1) };
        MeteringRectangle[] regionAWB = new MeteringRectangle[] {
                new MeteringRectangle(0, 0, width, height, 1) };
        if (params.has(REGION_KEY)) {
            JSONObject regions = params.getJSONObject(REGION_KEY);
            if (regions.has(REGION_AE_KEY)) {
                regionAE = ItsUtils.getJsonWeightedRectsFromArray(regions.getJSONArray(REGION_AE_KEY), true,
                        width, height);
            }
            if (regions.has(REGION_AF_KEY)) {
                regionAF = ItsUtils.getJsonWeightedRectsFromArray(regions.getJSONArray(REGION_AF_KEY), true,
                        width, height);
            }
            if (regions.has(REGION_AWB_KEY)) {
                regionAWB = ItsUtils.getJsonWeightedRectsFromArray(regions.getJSONArray(REGION_AWB_KEY), true,
                        width, height);
            }
        }

        // If AE or AWB lock is specified, then the 3A will converge first and then lock these
        // values, waiting until the HAL has reported that the lock was successful.
        mNeedsLockedAE = params.optBoolean(LOCK_AE_KEY, false);
        mNeedsLockedAWB = params.optBoolean(LOCK_AWB_KEY, false);

        // By default, AE and AF both get triggered, but the user can optionally override this.
        // Also, AF won't get triggered if the lens is fixed-focus.
        boolean doAE = true;
        boolean doAF = true;
        if (params.has(TRIGGER_KEY)) {
            JSONObject triggers = params.getJSONObject(TRIGGER_KEY);
            if (triggers.has(TRIGGER_AE_KEY)) {
                doAE = triggers.getBoolean(TRIGGER_AE_KEY);
            }
            if (triggers.has(TRIGGER_AF_KEY)) {
                doAF = triggers.getBoolean(TRIGGER_AF_KEY);
            }
        }
        if (doAF && mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE) == 0) {
            // Send a dummy result back for the code that is waiting for this message to see
            // that AF has converged.
            Logt.i(TAG, "Ignoring request for AF on fixed-focus camera");
            mSocketRunnableObj.sendResponse("afResult", "0.0");
            doAF = false;
        }

        mInterlock3A.open();
        mIssuedRequest3A = false;
        mConvergedAE = false;
        mConvergedAWB = false;
        mConvergedAF = false;
        mLockedAE = false;
        mLockedAWB = false;
        long tstart = System.currentTimeMillis();
        boolean triggeredAE = false;
        boolean triggeredAF = false;

        Logt.i(TAG, String.format("Initiating 3A: AE:%d, AF:%d, AWB:1, AELOCK:%d, AWBLOCK:%d", doAE ? 1 : 0,
                doAF ? 1 : 0, mNeedsLockedAE ? 1 : 0, mNeedsLockedAWB ? 1 : 0));

        // Keep issuing capture requests until 3A has converged.
        while (true) {

            // Block until can take the next 3A frame. Only want one outstanding frame
            // at a time, to simplify the logic here.
            if (!mInterlock3A.block(TIMEOUT_3A * 1000)
                    || System.currentTimeMillis() - tstart > TIMEOUT_3A * 1000) {
                throw new ItsException("3A failed to converge (timeout)");
            }
            mInterlock3A.close();

            // If not converged yet, issue another capture request.
            if ((doAE && (!triggeredAE || !mConvergedAE)) || !mConvergedAWB
                    || (doAF && (!triggeredAF || !mConvergedAF)) || (doAE && mNeedsLockedAE && !mLockedAE)
                    || (mNeedsLockedAWB && !mLockedAWB)) {

                // Baseline capture request for 3A.
                CaptureRequest.Builder req = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                req.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
                req.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
                req.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
                req.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
                req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
                req.set(CaptureRequest.CONTROL_AE_LOCK, false);
                req.set(CaptureRequest.CONTROL_AE_REGIONS, regionAE);
                req.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
                req.set(CaptureRequest.CONTROL_AF_REGIONS, regionAF);
                req.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
                req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
                req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);

                if (mConvergedAE && mNeedsLockedAE) {
                    req.set(CaptureRequest.CONTROL_AE_LOCK, true);
                }
                if (mConvergedAWB && mNeedsLockedAWB) {
                    req.set(CaptureRequest.CONTROL_AWB_LOCK, true);
                }

                // Trigger AE first.
                if (doAE && !triggeredAE) {
                    Logt.i(TAG, "Triggering AE");
                    req.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                            CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
                    triggeredAE = true;
                }

                // After AE has converged, trigger AF.
                if (doAF && !triggeredAF && (!doAE || (triggeredAE && mConvergedAE))) {
                    Logt.i(TAG, "Triggering AF");
                    req.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
                    triggeredAF = true;
                }

                req.addTarget(mCaptureReaders[0].getSurface());

                mIssuedRequest3A = true;
                mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
            } else {
                mSocketRunnableObj.sendResponse("3aConverged", "");
                Logt.i(TAG, "3A converged");
                break;
            }
        }
    } catch (android.hardware.camera2.CameraAccessException e) {
        throw new ItsException("Access error: ", e);
    } catch (org.json.JSONException e) {
        throw new ItsException("JSON error: ", e);
    } finally {
        mSocketRunnableObj.sendResponse("3aDone", "");
    }
}