Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -20277,6 +20277,7 @@ package android.hardware.camera2.params { method public long getDynamicRangeProfile(); method public int getMaxSharedSurfaceCount(); method public int getMirrorMode(); method @FlaggedApi("com.android.internal.camera.flags.mirror_mode_shared_surfaces") public int getMirrorMode(@NonNull android.view.Surface); method public long getStreamUseCase(); method @Nullable public android.view.Surface getSurface(); method public int getSurfaceGroupId(); Loading @@ -20287,6 +20288,7 @@ package android.hardware.camera2.params { method public void removeSurface(@NonNull android.view.Surface); method public void setDynamicRangeProfile(long); method public void setMirrorMode(int); method @FlaggedApi("com.android.internal.camera.flags.mirror_mode_shared_surfaces") public void setMirrorMode(@NonNull android.view.Surface, int); method public void setPhysicalCameraId(@Nullable String); method public void setReadoutTimestampEnabled(boolean); method public void setStreamUseCase(long); core/java/android/hardware/camera2/params/OutputConfiguration.java +116 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.hardware.camera2.utils.SurfaceUtils; import android.media.ImageReader; import android.os.Parcel; import android.os.Parcelable; import android.util.IntArray; import android.util.Log; import android.util.Size; import android.view.Surface; Loading Loading @@ -596,6 +597,10 @@ public final class OutputConfiguration implements Parcelable { mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; mTimestampBase = TIMESTAMP_BASE_DEFAULT; mMirrorMode = MIRROR_MODE_AUTO; mMirrorModeForSurfaces = new IntArray(); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.add(mMirrorMode); } mReadoutTimestampEnabled = false; mIsReadoutSensorTimestampBase = false; mUsage = 0; Loading Loading @@ -827,6 +832,7 @@ public final class OutputConfiguration implements Parcelable { mSurfaceGroupId = SURFACE_GROUP_ID_NONE; mSurfaces = new ArrayList<Surface>(); mMirrorModeForSurfaces = new IntArray(); mRotation = ROTATION_0; mConfiguredSize = surfaceSize; mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(ImageFormat.PRIVATE); Loading Loading @@ -971,6 +977,9 @@ public final class OutputConfiguration implements Parcelable { mDynamicRangeProfile = DynamicRangeProfiles.STANDARD; mColorSpace = ColorSpaceProfiles.UNSPECIFIED; mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; mTimestampBase = TIMESTAMP_BASE_DEFAULT; mMirrorMode = MIRROR_MODE_AUTO; mMirrorModeForSurfaces = new IntArray(); mReadoutTimestampEnabled = false; mIsReadoutSensorTimestampBase = false; mUsage = usage; Loading Loading @@ -1239,6 +1248,9 @@ public final class OutputConfiguration implements Parcelable { } mSurfaces.add(surface); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.add(mMirrorMode); } } /** Loading Loading @@ -1266,9 +1278,16 @@ public final class OutputConfiguration implements Parcelable { throw new IllegalArgumentException( "Cannot remove surface associated with this output configuration"); } if (!mSurfaces.remove(surface)) { int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface is not part of this output configuration"); } mSurfaces.remove(surfaceIndex); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.remove(surfaceIndex); } } /** Loading Loading @@ -1405,6 +1424,11 @@ public final class OutputConfiguration implements Parcelable { * ImageReader, MediaRecorder, or MediaCodec, the mirror mode has no effect. If mirroring is * needed for such outputs, the application needs to mirror the image buffers itself before * passing them onward.</p> * * <p>Starting from Android 16, this function sets the mirror modes for all of the output * surfaces contained within this OutputConfiguration. To set the mirror mode for a particular * output surface, the application can call {@link #setMirrorMode(Surface, int)}. Prior to * Android 16, this function is only applicable if surface sharing is not enabled.</p> */ public void setMirrorMode(@MirrorMode int mirrorMode) { // Verify that the value is in range Loading @@ -1413,6 +1437,9 @@ public final class OutputConfiguration implements Parcelable { throw new IllegalArgumentException("Not a valid mirror mode " + mirrorMode); } mMirrorMode = mirrorMode; for (int j = 0; j < mMirrorModeForSurfaces.size(); j++) { mMirrorModeForSurfaces.set(j, mirrorMode); } } /** Loading @@ -1427,6 +1454,72 @@ public final class OutputConfiguration implements Parcelable { return mMirrorMode; } /** * Set the mirroring mode for a surface belonging to this OutputConfiguration * * <p>This function is identical to {@link #setMirroMode(int)} if {@code surface} is * the only surface belonging to this OutputConfiguration.</p> * * <p>If this OutputConfiguration contains a deferred surface, the application can either * call {@link #setMirrorMode(int)}, or call this function after calling {@link #addSurface}. * </p> * * <p>If this OutputConfiguration contains shared surfaces, the application can set * different mirroring modes for different surfaces.</p> * * <p>For efficiency, the mirror effect is applied as a transform flag, so it is only effective * in some outputs. It works automatically for SurfaceView and TextureView outputs. For manual * use of SurfaceTexture, it is reflected in the value of * {@link android.graphics.SurfaceTexture#getTransformMatrix}. For other end points, such as * ImageReader, MediaRecorder, or MediaCodec, the mirror mode has no effect. If mirroring is * needed for such outputs, the application needs to mirror the image buffers itself before * passing them onward.</p> * * @throws IllegalArgumentException If the {@code surface} doesn't belong to this * OutputConfiguration, or the {@code mirrorMode} value is * not valid. */ @FlaggedApi(Flags.FLAG_MIRROR_MODE_SHARED_SURFACES) public void setMirrorMode(@NonNull Surface surface, @MirrorMode int mirrorMode) { checkNotNull(surface, "Surface must not be null"); // Verify that the value is in range if (mirrorMode < MIRROR_MODE_AUTO || mirrorMode > MIRROR_MODE_V) { throw new IllegalArgumentException("Not a valid mirror mode " + mirrorMode); } int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface not part of the OutputConfiguration"); } mMirrorModeForSurfaces.set(surfaceIndex, mirrorMode); } /** * Get the current mirroring mode for an output surface * * <p>If no {@link #setMirrorMode} is called first, this function returns * {@link #MIRROR_MODE_AUTO}.</p> * * <p>If only {@link #setMirrorMode(int)} is called, the mirroring mode set by that * function will be returned here as long as the {@code surface} belongs to this * output configuration.</p> * * @throws IllegalArgumentException If the {@code surface} doesn't belong to this * OutputConfiguration. * * @return The mirroring mode for the specified output surface */ @FlaggedApi(Flags.FLAG_MIRROR_MODE_SHARED_SURFACES) public @MirrorMode int getMirrorMode(@NonNull Surface surface) { checkNotNull(surface, "Surface must not be null"); int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface not part of the OutputConfiguration"); } return mMirrorModeForSurfaces.get(surfaceIndex); } /** * Use the camera sensor's readout time for the image timestamp. * Loading Loading @@ -1491,6 +1584,7 @@ public final class OutputConfiguration implements Parcelable { this.mStreamUseCase = other.mStreamUseCase; this.mTimestampBase = other.mTimestampBase; this.mMirrorMode = other.mMirrorMode; this.mMirrorModeForSurfaces = other.mMirrorModeForSurfaces.clone(); this.mReadoutTimestampEnabled = other.mReadoutTimestampEnabled; this.mUsage = other.mUsage; } Loading Loading @@ -1520,6 +1614,7 @@ public final class OutputConfiguration implements Parcelable { int timestampBase = source.readInt(); int mirrorMode = source.readInt(); int[] mirrorModeForSurfaces = source.createIntArray(); boolean readoutTimestampEnabled = source.readInt() == 1; int format = source.readInt(); int dataSpace = source.readInt(); Loading @@ -1531,7 +1626,6 @@ public final class OutputConfiguration implements Parcelable { mConfiguredSize = new Size(width, height); mIsDeferredConfig = isDeferred; mIsShared = isShared; mSurfaces = surfaces; mUsage = 0; if (mSurfaces.size() > 0) { mSurfaceType = SURFACE_TYPE_UNKNOWN; Loading Loading @@ -1560,6 +1654,7 @@ public final class OutputConfiguration implements Parcelable { mStreamUseCase = streamUseCase; mTimestampBase = timestampBase; mMirrorMode = mirrorMode; mMirrorModeForSurfaces = IntArray.wrap(mirrorModeForSurfaces); mReadoutTimestampEnabled = readoutTimestampEnabled; } Loading Loading @@ -1706,6 +1801,7 @@ public final class OutputConfiguration implements Parcelable { dest.writeLong(mStreamUseCase); dest.writeInt(mTimestampBase); dest.writeInt(mMirrorMode); dest.writeIntArray(mMirrorModeForSurfaces.toArray()); dest.writeInt(mReadoutTimestampEnabled ? 1 : 0); dest.writeInt(mConfiguredFormat); dest.writeInt(mConfiguredDataspace); Loading Loading @@ -1756,6 +1852,16 @@ public final class OutputConfiguration implements Parcelable { return false; } } if (Flags.mirrorModeSharedSurfaces()) { if (mMirrorModeForSurfaces.size() != other.mMirrorModeForSurfaces.size()) { return false; } for (int j = 0; j < mMirrorModeForSurfaces.size(); j++) { if (mMirrorModeForSurfaces.get(j) != other.mMirrorModeForSurfaces.get(j)) { return false; } } } int minLen = Math.min(mSurfaces.size(), other.mSurfaces.size()); for (int i = 0; i < minLen; i++) { if (mSurfaces.get(i) != other.mSurfaces.get(i)) Loading Loading @@ -1799,8 +1905,9 @@ public final class OutputConfiguration implements Parcelable { mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); mTimestampBase, mMirrorMode, HashCodeHelpers.hashCode(mMirrorModeForSurfaces.toArray()), mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); } return HashCodeHelpers.hashCode( Loading @@ -1810,7 +1917,9 @@ public final class OutputConfiguration implements Parcelable { mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); mMirrorMode, HashCodeHelpers.hashCode(mMirrorModeForSurfaces.toArray()), mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); } private static final String TAG = "OutputConfiguration"; Loading Loading @@ -1852,6 +1961,8 @@ public final class OutputConfiguration implements Parcelable { private int mTimestampBase; // Mirroring mode private int mMirrorMode; // Per-surface mirror modes private IntArray mMirrorModeForSurfaces; // readout timestamp private boolean mReadoutTimestampEnabled; // Whether the timestamp base is set to READOUT_SENSOR Loading Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -20277,6 +20277,7 @@ package android.hardware.camera2.params { method public long getDynamicRangeProfile(); method public int getMaxSharedSurfaceCount(); method public int getMirrorMode(); method @FlaggedApi("com.android.internal.camera.flags.mirror_mode_shared_surfaces") public int getMirrorMode(@NonNull android.view.Surface); method public long getStreamUseCase(); method @Nullable public android.view.Surface getSurface(); method public int getSurfaceGroupId(); Loading @@ -20287,6 +20288,7 @@ package android.hardware.camera2.params { method public void removeSurface(@NonNull android.view.Surface); method public void setDynamicRangeProfile(long); method public void setMirrorMode(int); method @FlaggedApi("com.android.internal.camera.flags.mirror_mode_shared_surfaces") public void setMirrorMode(@NonNull android.view.Surface, int); method public void setPhysicalCameraId(@Nullable String); method public void setReadoutTimestampEnabled(boolean); method public void setStreamUseCase(long);
core/java/android/hardware/camera2/params/OutputConfiguration.java +116 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.hardware.camera2.utils.SurfaceUtils; import android.media.ImageReader; import android.os.Parcel; import android.os.Parcelable; import android.util.IntArray; import android.util.Log; import android.util.Size; import android.view.Surface; Loading Loading @@ -596,6 +597,10 @@ public final class OutputConfiguration implements Parcelable { mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; mTimestampBase = TIMESTAMP_BASE_DEFAULT; mMirrorMode = MIRROR_MODE_AUTO; mMirrorModeForSurfaces = new IntArray(); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.add(mMirrorMode); } mReadoutTimestampEnabled = false; mIsReadoutSensorTimestampBase = false; mUsage = 0; Loading Loading @@ -827,6 +832,7 @@ public final class OutputConfiguration implements Parcelable { mSurfaceGroupId = SURFACE_GROUP_ID_NONE; mSurfaces = new ArrayList<Surface>(); mMirrorModeForSurfaces = new IntArray(); mRotation = ROTATION_0; mConfiguredSize = surfaceSize; mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(ImageFormat.PRIVATE); Loading Loading @@ -971,6 +977,9 @@ public final class OutputConfiguration implements Parcelable { mDynamicRangeProfile = DynamicRangeProfiles.STANDARD; mColorSpace = ColorSpaceProfiles.UNSPECIFIED; mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; mTimestampBase = TIMESTAMP_BASE_DEFAULT; mMirrorMode = MIRROR_MODE_AUTO; mMirrorModeForSurfaces = new IntArray(); mReadoutTimestampEnabled = false; mIsReadoutSensorTimestampBase = false; mUsage = usage; Loading Loading @@ -1239,6 +1248,9 @@ public final class OutputConfiguration implements Parcelable { } mSurfaces.add(surface); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.add(mMirrorMode); } } /** Loading Loading @@ -1266,9 +1278,16 @@ public final class OutputConfiguration implements Parcelable { throw new IllegalArgumentException( "Cannot remove surface associated with this output configuration"); } if (!mSurfaces.remove(surface)) { int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface is not part of this output configuration"); } mSurfaces.remove(surfaceIndex); if (Flags.mirrorModeSharedSurfaces()) { mMirrorModeForSurfaces.remove(surfaceIndex); } } /** Loading Loading @@ -1405,6 +1424,11 @@ public final class OutputConfiguration implements Parcelable { * ImageReader, MediaRecorder, or MediaCodec, the mirror mode has no effect. If mirroring is * needed for such outputs, the application needs to mirror the image buffers itself before * passing them onward.</p> * * <p>Starting from Android 16, this function sets the mirror modes for all of the output * surfaces contained within this OutputConfiguration. To set the mirror mode for a particular * output surface, the application can call {@link #setMirrorMode(Surface, int)}. Prior to * Android 16, this function is only applicable if surface sharing is not enabled.</p> */ public void setMirrorMode(@MirrorMode int mirrorMode) { // Verify that the value is in range Loading @@ -1413,6 +1437,9 @@ public final class OutputConfiguration implements Parcelable { throw new IllegalArgumentException("Not a valid mirror mode " + mirrorMode); } mMirrorMode = mirrorMode; for (int j = 0; j < mMirrorModeForSurfaces.size(); j++) { mMirrorModeForSurfaces.set(j, mirrorMode); } } /** Loading @@ -1427,6 +1454,72 @@ public final class OutputConfiguration implements Parcelable { return mMirrorMode; } /** * Set the mirroring mode for a surface belonging to this OutputConfiguration * * <p>This function is identical to {@link #setMirroMode(int)} if {@code surface} is * the only surface belonging to this OutputConfiguration.</p> * * <p>If this OutputConfiguration contains a deferred surface, the application can either * call {@link #setMirrorMode(int)}, or call this function after calling {@link #addSurface}. * </p> * * <p>If this OutputConfiguration contains shared surfaces, the application can set * different mirroring modes for different surfaces.</p> * * <p>For efficiency, the mirror effect is applied as a transform flag, so it is only effective * in some outputs. It works automatically for SurfaceView and TextureView outputs. For manual * use of SurfaceTexture, it is reflected in the value of * {@link android.graphics.SurfaceTexture#getTransformMatrix}. For other end points, such as * ImageReader, MediaRecorder, or MediaCodec, the mirror mode has no effect. If mirroring is * needed for such outputs, the application needs to mirror the image buffers itself before * passing them onward.</p> * * @throws IllegalArgumentException If the {@code surface} doesn't belong to this * OutputConfiguration, or the {@code mirrorMode} value is * not valid. */ @FlaggedApi(Flags.FLAG_MIRROR_MODE_SHARED_SURFACES) public void setMirrorMode(@NonNull Surface surface, @MirrorMode int mirrorMode) { checkNotNull(surface, "Surface must not be null"); // Verify that the value is in range if (mirrorMode < MIRROR_MODE_AUTO || mirrorMode > MIRROR_MODE_V) { throw new IllegalArgumentException("Not a valid mirror mode " + mirrorMode); } int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface not part of the OutputConfiguration"); } mMirrorModeForSurfaces.set(surfaceIndex, mirrorMode); } /** * Get the current mirroring mode for an output surface * * <p>If no {@link #setMirrorMode} is called first, this function returns * {@link #MIRROR_MODE_AUTO}.</p> * * <p>If only {@link #setMirrorMode(int)} is called, the mirroring mode set by that * function will be returned here as long as the {@code surface} belongs to this * output configuration.</p> * * @throws IllegalArgumentException If the {@code surface} doesn't belong to this * OutputConfiguration. * * @return The mirroring mode for the specified output surface */ @FlaggedApi(Flags.FLAG_MIRROR_MODE_SHARED_SURFACES) public @MirrorMode int getMirrorMode(@NonNull Surface surface) { checkNotNull(surface, "Surface must not be null"); int surfaceIndex = mSurfaces.indexOf(surface); if (surfaceIndex == -1) { throw new IllegalArgumentException("Surface not part of the OutputConfiguration"); } return mMirrorModeForSurfaces.get(surfaceIndex); } /** * Use the camera sensor's readout time for the image timestamp. * Loading Loading @@ -1491,6 +1584,7 @@ public final class OutputConfiguration implements Parcelable { this.mStreamUseCase = other.mStreamUseCase; this.mTimestampBase = other.mTimestampBase; this.mMirrorMode = other.mMirrorMode; this.mMirrorModeForSurfaces = other.mMirrorModeForSurfaces.clone(); this.mReadoutTimestampEnabled = other.mReadoutTimestampEnabled; this.mUsage = other.mUsage; } Loading Loading @@ -1520,6 +1614,7 @@ public final class OutputConfiguration implements Parcelable { int timestampBase = source.readInt(); int mirrorMode = source.readInt(); int[] mirrorModeForSurfaces = source.createIntArray(); boolean readoutTimestampEnabled = source.readInt() == 1; int format = source.readInt(); int dataSpace = source.readInt(); Loading @@ -1531,7 +1626,6 @@ public final class OutputConfiguration implements Parcelable { mConfiguredSize = new Size(width, height); mIsDeferredConfig = isDeferred; mIsShared = isShared; mSurfaces = surfaces; mUsage = 0; if (mSurfaces.size() > 0) { mSurfaceType = SURFACE_TYPE_UNKNOWN; Loading Loading @@ -1560,6 +1654,7 @@ public final class OutputConfiguration implements Parcelable { mStreamUseCase = streamUseCase; mTimestampBase = timestampBase; mMirrorMode = mirrorMode; mMirrorModeForSurfaces = IntArray.wrap(mirrorModeForSurfaces); mReadoutTimestampEnabled = readoutTimestampEnabled; } Loading Loading @@ -1706,6 +1801,7 @@ public final class OutputConfiguration implements Parcelable { dest.writeLong(mStreamUseCase); dest.writeInt(mTimestampBase); dest.writeInt(mMirrorMode); dest.writeIntArray(mMirrorModeForSurfaces.toArray()); dest.writeInt(mReadoutTimestampEnabled ? 1 : 0); dest.writeInt(mConfiguredFormat); dest.writeInt(mConfiguredDataspace); Loading Loading @@ -1756,6 +1852,16 @@ public final class OutputConfiguration implements Parcelable { return false; } } if (Flags.mirrorModeSharedSurfaces()) { if (mMirrorModeForSurfaces.size() != other.mMirrorModeForSurfaces.size()) { return false; } for (int j = 0; j < mMirrorModeForSurfaces.size(); j++) { if (mMirrorModeForSurfaces.get(j) != other.mMirrorModeForSurfaces.get(j)) { return false; } } } int minLen = Math.min(mSurfaces.size(), other.mSurfaces.size()); for (int i = 0; i < minLen; i++) { if (mSurfaces.get(i) != other.mSurfaces.get(i)) Loading Loading @@ -1799,8 +1905,9 @@ public final class OutputConfiguration implements Parcelable { mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); mTimestampBase, mMirrorMode, HashCodeHelpers.hashCode(mMirrorModeForSurfaces.toArray()), mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); } return HashCodeHelpers.hashCode( Loading @@ -1810,7 +1917,9 @@ public final class OutputConfiguration implements Parcelable { mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(), mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(), mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); mMirrorMode, HashCodeHelpers.hashCode(mMirrorModeForSurfaces.toArray()), mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage)); } private static final String TAG = "OutputConfiguration"; Loading Loading @@ -1852,6 +1961,8 @@ public final class OutputConfiguration implements Parcelable { private int mTimestampBase; // Mirroring mode private int mMirrorMode; // Per-surface mirror modes private IntArray mMirrorModeForSurfaces; // readout timestamp private boolean mReadoutTimestampEnabled; // Whether the timestamp base is set to READOUT_SENSOR Loading