FileDocCategorySizeDatePackage
LegacyFaceDetectMapper.javaAPI DocAndroid 5.1 API10637Thu Mar 12 22:22:10 GMT 2015android.hardware.camera2.legacy

LegacyFaceDetectMapper

public class LegacyFaceDetectMapper extends Object
Map legacy face detect callbacks into face detection results.

Fields Summary
private static String
TAG
private static final boolean
VERBOSE
private final android.hardware.Camera
mCamera
private final boolean
mFaceDetectSupported
Is the camera capable of face detection?
private boolean
mFaceDetectEnabled
Is the camera is running face detection?
private boolean
mFaceDetectScenePriority
Did the last request say to use SCENE_MODE = FACE_PRIORITY?
private boolean
mFaceDetectReporting
Did the last request enable the face detect mode to ON?
private final Object
mLock
Synchronize access to all fields
private Camera.Face[]
mFaces
private Camera.Face[]
mFacesPrev
Constructors Summary
public LegacyFaceDetectMapper(android.hardware.Camera camera, android.hardware.camera2.CameraCharacteristics characteristics)
Instantiate a new face detect mapper.

param
camera a non-{@code null} camera1 device
param
characteristics a non-{@code null} camera characteristics for that camera1
throws
NullPointerException if any of the args were {@code null}

                                           
         
        mCamera = checkNotNull(camera, "camera must not be null");
        checkNotNull(characteristics, "characteristics must not be null");

        mFaceDetectSupported = ArrayUtils.contains(
                characteristics.get(
                        CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES),
                STATISTICS_FACE_DETECT_MODE_SIMPLE);

        if (!mFaceDetectSupported) {
            return;
        }

       mCamera.setFaceDetectionListener(new FaceDetectionListener() {

        @Override
        public void onFaceDetection(Camera.Face[] faces, Camera camera) {
            int lengthFaces = faces == null ? 0 : faces.length;
            synchronized (mLock) {
                if (mFaceDetectEnabled) {
                    mFaces = faces;
                } else if (lengthFaces > 0) {
                    // stopFaceDetectMode could race against the requests, print a debug log
                    Log.d(TAG,
                            "onFaceDetection - Ignored some incoming faces since" +
                            "face detection was disabled");
                }
            }

            if (VERBOSE) {
                Log.v(TAG, "onFaceDetection - read " + lengthFaces + " faces");
            }
        }
       });
    
Methods Summary
public voidmapResultFaces(android.hardware.camera2.impl.CameraMetadataNative result, LegacyRequest legacyRequest)
Update the {@code result} camera metadata map with the new value for the {@code statistics.faces} and {@code statistics.faceDetectMode}.

Face detect callbacks are processed in the background, and each call to {@link #mapResultFaces} will have the latest faces as reflected by the camera1 callbacks.

If the scene mode was set to {@code FACE_PRIORITY} but face detection is disabled, the camera will still run face detection in the background, but no faces will be reported in the capture result.

param
result a non-{@code null} result
param
legacyRequest a non-{@code null} request (read-only)

        checkNotNull(result, "result must not be null");
        checkNotNull(legacyRequest, "legacyRequest must not be null");

        Camera.Face[] faces, previousFaces;
        int fdMode;
        boolean fdScenePriority;
        synchronized (mLock) {
            fdMode = mFaceDetectReporting ?
                            STATISTICS_FACE_DETECT_MODE_SIMPLE : STATISTICS_FACE_DETECT_MODE_OFF;

            if (mFaceDetectReporting) {
                faces = mFaces;
            } else {
                faces = null;
            }

            fdScenePriority = mFaceDetectScenePriority;

            previousFaces = mFacesPrev;
            mFacesPrev = faces;
        }

        CameraCharacteristics characteristics = legacyRequest.characteristics;
        CaptureRequest request = legacyRequest.captureRequest;
        Size previewSize = legacyRequest.previewSize;
        Camera.Parameters params = legacyRequest.parameters;

        Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
        ZoomData zoomData = ParameterUtils.convertScalerCropRegion(activeArray,
                request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params);

        List<Face> convertedFaces = new ArrayList<>();
        if (faces != null) {
            for (Camera.Face face : faces) {
                if (face != null) {
                    convertedFaces.add(
                            ParameterUtils.convertFaceFromLegacy(face, activeArray, zoomData));
                } else {
                    Log.w(TAG, "mapResultFaces - read NULL face from camera1 device");
                }
            }
        }

        if (VERBOSE && previousFaces != faces) { // Log only in verbose and IF the faces changed
            Log.v(TAG, "mapResultFaces - changed to " + ListUtils.listToString(convertedFaces));
        }

        result.set(CaptureResult.STATISTICS_FACES, convertedFaces.toArray(new Face[0]));
        result.set(CaptureResult.STATISTICS_FACE_DETECT_MODE, fdMode);

        // Override scene mode with FACE_PRIORITY if the request was using FACE_PRIORITY
        if (fdScenePriority) {
            result.set(CaptureResult.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_FACE_PRIORITY);
        }
    
public voidprocessFaceDetectMode(android.hardware.camera2.CaptureRequest captureRequest, Camera.Parameters parameters)
Process the face detect mode from the capture request into an api1 face detect toggle.

This method should be called after the parameters are {@link LegacyRequestMapper mapped} with the request.

Callbacks are processed in the background, and the next call to {@link #mapResultTriggers} will have the latest faces detected as reflected by the camera1 callbacks.

None of the arguments will be mutated.

param
captureRequest a non-{@code null} request
param
parameters a non-{@code null} parameters corresponding to this request (read-only)

        checkNotNull(captureRequest, "captureRequest must not be null");

        /*
         * statistics.faceDetectMode
         */
        int fdMode = ParamsUtils.getOrDefault(captureRequest, STATISTICS_FACE_DETECT_MODE,
                STATISTICS_FACE_DETECT_MODE_OFF);

        if (fdMode != STATISTICS_FACE_DETECT_MODE_OFF && !mFaceDetectSupported) {
            Log.w(TAG,
                    "processFaceDetectMode - Ignoring statistics.faceDetectMode; " +
                    "face detection is not available");
            return;
        }

        /*
         * control.sceneMode
         */
        int sceneMode = ParamsUtils.getOrDefault(captureRequest, CONTROL_SCENE_MODE,
                CONTROL_SCENE_MODE_DISABLED);
        if (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY && !mFaceDetectSupported) {
            Log.w(TAG, "processFaceDetectMode - ignoring control.sceneMode == FACE_PRIORITY; " +
                    "face detection is not available");
            return;
        }

        // Print some warnings out in case the values were wrong
        switch (fdMode) {
            case STATISTICS_FACE_DETECT_MODE_OFF:
            case STATISTICS_FACE_DETECT_MODE_SIMPLE:
                break;
            case STATISTICS_FACE_DETECT_MODE_FULL:
                Log.w(TAG,
                        "processFaceDetectMode - statistics.faceDetectMode == FULL unsupported, " +
                        "downgrading to SIMPLE");
                break;
            default:
                Log.w(TAG, "processFaceDetectMode - ignoring unknown statistics.faceDetectMode = "
                        + fdMode);
                return;
        }

        boolean enableFaceDetect = (fdMode != STATISTICS_FACE_DETECT_MODE_OFF)
                || (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY);
        synchronized (mLock) {
            // Enable/disable face detection if it's changed since last time
            if (enableFaceDetect != mFaceDetectEnabled) {
                if (enableFaceDetect) {
                    mCamera.startFaceDetection();

                    if (VERBOSE) {
                        Log.v(TAG, "processFaceDetectMode - start face detection");
                    }
                } else {
                    mCamera.stopFaceDetection();

                    if (VERBOSE) {
                        Log.v(TAG, "processFaceDetectMode - stop face detection");
                    }

                    mFaces = null;
                }

                mFaceDetectEnabled = enableFaceDetect;
                mFaceDetectScenePriority = sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY;
                mFaceDetectReporting = fdMode != STATISTICS_FACE_DETECT_MODE_OFF;
            }
        }