public final class

OutputConfigurationCompat

extends java.lang.Object

 java.lang.Object

↳androidx.camera.camera2.impl.compat.params.OutputConfigurationCompat

Overview

Helper for accessing features in OutputConfiguration in a backwards compatible fashion.

Summary

Fields
public static final intSURFACE_GROUP_ID_NONE

Invalid surface group ID.

Constructors
publicOutputConfigurationCompat(Size surfaceSize, java.lang.Class<java.lang.Object> klass)

Create a new OutputConfigurationCompat instance, with desired Surface size and Surface source class.

publicOutputConfigurationCompat(Surface surface)

Methods
public voidaddSurface(Surface surface)

Add a surface to this OutputConfiguration.

public voidenableSurfaceSharing()

Enable multiple surfaces sharing the same OutputConfiguration.

public booleanequals(java.lang.Object obj)

Check if this OutputConfigurationCompat is equal to another OutputConfigurationCompat.

public intgetMaxSharedSurfaceCount()

Get the maximum supported shared count.

public java.lang.StringgetPhysicalCameraId()

Retrieve the physical camera ID set by OutputConfigurationCompat.setPhysicalCameraId(String).

public SurfacegetSurface()

Get the associated with this OutputConfigurationCompat.

public intgetSurfaceGroupId()

Get the surface group ID associated with this OutputConfigurationCompat.

public java.util.List<Surface>getSurfaces()

Get the immutable list of surfaces associated with this OutputConfigurationCompat.

public inthashCode()

public voidremoveSurface(Surface surface)

Remove a surface from this OutputConfiguration.

public voidsetPhysicalCameraId(java.lang.String physicalCameraId)

Set the id of the physical camera for this OutputConfiguration.

public java.lang.Objectunwrap()

Gets the underlying framework android.hardware.camera2.params.OutputConfiguration object.

public static OutputConfigurationCompatwrap(java.lang.Object outputConfiguration)

Creates an instance from a framework android.hardware.camera2.params.OutputConfiguration object.

from java.lang.Objectclone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait

Fields

public static final int SURFACE_GROUP_ID_NONE

Invalid surface group ID.

An OutputConfiguration with this value indicates that the included surface doesn't belong to any surface group.

Constructors

public OutputConfigurationCompat(Surface surface)

public OutputConfigurationCompat(Size surfaceSize, java.lang.Class<java.lang.Object> klass)

Create a new OutputConfigurationCompat instance, with desired Surface size and Surface source class.

This constructor takes an argument for desired Surface size and the Surface source class without providing the actual output Surface. This is used to setup an output configuration with a deferred Surface. The application can use this output configuration to create a session.

However, the actual output Surface must be set via OutputConfigurationCompat.addSurface(Surface) and the deferred Surface configuration must be finalized via CameraCaptureSession before submitting a request with this Surface target. The deferred Surface can only be obtained either from by calling , or from via ).

Parameters:

surfaceSize: Size for the deferred surface.
klass: a non-null java.lang.Class object reference that indicates the source of this surface. Only and are supported.

Methods

public static OutputConfigurationCompat wrap(java.lang.Object outputConfiguration)

Creates an instance from a framework android.hardware.camera2.params.OutputConfiguration object.

This method always returns null on API <= 23.

Parameters:

outputConfiguration: an android.hardware.camera2.params.OutputConfiguration object, or null if none.

Returns:

an equivalent OutputConfigurationCompat object, or null if not supported.

public void enableSurfaceSharing()

Enable multiple surfaces sharing the same OutputConfiguration.

For advanced use cases, a camera application may require more streams than the combination guaranteed by CameraDevice.createCaptureSession. In this case, more than one compatible surface can be attached to an OutputConfiguration so that they map to one camera stream, and the outputs share memory buffers when possible. Due to buffer sharing clients should be careful when adding surface outputs that modify their input data. If such case exists, camera clients should have an additional mechanism to synchronize read and write access between individual consumers.

Two surfaces are compatible in the below cases:

  • Surfaces with the same size, format, dataSpace, and Surface source class. In this case, CameraDevice.createCaptureSessionByOutputConfigurations is guaranteed to succeed.
  • Surfaces with the same size, format, and dataSpace, but different Surface source classes that are generally not compatible. However, on some devices, the underlying camera device is able to use the same buffer layout for both surfaces. The only way to discover if this is the case is to create a capture session with that output configuration. For example, if the camera device uses the same private buffer format between a SurfaceView/SurfaceTexture and a MediaRecorder/MediaCodec, CameraDevice.createCaptureSessionByOutputConfigurations will succeed. Otherwise, it fails with .

    To enable surface sharing, this function must be called before CameraDevice.createCaptureSessionByOutputConfigurations or CameraDevice.createReprocessableCaptureSessionByConfigurations. Calling this function after CameraDevice.createCaptureSessionByOutputConfigurations has no effect.

    Up to OutputConfigurationCompat.getMaxSharedSurfaceCount() surfaces can be shared for an OutputConfiguration. The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView, MediaRecorder, MediaCodec, or implementation defined ImageReader.

    public java.lang.String getPhysicalCameraId()

    Retrieve the physical camera ID set by OutputConfigurationCompat.setPhysicalCameraId(String).

    public void setPhysicalCameraId(java.lang.String physicalCameraId)

    Set the id of the physical camera for this OutputConfiguration.

    In the case one logical camera is made up of multiple physical cameras, it could be desirable for the camera application to request streams from individual physical cameras. This call achieves it by mapping the OutputConfiguration to the physical camera id.

    The valid physical camera ids can be queried by CameraCharacteristics.getPhysicalCameraIds on API >= 28.

    On API <= 27, the physical camera id will be ignored since logical camera is not supported on these API levels.

    Passing in a null physicalCameraId means that the OutputConfiguration is for a logical stream.

    This function must be called before CameraDevice.createCaptureSessionByOutputConfigurations or CameraDevice.createReprocessableCaptureSessionByConfigurations. Calling this function after CameraDevice.createCaptureSessionByOutputConfigurations or CameraDevice.createReprocessableCaptureSessionByConfigurations has no effect.

    The surface belonging to a physical camera OutputConfiguration must not be used as input or output of a reprocessing request.

    public void addSurface(Surface surface)

    Add a surface to this OutputConfiguration.

    This method will always throw on API <= 25, as these API levels do not support surface sharing. Users should always check OutputConfigurationCompat.getMaxSharedSurfaceCount() before attempting to add a surface.

    This function can be called before or after CameraDevice#createCaptureSessionByOutputConfigurations. If it's called after, the application must finalize the capture session with CameraCaptureSession.finalizeOutputConfigurations. It is possible to call this method after the output configurations have been finalized only in cases of enabled surface sharing see OutputConfigurationCompat.enableSurfaceSharing(). The modified output configuration must be updated with CameraCaptureSession.updateOutputConfiguration.

    If the OutputConfiguration was constructed with a deferred surface by OutputConfigurationCompat.OutputConfigurationCompat(Size, Class), the added surface must be obtained from by calling , or from via ).

    If the OutputConfiguration was constructed by other constructors, the added surface must be compatible with the existing surface. See OutputConfigurationCompat.enableSurfaceSharing() for details of compatible surfaces.

    If the OutputConfiguration already contains a Surface, OutputConfigurationCompat.enableSurfaceSharing() must be called before calling this function to add a new Surface.

    Parameters:

    surface: The surface to be added.

    public void removeSurface(Surface surface)

    Remove a surface from this OutputConfiguration.

    Surfaces added via calls to OutputConfigurationCompat.addSurface(Surface) can also be removed from the OutputConfiguration. The only notable exception is the surface associated with the OutputConfigration see OutputConfigurationCompat.getSurface() which was passed as part of the constructor or was added first in the deferred case OutputConfigurationCompat.OutputConfigurationCompat(Size, Class).

    Parameters:

    surface: The surface to be removed.

    public int getMaxSharedSurfaceCount()

    Get the maximum supported shared count.

    Returns:

    the maximum number of surfaces that can be added per each OutputConfiguration.

    See also: OutputConfigurationCompat.enableSurfaceSharing()

    public Surface getSurface()

    Get the associated with this OutputConfigurationCompat. If more than one surface is associated with this OutputConfigurationCompat, return the first one as specified in the constructor or OutputConfigurationCompat.addSurface(Surface).

    public java.util.List<Surface> getSurfaces()

    Get the immutable list of surfaces associated with this OutputConfigurationCompat.

    Returns:

    the list of surfaces associated with this OutputConfigurationCompat as specified in the constructor and OutputConfigurationCompat.addSurface(Surface). The list should not be modified.

    public int getSurfaceGroupId()

    Get the surface group ID associated with this OutputConfigurationCompat.

    Returns:

    the surface group ID associated with this OutputConfigurationCompat. The default value is #SURFACE_GROUP_ID_NONE.

    public boolean equals(java.lang.Object obj)

    Check if this OutputConfigurationCompat is equal to another OutputConfigurationCompat.

    Two output configurations are only equal if and only if the underlying surfaces, surface properties (width, height, format, dataspace) when the output configurations are created, and all other configuration parameters are equal.

    Returns:

    true if the objects were equal, false otherwise

    public int hashCode()

    public java.lang.Object unwrap()

    Gets the underlying framework android.hardware.camera2.params.OutputConfiguration object.

    This method always returns null on API <= 23.

    Returns:

    an equivalent android.hardware.camera2.params.OutputConfiguration object, or null if not supported.

    Source

    /*
     * Copyright 2019 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 androidx.camera.camera2.impl.compat.params;
    
    import android.hardware.camera2.CameraCaptureSession;
    import android.hardware.camera2.params.OutputConfiguration;
    import android.os.Build;
    import android.util.Size;
    import android.view.Surface;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.annotation.RequiresApi;
    import androidx.annotation.RestrictTo;
    import androidx.annotation.RestrictTo.Scope;
    
    import java.util.List;
    
    /**
     * Helper for accessing features in OutputConfiguration in a backwards compatible fashion.
     */
    @RequiresApi(21)
    public final class OutputConfigurationCompat {
    
        /**
         * Invalid surface group ID.
         *
         * <p>An OutputConfiguration with this value indicates that the included surface
         * doesn't belong to any surface group.</p>
         */
        public static final int SURFACE_GROUP_ID_NONE = -1;
    
        private final OutputConfigurationCompatImpl mImpl;
    
        public OutputConfigurationCompat(@NonNull Surface surface) {
            if (Build.VERSION.SDK_INT >= 28) {
                mImpl = new OutputConfigurationCompatApi28Impl(surface);
            } else if (Build.VERSION.SDK_INT >= 26) {
                mImpl = new OutputConfigurationCompatApi26Impl(surface);
            } else if (Build.VERSION.SDK_INT >= 24) {
                mImpl = new OutputConfigurationCompatApi24Impl(surface);
            } else {
                mImpl = new OutputConfigurationCompatBaseImpl(surface);
            }
        }
    
    
        /**
         * Create a new {@link OutputConfigurationCompat} instance, with desired Surface size and
         * Surface source class.
         *
         * <p>
         * This constructor takes an argument for desired Surface size and the Surface source class
         * without providing the actual output Surface. This is used to setup an output configuration
         * with a deferred Surface. The application can use this output configuration to create a
         * session.
         * </p>
         * <p>
         * However, the actual output Surface must be set via {@link #addSurface} and the deferred
         * Surface configuration must be finalized via {@link
         * CameraCaptureSession#finalizeOutputConfigurations} before submitting a request with this
         * Surface target. The deferred Surface can only be obtained either from {@link
         * android.view.SurfaceView} by calling {@link android.view.SurfaceHolder#getSurface}, or from
         * {@link android.graphics.SurfaceTexture} via
         * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}).
         * </p>
         *
         * @param surfaceSize Size for the deferred surface.
         * @param klass       a non-{@code null} {@link Class} object reference that indicates the
         *                    source of
         *                    this surface. Only {@link android.view.SurfaceHolder SurfaceHolder
         *                    .class} and
         *                    {@link android.graphics.SurfaceTexture SurfaceTexture.class} are
         *                    supported.
         * @throws IllegalArgumentException if the Surface source class is not supported, or Surface
         *                                  size is zero.
         */
        @RequiresApi(26)
        public <T> OutputConfigurationCompat(@NonNull Size surfaceSize, @NonNull Class<T> klass) {
            OutputConfiguration deferredConfig = new OutputConfiguration(surfaceSize, klass);
            if (Build.VERSION.SDK_INT >= 28) {
                mImpl = OutputConfigurationCompatApi28Impl.wrap(deferredConfig);
            } else {
                mImpl = OutputConfigurationCompatApi26Impl.wrap(deferredConfig);
            }
        }
    
        private OutputConfigurationCompat(@NonNull OutputConfigurationCompatImpl impl) {
            mImpl = impl;
        }
    
        /**
         * Creates an instance from a framework android.hardware.camera2.params.OutputConfiguration
         * object.
         *
         * <p>This method always returns {@code null} on API &lt;= 23.</p>
         *
         * @param outputConfiguration an android.hardware.camera2.params.OutputConfiguration object, or
         *                            {@code null} if none.
         * @return an equivalent {@link OutputConfigurationCompat} object, or {@code null} if not
         * supported.
         */
        @Nullable
        public static OutputConfigurationCompat wrap(@Nullable Object outputConfiguration) {
            if (outputConfiguration == null) {
                return null;
            }
    
            OutputConfigurationCompatImpl outputConfigurationCompatImpl = null;
            if (Build.VERSION.SDK_INT >= 28) {
                outputConfigurationCompatImpl = OutputConfigurationCompatApi28Impl.wrap(
                        (OutputConfiguration) outputConfiguration);
            } else if (Build.VERSION.SDK_INT >= 26) {
                outputConfigurationCompatImpl = OutputConfigurationCompatApi26Impl.wrap(
                        (OutputConfiguration) outputConfiguration);
            } else if (Build.VERSION.SDK_INT >= 24) {
                outputConfigurationCompatImpl = OutputConfigurationCompatApi24Impl.wrap(
                        (OutputConfiguration) outputConfiguration);
            }
    
            if (outputConfigurationCompatImpl == null) {
                return null;
            }
    
            return new OutputConfigurationCompat(outputConfigurationCompatImpl);
        }
    
        /**
         * Enable multiple surfaces sharing the same OutputConfiguration.
         *
         * <p>For advanced use cases, a camera application may require more streams than the combination
         * guaranteed by {@code CameraDevice.createCaptureSession}. In this case, more than one
         * compatible surface can be attached to an OutputConfiguration so that they map to one
         * camera stream, and the outputs share memory buffers when possible. Due to buffer sharing
         * clients should be careful when adding surface outputs that modify their input data. If such
         * case exists, camera clients should have an additional mechanism to synchronize read and write
         * access between individual consumers.</p>
         *
         * <p>Two surfaces are compatible in the below cases:</p>
         *
         * <li> Surfaces with the same size, format, dataSpace, and Surface source class. In this case,
         * {@code CameraDevice.createCaptureSessionByOutputConfigurations} is guaranteed to succeed.
         *
         * <li> Surfaces with the same size, format, and dataSpace, but different Surface source classes
         * that are generally not compatible. However, on some devices, the underlying camera device is
         * able to use the same buffer layout for both surfaces. The only way to discover if this is the
         * case is to create a capture session with that output configuration. For example, if the
         * camera device uses the same private buffer format between a SurfaceView/SurfaceTexture and a
         * MediaRecorder/MediaCodec, {@code CameraDevice.createCaptureSessionByOutputConfigurations}
         * will succeed. Otherwise, it fails with {@link
         * CameraCaptureSession.StateCallback#onConfigureFailed}.
         * </ol>
         *
         * <p>To enable surface sharing, this function must be called before {@code
         * CameraDevice.createCaptureSessionByOutputConfigurations} or {@code
         * CameraDevice.createReprocessableCaptureSessionByConfigurations}. Calling this function after
         * {@code CameraDevice.createCaptureSessionByOutputConfigurations} has no effect.</p>
         *
         * <p>Up to {@link #getMaxSharedSurfaceCount} surfaces can be shared for an OutputConfiguration.
         * The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView,
         * MediaRecorder, MediaCodec, or implementation defined ImageReader.</p>
         */
        public void enableSurfaceSharing() {
            mImpl.enableSurfaceSharing();
        }
    
        /**
         * Retrieve the physical camera ID set by {@link #setPhysicalCameraId(String)}.
         *
         * @hide Not supported on all API levels. Used for compatibility checks on lower API levels.
         */
        @RestrictTo(Scope.LIBRARY)
        @Nullable
        public String getPhysicalCameraId() {
            return mImpl.getPhysicalCameraId();
        }
    
        /**
         * Set the id of the physical camera for this OutputConfiguration.
         *
         * <p>In the case one logical camera is made up of multiple physical cameras, it could be
         * desirable for the camera application to request streams from individual physical cameras.
         * This call achieves it by mapping the OutputConfiguration to the physical camera id.</p>
         *
         * <p>The valid physical camera ids can be queried by {@code
         * CameraCharacteristics.getPhysicalCameraIds} on API &gt;= 28.
         * </p>
         *
         * <p>On API &lt;= 27, the physical camera id will be ignored since logical camera is not
         * supported on these API levels.
         * </p>
         *
         * <p>Passing in a null physicalCameraId means that the OutputConfiguration is for a logical
         * stream.</p>
         *
         * <p>This function must be called before {@code
         * CameraDevice.createCaptureSessionByOutputConfigurations} or {@code
         * CameraDevice.createReprocessableCaptureSessionByConfigurations}. Calling this function
         * after {@code CameraDevice.createCaptureSessionByOutputConfigurations} or {@code
         * CameraDevice.createReprocessableCaptureSessionByConfigurations} has no effect.</p>
         *
         * <p>The surface belonging to a physical camera OutputConfiguration must not be used as input
         * or output of a reprocessing request. </p>
         */
        public void setPhysicalCameraId(@Nullable String physicalCameraId) {
            mImpl.setPhysicalCameraId(physicalCameraId);
        }
    
        /**
         * Add a surface to this OutputConfiguration.
         *
         * <p> This method will always throw on API &lt;= 25, as these API levels do not support surface
         * sharing. Users should always check {@link #getMaxSharedSurfaceCount} before attempting to
         * add a surface.
         *
         * <p> This function can be called before or after {@code
         * CameraDevice#createCaptureSessionByOutputConfigurations}. If it's called after,
         * the application must finalize the capture session with
         * {@code CameraCaptureSession.finalizeOutputConfigurations}. It is possible to call this method
         * after the output configurations have been finalized only in cases of enabled surface sharing
         * see {@link #enableSurfaceSharing}. The modified output configuration must be updated with
         * {@code CameraCaptureSession.updateOutputConfiguration}.</p>
         *
         * <p> If the OutputConfiguration was constructed with a deferred surface by {@link
         * OutputConfigurationCompat#OutputConfigurationCompat(Size, Class)}, the added surface must
         * be obtained
         * from {@link android.view.SurfaceView} by calling
         * {@link android.view.SurfaceHolder#getSurface},
         * or from {@link android.graphics.SurfaceTexture} via
         * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}).</p>
         *
         * <p> If the OutputConfiguration was constructed by other constructors, the added
         * surface must be compatible with the existing surface. See {@link #enableSurfaceSharing} for
         * details of compatible surfaces.</p>
         *
         * <p> If the OutputConfiguration already contains a Surface, {@link #enableSurfaceSharing} must
         * be called before calling this function to add a new Surface.</p>
         *
         * @param surface The surface to be added.
         * @throws IllegalArgumentException if the Surface is invalid, the Surface's
         *                                  dataspace/format doesn't match, or adding the Surface
         *                                  would exceed number of
         *                                  shared surfaces supported.
         * @throws IllegalStateException    if the Surface was already added to this
         *                                  OutputConfiguration,
         *                                  or if the OutputConfiguration is not shared and it
         *                                  already has a surface associated
         *                                  with it.
         */
        public void addSurface(@NonNull Surface surface) {
            mImpl.addSurface(surface);
        }
    
        /**
         * Remove a surface from this OutputConfiguration.
         *
         * <p> Surfaces added via calls to {@link #addSurface} can also be removed from the
         * OutputConfiguration. The only notable exception is the surface associated with
         * the OutputConfigration see {@link #getSurface} which was passed as part of the constructor
         * or was added first in the deferred case
         * {@link OutputConfigurationCompat#OutputConfigurationCompat(Size, Class)}.</p>
         *
         * @param surface The surface to be removed.
         * @throws IllegalArgumentException If the surface is associated with this OutputConfiguration
         *                                  (see {@link #getSurface}) or the surface didn't get added
         *                                  with {@link #addSurface}.
         */
        public void removeSurface(@NonNull Surface surface) {
            mImpl.removeSurface(surface);
        }
    
        /**
         * Get the maximum supported shared {@link Surface} count.
         *
         * @return the maximum number of surfaces that can be added per each OutputConfiguration.
         * @see #enableSurfaceSharing
         */
        public int getMaxSharedSurfaceCount() {
            return mImpl.getMaxSharedSurfaceCount();
        }
    
        /**
         * Get the {@link Surface} associated with this {@link OutputConfigurationCompat}.
         *
         * If more than one surface is associated with this {@link OutputConfigurationCompat}, return
         * the
         * first one as specified in the constructor or {@link OutputConfigurationCompat#addSurface}.
         */
        @Nullable
        public Surface getSurface() {
            return mImpl.getSurface();
        }
    
        /**
         * Get the immutable list of surfaces associated with this {@link OutputConfigurationCompat}.
         *
         * @return the list of surfaces associated with this {@link OutputConfigurationCompat} as
         * specified in
         * the constructor and {@link OutputConfigurationCompat#addSurface}. The list should not be
         * modified.
         */
        @NonNull
        public List<Surface> getSurfaces() {
            return mImpl.getSurfaces();
        }
    
        /**
         * Get the surface group ID associated with this {@link OutputConfigurationCompat}.
         *
         * @return the surface group ID associated with this {@link OutputConfigurationCompat}.
         * The default value is {@value #SURFACE_GROUP_ID_NONE}.
         */
        public int getSurfaceGroupId() {
            return mImpl.getSurfaceGroupId();
        }
    
        /**
         * Check if this {@link OutputConfigurationCompat} is equal to another
         * {@link OutputConfigurationCompat}.
         *
         * <p>Two output configurations are only equal if and only if the underlying surfaces, surface
         * properties (width, height, format, dataspace) when the output configurations are created,
         * and all other configuration parameters are equal. </p>
         *
         * @return {@code true} if the objects were equal, {@code false} otherwise
         */
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof OutputConfigurationCompat)) {
                return false;
            }
    
            return mImpl.equals(((OutputConfigurationCompat) obj).mImpl);
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode() {
            return mImpl.hashCode();
        }
    
        /**
         * Gets the underlying framework android.hardware.camera2.params.OutputConfiguration object.
         *
         * <p>This method always returns {@code null} on API &lt;= 23.</p>
         *
         * @return an equivalent android.hardware.camera2.params.OutputConfiguration object, or {@code
         * null} if not supported.
         */
        @Nullable
        public Object unwrap() {
            return mImpl.getOutputConfiguration();
        }
    
        interface OutputConfigurationCompatImpl {
            void enableSurfaceSharing();
    
            @Nullable
            String getPhysicalCameraId();
    
            void setPhysicalCameraId(@Nullable String physicalCameraId);
    
            void addSurface(@NonNull Surface surface);
    
            void removeSurface(@NonNull Surface surface);
    
            int getMaxSharedSurfaceCount();
    
            @Nullable
            Surface getSurface();
    
            List<Surface> getSurfaces();
    
            int getSurfaceGroupId();
    
            @Nullable
            Object getOutputConfiguration();
        }
    }