diff --git a/api/current.txt b/api/current.txt
index 1c77142a583db..58986e7065efc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14437,13 +14437,13 @@ package android.hardware.camera2.params {
public final class OutputConfiguration implements android.os.Parcelable {
ctor public OutputConfiguration(android.view.Surface);
+ ctor public OutputConfiguration(int, android.view.Surface);
method public int describeContents();
method public android.view.Surface getSurface();
- method public int getSurfaceSetId();
- method public void setSurfaceSetId(int);
+ method public int getSurfaceGroupId();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator An {@link OutputConfiguration} with this value indicates that the included surface
- *doesn't belong to any surface set.
This constructor creates a default configuration.
+ *This constructor creates a default configuration, with a surface group ID of + * {@value #SURFACE_GROUP_ID_NONE}.
* */ - public OutputConfiguration(Surface surface) { - this(surface, ROTATION_0); + public OutputConfiguration(@NonNull Surface surface) { + this(SURFACE_GROUP_ID_NONE, surface, ROTATION_0); + } + + /** + * Create a new {@link OutputConfiguration} instance with a {@link Surface}, + * with a surface group ID. + * + *+ * A surface group ID is used to identify which surface group this output surface belongs to. A + * surface group is a group of output surfaces that are not intended to receive camera output + * buffer streams simultaneously. The {@link CameraDevice} may be able to share the buffers used + * by all the surfaces from the same surface group, therefore may reduce the overall memory + * footprint. The application should only set the same set ID for the streams that are not + * simultaneously streaming. A negative ID indicates that this surface doesn't belong to any + * surface group. The default value is {@value #SURFACE_GROUP_ID_NONE}.
+ * + *For example, a video chat application that has an adaptive output resolution feature would + * need two (or more) output resolutions, to switch resolutions without any output glitches. + * However, at any given time, only one output is active to minimize outgoing network bandwidth + * and encoding overhead. To save memory, the application should set the video outputs to have + * the same non-negative group ID, so that the camera device can share the same memory region + * for the alternating outputs.
+ * + *It is not an error to include output streams with the same group ID in the same capture + * request, but the resulting memory consumption may be higher than if the two streams were + * not in the same surface group to begin with, especially if the outputs have substantially + * different dimensions.
+ * + * @param surfaceGroupId + * A group ID for this output, used for sharing memory between multiple outputs. + * @param surface + * A Surface for camera to output to. + * + */ + public OutputConfiguration(int surfaceGroupId, @NonNull Surface surface) { + this(surfaceGroupId, surface, ROTATION_0); } /** @@ -100,9 +138,9 @@ public final class OutputConfiguration implements Parcelable { * A Surface for camera to output to. * @param rotation * The desired rotation to be applied on camera output. Value must be one of - * ROTATION_[0, 90, 180, 270]. Note that when the rotation is 90 or 270 degree, + * ROTATION_[0, 90, 180, 270]. Note that when the rotation is 90 or 270 degrees, * application should make sure corresponding surface size has width and height - * transposed corresponding to the width and height without rotation. For example, + * transposed relative to the width and height without rotation. For example, * if application needs camera to capture 1280x720 picture and rotate it by 90 degree, * application should set rotation to {@code ROTATION_90} and make sure the * corresponding Surface size is 720x1280. Note that {@link CameraDevice} might @@ -110,15 +148,43 @@ public final class OutputConfiguration implements Parcelable { * @hide */ @SystemApi - public OutputConfiguration(Surface surface, int rotation) { + public OutputConfiguration(@NonNull Surface surface, int rotation) { + this(SURFACE_GROUP_ID_NONE, surface, rotation); + } + + + /** + * Create a new {@link OutputConfiguration} instance, with rotation and a group ID. + * + *This constructor takes an argument for desired camera rotation and for the surface group + * ID. See {@link #OutputConfiguration(int, Surface)} for details of the group ID.
+ * + * @param surfaceGroupId + * A group ID for this output, used for sharing memory between multiple outputs. + * @param surface + * A Surface for camera to output to. + * @param rotation + * The desired rotation to be applied on camera output. Value must be one of + * ROTATION_[0, 90, 180, 270]. Note that when the rotation is 90 or 270 degrees, + * application should make sure corresponding surface size has width and height + * transposed relative to the width and height without rotation. For example, + * if application needs camera to capture 1280x720 picture and rotate it by 90 degree, + * application should set rotation to {@code ROTATION_90} and make sure the + * corresponding Surface size is 720x1280. Note that {@link CameraDevice} might + * throw {@code IllegalArgumentException} if device cannot perform such rotation. + * @hide + */ + @SystemApi + public OutputConfiguration(int surfaceGroupId, @NonNull Surface surface, int rotation) { checkNotNull(surface, "Surface must not be null"); checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant"); - mSurfaceSetId = SURFACE_SET_ID_INVALID; + mSurfaceGroupId = surfaceGroupId; mSurface = surface; mRotation = rotation; mConfiguredSize = SurfaceUtils.getSurfaceSize(surface); mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface); mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface); + mConfiguredGenerationId = surface.getGenerationId(); } /** @@ -129,35 +195,36 @@ public final class OutputConfiguration implements Parcelable { * * @hide */ - @SystemApi - public OutputConfiguration(OutputConfiguration other) { + public OutputConfiguration(@NonNull OutputConfiguration other) { if (other == null) { throw new IllegalArgumentException("OutputConfiguration shouldn't be null"); } this.mSurface = other.mSurface; this.mRotation = other.mRotation; - this.mSurfaceSetId = other.mSurfaceSetId; + this.mSurfaceGroupId = other.mSurfaceGroupId; this.mConfiguredDataspace = other.mConfiguredDataspace; this.mConfiguredFormat = other.mConfiguredFormat; this.mConfiguredSize = other.mConfiguredSize; + this.mConfiguredGenerationId = other.mConfiguredGenerationId; } /** * Create an OutputConfiguration from Parcel. */ - private OutputConfiguration(Parcel source) { + private OutputConfiguration(@NonNull Parcel source) { int rotation = source.readInt(); int surfaceSetId = source.readInt(); Surface surface = Surface.CREATOR.createFromParcel(source); checkNotNull(surface, "Surface must not be null"); checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant"); - mSurfaceSetId = surfaceSetId; + mSurfaceGroupId = surfaceSetId; mSurface = surface; mRotation = rotation; mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface); mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurface); mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(mSurface); + mConfiguredGenerationId = mSurface.getGenerationId(); } /** @@ -165,6 +232,7 @@ public final class OutputConfiguration implements Parcelable { * * @return the {@link Surface} associated with this {@link OutputConfiguration}. */ + @NonNull public Surface getSurface() { return mSurface; } @@ -183,35 +251,13 @@ public final class OutputConfiguration implements Parcelable { } /** - * Set the surface set ID to this {@link OutputConfiguration}. + * Get the surface group ID associated with this {@link OutputConfiguration}. * - *- * A surface set ID is used to identify which surface set this output surface belongs to. A - * surface set is a group of output surfaces that are not intended to receive camera output - * buffer streams simultaneously. The {@link CameraDevice} may be able to share the buffers used - * by all the surfaces from the same surface set, therefore may save the overall memory - * footprint. The application should only set the same set ID for the streams that are not - * simultaneously streaming. A negative ID indicates that this surface doesn't belong to any - * surface set. The default value will be {@value #SURFACE_SET_ID_INVALID}. - *
- * - * @param setId + * @return the surface group ID associated with this {@link OutputConfiguration}. + * The default value is {@value #SURFACE_GROUP_ID_NONE}. */ - public void setSurfaceSetId(int setId) { - if (setId < 0) { - setId = SURFACE_SET_ID_INVALID; - } - mSurfaceSetId = setId; - } - - /** - * Get the surface set Id associated with this {@link OutputConfiguration}. - * - * @return the surface set Id associated with this {@link OutputConfiguration}. - * Value will be one of ROTATION_[0, 90, 180, 270] - */ - public int getSurfaceSetId() { - return mSurfaceSetId; + public int getSurfaceGroupId() { + return mSurfaceGroupId; } public static final Parcelable.Creator