Skip to content

Commit 8705eb9

Browse files
author
Geoff Mendal
committed
Merge branch 'lmp-dev' of sso://googleplex-android.git.corp.google.com/platform/frameworks/base into lmp-dev
2 parents 3f19789 + d42a5fd commit 8705eb9

5 files changed

Lines changed: 181 additions & 18 deletions

File tree

core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,16 @@ public class LegacyFaceDetectMapper {
4848
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
4949

5050
private final Camera mCamera;
51+
/** Is the camera capable of face detection? */
5152
private final boolean mFaceDetectSupported;
53+
/** Is the camera is running face detection? */
5254
private boolean mFaceDetectEnabled = false;
55+
/** Did the last request say to use SCENE_MODE = FACE_PRIORITY? */
56+
private boolean mFaceDetectScenePriority = false;
57+
/** Did the last request enable the face detect mode to ON? */
58+
private boolean mFaceDetectReporting = false;
5359

60+
/** Synchronize access to all fields */
5461
private final Object mLock = new Object();
5562
private Camera.Face[] mFaces;
5663
private Camera.Face[] mFacesPrev;
@@ -129,6 +136,17 @@ public void processFaceDetectMode(CaptureRequest captureRequest,
129136
return;
130137
}
131138

139+
/*
140+
* control.sceneMode
141+
*/
142+
int sceneMode = ParamsUtils.getOrDefault(captureRequest, CONTROL_SCENE_MODE,
143+
CONTROL_SCENE_MODE_DISABLED);
144+
if (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY && !mFaceDetectSupported) {
145+
Log.w(TAG, "processFaceDetectMode - ignoring control.sceneMode == FACE_PRIORITY; " +
146+
"face detection is not available");
147+
return;
148+
}
149+
132150
// Print some warnings out in case the values were wrong
133151
switch (fdMode) {
134152
case STATISTICS_FACE_DETECT_MODE_OFF:
@@ -145,7 +163,8 @@ public void processFaceDetectMode(CaptureRequest captureRequest,
145163
return;
146164
}
147165

148-
boolean enableFaceDetect = fdMode != STATISTICS_FACE_DETECT_MODE_OFF;
166+
boolean enableFaceDetect = (fdMode != STATISTICS_FACE_DETECT_MODE_OFF)
167+
|| (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY);
149168
synchronized (mLock) {
150169
// Enable/disable face detection if it's changed since last time
151170
if (enableFaceDetect != mFaceDetectEnabled) {
@@ -166,6 +185,8 @@ public void processFaceDetectMode(CaptureRequest captureRequest,
166185
}
167186

168187
mFaceDetectEnabled = enableFaceDetect;
188+
mFaceDetectScenePriority = sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY;
189+
mFaceDetectReporting = fdMode != STATISTICS_FACE_DETECT_MODE_OFF;
169190
}
170191
}
171192
}
@@ -177,6 +198,10 @@ public void processFaceDetectMode(CaptureRequest captureRequest,
177198
* <p>Face detect callbacks are processed in the background, and each call to
178199
* {@link #mapResultFaces} will have the latest faces as reflected by the camera1 callbacks.</p>
179200
*
201+
* <p>If the scene mode was set to {@code FACE_PRIORITY} but face detection is disabled,
202+
* the camera will still run face detection in the background, but no faces will be reported
203+
* in the capture result.</p>
204+
*
180205
* @param result a non-{@code null} result
181206
* @param legacyRequest a non-{@code null} request (read-only)
182207
*/
@@ -186,16 +211,19 @@ public void mapResultFaces(CameraMetadataNative result, LegacyRequest legacyRequ
186211

187212
Camera.Face[] faces, previousFaces;
188213
int fdMode;
214+
boolean fdScenePriority;
189215
synchronized (mLock) {
190-
fdMode = mFaceDetectEnabled ?
216+
fdMode = mFaceDetectReporting ?
191217
STATISTICS_FACE_DETECT_MODE_SIMPLE : STATISTICS_FACE_DETECT_MODE_OFF;
192218

193-
if (mFaceDetectEnabled) {
219+
if (mFaceDetectReporting) {
194220
faces = mFaces;
195221
} else {
196222
faces = null;
197223
}
198224

225+
fdScenePriority = mFaceDetectScenePriority;
226+
199227
previousFaces = mFacesPrev;
200228
mFacesPrev = faces;
201229
}
@@ -227,5 +255,10 @@ public void mapResultFaces(CameraMetadataNative result, LegacyRequest legacyRequ
227255

228256
result.set(CaptureResult.STATISTICS_FACES, convertedFaces.toArray(new Face[0]));
229257
result.set(CaptureResult.STATISTICS_FACE_DETECT_MODE, fdMode);
258+
259+
// Override scene mode with FACE_PRIORITY if the request was using FACE_PRIORITY
260+
if (fdScenePriority) {
261+
result.set(CaptureResult.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_FACE_PRIORITY);
262+
}
230263
}
231264
}

core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import android.util.Log;
3737
import android.util.Range;
3838
import android.util.Size;
39+
import android.util.SizeF;
3940

4041
import java.util.ArrayList;
4142
import java.util.Arrays;
@@ -187,10 +188,6 @@ private static void mapCharacteristicsFromParameters(CameraMetadataNative m,
187188
*/
188189
mapFlash(m, p);
189190

190-
/*
191-
* request.*
192-
*/
193-
mapRequest(m, p);
194191
// TODO: map other fields
195192

196193
/*
@@ -223,6 +220,13 @@ private static void mapCharacteristicsFromParameters(CameraMetadataNative m,
223220
*/
224221
mapScalerStreamConfigs(m, p);
225222

223+
// Order matters below: Put this last so that we can read the metadata set previously
224+
225+
/*
226+
* request.*
227+
*/
228+
mapRequest(m, p);
229+
226230
}
227231

228232
private static void mapScalerStreamConfigs(CameraMetadataNative m, Camera.Parameters p) {
@@ -535,21 +539,40 @@ private static void mapControlOther(CameraMetadataNative m, Camera.Parameters p)
535539
* android.control.availableSceneModes
536540
*/
537541
List<String> sceneModes = p.getSupportedSceneModes();
538-
int[] supportedSceneModes = (sceneModes == null) ? new int[0] :
539-
ArrayUtils.convertStringListToIntArray(sceneModes, sLegacySceneModes, sSceneModes);
540-
m.set(CONTROL_AVAILABLE_SCENE_MODES, supportedSceneModes);
542+
List<Integer> supportedSceneModes =
543+
ArrayUtils.convertStringListToIntList(sceneModes, sLegacySceneModes, sSceneModes);
544+
if (supportedSceneModes == null) { // camera1 doesn't support scene mode settings
545+
supportedSceneModes = new ArrayList<Integer>();
546+
supportedSceneModes.add(CONTROL_SCENE_MODE_DISABLED); // disabled is always available
547+
}
548+
if (p.getMaxNumDetectedFaces() > 0) { // always supports FACE_PRIORITY when face detecting
549+
supportedSceneModes.add(CONTROL_SCENE_MODE_FACE_PRIORITY);
550+
}
551+
m.set(CONTROL_AVAILABLE_SCENE_MODES, ArrayUtils.toIntArray(supportedSceneModes));
541552
}
542553

543554
private static void mapLens(CameraMetadataNative m, Camera.Parameters p) {
544555
/*
545556
* We can tell if the lens is fixed focus;
546557
* but if it's not, we can't tell the minimum focus distance, so leave it null then.
547558
*/
548-
if (p.getFocusMode() == Camera.Parameters.FOCUS_MODE_FIXED) {
559+
if (VERBOSE) {
560+
Log.v(TAG, "mapLens - focus-mode='" + p.getFocusMode() + "'");
561+
}
562+
563+
if (Camera.Parameters.FOCUS_MODE_FIXED.equals(p.getFocusMode())) {
549564
/*
550565
* lens.info.minimumFocusDistance
551566
*/
552567
m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS);
568+
569+
if (VERBOSE) {
570+
Log.v(TAG, "mapLens - lens.info.minimumFocusDistance = 0");
571+
}
572+
} else {
573+
if (VERBOSE) {
574+
Log.v(TAG, "mapLens - lens.info.minimumFocusDistance is unknown");
575+
}
553576
}
554577

555578
float[] focalLengths = new float[] { p.getFocalLength() };
@@ -620,7 +643,17 @@ private static void mapRequest(CameraMetadataNative m, Parameters p) {
620643
CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT ,
621644
CameraCharacteristics.SYNC_MAX_LATENCY ,
622645
};
623-
m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, getTagsForKeys(availableKeys));
646+
List<Key<?>> characteristicsKeys = new ArrayList<>(Arrays.asList(availableKeys));
647+
648+
/*
649+
* Add the conditional keys
650+
*/
651+
if (m.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE) != null) {
652+
characteristicsKeys.add(LENS_INFO_MINIMUM_FOCUS_DISTANCE);
653+
}
654+
655+
m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
656+
getTagsForKeys(characteristicsKeys.toArray(new Key<?>[0])));
624657
}
625658

626659
/*
@@ -757,6 +790,23 @@ private static void mapSensor(CameraMetadataNative m, Parameters p) {
757790
* sensor.info.pixelArraySize
758791
*/
759792
m.set(SENSOR_INFO_PIXEL_ARRAY_SIZE, largestJpegSize);
793+
794+
/*
795+
* sensor.info.physicalSize
796+
*/
797+
{
798+
/*
799+
* Assume focal length is at infinity focus and that the lens is rectilinear.
800+
*/
801+
float focalLength = p.getFocalLength(); // in mm
802+
double angleHor = p.getHorizontalViewAngle() * Math.PI / 180; // to radians
803+
double angleVer = p.getVerticalViewAngle() * Math.PI / 180; // to radians
804+
805+
float height = (float)Math.abs(2 * focalLength * Math.tan(angleVer / 2));
806+
float width = (float)Math.abs(2 * focalLength * Math.tan(angleHor / 2));
807+
808+
m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm
809+
}
760810
}
761811

762812
private static void mapStatistics(CameraMetadataNative m, Parameters p) {
@@ -850,6 +900,11 @@ static int convertSceneModeFromLegacy(String mode) {
850900
}
851901

852902
static String convertSceneModeToLegacy(int mode) {
903+
if (mode == CONTROL_SCENE_MODE_FACE_PRIORITY) {
904+
// OK: Let LegacyFaceDetectMapper handle turning face detection on/off
905+
return Parameters.SCENE_MODE_AUTO;
906+
}
907+
853908
int index = ArrayUtils.getArrayIndex(sSceneModes, mode);
854909
if (index < 0) {
855910
return null;
@@ -1057,7 +1112,24 @@ public static CameraMetadataNative createRequestTemplate(
10571112
}
10581113

10591114
// control.captureIntent
1060-
m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, templateId);
1115+
{
1116+
int captureIntent;
1117+
switch (templateId) {
1118+
case CameraDevice.TEMPLATE_PREVIEW:
1119+
captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
1120+
break;
1121+
case CameraDevice.TEMPLATE_STILL_CAPTURE:
1122+
captureIntent = CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1123+
break;
1124+
case CameraDevice.TEMPLATE_RECORD:
1125+
captureIntent = CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1126+
break;
1127+
default:
1128+
// Can't get anything else since it's guarded by the IAE check
1129+
throw new AssertionError("Impossible; keep in sync with sAllowedTemplates");
1130+
}
1131+
m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, captureIntent);
1132+
}
10611133

10621134
// control.aeMode
10631135
m.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
@@ -1094,6 +1166,11 @@ public static CameraMetadataNative createRequestTemplate(
10941166
}
10951167
}
10961168

1169+
if (VERBOSE) {
1170+
Log.v(TAG, "createRequestTemplate (templateId=" + templateId + ")," +
1171+
" afMode=" + afMode + ", minimumFocusDistance=" + minimumFocusDistance);
1172+
}
1173+
10971174
m.set(CaptureRequest.CONTROL_AF_MODE, afMode);
10981175
}
10991176

core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,19 @@ public static void convertRequestMetadata(LegacyRequest legacyRequest) {
246246
// TODO: Don't add control.awbLock to availableRequestKeys if it's not supported
247247
}
248248

249+
// control.captureIntent
250+
{
251+
int captureIntent = ParamsUtils.getOrDefault(request,
252+
CONTROL_CAPTURE_INTENT,
253+
/*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW);
254+
255+
captureIntent = filterSupportedCaptureIntent(captureIntent);
256+
257+
params.setRecordingHint(
258+
captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD ||
259+
captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
260+
}
261+
249262
// control.videoStabilizationMode
250263
{
251264
Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE,
@@ -284,7 +297,7 @@ public static void convertRequestMetadata(LegacyRequest legacyRequest) {
284297
switch (controlMode) {
285298
case CONTROL_MODE_USE_SCENE_MODE: {
286299
int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE,
287-
/*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
300+
/*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
288301
String legacySceneMode = LegacyMetadataMapper.
289302
convertSceneModeToLegacy(sceneMode);
290303
if (legacySceneMode != null) {
@@ -339,6 +352,28 @@ public static void convertRequestMetadata(LegacyRequest legacyRequest) {
339352
}
340353
}
341354

355+
static int filterSupportedCaptureIntent(int captureIntent) {
356+
switch (captureIntent) {
357+
case CONTROL_CAPTURE_INTENT_CUSTOM:
358+
case CONTROL_CAPTURE_INTENT_PREVIEW:
359+
case CONTROL_CAPTURE_INTENT_STILL_CAPTURE:
360+
case CONTROL_CAPTURE_INTENT_VIDEO_RECORD:
361+
case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT:
362+
break;
363+
case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG:
364+
case CONTROL_CAPTURE_INTENT_MANUAL:
365+
captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
366+
Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent
367+
+ "; default to PREVIEW");
368+
default:
369+
captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
370+
Log.w(TAG, "Unknown control.captureIntent value " + captureIntent
371+
+ "; default to PREVIEW");
372+
}
373+
374+
return captureIntent;
375+
}
376+
342377
private static List<Camera.Area> convertMeteringRegionsToLegacy(
343378
Rect activeArray, ParameterUtils.ZoomData zoomData,
344379
MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) {

core/java/android/hardware/camera2/legacy/LegacyResultMapper.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@
3535
import java.util.List;
3636

3737
import static com.android.internal.util.Preconditions.*;
38-
import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF;
39-
import static android.hardware.camera2.CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON;
40-
import static android.hardware.camera2.CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE;
4138
import static android.hardware.camera2.CaptureResult.*;
4239

4340
/**
@@ -145,6 +142,19 @@ private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRe
145142
*/
146143
mapAwb(result, /*out*/params);
147144

145+
/*
146+
* control.captureIntent
147+
*/
148+
{
149+
int captureIntent = ParamsUtils.getOrDefault(request,
150+
CaptureRequest.CONTROL_CAPTURE_INTENT,
151+
/*defaultValue*/CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
152+
153+
captureIntent = LegacyRequestMapper.filterSupportedCaptureIntent(captureIntent);
154+
155+
result.set(CONTROL_CAPTURE_INTENT, captureIntent);
156+
}
157+
148158
/*
149159
* control.mode
150160
*/
@@ -166,6 +176,8 @@ private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRe
166176
int mode = LegacyMetadataMapper.convertSceneModeFromLegacy(legacySceneMode);
167177
if (mode != LegacyMetadataMapper.UNKNOWN_MODE) {
168178
result.set(CaptureResult.CONTROL_SCENE_MODE, mode);
179+
// In case of SCENE_MODE == FACE_PRIORITY, LegacyFaceDetectMapper will override
180+
// the result to say SCENE_MODE == FACE_PRIORITY.
169181
} else {
170182
Log.w(TAG, "Unknown scene mode " + legacySceneMode +
171183
" returned by camera HAL, setting to disabled.");

core/java/android/hardware/camera2/legacy/RequestThreadManager.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,15 @@ public boolean handleMessage(Message msg) {
725725

726726
CameraMetadataNative result = mMapper.cachedConvertResultMetadata(
727727
mLastRequest, timestampMutable.value);
728+
/*
729+
* Order matters: The default result mapper is state-less; the
730+
* other mappers carry state and may override keys set by the default
731+
* mapper with their own values.
732+
*/
733+
728734
// Update AF state
729735
mFocusStateMapper.mapResultTriggers(result);
730-
// Update detected faces list
736+
// Update face-related results
731737
mFaceDetectMapper.mapResultFaces(result, mLastRequest);
732738

733739
mDeviceState.setCaptureResult(holder, result);

0 commit comments

Comments
 (0)