summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/util/CameraUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/util/CameraUtil.java')
-rw-r--r--src/com/android/camera/util/CameraUtil.java94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 838f8d950..cb414bac0 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -71,9 +71,22 @@ import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
+import java.util.ArrayList;
import java.util.Locale;
+import android.util.Range;
import java.util.StringTokenizer;
+import com.android.camera.SettingsManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.utils.SurfaceUtils;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
/**
* Collection of utility functions used in this package.
*/
@@ -1275,4 +1288,85 @@ public class CameraUtil {
(long) rhs.getWidth() * rhs.getHeight());
}
}
+
+ public static List<CaptureRequest> createHighSpeedRequestList(CaptureRequest request
+ ,int cameraId) throws CameraAccessException {
+ if (request == null) {
+ throw new IllegalArgumentException("Input capture request must not be null");
+ }
+ Collection<Surface> outputSurfaces = request.getTargets();
+ Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+
+ StreamConfigurationMap config =
+ SettingsManager.getInstance().getStreamConfigurationMap(cameraId);
+ SurfaceUtils.checkConstrainedHighSpeedSurfaces(outputSurfaces, fpsRange, config);
+
+ // Request list size: to limit the preview to 30fps, need use maxFps/30; to maximize
+ // the preview frame rate, should use maxBatch size for that high speed stream
+ // configuration. We choose the former for now.
+ int requestListSize = fpsRange.getUpper() / 30;
+ List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
+
+ // Prepare the Request builders: need carry over the request controls.
+ // First, create a request builder that will only include preview or recording target.
+ CameraMetadataNative requestMetadata = new CameraMetadataNative(request.getNativeCopy());
+ // Note that after this step, the requestMetadata is mutated (swapped) and can not be used
+ // for next request builder creation.
+ CaptureRequest.Builder singleTargetRequestBuilder = new CaptureRequest.Builder(
+ requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+ singleTargetRequestBuilder.setTag(cameraId);
+
+ // Overwrite the capture intent to make sure a good value is set.
+ Iterator<Surface> iterator = outputSurfaces.iterator();
+ Surface firstSurface = iterator.next();
+ Surface secondSurface = null;
+ if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(firstSurface)) {
+ singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
+ } else {
+ // Video only, or preview + video
+ singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ }
+ singleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
+
+ // Second, Create a request builder that will include both preview and recording targets.
+ CaptureRequest.Builder doubleTargetRequestBuilder = null;
+ if (outputSurfaces.size() == 2) {
+ // Have to create a new copy, the original one was mutated after a new
+ // CaptureRequest.Builder creation.
+ requestMetadata = new CameraMetadataNative(request.getNativeCopy());
+ doubleTargetRequestBuilder = new CaptureRequest.Builder(
+ requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+ doubleTargetRequestBuilder.setTag(cameraId);
+ doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ doubleTargetRequestBuilder.addTarget(firstSurface);
+ secondSurface = iterator.next();
+ doubleTargetRequestBuilder.addTarget(secondSurface);
+ doubleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
+ // Make sure singleTargetRequestBuilder contains only recording surface for
+ // preview + recording case.
+ Surface recordingSurface = firstSurface;
+ if (!SurfaceUtils.isSurfaceForHwVideoEncoder(recordingSurface)) {
+ recordingSurface = secondSurface;
+ }
+ singleTargetRequestBuilder.addTarget(recordingSurface);
+ } else {
+ // Single output case: either recording or preview.
+ singleTargetRequestBuilder.addTarget(firstSurface);
+ }
+
+ // Generate the final request list.
+ for (int i = 0; i < requestListSize; i++) {
+ if (i == 0 && doubleTargetRequestBuilder != null) {
+ // First request should be recording + preview request
+ requestList.add(doubleTargetRequestBuilder.build());
+ } else {
+ requestList.add(singleTargetRequestBuilder.build());
+ }
+ }
+
+ return Collections.unmodifiableList(requestList);
+ }
}