Skip to content

Commit

Permalink
Merge "[Multi-Cam] Add setMirrorMode() for Preview" into androidx-main
Browse files Browse the repository at this point in the history
  • Loading branch information
Treehugger Robot authored and Gerrit Code Review committed May 18, 2024
2 parents e3467d0 + 5dcf60e commit c7b620b
Show file tree
Hide file tree
Showing 23 changed files with 254 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package androidx.camera.camera2.pipe.integration.impl
import android.content.Context
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.params.OutputConfiguration
import android.hardware.camera2.params.SessionConfiguration.SESSION_HIGH_SPEED
import android.hardware.camera2.params.SessionConfiguration.SESSION_REGULAR
import android.media.MediaCodec
Expand Down Expand Up @@ -54,6 +55,7 @@ import androidx.camera.camera2.pipe.integration.config.UseCaseGraphConfig
import androidx.camera.camera2.pipe.integration.interop.Camera2CameraControl
import androidx.camera.camera2.pipe.integration.interop.ExperimentalCamera2Interop
import androidx.camera.core.DynamicRange
import androidx.camera.core.MirrorMode
import androidx.camera.core.UseCase
import androidx.camera.core.impl.CameraControlInternal
import androidx.camera.core.impl.CameraInfoInternal
Expand Down Expand Up @@ -702,6 +704,7 @@ class UseCaseManager @Inject constructor(
val deferrableSurface = outputConfig.surface
val physicalCameraId =
physicalCameraIdForAllStreams ?: outputConfig.physicalCameraId
val mirrorMode = outputConfig.mirrorMode
val outputStreamConfig = OutputStream.Config.create(
size = deferrableSurface.prescribedSize,
format = StreamFormat(deferrableSurface.prescribedStreamFormat),
Expand All @@ -710,6 +713,15 @@ class UseCaseManager @Inject constructor(
} else {
CameraId.fromCamera2Id(physicalCameraId)
},
// No need to map MIRROR_MODE_ON_FRONT_ONLY to MIRROR_MODE_AUTO
// since its default value in framework
mirrorMode = when (mirrorMode) {
MirrorMode.MIRROR_MODE_OFF -> OutputStream.MirrorMode(
OutputConfiguration.MIRROR_MODE_NONE)
MirrorMode.MIRROR_MODE_ON -> OutputStream.MirrorMode(
OutputConfiguration.MIRROR_MODE_H)
else -> null
},
streamUseCase = getStreamUseCase(
deferrableSurface,
sessionConfigAdapter.surfaceToStreamUseCaseMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.os.Build;
import android.view.Surface;

Expand All @@ -44,6 +45,7 @@
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.DynamicRange;
import androidx.camera.core.Logger;
import androidx.camera.core.MirrorMode;
import androidx.camera.core.impl.CameraCaptureCallback;
import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.DeferrableSurface;
Expand Down Expand Up @@ -391,6 +393,14 @@ private OutputConfigurationCompat getOutputConfigurationCompat(
outputConfig.getPhysicalCameraId());
}

// No need to map MIRROR_MODE_ON_FRONT_ONLY to MIRROR_MODE_AUTO
// since its default value in framework
if (outputConfig.getMirrorMode() == MirrorMode.MIRROR_MODE_OFF) {
outputConfiguration.setMirrorMode(OutputConfiguration.MIRROR_MODE_NONE);
} else if (outputConfig.getMirrorMode() == MirrorMode.MIRROR_MODE_ON) {
outputConfiguration.setMirrorMode(OutputConfiguration.MIRROR_MODE_H);
}

if (!outputConfig.getSharedSurfaces().isEmpty()) {
outputConfiguration.enableSurfaceSharing();
for (DeferrableSurface sharedDeferSurface : outputConfig.getSharedSurfaces()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,24 @@ public void enableSurfaceSharing() {
mImpl.enableSurfaceSharing();
}

/**
* Returns mirror mode of {@link OutputConfiguration}.
* @return {@link OutputConfiguration#getMirrorMode()}
* @see OutputConfiguration#getMirrorMode()
*/
public int getMirrorMode() {
return mImpl.getMirrorMode();
}

/**
* Sets mirror mode of {@link OutputConfiguration}.
* @param mirrorMode mirror mode to set for {@link OutputConfiguration}.
* @see OutputConfiguration#setMirrorMode(int)
*/
public void setMirrorMode(int mirrorMode) {
mImpl.setMirrorMode(mirrorMode);
}

/**
* Retrieve the physical camera ID set by {@link #setPhysicalCameraId(String)}.
*
Expand Down Expand Up @@ -488,6 +506,10 @@ public Object unwrap() {
interface OutputConfigurationCompatImpl {
void enableSurfaceSharing();

int getMirrorMode();

void setMirrorMode(int mirrorMode);

@Nullable
String getPhysicalCameraId();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ static OutputConfigurationCompatApi33Impl wrap(
return new OutputConfigurationCompatApi33Impl(outputConfiguration);
}

@Override
public int getMirrorMode() {
return ((OutputConfiguration) getOutputConfiguration()).getMirrorMode();
}

@Override
public void setMirrorMode(int mirrorMode) {
((OutputConfiguration) getOutputConfiguration()).setMirrorMode(mirrorMode);
}

@Override
public long getDynamicRangeProfile() {
return ((OutputConfiguration) getOutputConfiguration()).getDynamicRangeProfile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.annotation.SuppressLint;
import android.graphics.ImageFormat;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.os.Build;
import android.util.Size;
import android.view.Surface;
Expand Down Expand Up @@ -82,6 +83,16 @@ public String getPhysicalCameraId() {
return ((OutputConfigurationParamsApi21) mObject).mPhysicalCameraId;
}

@Override
public void setMirrorMode(int mirrorMode) {
//No-op
}

@Override
public int getMirrorMode() {
return OutputConfiguration.MIRROR_MODE_AUTO;
}

/**
* Set stream use case for this OutputConfiguration.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package androidx.camera.camera2.internal.compat.params;

import static android.hardware.camera2.params.OutputConfiguration.MIRROR_MODE_H;
import static android.hardware.camera2.params.OutputConfiguration.MIRROR_MODE_NONE;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -239,6 +242,22 @@ public void canSetPhysicalCameraId() {
verify(outputConfig, times(1)).setPhysicalCameraId(PHYSICAL_CAMERA_ID);
}

@Test
@Config(minSdk = 33)
public void canSetMirrorMode() {
OutputConfiguration outputConfig = mock(OutputConfiguration.class);

OutputConfigurationCompat outputConfigCompat = OutputConfigurationCompat.wrap(outputConfig);

outputConfigCompat.setMirrorMode(MIRROR_MODE_NONE);

verify(outputConfig, times(1)).setMirrorMode(MIRROR_MODE_NONE);

outputConfigCompat.setMirrorMode(MIRROR_MODE_H);

verify(outputConfig, times(1)).setMirrorMode(MIRROR_MODE_H);
}

@Test
public void canSetDynamicRangeProfile() {
OutputConfigurationCompat outputConfigCompat =
Expand Down
4 changes: 4 additions & 0 deletions camera/camera-core/api/1.4.0-beta01.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ package androidx.camera.core {
@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalMirrorMode {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
}

Expand Down Expand Up @@ -507,6 +510,7 @@ package androidx.camera.core {
ctor public Preview.Builder();
method public androidx.camera.core.Preview build();
method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
method @SuppressCompatibility @androidx.camera.core.ExperimentalMirrorMode public androidx.camera.core.Preview.Builder setMirrorMode(int);
method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
Expand Down
4 changes: 4 additions & 0 deletions camera/camera-core/api/current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ package androidx.camera.core {
@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalMirrorMode {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
}

Expand Down Expand Up @@ -507,6 +510,7 @@ package androidx.camera.core {
ctor public Preview.Builder();
method public androidx.camera.core.Preview build();
method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
method @SuppressCompatibility @androidx.camera.core.ExperimentalMirrorMode public androidx.camera.core.Preview.Builder setMirrorMode(int);
method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
Expand Down
4 changes: 4 additions & 0 deletions camera/camera-core/api/restricted_1.4.0-beta01.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ package androidx.camera.core {
@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalMirrorMode {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
}

Expand Down Expand Up @@ -507,6 +510,7 @@ package androidx.camera.core {
ctor public Preview.Builder();
method public androidx.camera.core.Preview build();
method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
method @SuppressCompatibility @androidx.camera.core.ExperimentalMirrorMode public androidx.camera.core.Preview.Builder setMirrorMode(int);
method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
Expand Down
4 changes: 4 additions & 0 deletions camera/camera-core/api/restricted_current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ package androidx.camera.core {
@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalMirrorMode {
}

@SuppressCompatibility @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalRetryPolicy {
}

Expand Down Expand Up @@ -507,6 +510,7 @@ package androidx.camera.core {
ctor public Preview.Builder();
method public androidx.camera.core.Preview build();
method public androidx.camera.core.Preview.Builder setDynamicRange(androidx.camera.core.DynamicRange);
method @SuppressCompatibility @androidx.camera.core.ExperimentalMirrorMode public androidx.camera.core.Preview.Builder setMirrorMode(int);
method public androidx.camera.core.Preview.Builder setPreviewStabilizationEnabled(boolean);
method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.camera.core.CameraSelector.LENS_FACING_FRONT
import androidx.camera.core.MirrorMode.MIRROR_MODE_OFF
import androidx.camera.core.MirrorMode.MIRROR_MODE_ON
import androidx.camera.core.MirrorMode.MIRROR_MODE_ON_FRONT_ONLY
import androidx.camera.core.MirrorMode.MIRROR_MODE_UNSPECIFIED
import androidx.camera.core.UseCase.snapToSurfaceRotation
import androidx.camera.core.concurrent.CameraCoordinator
import androidx.camera.core.impl.Config
Expand Down Expand Up @@ -265,7 +266,7 @@ class UseCaseTest {
@Test
fun defaultMirrorModeIsOff() {
val fakeUseCase = createFakeUseCase()
assertThat(fakeUseCase.mirrorModeInternal).isEqualTo(MIRROR_MODE_OFF)
assertThat(fakeUseCase.mirrorModeInternal).isEqualTo(MIRROR_MODE_UNSPECIFIED)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2024 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.core;

import static java.lang.annotation.RetentionPolicy.CLASS;

import androidx.annotation.RequiresOptIn;

import java.lang.annotation.Retention;

/**
* Denotes that the annotated API is designed to be experimental for {@link MirrorMode}
*/
@Retention(CLASS)
@RequiresOptIn
public @interface ExperimentalMirrorMode {
}
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,10 @@ SessionConfig.Builder createPipeline(@NonNull String cameraId,

sessionConfigBuilder.setExpectedFrameRateRange(streamSpec.getExpectedFrameRateRange());

sessionConfigBuilder.addSurface(mDeferrableSurface, streamSpec.getDynamicRange(), null);
sessionConfigBuilder.addSurface(mDeferrableSurface,
streamSpec.getDynamicRange(),
null,
MirrorMode.MIRROR_MODE_UNSPECIFIED);

sessionConfigBuilder.addErrorListener((sessionConfig, error) -> {
clearPipeline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@ public class MirrorMode {
*/
public static final int MIRROR_MODE_ON_FRONT_ONLY = 2;

/** The mirror mode is not specified by the user **/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static final int MIRROR_MODE_UNSPECIFIED = -1;

private MirrorMode() {
}

/**
*/
@IntDef({MIRROR_MODE_OFF, MIRROR_MODE_ON, MIRROR_MODE_ON_FRONT_ONLY})
@IntDef({MIRROR_MODE_OFF, MIRROR_MODE_ON, MIRROR_MODE_ON_FRONT_ONLY, MIRROR_MODE_UNSPECIFIED})
@Retention(RetentionPolicy.SOURCE)
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public @interface Mirror {
Expand Down

0 comments on commit c7b620b

Please sign in to comment.