summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]src/com/android/camera/CaptureModule.java4
-rw-r--r--src/com/android/camera/SettingsManager.java5
-rw-r--r--src/com/android/camera/util/CameraUtil.java94
3 files changed, 101 insertions, 2 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 184b03a1d..e870161f3 100755..100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -2716,8 +2716,8 @@ public class CaptureModule implements CameraModule, PhotoController,
CameraConstrainedHighSpeedCaptureSession session =
(CameraConstrainedHighSpeedCaptureSession) mCurrentSession;
try {
- List list = session
- .createHighSpeedRequestList(mVideoRequestBuilder.build());
+ List list = CameraUtil
+ .createHighSpeedRequestList(mVideoRequestBuilder.build(),cameraId);
session.setRepeatingBurst(list, mCaptureCallback, mCameraHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to start high speed video recording "
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 3e2c7873d..6adbcfb64 100644
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -1101,6 +1101,11 @@ public class SettingsManager implements ListMenu.SettingsListener {
return mCharacteristics.get(cameraId).get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
}
+ public StreamConfigurationMap getStreamConfigurationMap(int cameraId){
+ return mCharacteristics.get(cameraId)
+ .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ }
+
public List<String> getSupportedColorEffects(int cameraId) {
int[] flashModes = mCharacteristics.get(cameraId).get(CameraCharacteristics
.CONTROL_AVAILABLE_EFFECTS);
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);
+ }
}