From b68dd5c8b92d376540ac4ae6ed59671db641685e Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Thu, 4 Sep 2014 21:23:42 -0700 Subject: [PATCH] camera2: Undo mirror for front camera in legacy mode. Bug: 16637957 - In Camera1 API, front facing camera preview is always mirrored across the vertical axis. Undo this flip in the legacy mode Camera2 API sampling operation when copying from the texture drawn to with the Camera1 API preview buffers. Change-Id: Ib8ae4fa97f4ad62a3e55ae7da7d474a8655e747d --- .../camera2/legacy/GLThreadManager.java | 5 ++-- .../camera2/legacy/RequestThreadManager.java | 2 +- .../legacy/SurfaceTextureRenderer.java | 28 +++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java index 06521cf16f59d..2c584ef7752ca 100644 --- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/GLThreadManager.java @@ -121,9 +121,10 @@ public class GLThreadManager { * Create a new GL thread and renderer. * * @param cameraId the camera id for this thread. + * @param facing direction the camera is facing. */ - public GLThreadManager(int cameraId) { - mTextureRenderer = new SurfaceTextureRenderer(); + public GLThreadManager(int cameraId, int facing) { + mTextureRenderer = new SurfaceTextureRenderer(facing); TAG = String.format("CameraDeviceGLThread-%d", cameraId); mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb); } diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index eb8debba0c9eb..e6ff17b86455b 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -399,7 +399,7 @@ public class RequestThreadManager { // TODO: Detect and optimize single-output paths here to skip stream teeing. if (mGLThreadManager == null) { - mGLThreadManager = new GLThreadManager(mCameraId); + mGLThreadManager = new GLThreadManager(mCameraId, facing); mGLThreadManager.start(); } mGLThreadManager.waitUntilStarted(); diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index b1b0f9b485f39..a35883c000709 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -18,6 +18,7 @@ package android.hardware.camera2.legacy; import android.graphics.ImageFormat; import android.graphics.RectF; import android.graphics.SurfaceTexture; +import android.hardware.camera2.CameraCharacteristics; import android.os.Environment; import android.opengl.EGL14; import android.opengl.EGLConfig; @@ -80,7 +81,18 @@ public class SurfaceTextureRenderer { private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; - private final float[] mTriangleVerticesData = { + + // Sampling is mirrored across the vertical axis to undo horizontal flip from the front camera + private static final float[] sFrontCameraTriangleVertices = { + // X, Y, Z, U, V + -1.0f, -1.0f, 0, 1.f, 0.f, + 1.0f, -1.0f, 0, 0.f, 0.f, + -1.0f, 1.0f, 0, 1.f, 1.f, + 1.0f, 1.0f, 0, 0.f, 1.f, + }; + + // Sampling is 1:1 for a straight copy for the back camera + private static final float[] sBackCameraTriangleVertices = { // X, Y, Z, U, V -1.0f, -1.0f, 0, 0.f, 0.f, 1.0f, -1.0f, 0, 1.f, 0.f, @@ -135,10 +147,16 @@ public class SurfaceTextureRenderer { private PerfMeasurement mPerfMeasurer = null; private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf"; - public SurfaceTextureRenderer() { - mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * - FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); - mTriangleVertices.put(mTriangleVerticesData).position(0); + public SurfaceTextureRenderer(int facing) { + if (facing == CameraCharacteristics.LENS_FACING_BACK) { + mTriangleVertices = ByteBuffer.allocateDirect(sBackCameraTriangleVertices.length * + FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTriangleVertices.put(sBackCameraTriangleVertices).position(0); + } else { + mTriangleVertices = ByteBuffer.allocateDirect(sFrontCameraTriangleVertices.length * + FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTriangleVertices.put(sFrontCameraTriangleVertices).position(0); + } Matrix.setIdentityM(mSTMatrix, 0); }