Skip to content

Commit 8c4486c

Browse files
committed
camera: (Legacy) Add support for SCENE_MODE == FACE_PRIORITY
Bug: 16898478 Change-Id: I4306f6380ea06e8bd95af8738e5dde1a42a8098c
1 parent 61da0fd commit 8c4486c

5 files changed

Lines changed: 61 additions & 11 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: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,9 +535,16 @@ private static void mapControlOther(CameraMetadataNative m, Camera.Parameters p)
535535
* android.control.availableSceneModes
536536
*/
537537
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);
538+
List<Integer> supportedSceneModes =
539+
ArrayUtils.convertStringListToIntList(sceneModes, sLegacySceneModes, sSceneModes);
540+
if (supportedSceneModes == null) { // camera1 doesn't support scene mode settings
541+
supportedSceneModes = new ArrayList<Integer>();
542+
supportedSceneModes.add(CONTROL_SCENE_MODE_DISABLED); // disabled is always available
543+
}
544+
if (p.getMaxNumDetectedFaces() > 0) { // always supports FACE_PRIORITY when face detecting
545+
supportedSceneModes.add(CONTROL_SCENE_MODE_FACE_PRIORITY);
546+
}
547+
m.set(CONTROL_AVAILABLE_SCENE_MODES, ArrayUtils.toIntArray(supportedSceneModes));
541548
}
542549

543550
private static void mapLens(CameraMetadataNative m, Camera.Parameters p) {
@@ -850,6 +857,11 @@ static int convertSceneModeFromLegacy(String mode) {
850857
}
851858

852859
static String convertSceneModeToLegacy(int mode) {
860+
if (mode == CONTROL_SCENE_MODE_FACE_PRIORITY) {
861+
// OK: Let LegacyFaceDetectMapper handle turning face detection on/off
862+
return Parameters.SCENE_MODE_AUTO;
863+
}
864+
853865
int index = ArrayUtils.getArrayIndex(sSceneModes, mode);
854866
if (index < 0) {
855867
return null;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public static void convertRequestMetadata(LegacyRequest legacyRequest) {
284284
switch (controlMode) {
285285
case CONTROL_MODE_USE_SCENE_MODE: {
286286
int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE,
287-
/*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
287+
/*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
288288
String legacySceneMode = LegacyMetadataMapper.
289289
convertSceneModeToLegacy(sceneMode);
290290
if (legacySceneMode != null) {

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

Lines changed: 2 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
/**
@@ -166,6 +163,8 @@ private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRe
166163
int mode = LegacyMetadataMapper.convertSceneModeFromLegacy(legacySceneMode);
167164
if (mode != LegacyMetadataMapper.UNKNOWN_MODE) {
168165
result.set(CaptureResult.CONTROL_SCENE_MODE, mode);
166+
// In case of SCENE_MODE == FACE_PRIORITY, LegacyFaceDetectMapper will override
167+
// the result to say SCENE_MODE == FACE_PRIORITY.
169168
} else {
170169
Log.w(TAG, "Unknown scene mode " + legacySceneMode +
171170
" 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)