summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Mendal <mendal@google.com>2014-08-11 13:31:17 -0700
committerGeoff Mendal <mendal@google.com>2014-08-11 13:31:17 -0700
commit8705eb95b0e00d54bbc511351c6bb180bf3273de (patch)
tree7c847360ac3e2710b767db0a03989d0064f68e2b
parent3f19789b7703695531b954cce9d8d65760ab1835 (diff)
parentd42a5fd3e7fff38dbc8a82484dac53bfbcb61ac4 (diff)
downloadframeworks_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
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java39
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java97
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java37
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyResultMapper.java18
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestThreadManager.java8
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);