diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-06-20 18:00:19 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-06-20 02:04:45 +0000 |
commit | a783875420805448d67c2142526c53daed7e03aa (patch) | |
tree | 2b6c9ee31bdd6a6aa2d61b5b96ad5af5ee1334a0 /core/java/android/hardware | |
parent | e76e8bce93361ce580f5a9ab8aa1dbc39dbb3353 (diff) | |
parent | 5776aafc7e70c0b79c4bee2bc50f44121b37c962 (diff) | |
download | frameworks_base-a783875420805448d67c2142526c53daed7e03aa.zip frameworks_base-a783875420805448d67c2142526c53daed7e03aa.tar.gz frameworks_base-a783875420805448d67c2142526c53daed7e03aa.tar.bz2 |
Merge "camera2: Add AE antibanding + fps range metadata."
Diffstat (limited to 'core/java/android/hardware')
4 files changed, 167 insertions, 17 deletions
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 2cfb611..5bc59dc 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -18,6 +18,7 @@ package android.hardware.camera2; import android.hardware.camera2.CameraCharacteristics.Key; import android.hardware.camera2.impl.CameraMetadataNative; +import android.hardware.camera2.utils.HashCodeHelpers; import android.hardware.camera2.utils.TypeReference; import android.os.Parcel; import android.os.Parcelable; @@ -280,7 +281,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> @Override public int hashCode() { - return mSettings.hashCode(); + return HashCodeHelpers.hashCode(mSettings, mSurfaceSet, mUserTag); } public static final Parcelable.Creator<CaptureRequest> CREATOR = diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java index aa2f026..e4412ce 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java @@ -169,6 +169,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { } int numSurfaces = mSurfaces.size(); if (numSurfaces > 0) { + surfaces = new ArrayList<>(); for (int i = 0; i < numSurfaces; ++i) { surfaces.add(mSurfaces.valueAt(i)); } diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java index e675f87..6fa2134 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java @@ -21,12 +21,16 @@ import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Size; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.params.StreamConfiguration; import android.hardware.camera2.params.StreamConfigurationDuration; import android.util.Log; +import android.util.Range; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static com.android.internal.util.Preconditions.*; @@ -91,6 +95,8 @@ public class LegacyMetadataMapper { private static void mapCameraParameters(CameraMetadataNative m, Camera.Parameters p) { mapStreamConfigs(m, p); + mapAeConfig(m, p); + mapCapabilities(m, p); // TODO: map other fields } @@ -137,12 +143,61 @@ public class LegacyMetadataMapper { StreamConfigurationDuration[] jpegStalls = new StreamConfigurationDuration[jpegSizes.size()]; int i = 0; + long longestStallDuration = -1; for (Camera.Size s : jpegSizes) { + long stallDuration = calculateJpegStallDuration(s); jpegStalls[i++] = new StreamConfigurationDuration(HAL_PIXEL_FORMAT_BLOB, s.width, - s.height, calculateJpegStallDuration(s)); + s.height, stallDuration); + if (longestStallDuration < stallDuration) { + longestStallDuration = stallDuration; + } } // Set stall durations for jpeg, other formats use default stall duration m.set(SCALER_AVAILABLE_STALL_DURATIONS, jpegStalls); + + m.set(SENSOR_INFO_MAX_FRAME_DURATION, longestStallDuration); + } + + @SuppressWarnings({"unchecked"}) + private static void mapAeConfig(CameraMetadataNative m, Camera.Parameters p) { + + List<int[]> fpsRanges = p.getSupportedPreviewFpsRange(); + if (fpsRanges == null) { + throw new AssertionError("Supported FPS ranges cannot be null."); + } + int rangesSize = fpsRanges.size(); + if (rangesSize <= 0) { + throw new AssertionError("At least one FPS range must be supported."); + } + Range<Integer>[] ranges = new Range[rangesSize]; + int i = 0; + for (int[] r : fpsRanges) { + ranges[i++] = Range.create(r[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], + r[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); + } + m.set(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, ranges); + + List<String> antiBandingModes = p.getSupportedAntibanding(); + int antiBandingModesSize = antiBandingModes.size(); + if (antiBandingModesSize > 0) { + int[] modes = new int[antiBandingModesSize]; + int j = 0; + for (String mode : antiBandingModes) { + int convertedMode = convertAntiBandingMode(mode); + if (convertedMode == -1) { + Log.w(TAG, "Antibanding mode " + ((mode == null) ? "NULL" : mode) + + " not supported, skipping..."); + } else { + modes[j++] = convertedMode; + } + } + m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, Arrays.copyOf(modes, j)); + } + } + + private static void mapCapabilities(CameraMetadataNative m, Camera.Parameters p) { + int[] capabilities = { REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE }; + m.set(REQUEST_AVAILABLE_CAPABILITIES, capabilities); } private static void appendStreamConfig( @@ -155,6 +210,63 @@ public class LegacyMetadataMapper { } /** + * Returns -1 if the anti-banding mode string is null, or not supported. + */ + private static int convertAntiBandingMode(final String mode) { + if (mode == null) { + return -1; + } + switch(mode) { + case Camera.Parameters.ANTIBANDING_OFF: { + return CONTROL_AE_ANTIBANDING_MODE_OFF; + } + case Camera.Parameters.ANTIBANDING_50HZ: { + return CONTROL_AE_ANTIBANDING_MODE_50HZ; + } + case Camera.Parameters.ANTIBANDING_60HZ: { + return CONTROL_AE_ANTIBANDING_MODE_60HZ; + } + case Camera.Parameters.ANTIBANDING_AUTO: { + return CONTROL_AE_ANTIBANDING_MODE_AUTO; + } + default: { + return -1; + } + } + } + + /** + * Returns null if the anti-banding mode enum is not supported. + */ + private static String convertAntiBandingModeToLegacy(int mode) { + switch(mode) { + case CONTROL_AE_ANTIBANDING_MODE_OFF: { + return Camera.Parameters.ANTIBANDING_OFF; + } + case CONTROL_AE_ANTIBANDING_MODE_50HZ: { + return Camera.Parameters.ANTIBANDING_50HZ; + } + case CONTROL_AE_ANTIBANDING_MODE_60HZ: { + return Camera.Parameters.ANTIBANDING_60HZ; + } + case CONTROL_AE_ANTIBANDING_MODE_AUTO: { + return Camera.Parameters.ANTIBANDING_AUTO; + } + default: { + return null; + } + } + } + + + private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) { + int[] legacyFps = new int[2]; + legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower(); + legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper(); + return legacyFps; + } + + /** * Return the stall duration for a given output jpeg size in nanoseconds. * * <p>An 8mp image is chosen to have a stall duration of 0.8 seconds.</p> @@ -166,4 +278,45 @@ public class LegacyMetadataMapper { APPROXIMATE_SENSOR_AREA; // 600ms stall for 8mp return baseDuration + area * stallPerArea; } + + /** + * Generate capture result metadata from legacy camera parameters. + * + * @param params a {@link Camera.Parameters} object to generate metadata from. + * @param request the {@link CaptureRequest} used for this result. + * @param timestamp the timestamp to use for this result in nanoseconds. + * @return a {@link CameraMetadataNative} object containing result metadata. + */ + public static CameraMetadataNative convertResultMetadata(Camera.Parameters params, + CaptureRequest request, + long timestamp) { + CameraMetadataNative result = new CameraMetadataNative(); + result.set(CaptureResult.LENS_FOCAL_LENGTH, params.getFocalLength()); + result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp); + + // TODO: Remaining result metadata tags conversions. + return result; + } + + /** + * Set the legacy parameters using the request metadata. + * + * @param request a {@link CaptureRequest} object to generate parameters from. + * @param params the a {@link Camera.Parameters} to set parameters in. + */ + public static void convertRequestMetadata(CaptureRequest request, + /*out*/Camera.Parameters params) { + Integer antiBandingMode = request.get(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE); + if (antiBandingMode != null) { + String legacyMode = convertAntiBandingModeToLegacy(antiBandingMode); + if (legacyMode != null) params.setAntibanding(legacyMode); + } + + Range<Integer> aeFpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE); + if (aeFpsRange != null) { + int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange); + params.setPreviewFpsRange(legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], + legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); + } + } } diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index 9b68e9b..e0f3429 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -19,7 +19,6 @@ package android.hardware.camera2.legacy; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.hardware.camera2.CaptureRequest; -import android.hardware.camera2.CaptureResult; import android.hardware.camera2.utils.LongParcelable; import android.hardware.camera2.impl.CameraMetadataNative; import android.os.ConditionVariable; @@ -84,6 +83,7 @@ public class RequestThreadManager { private Size mIntermediateBufferSize; private final RequestQueue mRequestQueue = new RequestQueue(); + private CaptureRequest mLastRequest = null; private SurfaceTexture mDummyTexture; private Surface mDummySurface; @@ -430,7 +430,6 @@ public class RequestThreadManager { private final Handler.Callback mRequestHandlerCb = new Handler.Callback() { private boolean mCleanup = false; - private final List<RequestHolder> mRepeating = null; @SuppressWarnings("unchecked") @Override @@ -474,6 +473,13 @@ public class RequestThreadManager { List<RequestHolder> requests = nextBurst.first.produceRequestHolders(nextBurst.second); for (RequestHolder holder : requests) { + CaptureRequest request = holder.getRequest(); + if (mLastRequest == null || mLastRequest != request) { + mLastRequest = request; + LegacyMetadataMapper.convertRequestMetadata(mLastRequest, + /*out*/mParams); + mCamera.setParameters(mParams); + } mDeviceState.setCaptureStart(holder); long timestamp = 0; try { @@ -501,8 +507,8 @@ public class RequestThreadManager { // TODO: err handling throw new IOError(e); } - CameraMetadataNative result = convertResultMetadata(mParams, - holder.getRequest(), timestamp); + CameraMetadataNative result = LegacyMetadataMapper.convertResultMetadata(mParams, + request, timestamp); mDeviceState.setCaptureResult(holder, result); } if (DEBUG) { @@ -526,17 +532,6 @@ public class RequestThreadManager { } }; - private CameraMetadataNative convertResultMetadata(Camera.Parameters params, - CaptureRequest request, - long timestamp) { - CameraMetadataNative result = new CameraMetadataNative(); - result.set(CaptureResult.LENS_FOCAL_LENGTH, params.getFocalLength()); - result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp); - - // TODO: Remaining result metadata tags conversions. - return result; - } - /** * Create a new RequestThreadManager. * |