diff options
author | Geoff Mendal <mendal@google.com> | 2014-08-11 13:31:17 -0700 |
---|---|---|
committer | Geoff Mendal <mendal@google.com> | 2014-08-11 13:31:17 -0700 |
commit | 8705eb95b0e00d54bbc511351c6bb180bf3273de (patch) | |
tree | 7c847360ac3e2710b767db0a03989d0064f68e2b | |
parent | 3f19789b7703695531b954cce9d8d65760ab1835 (diff) | |
parent | d42a5fd3e7fff38dbc8a82484dac53bfbcb61ac4 (diff) | |
download | frameworks_base-8705eb95b0e00d54bbc511351c6bb180bf3273de.zip frameworks_base-8705eb95b0e00d54bbc511351c6bb180bf3273de.tar.gz frameworks_base-8705eb95b0e00d54bbc511351c6bb180bf3273de.tar.bz2 |
Merge branch 'lmp-dev' of sso://googleplex-android.git.corp.google.com/platform/frameworks/base into lmp-dev
5 files changed, 181 insertions, 18 deletions
diff --git a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java index 1470b70..6215a8f 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java @@ -48,9 +48,16 @@ public class LegacyFaceDetectMapper { private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); private final Camera mCamera; + /** Is the camera capable of face detection? */ private final boolean mFaceDetectSupported; + /** Is the camera is running face detection? */ private boolean mFaceDetectEnabled = false; + /** Did the last request say to use SCENE_MODE = FACE_PRIORITY? */ + private boolean mFaceDetectScenePriority = false; + /** Did the last request enable the face detect mode to ON? */ + private boolean mFaceDetectReporting = false; + /** Synchronize access to all fields */ private final Object mLock = new Object(); private Camera.Face[] mFaces; private Camera.Face[] mFacesPrev; @@ -129,6 +136,17 @@ public class LegacyFaceDetectMapper { 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: @@ -145,7 +163,8 @@ public class LegacyFaceDetectMapper { return; } - boolean enableFaceDetect = fdMode != STATISTICS_FACE_DETECT_MODE_OFF; + 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) { @@ -166,6 +185,8 @@ public class LegacyFaceDetectMapper { } mFaceDetectEnabled = enableFaceDetect; + mFaceDetectScenePriority = sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY; + mFaceDetectReporting = fdMode != STATISTICS_FACE_DETECT_MODE_OFF; } } } @@ -177,6 +198,10 @@ public class LegacyFaceDetectMapper { * <p>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.</p> * + * <p>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.</p> + * * @param result a non-{@code null} result * @param legacyRequest a non-{@code null} request (read-only) */ @@ -186,16 +211,19 @@ public class LegacyFaceDetectMapper { Camera.Face[] faces, previousFaces; int fdMode; + boolean fdScenePriority; synchronized (mLock) { - fdMode = mFaceDetectEnabled ? + fdMode = mFaceDetectReporting ? STATISTICS_FACE_DETECT_MODE_SIMPLE : STATISTICS_FACE_DETECT_MODE_OFF; - if (mFaceDetectEnabled) { + if (mFaceDetectReporting) { faces = mFaces; } else { faces = null; } + fdScenePriority = mFaceDetectScenePriority; + previousFaces = mFacesPrev; mFacesPrev = faces; } @@ -227,5 +255,10 @@ public class LegacyFaceDetectMapper { 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); + } } } diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java index b05508b..0337c96 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java @@ -36,6 +36,7 @@ import android.hardware.camera2.utils.ParamsUtils; import android.util.Log; import android.util.Range; import android.util.Size; +import android.util.SizeF; import java.util.ArrayList; import java.util.Arrays; @@ -187,10 +188,6 @@ public class LegacyMetadataMapper { */ mapFlash(m, p); - /* - * request.* - */ - mapRequest(m, p); // TODO: map other fields /* @@ -223,6 +220,13 @@ public class LegacyMetadataMapper { */ mapScalerStreamConfigs(m, p); + // Order matters below: Put this last so that we can read the metadata set previously + + /* + * request.* + */ + mapRequest(m, p); + } private static void mapScalerStreamConfigs(CameraMetadataNative m, Camera.Parameters p) { @@ -535,9 +539,16 @@ public class LegacyMetadataMapper { * android.control.availableSceneModes */ List<String> sceneModes = p.getSupportedSceneModes(); - int[] supportedSceneModes = (sceneModes == null) ? new int[0] : - ArrayUtils.convertStringListToIntArray(sceneModes, sLegacySceneModes, sSceneModes); - m.set(CONTROL_AVAILABLE_SCENE_MODES, supportedSceneModes); + List<Integer> supportedSceneModes = + ArrayUtils.convertStringListToIntList(sceneModes, sLegacySceneModes, sSceneModes); + if (supportedSceneModes == null) { // camera1 doesn't support scene mode settings + supportedSceneModes = new ArrayList<Integer>(); + supportedSceneModes.add(CONTROL_SCENE_MODE_DISABLED); // disabled is always available + } + if (p.getMaxNumDetectedFaces() > 0) { // always supports FACE_PRIORITY when face detecting + supportedSceneModes.add(CONTROL_SCENE_MODE_FACE_PRIORITY); + } + m.set(CONTROL_AVAILABLE_SCENE_MODES, ArrayUtils.toIntArray(supportedSceneModes)); } private static void mapLens(CameraMetadataNative m, Camera.Parameters p) { @@ -545,11 +556,23 @@ public class LegacyMetadataMapper { * We can tell if the lens is fixed focus; * but if it's not, we can't tell the minimum focus distance, so leave it null then. */ - if (p.getFocusMode() == Camera.Parameters.FOCUS_MODE_FIXED) { + if (VERBOSE) { + Log.v(TAG, "mapLens - focus-mode='" + p.getFocusMode() + "'"); + } + + if (Camera.Parameters.FOCUS_MODE_FIXED.equals(p.getFocusMode())) { /* * lens.info.minimumFocusDistance */ m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS); + + if (VERBOSE) { + Log.v(TAG, "mapLens - lens.info.minimumFocusDistance = 0"); + } + } else { + if (VERBOSE) { + Log.v(TAG, "mapLens - lens.info.minimumFocusDistance is unknown"); + } } float[] focalLengths = new float[] { p.getFocalLength() }; @@ -620,7 +643,17 @@ public class LegacyMetadataMapper { CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT , CameraCharacteristics.SYNC_MAX_LATENCY , }; - m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, getTagsForKeys(availableKeys)); + List<Key<?>> characteristicsKeys = new ArrayList<>(Arrays.asList(availableKeys)); + + /* + * Add the conditional keys + */ + if (m.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE) != null) { + characteristicsKeys.add(LENS_INFO_MINIMUM_FOCUS_DISTANCE); + } + + m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, + getTagsForKeys(characteristicsKeys.toArray(new Key<?>[0]))); } /* @@ -757,6 +790,23 @@ public class LegacyMetadataMapper { * sensor.info.pixelArraySize */ m.set(SENSOR_INFO_PIXEL_ARRAY_SIZE, largestJpegSize); + + /* + * sensor.info.physicalSize + */ + { + /* + * Assume focal length is at infinity focus and that the lens is rectilinear. + */ + float focalLength = p.getFocalLength(); // in mm + double angleHor = p.getHorizontalViewAngle() * Math.PI / 180; // to radians + double angleVer = p.getVerticalViewAngle() * Math.PI / 180; // to radians + + float height = (float)Math.abs(2 * focalLength * Math.tan(angleVer / 2)); + float width = (float)Math.abs(2 * focalLength * Math.tan(angleHor / 2)); + + m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm + } } private static void mapStatistics(CameraMetadataNative m, Parameters p) { @@ -850,6 +900,11 @@ public class LegacyMetadataMapper { } static String convertSceneModeToLegacy(int mode) { + if (mode == CONTROL_SCENE_MODE_FACE_PRIORITY) { + // OK: Let LegacyFaceDetectMapper handle turning face detection on/off + return Parameters.SCENE_MODE_AUTO; + } + int index = ArrayUtils.getArrayIndex(sSceneModes, mode); if (index < 0) { return null; @@ -1057,7 +1112,24 @@ public class LegacyMetadataMapper { } // control.captureIntent - m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, templateId); + { + int captureIntent; + switch (templateId) { + case CameraDevice.TEMPLATE_PREVIEW: + captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; + break; + case CameraDevice.TEMPLATE_STILL_CAPTURE: + captureIntent = CONTROL_CAPTURE_INTENT_STILL_CAPTURE; + break; + case CameraDevice.TEMPLATE_RECORD: + captureIntent = CONTROL_CAPTURE_INTENT_VIDEO_RECORD; + break; + default: + // Can't get anything else since it's guarded by the IAE check + throw new AssertionError("Impossible; keep in sync with sAllowedTemplates"); + } + m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, captureIntent); + } // control.aeMode m.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON); @@ -1094,6 +1166,11 @@ public class LegacyMetadataMapper { } } + if (VERBOSE) { + Log.v(TAG, "createRequestTemplate (templateId=" + templateId + ")," + + " afMode=" + afMode + ", minimumFocusDistance=" + minimumFocusDistance); + } + m.set(CaptureRequest.CONTROL_AF_MODE, afMode); } diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java index 20f3fd2..35646fe 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java @@ -246,6 +246,19 @@ public class LegacyRequestMapper { // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported } + // control.captureIntent + { + int captureIntent = ParamsUtils.getOrDefault(request, + CONTROL_CAPTURE_INTENT, + /*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW); + + captureIntent = filterSupportedCaptureIntent(captureIntent); + + params.setRecordingHint( + captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD || + captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT); + } + // control.videoStabilizationMode { Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE, @@ -284,7 +297,7 @@ public class LegacyRequestMapper { switch (controlMode) { case CONTROL_MODE_USE_SCENE_MODE: { int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE, - /*defaultValue*/CONTROL_SCENE_MODE_DISABLED); + /*defaultValue*/CONTROL_SCENE_MODE_DISABLED); String legacySceneMode = LegacyMetadataMapper. convertSceneModeToLegacy(sceneMode); if (legacySceneMode != null) { @@ -339,6 +352,28 @@ public class LegacyRequestMapper { } } + static int filterSupportedCaptureIntent(int captureIntent) { + switch (captureIntent) { + case CONTROL_CAPTURE_INTENT_CUSTOM: + case CONTROL_CAPTURE_INTENT_PREVIEW: + case CONTROL_CAPTURE_INTENT_STILL_CAPTURE: + case CONTROL_CAPTURE_INTENT_VIDEO_RECORD: + case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT: + break; + case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG: + case CONTROL_CAPTURE_INTENT_MANUAL: + captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; + Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent + + "; default to PREVIEW"); + default: + captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; + Log.w(TAG, "Unknown control.captureIntent value " + captureIntent + + "; default to PREVIEW"); + } + + return captureIntent; + } + private static List<Camera.Area> convertMeteringRegionsToLegacy( Rect activeArray, ParameterUtils.ZoomData zoomData, MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) { diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java index a2487f4..a2f9b4c 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java @@ -35,9 +35,6 @@ import java.util.ArrayList; import java.util.List; import static com.android.internal.util.Preconditions.*; -import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF; -import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON; -import static android.hardware.camera2.CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE; import static android.hardware.camera2.CaptureResult.*; /** @@ -146,6 +143,19 @@ public class LegacyResultMapper { mapAwb(result, /*out*/params); /* + * control.captureIntent + */ + { + int captureIntent = ParamsUtils.getOrDefault(request, + CaptureRequest.CONTROL_CAPTURE_INTENT, + /*defaultValue*/CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW); + + captureIntent = LegacyRequestMapper.filterSupportedCaptureIntent(captureIntent); + + result.set(CONTROL_CAPTURE_INTENT, captureIntent); + } + + /* * control.mode */ { @@ -166,6 +176,8 @@ public class LegacyResultMapper { int mode = LegacyMetadataMapper.convertSceneModeFromLegacy(legacySceneMode); if (mode != LegacyMetadataMapper.UNKNOWN_MODE) { result.set(CaptureResult.CONTROL_SCENE_MODE, mode); + // In case of SCENE_MODE == FACE_PRIORITY, LegacyFaceDetectMapper will override + // the result to say SCENE_MODE == FACE_PRIORITY. } else { Log.w(TAG, "Unknown scene mode " + legacySceneMode + " returned by camera HAL, setting to disabled."); diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index ec233da7..5c66753 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -725,9 +725,15 @@ public class RequestThreadManager { CameraMetadataNative result = mMapper.cachedConvertResultMetadata( mLastRequest, timestampMutable.value); + /* + * Order matters: The default result mapper is state-less; the + * other mappers carry state and may override keys set by the default + * mapper with their own values. + */ + // Update AF state mFocusStateMapper.mapResultTriggers(result); - // Update detected faces list + // Update face-related results mFaceDetectMapper.mapResultFaces(result, mLastRequest); mDeviceState.setCaptureResult(holder, result); |