diff options
Diffstat (limited to 'src/com/android/camera/util/CameraUtil.java')
-rw-r--r-- | src/com/android/camera/util/CameraUtil.java | 94 |
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); + } } |