Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89d277a9 authored by Shuzhen Wang's avatar Shuzhen Wang Committed by Android (Google) Code Review
Browse files

Merge "Camera: Add support for recommended stream configurations"

parents 7c626383 2776ca3f
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -16303,6 +16303,7 @@ package android.hardware.camera2 {
    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeysNeedingPermission();
    method public java.util.Set<java.lang.String> getPhysicalCameraIds();
    method public android.hardware.camera2.params.RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(int);
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
    field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -16965,6 +16966,33 @@ package android.hardware.camera2.params {
    field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff
  }
  public final class RecommendedStreamConfigurationMap {
    method public java.util.Set<android.util.Size> getHighResolutionOutputSizes(int);
    method public java.util.Set<android.util.Range<java.lang.Integer>> getHighSpeedVideoFpsRanges();
    method public java.util.Set<android.util.Range<java.lang.Integer>> getHighSpeedVideoFpsRangesFor(android.util.Size);
    method public java.util.Set<android.util.Size> getHighSpeedVideoSizes();
    method public java.util.Set<android.util.Size> getHighSpeedVideoSizesFor(android.util.Range<java.lang.Integer>);
    method public java.util.Set<java.lang.Integer> getInputFormats();
    method public java.util.Set<android.util.Size> getInputSizes(int);
    method public java.util.Set<java.lang.Integer> getOutputFormats();
    method public long getOutputMinFrameDuration(int, android.util.Size);
    method public <T> long getOutputMinFrameDuration(java.lang.Class<T>, android.util.Size);
    method public java.util.Set<android.util.Size> getOutputSizes(int);
    method public <T> java.util.Set<android.util.Size> getOutputSizes(java.lang.Class<T>);
    method public long getOutputStallDuration(int, android.util.Size);
    method public <T> long getOutputStallDuration(java.lang.Class<T>, android.util.Size);
    method public int getRecommendedUseCase();
    method public java.util.Set<java.lang.Integer> getValidOutputFormatsForInput(int);
    method public boolean isOutputSupportedFor(int);
    method public boolean isOutputSupportedFor(android.view.Surface);
    field public static final int USECASE_PREVIEW = 0; // 0x0
    field public static final int USECASE_RAW = 5; // 0x5
    field public static final int USECASE_RECORD = 1; // 0x1
    field public static final int USECASE_SNAPSHOT = 3; // 0x3
    field public static final int USECASE_VIDEO_SNAPSHOT = 2; // 0x2
    field public static final int USECASE_ZSL = 4; // 0x4
  }
  public final class RggbChannelVector {
    ctor public RggbChannelVector(float, float, float, float);
    method public void copyTo(float[], int);
+147 −1
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import android.annotation.UnsupportedAppUsage;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.PublicKey;
import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.utils.ArrayUtils;
import android.hardware.camera2.utils.TypeReference;
import android.util.Rational;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -193,6 +195,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
    private List<CaptureRequest.Key<?>> mAvailableSessionKeys;
    private List<CaptureRequest.Key<?>> mAvailablePhysicalRequestKeys;
    private List<CaptureResult.Key<?>> mAvailableResultKeys;
    private ArrayList<RecommendedStreamConfigurationMap> mRecommendedConfigurations;

    /**
     * Takes ownership of the passed-in properties object
@@ -312,6 +315,103 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
        return mKeysNeedingPermission;
    }

    /**
     * <p>Retrieve camera device recommended stream configuration map
     * {@link RecommendedStreamConfigurationMap} for a given use case.</p>
     *
     * <p>The stream configurations advertised here are efficient in terms of power and performance
     * for common use cases like preview, video, snapshot, etc. The recommended maps are usually
     * only small subsets of the exhaustive list provided in
     * {@link #SCALER_STREAM_CONFIGURATION_MAP} and suggested for a particular use case by the
     * camera device implementation. For further information about the expected configurations in
     * various scenarios please refer to:
     * <ul>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_PREVIEW}</li>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_RECORD}</li>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_VIDEO_SNAPSHOT}</li>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_SNAPSHOT}</li>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_RAW}</li>
     * <li>{@link RecommendedStreamConfigurationMap#USECASE_ZSL}</li>
     * </ul>
     * </p>
     *
     * <p>For example on how this can be used by camera clients to find out the maximum recommended
     * preview and snapshot resolution, consider the following pseudo-code:
     * </p>
     * <pre><code>
     * public static Size getMaxSize(Size... sizes) {
     *     if (sizes == null || sizes.length == 0) {
     *         throw new IllegalArgumentException("sizes was empty");
     *     }
     *
     *     Size sz = sizes[0];
     *     for (Size size : sizes) {
     *         if (size.getWidth() * size.getHeight() &gt; sz.getWidth() * sz.getHeight()) {
     *             sz = size;
     *         }
     *     }
     *
     *     return sz;
     * }
     *
     * CameraCharacteristics characteristics =
     *         cameraManager.getCameraCharacteristics(cameraId);
     * RecommendedStreamConfigurationMap previewConfig =
     *         characteristics.getRecommendedStreamConfigurationMap(
     *                  RecommendedStreamConfigurationMap.USECASE_PREVIEW);
     * RecommendedStreamConfigurationMap snapshotConfig =
     *         characteristics.getRecommendedStreamConfigurationMap(
     *                  RecommendedStreamConfigurationMap.USECASE_SNAPSHOT);
     *
     * if ((previewConfig != null) &amp;&amp; (snapshotConfig != null)) {
     *
     *      Set<Size> snapshotSizeSet = snapshotConfig.getOutputSizes(
     *              ImageFormat.JPEG);
     *      Size[] snapshotSizes = new Size[snapshotSizeSet.size()];
     *      snapshotSizes = snapshotSizeSet.toArray(snapshotSizes);
     *      Size suggestedMaxJpegSize = getMaxSize(snapshotSizes);
     *
     *      Set<Size> previewSizeSet = snapshotConfig.getOutputSizes(
     *              ImageFormat.PRIVATE);
     *      Size[] previewSizes = new Size[previewSizeSet.size()];
     *      previewSizes = previewSizeSet.toArray(previewSizes);
     *      Size suggestedMaxPreviewSize = getMaxSize(previewSizes);
     * }
     *
     * </code></pre>
     *
     * <p>Similar logic can be used for other use cases as well.</p>
     *
     * <p>Support for recommended stream configurations is optional. In case there a no
     * suggested configurations for the particular use case, please refer to
     * {@link #SCALER_STREAM_CONFIGURATION_MAP} for the exhaustive available list.</p>
     *
     * @param usecase Use case id.
     *
     * @throws IllegalArgumentException In case the use case argument is invalid.
     * @return Valid {@link RecommendedStreamConfigurationMap} or null in case the camera device
     *         doesn't have any recommendation for this use case or the recommended configurations
     *         are invalid.
     */
    public RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
            @RecommendedStreamConfigurationMap.RecommendedUsecase int usecase) {
        if (((usecase >= RecommendedStreamConfigurationMap.USECASE_PREVIEW) &&
                (usecase <= RecommendedStreamConfigurationMap.USECASE_RAW)) ||
                ((usecase >= RecommendedStreamConfigurationMap.USECASE_VENDOR_START) &&
                (usecase < RecommendedStreamConfigurationMap.MAX_USECASE_COUNT))) {
            if (mRecommendedConfigurations == null) {
                mRecommendedConfigurations = mProperties.getRecommendedStreamConfigurations();
                if (mRecommendedConfigurations == null) {
                    return null;
                }
            }

            return mRecommendedConfigurations.get(usecase);
        }

        throw new IllegalArgumentException(String.format("Invalid use case: %d", usecase));
    }

    /**
     * <p>Returns a subset of {@link #getAvailableCaptureRequestKeys} keys that the
     * camera device can pass as part of the capture session initialization.</p>
@@ -329,7 +429,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
     * but clients should be aware and expect delays during their application.
     * An example usage scenario could look like this:</p>
     * <ul>
     * <li>The camera client starts by quering the session parameter key list via
     * <li>The camera client starts by querying the session parameter key list via
     *   {@link android.hardware.camera2.CameraCharacteristics#getAvailableSessionKeys }.</li>
     * <li>Before triggering the capture session create sequence, a capture request
     *   must be built via {@link CameraDevice#createCaptureRequest } using an
@@ -2477,6 +2577,37 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
    public static final Key<Integer> SCALER_CROPPING_TYPE =
            new Key<Integer>("android.scaler.croppingType", int.class);

    /**
     * <p>Recommended stream configurations for common client use cases.</p>
     * <p>Optional subset of the android.scaler.availableStreamConfigurations that contains
     * similar tuples listed as
     * (i.e. width, height, format, output/input stream, usecase bit field).
     * Camera devices will be able to suggest particular stream configurations which are
     * power and performance efficient for specific use cases. For more information about
     * retrieving the suggestions see
     * {@link android.hardware.camera2.CameraCharacteristics#getRecommendedStreamConfigurationMap }.</p>
     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
     * @hide
     */
    public static final Key<android.hardware.camera2.params.RecommendedStreamConfiguration[]> SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS =
            new Key<android.hardware.camera2.params.RecommendedStreamConfiguration[]>("android.scaler.availableRecommendedStreamConfigurations", android.hardware.camera2.params.RecommendedStreamConfiguration[].class);

    /**
     * <p>Recommended mappings of image formats that are supported by this
     * camera device for input streams, to their corresponding output formats.</p>
     * <p>This is a recommended subset of the complete list of mappings found in
     * android.scaler.availableInputOutputFormatsMap. The same requirements apply here as well.
     * The list however doesn't need to contain all available and supported mappings. Instead of
     * this developers must list only recommended and efficient entries.
     * If set, the information will be available in the ZERO_SHUTTER_LAG recommended stream
     * configuration see
     * {@link android.hardware.camera2.CameraCharacteristics#getRecommendedStreamConfigurationMap }.</p>
     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
     * @hide
     */
    public static final Key<android.hardware.camera2.params.ReprocessFormatsMap> SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP =
            new Key<android.hardware.camera2.params.ReprocessFormatsMap>("android.scaler.availableRecommendedInputOutputFormatsMap", android.hardware.camera2.params.ReprocessFormatsMap.class);

    /**
     * <p>The area of the image sensor which corresponds to active pixels after any geometric
     * distortion correction has been applied.</p>
@@ -3517,6 +3648,21 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
    public static final Key<Boolean> DEPTH_DEPTH_IS_EXCLUSIVE =
            new Key<Boolean>("android.depth.depthIsExclusive", boolean.class);

    /**
     * <p>Recommended depth stream configurations for common client use cases.</p>
     * <p>Optional subset of the android.depth.availableDepthStreamConfigurations that
     * contains similar tuples listed as
     * (i.e. width, height, format, output/input stream, usecase bit field).
     * Camera devices will be able to suggest particular depth stream configurations which are
     * power and performance efficient for specific use cases. For more information about
     * retrieving the suggestions see
     * {@link android.hardware.camera2.CameraCharacteristics#getRecommendedStreamConfigurationMap }.</p>
     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
     * @hide
     */
    public static final Key<android.hardware.camera2.params.RecommendedStreamConfiguration[]> DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS =
            new Key<android.hardware.camera2.params.RecommendedStreamConfiguration[]>("android.depth.availableRecommendedDepthStreamConfigurations", android.hardware.camera2.params.RecommendedStreamConfiguration[].class);

    /**
     * <p>String containing the ids of the underlying physical cameras.</p>
     * <p>For a logical camera, this is concatenation of all underlying physical camera ids.
+252 −8

File changed.

Preview size limit exceeded, changes collapsed.

+84 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.RecommendedStreamConfiguration;
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.scaler.availableRecommendedStreamConfigurations} custom class
 * {@link RecommendedStreamConfiguration}
 *
 * <p>Data is stored as {@code (width, height, format, input, usecaseBitmap)} tuples (int32).</p>
 */
public class MarshalQueryableRecommendedStreamConfiguration
        implements MarshalQueryable<RecommendedStreamConfiguration> {
    private static final int SIZE = SIZEOF_INT32 * 5;

    private class MarshalerRecommendedStreamConfiguration
            extends Marshaler<RecommendedStreamConfiguration> {
        protected MarshalerRecommendedStreamConfiguration(
                TypeReference<RecommendedStreamConfiguration> typeReference, int nativeType) {
            super(MarshalQueryableRecommendedStreamConfiguration.this, typeReference, nativeType);
        }

        @Override
        public void marshal(RecommendedStreamConfiguration value, ByteBuffer buffer) {
            buffer.putInt(value.getWidth());
            buffer.putInt(value.getHeight());
            buffer.putInt(value.getFormat());
            buffer.putInt(value.isInput() ? 1 : 0);
            buffer.putInt(value.getUsecaseBitmap());
        }

        @Override
        public RecommendedStreamConfiguration unmarshal(ByteBuffer buffer) {
            int width = buffer.getInt();
            int height = buffer.getInt();
            int format = buffer.getInt();
            boolean input = buffer.getInt() != 0;
            int usecaseBitmap = buffer.getInt();

            return new RecommendedStreamConfiguration(format, width, height, input, usecaseBitmap);
        }

        @Override
        public int getNativeSize() {
            return SIZE;
        }

    }

    @Override
    public Marshaler<RecommendedStreamConfiguration> createMarshaler(
            TypeReference<RecommendedStreamConfiguration> managedType, int nativeType) {
        return new MarshalerRecommendedStreamConfiguration(managedType, nativeType);
    }

    @Override
    public boolean isTypeMappingSupported(TypeReference<RecommendedStreamConfiguration> managedType,
            int nativeType) {
        return nativeType ==
            TYPE_INT32 && managedType.getType().equals(RecommendedStreamConfiguration.class);
    }
}
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.utils.HashCodeHelpers;

/**
 * Immutable class to store the recommended stream configurations to set up
 * {@link android.view.Surface Surfaces} for creating a {@link CameraCaptureSession capture session}
 * with {@link CameraDevice#createCaptureSession}.
 *
 * @see CameraCharacteristics#getRecommendedStreamConfigurationMap
 *
 * @hide
 */
public final class RecommendedStreamConfiguration extends StreamConfiguration{

    /**
     * Create a new {@link RecommendedStreamConfiguration}.
     *
     * @param format image format
     * @param width image width, in pixels (positive)
     * @param height image height, in pixels (positive)
     * @param input true if this is an input configuration, false for output configurations
     * @param usecaseBitmap Use case bitmap
     *
     * @throws IllegalArgumentException
     *              if width/height were not positive
     *              or if the format was not user-defined in ImageFormat/PixelFormat
     *                  (IMPL_DEFINED is ok)
     *
     * @hide
     */
    public RecommendedStreamConfiguration(
            final int format, final int width, final int height, final boolean input, final int
            usecaseBitmap) {
        super(format, width, height, input);
        mUsecaseBitmap = usecaseBitmap;
    }

    /**
     * Return usecase bitmap.
     *
     * @return usecase bitmap
     */
    public int getUsecaseBitmap() {
        return mUsecaseBitmap;
    }

    /**
     * Check if this {@link RecommendedStreamConfiguration} is equal to another
     * {@link RecommendedStreamConfiguration}.
     *
     * <p>Two vectors are only 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 RecommendedStreamConfiguration) {
            final RecommendedStreamConfiguration other = (RecommendedStreamConfiguration) obj;
            return mFormat == other.mFormat &&
                    mWidth == other.mWidth &&
                    mHeight == other.mHeight &&
                    mUsecaseBitmap == other.mUsecaseBitmap &&
                    mInput == other.mInput;
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return HashCodeHelpers.hashCode(mFormat, mWidth, mHeight, mInput ? 1 : 0, mUsecaseBitmap);
    }

    private final int mUsecaseBitmap;
}
Loading