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

Commit 77bb682e authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera: Refactor API for session configration query

- Modify OutputConfiguration class so that it can be created without
  output surfaces for SurfaceView, SurfaceTexture, MediaRecorder,
  MediaCodec, and ImageReader. This makes it possible to do feature
  combination query with minimum latency. The application can then call
  OutputConfiguration#addSurface before creating capture session.
- Enhance SessionConfiguration class for CameraDeviceSetup operations.

Test: atest CtsCameraTestCases
Bug: 298033056
Bug: 309627704
Change-Id: Ic943c225d07f1553efe22b7125642673d659c2a2
parent 4972f329
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -20138,9 +20138,14 @@ package android.hardware.camera2.params {
    ctor public OutputConfiguration(@NonNull android.view.Surface);
    ctor public OutputConfiguration(@NonNull android.view.Surface);
    ctor public OutputConfiguration(int, @NonNull android.view.Surface);
    ctor public OutputConfiguration(int, @NonNull android.view.Surface);
    ctor public <T> OutputConfiguration(@NonNull android.util.Size, @NonNull Class<T>);
    ctor public <T> OutputConfiguration(@NonNull android.util.Size, @NonNull Class<T>);
    ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, @NonNull android.util.Size);
    ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, int, @NonNull android.util.Size);
    ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, @NonNull android.util.Size, long);
    ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, int, @NonNull android.util.Size, long);
    method public void addSensorPixelModeUsed(int);
    method public void addSensorPixelModeUsed(int);
    method public void addSurface(@NonNull android.view.Surface);
    method public void addSurface(@NonNull android.view.Surface);
    method @NonNull public static java.util.Collection<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull android.hardware.camera2.MultiResolutionImageReader);
    method @NonNull public static java.util.Collection<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull android.hardware.camera2.MultiResolutionImageReader);
    method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") @NonNull public static java.util.List<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>, int);
    method public int describeContents();
    method public int describeContents();
    method public void enableSurfaceSharing();
    method public void enableSurfaceSharing();
    method public long getDynamicRangeProfile();
    method public long getDynamicRangeProfile();
@@ -20159,6 +20164,7 @@ package android.hardware.camera2.params {
    method public void setPhysicalCameraId(@Nullable String);
    method public void setPhysicalCameraId(@Nullable String);
    method public void setReadoutTimestampEnabled(boolean);
    method public void setReadoutTimestampEnabled(boolean);
    method public void setStreamUseCase(long);
    method public void setStreamUseCase(long);
    method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public static void setSurfacesForMultiResolutionOutput(@NonNull java.util.Collection<android.hardware.camera2.params.OutputConfiguration>, @NonNull android.hardware.camera2.MultiResolutionImageReader);
    method public void setTimestampBase(int);
    method public void setTimestampBase(int);
    method public void writeToParcel(android.os.Parcel, int);
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
@@ -20220,6 +20226,7 @@ package android.hardware.camera2.params {
  public final class SessionConfiguration implements android.os.Parcelable {
  public final class SessionConfiguration implements android.os.Parcelable {
    ctor public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
    ctor public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
    ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>);
    method public void clearColorSpace();
    method public void clearColorSpace();
    method public int describeContents();
    method public int describeContents();
    method @Nullable public android.graphics.ColorSpace getColorSpace();
    method @Nullable public android.graphics.ColorSpace getColorSpace();
@@ -20229,6 +20236,7 @@ package android.hardware.camera2.params {
    method public android.hardware.camera2.CaptureRequest getSessionParameters();
    method public android.hardware.camera2.CaptureRequest getSessionParameters();
    method public int getSessionType();
    method public int getSessionType();
    method public android.hardware.camera2.CameraCaptureSession.StateCallback getStateCallback();
    method public android.hardware.camera2.CameraCaptureSession.StateCallback getStateCallback();
    method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public void setCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
    method public void setColorSpace(@NonNull android.graphics.ColorSpace.Named);
    method public void setColorSpace(@NonNull android.graphics.ColorSpace.Named);
    method public void setInputConfiguration(@NonNull android.hardware.camera2.params.InputConfiguration);
    method public void setInputConfiguration(@NonNull android.hardware.camera2.params.InputConfiguration);
    method public void setSessionParameters(android.hardware.camera2.CaptureRequest);
    method public void setSessionParameters(android.hardware.camera2.CaptureRequest);
+48 −12
Original line number Original line Diff line number Diff line
@@ -585,6 +585,11 @@ public abstract class CameraDevice implements AutoCloseable {
     * <p>Configuring a session with an empty or null list will close the current session, if
     * <p>Configuring a session with an empty or null list will close the current session, if
     * any. This can be used to release the current session's target surfaces for another use.</p>
     * any. This can be used to release the current session's target surfaces for another use.</p>
     *
     *
     * <p>This function throws an {@code IllegalArgumentException} if called with a
     * SessionConfiguration lacking state callbacks or valid output surfaces. The only exceptions
     * are deferred SurfaceView or SurfaceTexture outputs. See {@link
     * OutputConfiguration#OutputConfiguration(Size, Class)} for details.</p>
     *
     * <h3>Regular capture</h3>
     * <h3>Regular capture</h3>
     *
     *
     * <p>While any of the sizes from {@link StreamConfigurationMap#getOutputSizes} can be used when
     * <p>While any of the sizes from {@link StreamConfigurationMap#getOutputSizes} can be used when
@@ -1675,19 +1680,32 @@ public abstract class CameraDevice implements AutoCloseable {
         *
         *
         * <p><b>IMPORTANT:</b></p>
         * <p><b>IMPORTANT:</b></p>
         * <ul>
         * <ul>
         * <li>If a feature support can be queried via
         * <li>If feature support can be queried via
         * {@link CameraCharacteristics#SCALER_MANDATORY_STREAM_COMBINATIONS} or
         * {@link CameraCharacteristics#SCALER_MANDATORY_STREAM_COMBINATIONS} or
         * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}, applications should
         * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}, applications should
         * directly use it rather than calling this function as: (1) using
         * directly use that route rather than calling this function as: (1) using
         * {@code CameraCharacteristics} is more efficient, and (2) calling this function with on
         * {@code CameraCharacteristics} is more efficient, and (2) calling this function with
         * non-supported devices will throw a {@link UnsupportedOperationException}.
         * certain non-supported features will throw a {@link IllegalArgumentException}.</li>
         *
         *
         * <li>To minimize latency of {@link SessionConfiguration} creation, applications can
         * <li>To minimize {@link SessionConfiguration} creation latency due to its dependency on
         * use deferred surfaces for SurfaceView and SurfaceTexture to avoid waiting for UI
         * output surfaces, the application can call this method before acquiring valid
         * creation before setting up the camera. For {@link android.media.MediaRecorder} and
         * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture},
         * {@link android.media.MediaCodec} uses, applications can use {@code ImageReader} with
         * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec}, or {@link
         * {@link android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE}. The lightweight nature of
         * android.media.ImageReader} surfaces. For {@link android.view.SurfaceView},
         * {@code ImageReader} helps minimize the latency cost.
         * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, and
         * {@link android.media.MediaCodec}, the application can call
         * {@link OutputConfiguration#OutputConfiguration(Size, Class)}. For {@link
         * android.media.ImageReader}, the application can call {@link
         * OutputConfiguration#OutputConfiguration(int, Size)}, {@link
         * OutputConfiguration#OutputConfiguration(int, int, Size)}, {@link
         * OutputConfiguration#OutputConfiguration(int, Size, long)}, or {@link
         * OutputConfiguration#OutputConfiguration(int, int, Size, long)}. The {@link
         * SessionConfiguration} can then be created using the OutputConfiguration objects and
         * be used to query whether it's supported by the camera device. To create the
         * CameraCaptureSession, the application still needs to make sure all output surfaces
         * are added via {@link OutputConfiguration#addSurfaces} with the exception of deferred
         * surfaces for {@link android.view.SurfaceView} and
         * {@link android.graphics.SurfaceTexture}.</li>
         * </ul>
         * </ul>
         *
         *
         * @return {@code true} if the given session configuration is supported by the camera
         * @return {@code true} if the given session configuration is supported by the camera
@@ -1706,8 +1724,8 @@ public abstract class CameraDevice implements AutoCloseable {
                @NonNull SessionConfiguration config) throws CameraAccessException;
                @NonNull SessionConfiguration config) throws CameraAccessException;


        /**
        /**
         * <p>Get camera characteristics for a particular session configuration for this camera
         * Get camera characteristics for a particular session configuration for this camera
         * device</p>
         * device.
         *
         *
         * <p>The camera characteristics returned by this method are different from those returned
         * <p>The camera characteristics returned by this method are different from those returned
         * from {@link CameraManager#getCameraCharacteristics}. The characteristics returned here
         * from {@link CameraManager#getCameraCharacteristics}. The characteristics returned here
@@ -1718,6 +1736,24 @@ public abstract class CameraDevice implements AutoCloseable {
         * <p>Other than that, the characteristics returned here can be used in the same way as
         * <p>Other than that, the characteristics returned here can be used in the same way as
         * those returned from {@link CameraManager#getCameraCharacteristics}.</p>
         * those returned from {@link CameraManager#getCameraCharacteristics}.</p>
         *
         *
         * <p>To optimize latency, the application can call this method before acquiring valid
         * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture},
         * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec}, or {@link
         * android.media.ImageReader} surfaces. For {@link android.view.SurfaceView},
         * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, and
         * {@link android.media.MediaCodec}, the application can call
         * {@link OutputConfiguration#OutputConfiguration(Size, Class)}. For {@link
         * android.media.ImageReader}, the application can call {@link
         * OutputConfiguration#OutputConfiguration(int, Size)}, {@link
         * OutputConfiguration#OutputConfiguration(int, int, Size)}, {@link
         * OutputConfiguration#OutputConfiguration(int, Size, long)}, or {@link
         * OutputConfiguration#OutputConfiguration(int, int, Size, long)}. The {@link
         * SessionConfiguration} can then be created using the OutputConfiguration objects and
         * be used for this function. To create the CameraCaptureSession, the application still
         * needs to make sure all output surfaces are added via {@link
         * OutputConfiguration#addSurfaces} with the exception of deferred surfaces for {@link
         * android.view.SurfaceView} and {@link android.graphics.SurfaceTexture}.</p>
         *
         * @param sessionConfig The session configuration for which characteristics are fetched.
         * @param sessionConfig The session configuration for which characteristics are fetched.
         * @return CameraCharacteristics specific to a given session configuration.
         * @return CameraCharacteristics specific to a given session configuration.
         *
         *
+50 −7
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package android.hardware.camera2;
package android.hardware.camera2;


import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.CallbackExecutor;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.FlaggedApi;
import android.annotation.IntRange;
import android.annotation.IntRange;
@@ -26,20 +28,15 @@ import android.graphics.ImageFormat;
import android.graphics.ImageFormat.Format;
import android.graphics.ImageFormat.Format;
import android.hardware.HardwareBuffer;
import android.hardware.HardwareBuffer;
import android.hardware.HardwareBuffer.Usage;
import android.hardware.HardwareBuffer.Usage;
import android.hardware.camera2.params.MultiResolutionStreamInfo;
import android.media.Image;
import android.media.Image;
import android.media.ImageReader;
import android.media.ImageReader;
import android.hardware.camera2.params.MultiResolutionStreamInfo;
import android.util.Size;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Surface;
import android.view.Surface;


import com.android.internal.camera.flags.Flags;
import com.android.internal.camera.flags.Flags;


import java.nio.NioUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;


/**
/**
@@ -350,6 +347,52 @@ public class MultiResolutionImageReader implements AutoCloseable {
        return mReaders;
        return mReaders;
    }
    }


    /**
     * Get the internal ImageReader surface based on configured size and physical camera Id.
     *
     * <p>The {@code configuredSize} and {@code physicalCameraId} parameters must match one of the
     * MultiResolutionStreamInfo used to create this {@link MultiResolutionImageReader}.</p>
     *
     * <p>The Surface returned from this function isn't meant to be used directly as part of a
     * {@link CaptureRequest}. It should instead be used for creating an OutputConfiguration
     * before session creation. See {@link OutputConfiguration#setSurfacesForMultiResolutionOutput}
     * for details. For {@link CaptureRequest}, use {@link #getSurface()} instead.</p>
     *
     * <p>Please note that holding on to the Surface objects returned by this method is not enough
     * to keep their parent MultiResolutionImageReaders from being reclaimed. In that sense, a
     * Surface acts like a {@link java.lang.ref.WeakReference weak reference} to the
     * MultiResolutionImageReader that provides it.</p>
     *
     * @param configuredSize The configured size corresponding to one of the internal ImageReader.
     * @param physicalCameraId The physical camera Id the internal ImageReader targets for. If
     *                         the ImageReader is not targeting a physical camera of a logical
     *                         multi-camera, this parameter is set to "".
     *
     * @return The {@link Surface} of the internal ImageReader corresponding to the provided
     *         configured size and physical camera Id.
     *
     * @throws IllegalArgumentException If {@code configuredSize} is {@code null}, or the ({@code
     *                                  configuredSize} and {@code physicalCameraId}) combo is not
     *                                  part of this {@code MultiResolutionImageReader}.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
    public @NonNull Surface getSurface(@NonNull Size configuredSize,
            @NonNull String physicalCameraId) {
        checkNotNull(configuredSize, "configuredSize must not be null");
        checkNotNull(physicalCameraId, "physicalCameraId must not be null");

        for (int i = 0; i < mStreamInfo.length; i++) {
            if (mStreamInfo[i].getWidth() == configuredSize.getWidth()
                    && mStreamInfo[i].getHeight() == configuredSize.getHeight()
                    && physicalCameraId.equals(mStreamInfo[i].getPhysicalCameraId())) {
                return mReaders[i].getSurface();
            }
        }
        throw new IllegalArgumentException("configuredSize and physicalCameraId don't match with "
                + "this MultiResolutionImageReader");
    }

    /**
    /**
     * Get the surface that is used as a target for {@link CaptureRequest}
     * Get the surface that is used as a target for {@link CaptureRequest}
     *
     *
+0 −1
Original line number Original line Diff line number Diff line
@@ -90,7 +90,6 @@ public class CameraDeviceSetupImpl extends CameraDevice.CameraDeviceSetup {
    @Override
    @Override
    public boolean isSessionConfigurationSupported(@NonNull SessionConfiguration config)
    public boolean isSessionConfigurationSupported(@NonNull SessionConfiguration config)
            throws CameraAccessException {
            throws CameraAccessException {
        // TODO(b/298033056): restructure the OutputConfiguration API for better usability
        synchronized (mInterfaceLock) {
        synchronized (mInterfaceLock) {
            if (mCameraManager.isCameraServiceDisabled()) {
            if (mCameraManager.isCameraServiceDisabled()) {
                throw new IllegalArgumentException("No cameras available on device");
                throw new IllegalArgumentException("No cameras available on device");
+411 −51

File changed.

Preview size limit exceeded, changes collapsed.

Loading