diff options
author | Yin-Chia Yeh <yinchiayeh@google.com> | 2014-07-15 10:37:31 -0700 |
---|---|---|
committer | Yin-Chia Yeh <yinchiayeh@google.com> | 2014-07-18 16:00:53 -0700 |
commit | 12da140082323d9aa048b3e928505a0a2adfdda7 (patch) | |
tree | ed8d6f11bc72817b7f9f69c6d8b3c4d2c5764109 | |
parent | a4ab780877808dbee334f7c7cc4acefa0aa313b2 (diff) | |
download | frameworks_base-12da140082323d9aa048b3e928505a0a2adfdda7.zip frameworks_base-12da140082323d9aa048b3e928505a0a2adfdda7.tar.gz frameworks_base-12da140082323d9aa048b3e928505a0a2adfdda7.tar.bz2 |
Camera2: add highSpeedVideoConfig wrapper and APIs
- Add wrapper class for highSpeedVideoConfiguration.
- Add APIs to query high speed video recording configurations in
StreamConfigurationMap
- Fix ColorSpaceTransform unit test in CameraMetadataTest
- Fix a bug in HashCodeHelper
Change-Id: I192e57f6ab5dfbba6d958571352f067a9eaec7b2
8 files changed, 483 insertions, 11 deletions
diff --git a/api/current.txt b/api/current.txt index 623c281..2c07d55 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12946,6 +12946,10 @@ package android.hardware.camera2.params { } public final class StreamConfigurationMap { + method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges(); + method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size); + method public android.util.Size[] getHighSpeedVideoSizes(); + method public android.util.Size[] getHighSpeedVideoSizesFor(android.util.Range<java.lang.Integer>); method public final int[] getOutputFormats(); method public long getOutputMinFrameDuration(int, android.util.Size); method public long getOutputMinFrameDuration(java.lang.Class<T>, android.util.Size); diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 4b1659f..f2553b19 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -494,7 +494,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * to do high speed recording, it can select the maximum size reported by this metadata to * configure output streams. Once the size is selected, application can filter this metadata * by selected size and get the supported fps ranges, and use these fps ranges to setup the - * recording requests.</p> + * recording requests. Note that for the use case of multiple output streams, application + * must select one unique size from this metadata to use. Otherwise a request error might + * occur.</p> * <p>For normal video recording use case, where some application will NOT set * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the fps ranges * reported in this metadata must not be used to setup capture requests, or it will cause @@ -504,8 +506,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see CaptureRequest#CONTROL_SCENE_MODE * @hide */ - public static final Key<int[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = - new Key<int[]>("android.control.availableHighSpeedVideoConfigurations", int[].class); + public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = + new Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]>("android.control.availableHighSpeedVideoConfigurations", android.hardware.camera2.params.HighSpeedVideoConfiguration[].class); /** * <p>The set of edge enhancement modes supported by this camera device.</p> diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 6de5c25..5f87efb 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -30,6 +30,7 @@ import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean; import android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern; import android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform; import android.hardware.camera2.marshal.impl.MarshalQueryableEnum; +import android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration; import android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle; import android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger; import android.hardware.camera2.marshal.impl.MarshalQueryablePair; @@ -45,6 +46,7 @@ import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration; import android.hardware.camera2.marshal.impl.MarshalQueryableString; import android.hardware.camera2.params.Face; +import android.hardware.camera2.params.HighSpeedVideoConfiguration; import android.hardware.camera2.params.LensShadingMap; import android.hardware.camera2.params.StreamConfiguration; import android.hardware.camera2.params.StreamConfigurationDuration; @@ -665,8 +667,11 @@ public class CameraMetadataNative implements Parcelable { CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS); StreamConfigurationDuration[] stallDurations = getBase( CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS); + HighSpeedVideoConfiguration[] highSpeedVideoConfigurations = getBase( + CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS); - return new StreamConfigurationMap(configurations, minFrameDurations, stallDurations); + return new StreamConfigurationMap( + configurations, minFrameDurations, stallDurations, highSpeedVideoConfigurations); } private <T> Integer getMaxRegions(Key<T> key) { @@ -1015,6 +1020,7 @@ public class CameraMetadataNative implements Parcelable { new MarshalQueryableStreamConfigurationDuration(), new MarshalQueryableRggbChannelVector(), new MarshalQueryableBlackLevelPattern(), + new MarshalQueryableHighSpeedVideoConfiguration(), // generic parcelable marshaler (MUST BE LAST since it has lowest priority) new MarshalQueryableParcelable(), diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java new file mode 100644 index 0000000..c03144b --- /dev/null +++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.camera2.marshal.impl; + +import android.hardware.camera2.marshal.Marshaler; +import android.hardware.camera2.marshal.MarshalQueryable; +import android.hardware.camera2.params.HighSpeedVideoConfiguration; +import android.hardware.camera2.utils.TypeReference; + +import static android.hardware.camera2.impl.CameraMetadataNative.*; +import static android.hardware.camera2.marshal.MarshalHelpers.*; + +import java.nio.ByteBuffer; + +/** + * Marshaler for {@code android.control.availableHighSpeedVideoConfigurations} custom class + * {@link HighSpeedVideoConfiguration} + * + * <p>Data is stored as {@code (width, height, fpsMin, fpsMax)} tuples (int32).</p> + */ +public class MarshalQueryableHighSpeedVideoConfiguration + implements MarshalQueryable<HighSpeedVideoConfiguration> { + private static final int SIZE = SIZEOF_INT32 * 4; + + private class MarshalerHighSpeedVideoConfiguration + extends Marshaler<HighSpeedVideoConfiguration> { + protected MarshalerHighSpeedVideoConfiguration( + TypeReference<HighSpeedVideoConfiguration> typeReference, + int nativeType) { + super(MarshalQueryableHighSpeedVideoConfiguration.this, typeReference, nativeType); + } + + @Override + public void marshal(HighSpeedVideoConfiguration value, ByteBuffer buffer) { + buffer.putInt(value.getWidth()); + buffer.putInt(value.getHeight()); + buffer.putInt(value.getFpsMin()); + buffer.putInt(value.getFpsMax()); + } + + @Override + public HighSpeedVideoConfiguration unmarshal(ByteBuffer buffer) { + int width = buffer.getInt(); + int height = buffer.getInt(); + int fpsMin = buffer.getInt(); + int fpsMax = buffer.getInt(); + + return new HighSpeedVideoConfiguration(width, height, fpsMin, fpsMax); + } + + @Override + public int getNativeSize() { + return SIZE; + } + + } + + @Override + public Marshaler<HighSpeedVideoConfiguration> createMarshaler( + TypeReference<HighSpeedVideoConfiguration> managedType, int nativeType) { + return new MarshalerHighSpeedVideoConfiguration(managedType, nativeType); + } + + @Override + public boolean isTypeMappingSupported(TypeReference<HighSpeedVideoConfiguration> managedType, + int nativeType) { + return nativeType == TYPE_INT32 && + managedType.getType().equals(HighSpeedVideoConfiguration.class); + } +} diff --git a/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java new file mode 100644 index 0000000..088049f --- /dev/null +++ b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.camera2.params; + +import static com.android.internal.util.Preconditions.*; + +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.utils.HashCodeHelpers; +import android.util.Range; +import android.util.Size; + +/** + * Immutable class to store the available + * {@link CameraCharacteristics#CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS high speed video + * configurations} + * + * @see CameraCharacteristics#CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS + * + * @hide + */ +public final class HighSpeedVideoConfiguration { + + /** + * Create a new {@link HighSpeedVideoConfiguration}. + * + * @param width image width, in pixels (positive) + * @param height image height, in pixels (positive) + * @param fpsMin minimum frames per second for the configuration (positive) + * @param fpsMax maximum frames per second for the configuration (larger or equal to 60) + * + * @throws IllegalArgumentException + * if width/height/fpsMin were not positive or fpsMax less than 60 + * + * @hide + */ + public HighSpeedVideoConfiguration( + final int width, final int height, final int fpsMin, final int fpsMax) { + if (fpsMax < 60) { + throw new IllegalArgumentException("fpsMax must be at least 60"); + } + mFpsMax = fpsMax; + mWidth = checkArgumentPositive(width, "width must be positive"); + mHeight = checkArgumentPositive(height, "height must be positive"); + mFpsMin = checkArgumentPositive(fpsMin, "fpsMin must be positive"); + mSize = new Size(mWidth, mHeight); + mFpsRange = new Range<Integer>(mFpsMin, mFpsMax); + } + + /** + * Return the width of the high speed video configuration. + * + * @return width > 0 + */ + public int getWidth() { + return mWidth; + } + + /** + * Return the height of the high speed video configuration. + * + * @return height > 0 + */ + public int getHeight() { + return mHeight; + } + + /** + * Return the minimum frame per second of the high speed video configuration. + * + * @return fpsMin > 0 + */ + public int getFpsMin() { + return mFpsMin; + } + + /** + * Return the maximum frame per second of the high speed video configuration. + * + * @return fpsMax >= 60 + */ + public int getFpsMax() { + return mFpsMax; + } + + /** + * Convenience method to return the size of this high speed video configuration. + * + * @return a Size with positive width and height + */ + public Size getSize() { + return mSize; + } + + /** + * Convenience method to return the FPS range of this high speed video configuration. + * + * @return a Range with high bound >= 60 + */ + public Range<Integer> getFpsRange() { + return mFpsRange; + } + + /** + * Check if this {@link HighSpeedVideoConfiguration} is equal to another + * {@link HighSpeedVideoConfiguration}. + * + * <p>Two configurations are equal if and only if each of the respective elements is equal.</p> + * + * @return {@code true} if the objects were equal, {@code false} otherwise + */ + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (obj instanceof HighSpeedVideoConfiguration) { + final HighSpeedVideoConfiguration other = (HighSpeedVideoConfiguration) obj; + return mWidth == other.mWidth && + mHeight == other.mHeight && + mFpsMin == other.mFpsMin && + mFpsMax == other.mFpsMax; + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return HashCodeHelpers.hashCode(mWidth, mHeight, mFpsMin, mFpsMax); + } + + private final int mWidth; + private final int mHeight; + private final int mFpsMin; + private final int mFpsMax; + private final Size mSize; + private final Range<Integer> mFpsRange; +} diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java index 8385d63..8c30fd4 100644 --- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java @@ -24,6 +24,7 @@ import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.utils.HashCodeHelpers; import android.view.Surface; import android.util.Log; +import android.util.Range; import android.util.Size; import java.util.Arrays; @@ -78,19 +79,29 @@ public final class StreamConfigurationMap { * @param configurations a non-{@code null} array of {@link StreamConfiguration} * @param minFrameDurations a non-{@code null} array of {@link StreamConfigurationDuration} * @param stallDurations a non-{@code null} array of {@link StreamConfigurationDuration} + * @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if + * camera device does not support high speed video recording * - * @throws NullPointerException if any of the arguments or subelements were {@code null} + * @throws NullPointerException if any of the arguments except highSpeedVideoConfigurations + * were {@code null} or any subelements were {@code null} * * @hide */ public StreamConfigurationMap( StreamConfiguration[] configurations, StreamConfigurationDuration[] minFrameDurations, - StreamConfigurationDuration[] stallDurations) { + StreamConfigurationDuration[] stallDurations, + HighSpeedVideoConfiguration[] highSpeedVideoConfigurations) { mConfigurations = checkArrayElementsNotNull(configurations, "configurations"); mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations"); mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations"); + if (highSpeedVideoConfigurations == null) { + mHighSpeedVideoConfigurations = new HighSpeedVideoConfiguration[0]; + } else { + mHighSpeedVideoConfigurations = checkArrayElementsNotNull( + highSpeedVideoConfigurations, "highSpeedVideoConfigurations"); + } // For each format, track how many sizes there are available to configure for (StreamConfiguration config : configurations) { @@ -110,6 +121,22 @@ public final class StreamConfigurationMap { throw new AssertionError( "At least one stream configuration for IMPLEMENTATION_DEFINED must exist"); } + + // For each Size/FPS range, track how many FPS range/Size there are available + for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { + Size size = config.getSize(); + Range<Integer> fpsRange = config.getFpsRange(); + Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size); + if (fpsRangeCount == null) { + fpsRangeCount = 0; + } + mHighSpeedVideoSizeMap.put(size, fpsRangeCount + 1); + Integer sizeCount = mHighSpeedVideoFpsRangeMap.get(fpsRange); + if (sizeCount == null) { + sizeCount = 0; + } + mHighSpeedVideoFpsRangeMap.put(fpsRange, sizeCount + 1); + } } /** @@ -343,6 +370,153 @@ public final class StreamConfigurationMap { } /** + * Get a list of supported high speed video recording sizes. + * + * <p> When HIGH_SPEED_VIDEO is supported in + * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this + * method will list the supported high speed video size configurations. All the sizes listed + * will be a subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling + * formats (typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12)</p> + * + * <p> To enable high speed video recording, application must set + * {@link CaptureRequest#CONTROL_SCENE_MODE} to + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture + * requests and select the video size from this method and + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from + * {@link #getHighSpeedVideoFpsRangesFor} to configure the recording and preview streams and + * setup the recording requests. For example, if the application intends to do high speed + * recording, it can select the maximum size reported by this method to configure output + * streams. Note that for the use case of multiple output streams, application must select one + * unique size from this method to use. Otherwise a request error might occur. Once the size is + * selected, application can get the supported FPS ranges by + * {@link #getHighSpeedVideoFpsRangesFor}, and use these FPS ranges to setup the recording + * requests.</p> + * + * @return + * an array of supported high speed video recording sizes + * + * @see #getHighSpeedVideoFpsRangesFor(Size) + */ + public Size[] getHighSpeedVideoSizes() { + return (Size[]) mHighSpeedVideoSizeMap.keySet().toArray(); + } + + /** + * Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size. + * + * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p> + * + * <p> For normal video recording use case, where some application will NOT set + * {@link CaptureRequest#CONTROL_SCENE_MODE} to + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture + * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in + * this method must not be used to setup capture requests, or it will cause request error.</p> + * + * @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()} + * @return + * An array of FPS range to use with + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE TARGET_FPS_RANGE} when using + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene + * mode. + * The upper bound of returned ranges is guaranteed to be larger or equal to 60. + * + * @throws IllegalArgumentException if input size does not exist in the return value of + * getHighSpeedVideoSizes + * @see #getHighSpeedVideoSizes() + */ + public Range<Integer>[] getHighSpeedVideoFpsRangesFor(Size size) { + Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size); + if (fpsRangeCount == null || fpsRangeCount == 0) { + throw new IllegalArgumentException(String.format( + "Size %s does not support high speed video recording", size)); + } + + @SuppressWarnings("unchecked") + Range<Integer>[] fpsRanges = new Range[fpsRangeCount]; + int i = 0; + for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { + if (size.equals(config.getSize())) { + fpsRanges[i++] = config.getFpsRange(); + } + } + return fpsRanges; + } + + /** + * Get a list of supported high speed video recording FPS ranges. + * + * <p> When HIGH_SPEED_VIDEO is supported in + * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this + * method will list the supported high speed video FPS range configurations. Application can + * then use {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned + * FPS range.</p> + * + * <p> To enable high speed video recording, application must set + * {@link CaptureRequest#CONTROL_SCENE_MODE} to + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture + * requests and select the video size from {@link #getHighSpeedVideoSizesFor} and + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from + * this method to configure the recording and preview streams and setup the recording requests. + * For example, if the application intends to do high speed recording, it can select one FPS + * range reported by this method, query the video sizes corresponding to this FPS range by + * {@link #getHighSpeedVideoSizesFor} and select one of reported sizes to configure output + * streams. Note that for the use case of multiple output streams, application must select one + * unique size from {@link #getHighSpeedVideoSizesFor}, and use it for all output streams. + * Otherwise a request error might occur when attempting to enable + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}. + * Once the stream is configured, application can set the FPS range in the recording requests. + * </p> + * + * @return + * an array of supported high speed video recording FPS ranges + * The upper bound of returned ranges is guaranteed to be larger or equal to 60. + * + * @see #getHighSpeedVideoSizesFor + */ + @SuppressWarnings("unchecked") + public Range<Integer>[] getHighSpeedVideoFpsRanges() { + return (Range<Integer>[]) mHighSpeedVideoFpsRangeMap.keySet().toArray(); + } + + /** + * Get the supported video sizes for input FPS range. + * + * <p> See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.</p> + * + * <p> For normal video recording use case, where the application will NOT set + * {@link CaptureRequest#CONTROL_SCENE_MODE} to + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture + * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in + * this method must not be used to setup capture requests, or it will cause request error.</p> + * + * @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()} + * @return + * An array of video sizes to configure output stream when using + * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene + * mode. + * + * @throws IllegalArgumentException if input FPS range does not exist in the return value of + * getHighSpeedVideoFpsRanges + * @see #getHighSpeedVideoFpsRanges() + */ + public Size[] getHighSpeedVideoSizesFor(Range<Integer> fpsRange) { + Integer sizeCount = mHighSpeedVideoFpsRangeMap.get(fpsRange); + if (sizeCount == null || sizeCount == 0) { + throw new IllegalArgumentException(String.format( + "FpsRange %s does not support high speed video recording", fpsRange)); + } + + Size[] sizes = new Size[sizeCount]; + int i = 0; + for (HighSpeedVideoConfiguration config : mHighSpeedVideoConfigurations) { + if (fpsRange.equals(config.getFpsRange())) { + sizes[i++] = config.getSize(); + } + } + return sizes; + } + + /** * Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration} * for the format/size combination (in nanoseconds). * @@ -587,7 +761,9 @@ public final class StreamConfigurationMap { // XX: do we care about order? return Arrays.equals(mConfigurations, other.mConfigurations) && Arrays.equals(mMinFrameDurations, other.mMinFrameDurations) && - Arrays.equals(mStallDurations, other.mStallDurations); + Arrays.equals(mStallDurations, other.mStallDurations) && + Arrays.equals(mHighSpeedVideoConfigurations, + other.mHighSpeedVideoConfigurations); } return false; } @@ -598,7 +774,9 @@ public final class StreamConfigurationMap { @Override public int hashCode() { // XX: do we care about order? - return HashCodeHelpers.hashCode(mConfigurations, mMinFrameDurations, mStallDurations); + return HashCodeHelpers.hashCode( + mConfigurations, mMinFrameDurations, + mStallDurations, mHighSpeedVideoConfigurations); } // Check that the argument is supported by #getOutputFormats or #getInputFormats @@ -956,6 +1134,7 @@ public final class StreamConfigurationMap { private final StreamConfiguration[] mConfigurations; private final StreamConfigurationDuration[] mMinFrameDurations; private final StreamConfigurationDuration[] mStallDurations; + private final HighSpeedVideoConfiguration[] mHighSpeedVideoConfigurations; /** ImageFormat -> num output sizes mapping */ private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mOutputFormats = @@ -963,5 +1142,11 @@ public final class StreamConfigurationMap { /** ImageFormat -> num input sizes mapping */ private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mInputFormats = new HashMap<Integer, Integer>(); + /** High speed video Size -> FPS range count mapping*/ + private final HashMap</*HighSpeedVideoSize*/Size, /*Count*/Integer> mHighSpeedVideoSizeMap = + new HashMap<Size, Integer>(); + /** High speed video FPS range -> Size count mapping*/ + private final HashMap</*HighSpeedVideoFpsRange*/Range<Integer>, /*Count*/Integer> + mHighSpeedVideoFpsRangeMap = new HashMap<Range<Integer>, Integer>(); } diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java index b980549..7b4aa09 100644 --- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java +++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java @@ -113,7 +113,16 @@ public final class HashCodeHelpers { public static <T> int hashCode(T a, T b, T c) { int h = hashCode(a, b); - int x = (a == null) ? 0 : a.hashCode(); + int x = (c == null) ? 0 : c.hashCode(); + h = ((h << 5) - h) ^ x; // (h * 31) XOR x + + return h; + } + + public static <T> int hashCode(T a, T b, T c, T d) { + int h = hashCode(a, b, c); + + int x = (d == null) ? 0 : d.hashCode(); h = ((h << 5) - h) ^ x; // (h * 31) XOR x return h; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java index ef06d2c..29c3c75 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java @@ -36,6 +36,7 @@ import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.marshal.impl.MarshalQueryableEnum; import android.hardware.camera2.params.ColorSpaceTransform; import android.hardware.camera2.params.Face; +import android.hardware.camera2.params.HighSpeedVideoConfiguration; import android.hardware.camera2.params.MeteringRectangle; import android.hardware.camera2.params.ReprocessFormatsMap; import android.hardware.camera2.params.RggbChannelVector; @@ -51,7 +52,6 @@ import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*; import java.lang.reflect.Array; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.Arrays; import java.util.List; /** @@ -730,6 +730,32 @@ public class CameraMetadataTest extends junit.framework.TestCase { } @SmallTest + public void testReadWriteHighSpeedVideoConfiguration() { + // int32 x 4 x 1 + checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations", + new HighSpeedVideoConfiguration( + /*width*/1000, /*height*/255, /*fpsMin*/30, /*fpsMax*/200), + /* width, height, fpsMin, fpsMax */ + toByteArray(1000, 255, 30, 200)); + + // int32 x 4 x 3 + checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations", + new HighSpeedVideoConfiguration[] { + new HighSpeedVideoConfiguration( + /*width*/1280, /*height*/720, /*fpsMin*/60, /*fpsMax*/120), + new HighSpeedVideoConfiguration( + /*width*/123, /*height*/456, /*fpsMin*/1, /*fpsMax*/200), + new HighSpeedVideoConfiguration( + /*width*/4096, /*height*/2592, /*fpsMin*/30, /*fpsMax*/60) + }, + toByteArray( + 1280, 720, 60, 120, + 123, 456, 1, 200, + 4096, 2592, 30, 60 + )); + } + + @SmallTest public void testReadWriteColorSpaceTransform() { // rational x 3 x 3 checkKeyMarshal("android.colorCorrection.transform", @@ -741,7 +767,7 @@ public class CameraMetadataTest extends junit.framework.TestCase { toByteArray( 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, - 1, 5, 2, 8, 3, 9)); + 1, 5, 1, 4, 1, 3)); } @SmallTest |