13651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala/*
23651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * Copyright (C) 2016 The Android Open Source Project
33651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala *
43651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
53651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * you may not use this file except in compliance with the License.
63651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * You may obtain a copy of the License at
73651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala *
83651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
93651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala *
103651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
113651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
123651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * See the License for the specific language governing permissions and
143651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * limitations under the License.
153651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala */
163651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvalapackage com.android.devcamera;
17a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
18a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.content.Context;
19a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.graphics.ImageFormat;
20a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.graphics.SurfaceTexture;
21a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CameraAccessException;
22a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CameraCaptureSession;
239736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvalaimport android.hardware.camera2.CameraCharacteristics;
24a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CameraDevice;
25a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CameraManager;
26a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CameraMetadata;
27a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CaptureRequest;
28a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.CaptureResult;
29a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.TotalCaptureResult;
30a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.params.Face;
31a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.hardware.camera2.params.InputConfiguration;
32a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.media.Image;
33a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.media.ImageReader;
34a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.media.ImageWriter;
35a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.media.MediaActionSound;
36a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.opengl.GLES11Ext;
37a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.opengl.GLES20;
38a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.os.Handler;
39a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.os.HandlerThread;
40a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.os.SystemClock;
41a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.util.Log;
42a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.util.Size;
43a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport android.view.Surface;
44a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
45a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport java.nio.ByteBuffer;
46a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport java.util.ArrayList;
47a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport java.util.LinkedList;
48a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport java.util.List;
49a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
50a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvalaimport javax.microedition.khronos.opengles.GL10;
51a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
52a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
53a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala/**
543651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala * Api2Camera : a camera2 implementation
55a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala *
56a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala * The goal here is to make the simplest possible API2 camera,
57a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala * where individual streams and capture options (e.g. edge enhancement,
58a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala * noise reduction, face detection) can be toggled on and off.
59a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala *
60a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala */
61a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
623651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvalapublic class Api2Camera implements CameraInterface, SurfaceTexture.OnFrameAvailableListener {
633651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    private static final String TAG = "DevCamera_API2";
64a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
65a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Nth frame to log; put 10^6 if you don't want logging.
66a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static int LOG_NTH_FRAME = 30;
67a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Log dropped frames. There are a log on Angler MDA32.
68a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static boolean LOG_DROPPED_FRAMES = true;
69a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
70a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // IMPORTANT: Only one of these can be true:
71a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static boolean SECOND_YUV_IMAGEREADER_STREAM = true;
72a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static boolean SECOND_SURFACE_TEXTURE_STREAM = false;
73a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
74a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Enable raw stream if available.
75a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static boolean RAW_STREAM_ENABLE = true;
76a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Use JPEG ImageReader and YUV ImageWriter if reprocessing is available
77a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static final boolean USE_REPROCESSING_IF_AVAIL = true;
78a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
79a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Whether we are continuously taking pictures, or not.
80a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    boolean mIsBursting = false;
81a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Last total capture result
82a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    TotalCaptureResult mLastTotalCaptureResult;
83a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
84a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // ImageReader/Writer buffer sizes.
85a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static final int YUV1_IMAGEREADER_SIZE = 8;
86a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static final int YUV2_IMAGEREADER_SIZE = 8;
87a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static final int RAW_IMAGEREADER_SIZE = 8;
88a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static final int IMAGEWRITER_SIZE = 2;
89a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
90a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private CameraInfoCache mCameraInfoCache;
91a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private CameraManager mCameraManager;
92a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private CameraCaptureSession mCurrentCaptureSession;
93a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private MediaActionSound mMediaActionSound = new MediaActionSound();
94a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
95a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    MyCameraCallback mMyCameraCallback;
96a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
97a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Generally everything running on this thread & this module is *not thread safe*.
98a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private HandlerThread mOpsThread;
99a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private Handler mOpsHandler;
100a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private HandlerThread mInitThread;
101a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private Handler mInitHandler;
102a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private HandlerThread mJpegListenerThread;
103a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private Handler mJpegListenerHandler;
104a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
105a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    Context mContext;
106a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    boolean mCameraIsFront;
107a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    SurfaceTexture mSurfaceTexture;
108a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    Surface mSurfaceTextureSurface;
109a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
110a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private boolean mFirstFrameArrived;
111a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private ImageReader mYuv1ImageReader;
112a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private int mYuv1ImageCounter;
113a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Handle to last received Image: allows ZSL to be implemented.
114a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private Image mYuv1LastReceivedImage = null;
115a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Time at which reprocessing request went in (right now we are doing one at a time).
116a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private long mReprocessingRequestNanoTime;
117a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
118a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private ImageReader mJpegImageReader;
119a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private ImageReader mYuv2ImageReader;
120a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private int mYuv2ImageCounter;
121a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private ImageReader mRawImageReader;
122a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private int mRawImageCounter;
123a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
124a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Starting the preview requires each of these 3 to be true/non-null:
125a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    volatile private Surface mPreviewSurface;
126a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    volatile private CameraDevice mCameraDevice;
127a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    volatile boolean mAllThingsInitialized = false;
128a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
129a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    /**
130a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     * Constructor.
131a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     */
1323651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    public Api2Camera(Context context, boolean useFrontCamera) {
133a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mContext = context;
134a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mCameraIsFront = useFrontCamera;
135a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
136a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mCameraInfoCache = new CameraInfoCache(mCameraManager, useFrontCamera);
137a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
138a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Create thread and handler for camera operations.
139a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mOpsThread = new HandlerThread("CameraOpsThread");
140a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mOpsThread.start();
141a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mOpsHandler = new Handler(mOpsThread.getLooper());
142a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
143a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Create thread and handler for slow initialization operations.
144a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Don't want to use camera operations thread because we want to time camera open carefully.
145a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mInitThread = new HandlerThread("CameraInitThread");
146a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mInitThread.start();
147a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mInitHandler = new Handler(mInitThread.getLooper());
148a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mInitHandler.post(new Runnable() {
149a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            @Override
150a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            public void run() {
151a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                InitializeAllTheThings();
152a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mAllThingsInitialized = true;
153a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "STARTUP_REQUIREMENT ImageReader initialization done.");
154a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                tryToStartCaptureSession();
155a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
156a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        });
157a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
158a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Set initial Noise and Edge modes.
1599736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        if (mCameraInfoCache.isHardwareLevelAtLeast(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)) {
160a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // YUV streams.
1619736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            if (mCameraInfoCache.supportedModesContains(mCameraInfoCache.noiseModes,
1629736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                    CameraCharacteristics.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG)) {
1639736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                mCaptureNoiseMode = CameraCharacteristics.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG;
1649736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            } else {
1659736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                mCaptureNoiseMode = CameraCharacteristics.NOISE_REDUCTION_MODE_FAST;
1669736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            }
1679736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            if (mCameraInfoCache.supportedModesContains(mCameraInfoCache.edgeModes,
1689736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                    CameraCharacteristics.EDGE_MODE_ZERO_SHUTTER_LAG)) {
1699736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                mCaptureEdgeMode = CameraCharacteristics.EDGE_MODE_ZERO_SHUTTER_LAG;
1709736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            } else {
1719736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                mCaptureEdgeMode = CameraCharacteristics.EDGE_MODE_FAST;
1729736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            }
1739736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala
174a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // Reprocessing.
1759736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mReprocessingNoiseMode = CameraCharacteristics.NOISE_REDUCTION_MODE_HIGH_QUALITY;
1769736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mReprocessingEdgeMode = CameraCharacteristics.EDGE_MODE_HIGH_QUALITY;
177a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
178a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
179a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
180a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Ugh, why is this stuff so slow?
181a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private void InitializeAllTheThings() {
182a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
183a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Thread to handle returned JPEGs.
184a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mJpegListenerThread = new HandlerThread("CameraJpegThread");
185a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mJpegListenerThread.start();
186a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mJpegListenerHandler = new Handler(mJpegListenerThread.getLooper());
187a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
188a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Create ImageReader to receive JPEG image buffers via reprocessing.
189a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mJpegImageReader = ImageReader.newInstance(
190a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraInfoCache.getYuvStream1Size().getWidth(),
191a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraInfoCache.getYuvStream1Size().getHeight(),
192a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                ImageFormat.JPEG,
193a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                2);
194a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mJpegImageReader.setOnImageAvailableListener(mJpegImageListener, mJpegListenerHandler);
195a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
196a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Create ImageReader to receive YUV image buffers.
197a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mYuv1ImageReader = ImageReader.newInstance(
198a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraInfoCache.getYuvStream1Size().getWidth(),
199a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraInfoCache.getYuvStream1Size().getHeight(),
200a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                ImageFormat.YUV_420_888,
201a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                YUV1_IMAGEREADER_SIZE);
202a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mYuv1ImageReader.setOnImageAvailableListener(mYuv1ImageListener, mOpsHandler);
203a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
204a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (SECOND_YUV_IMAGEREADER_STREAM) {
205a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // Create ImageReader to receive YUV image buffers.
206a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mYuv2ImageReader = ImageReader.newInstance(
207a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraInfoCache.getYuvStream2Size().getWidth(),
208a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraInfoCache.getYuvStream2Size().getHeight(),
209a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    ImageFormat.YUV_420_888,
210a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    YUV2_IMAGEREADER_SIZE);
211a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mYuv2ImageReader.setOnImageAvailableListener(mYuv2ImageListener, mOpsHandler);
212a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
213a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
214a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (SECOND_SURFACE_TEXTURE_STREAM) {
215a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int[] textures = new int[1];
216a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // generate one texture pointer and bind it as an external texture.
217a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glGenTextures(1, textures, 0);
218a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
219a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // No mip-mapping with camera source.
220a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
221a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    GL10.GL_TEXTURE_MIN_FILTER,
222a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    GL10.GL_LINEAR);
223a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
224a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
225a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // Clamp to edge is only option.
226a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
227a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
228a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
229a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
230a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
231a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int texture_id = textures[0];
232a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mSurfaceTexture = new SurfaceTexture(texture_id);
233a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mSurfaceTexture.setDefaultBufferSize(320, 240);
234a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mSurfaceTexture.setOnFrameAvailableListener(this);
235a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mSurfaceTextureSurface = new Surface(mSurfaceTexture);
236a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
237a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
238a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (RAW_STREAM_ENABLE && mCameraInfoCache.rawAvailable()) {
239a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // Create ImageReader to receive thumbnail sized YUV image buffers.
240a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mRawImageReader = ImageReader.newInstance(
241a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraInfoCache.getRawStreamSize().getWidth(),
242a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraInfoCache.getRawStreamSize().getHeight(),
243a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraInfoCache.getRawFormat(),
244a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    RAW_IMAGEREADER_SIZE);
245a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mRawImageReader.setOnImageAvailableListener(mRawImageListener, mOpsHandler);
246a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
247a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
248a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Load click sound.
249a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mMediaActionSound.load(MediaActionSound.SHUTTER_CLICK);
250a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
251a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
252a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
253a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void setCallback(MyCameraCallback callback) {
254a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mMyCameraCallback = callback;
255a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
256a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
257a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void triggerAFScan() {
258a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "AF trigger");
259a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        issuePreviewCaptureRequest(true);
260a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
261a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
262a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void setCAF() {
263a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "run CAF");
264a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        issuePreviewCaptureRequest(false);
265a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
266a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
267a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void takePicture() {
268a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK);
269a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mOpsHandler.post(new Runnable() {
270a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            @Override
271a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            public void run() {
272a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                runReprocessing();
273a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
274a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        });
275a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
276a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
277a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void onFrameAvailable (SurfaceTexture surfaceTexture) {
278a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, " onFrameAvailable(SurfaceTexture)");
279a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
280a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
281a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void setBurst(boolean go) {
282a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // if false to true transition.
283a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (go && !mIsBursting) {
284a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            takePicture();
285a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
286a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mIsBursting = go;
287a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
288a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
289a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public boolean isRawAvailable() {
290a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        return mCameraInfoCache.rawAvailable();
291a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
292a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
293a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public boolean isReprocessingAvailable() {
2949736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        return mCameraInfoCache.isYuvReprocessingAvailable();
295a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
296a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
297a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    @Override
298a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public Size getPreviewSize() {
299a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        return mCameraInfoCache.getPreviewSize();
300a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
301a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
302a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    @Override
3039736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    public float[] getFieldOfView() {
3049736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        return mCameraInfoCache.getFieldOfView();
3059736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    }
3069736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala
3079736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    @Override
3083855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala    public int getOrientation() {
3093855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala        return mCameraInfoCache.sensorOrientation();
3103855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala    }
3113855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala
3123855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala    @Override
313a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void openCamera() {
3149736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        // If API2 FULL mode is not available, display toast
315a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (!mCameraInfoCache.isCamera2FullModeAvailable()) {
316a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mMyCameraCallback.noCamera2Full();
317a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
318a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
319a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "Opening camera " + mCameraInfoCache.getCameraId());
320a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mOpsHandler.post(new Runnable() {
321a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            @Override
322a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            public void run() {
3233651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                CameraTimer.t_open_start = SystemClock.elapsedRealtime();
324a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                try {
325a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mCameraManager.openCamera(mCameraInfoCache.getCameraId(), mCameraStateCallback, null);
326a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                } catch (CameraAccessException e) {
327a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Log.e(TAG, "Unable to openCamera().");
328a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
329a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
330a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        });
331a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
332a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
333a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    @Override
334a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void closeCamera() {
335a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // TODO: We are stalling main thread now which is bad.
336a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "Closing camera " + mCameraInfoCache.getCameraId());
337a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mCameraDevice != null) {
338a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            try {
339a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCurrentCaptureSession.abortCaptures();
340a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            } catch (CameraAccessException e) {
341a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.e(TAG, "Could not abortCaptures().");
342a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
343a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mCameraDevice.close();
344a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
345a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mCurrentCaptureSession = null;
346a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "Done closing camera " + mCameraInfoCache.getCameraId());
347a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
348a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
349a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void startPreview(final Surface surface) {
350a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "STARTUP_REQUIREMENT preview Surface ready.");
351a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mPreviewSurface = surface;
352a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        tryToStartCaptureSession();
353a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
354a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
3553651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    private CameraDevice.StateCallback mCameraStateCallback = new LoggingCallbacks.DeviceStateCallback() {
356a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        @Override
357a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        public void onOpened(CameraDevice camera) {
3583651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala            CameraTimer.t_open_end = SystemClock.elapsedRealtime();
359a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mCameraDevice = camera;
360a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "STARTUP_REQUIREMENT Done opening camera " + mCameraInfoCache.getCameraId() +
3613651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                    ". HAL open took: (" + (CameraTimer.t_open_end - CameraTimer.t_open_start) + " ms)");
362a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
363a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            super.onOpened(camera);
364a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            tryToStartCaptureSession();
365a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
366a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    };
367a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
368a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private void tryToStartCaptureSession() {
369a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mCameraDevice != null && mAllThingsInitialized && mPreviewSurface != null) {
370a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mOpsHandler.post(new Runnable() {
371a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                @Override
372a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                public void run() {
373a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    // It used to be: this needed to be posted on a Handler.
374a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    startCaptureSession();
375a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
376a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            });
377a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
378a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
379a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
380a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Create CameraCaptureSession. Callback will start repeating request with current parameters.
381a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private void startCaptureSession() {
3823651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala        CameraTimer.t_session_go = SystemClock.elapsedRealtime();
383a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
384a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "Configuring session..");
385a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        List<Surface> outputSurfaces = new ArrayList<Surface>(3);
386a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
387a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        outputSurfaces.add(mPreviewSurface);
388a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "  .. added SurfaceView " + mCameraInfoCache.getPreviewSize().getWidth() +
389a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                " x " + mCameraInfoCache.getPreviewSize().getHeight());
390a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
391a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        outputSurfaces.add(mYuv1ImageReader.getSurface());
392a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "  .. added YUV ImageReader " + mCameraInfoCache.getYuvStream1Size().getWidth() +
393a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                " x " + mCameraInfoCache.getYuvStream1Size().getHeight());
394a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
395a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (SECOND_YUV_IMAGEREADER_STREAM) {
396a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            outputSurfaces.add(mYuv2ImageReader.getSurface());
397a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "  .. added YUV ImageReader " + mCameraInfoCache.getYuvStream2Size().getWidth() +
398a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    " x " + mCameraInfoCache.getYuvStream2Size().getHeight());
399a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
400a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
401a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (SECOND_SURFACE_TEXTURE_STREAM) {
402a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            outputSurfaces.add(mSurfaceTextureSurface);
403a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "  .. added SurfaceTexture");
404a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
405a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
406a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (RAW_STREAM_ENABLE && mCameraInfoCache.rawAvailable()) {
407a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            outputSurfaces.add(mRawImageReader.getSurface());
408a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "  .. added Raw ImageReader " + mCameraInfoCache.getRawStreamSize().getWidth() +
409a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    " x " + mCameraInfoCache.getRawStreamSize().getHeight());
410a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
411a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
4129736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        if (USE_REPROCESSING_IF_AVAIL && mCameraInfoCache.isYuvReprocessingAvailable()) {
413a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            outputSurfaces.add(mJpegImageReader.getSurface());
414a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "  .. added JPEG ImageReader " + mCameraInfoCache.getJpegStreamSize().getWidth() +
415a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    " x " + mCameraInfoCache.getJpegStreamSize().getHeight());
416a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
417a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
418a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        try {
4199736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            if (USE_REPROCESSING_IF_AVAIL && mCameraInfoCache.isYuvReprocessingAvailable()) {
420a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                InputConfiguration inputConfig = new InputConfiguration(mCameraInfoCache.getYuvStream1Size().getWidth(),
421a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        mCameraInfoCache.getYuvStream1Size().getHeight(), ImageFormat.YUV_420_888);
422a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraDevice.createReprocessableCaptureSession(inputConfig, outputSurfaces,
423a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        mSessionStateCallback, null);
424a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "  Call to createReprocessableCaptureSession complete.");
425a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            } else {
426a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCameraDevice.createCaptureSession(outputSurfaces, mSessionStateCallback, null);
427a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "  Call to createCaptureSession complete.");
428a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
429a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
430a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        } catch (CameraAccessException e) {
431a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.e(TAG, "Error configuring ISP.");
432a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
433a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
434a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
435a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    ImageWriter mImageWriter;
436a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
4373651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    private CameraCaptureSession.StateCallback mSessionStateCallback = new LoggingCallbacks.SessionStateCallback() {
438a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        @Override
439a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        public void onReady(CameraCaptureSession session) {
4403651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala            Log.v(TAG, "capture session onReady().  HAL capture session took: (" + (SystemClock.elapsedRealtime() - CameraTimer.t_session_go) + " ms)");
441a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mCurrentCaptureSession = session;
442a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            issuePreviewCaptureRequest(false);
443a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
444a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (session.isReprocessable()) {
445a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mImageWriter = ImageWriter.newInstance(session.getInputSurface(), IMAGEWRITER_SIZE);
446a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mImageWriter.setOnImageReleasedListener(
447a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        new ImageWriter.OnImageReleasedListener() {
448a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            @Override
449a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            public void onImageReleased(ImageWriter writer) {
450a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                                Log.v(TAG, "ImageWriter.OnImageReleasedListener onImageReleased()");
451a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            }
452a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        }, null);
453a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "Created ImageWriter.");
454a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
455a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            super.onReady(session);
456a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
457a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    };
458a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
459a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Variables to hold capture flow state.
460a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private boolean mCaptureYuv1 = false;
461a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private boolean mCaptureYuv2 = false;
462a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private boolean mCaptureRaw = false;
4639736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    private int mCaptureNoiseMode = CaptureRequest.NOISE_REDUCTION_MODE_FAST;
4649736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    private int mCaptureEdgeMode = CaptureRequest.EDGE_MODE_FAST;
465a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private boolean mCaptureFace = false;
466a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Variables to hold reprocessing state.
4679736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    private int mReprocessingNoiseMode = CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY;
4689736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    private int mReprocessingEdgeMode = CaptureRequest.EDGE_MODE_HIGH_QUALITY;
469a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
470a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void setCaptureFlow(Boolean yuv1, Boolean yuv2, Boolean raw10, Boolean nr, Boolean edge, Boolean face) {
471a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (yuv1 != null) mCaptureYuv1 = yuv1;
472a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (yuv2 != null) mCaptureYuv2 = yuv2;
473a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (raw10 != null) mCaptureRaw = raw10 && RAW_STREAM_ENABLE;
474a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (nr) {
4759736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mCaptureNoiseMode = getNextMode(mCaptureNoiseMode, mCameraInfoCache.noiseModes);
476a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
477a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (edge) {
4789736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mCaptureEdgeMode = getNextMode(mCaptureEdgeMode, mCameraInfoCache.edgeModes);
479a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
480a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (face != null) mCaptureFace = face;
481a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mMyCameraCallback.setNoiseEdgeText(
4829736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                "NR " + noiseModeToString(mCaptureNoiseMode),
4839736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                "Edge " + edgeModeToString(mCaptureEdgeMode)
484a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        );
485a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
486a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mCurrentCaptureSession != null) {
487a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            issuePreviewCaptureRequest(false);
488a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
489a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
490a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
491a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void setReprocessingFlow(Boolean nr, Boolean edge) {
492a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (nr) {
4939736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mReprocessingNoiseMode = getNextMode(mReprocessingNoiseMode, mCameraInfoCache.noiseModes);
494a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
495a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (edge) {
4969736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            mReprocessingEdgeMode = getNextMode(mReprocessingEdgeMode, mCameraInfoCache.edgeModes);
497a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
498a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mMyCameraCallback.setNoiseEdgeTextForReprocessing(
4999736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                "NR " + noiseModeToString(mReprocessingNoiseMode),
5009736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                "Edge " + edgeModeToString(mReprocessingEdgeMode)
501a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        );
502a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
503a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
504a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public void issuePreviewCaptureRequest(boolean AFtrigger) {
5053651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala        CameraTimer.t_burst = SystemClock.elapsedRealtime();
506a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "issuePreviewCaptureRequest...");
507a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        try {
508a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            CaptureRequest.Builder b1 = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
509a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_USE_SCENE_MODE);
510a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.set(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_FACE_PRIORITY);
511a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (AFtrigger) {
512a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO);
513a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            } else {
514a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
515a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
516a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
5179736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            b1.set(CaptureRequest.NOISE_REDUCTION_MODE, mCaptureNoiseMode);
5189736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            b1.set(CaptureRequest.EDGE_MODE, mCaptureEdgeMode);
519a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, mCaptureFace ? mCameraInfoCache.bestFaceDetectionMode() : CaptureRequest.STATISTICS_FACE_DETECT_MODE_OFF);
520a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
5219736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            Log.v(TAG, "  .. NR=" + mCaptureNoiseMode + "  Edge=" + mCaptureEdgeMode + "  Face=" + mCaptureFace);
522a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
523a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (mCaptureYuv1) {
524a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.addTarget(mYuv1ImageReader.getSurface());
525a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "  .. YUV1 on");
526a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
527a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
528a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (mCaptureRaw) {
529a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.addTarget(mRawImageReader.getSurface());
530a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
531a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
532a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.addTarget(mPreviewSurface);
533a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
534a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (mCaptureYuv2) {
535a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (SECOND_SURFACE_TEXTURE_STREAM) {
536a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    b1.addTarget(mSurfaceTextureSurface);
537a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
538a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (SECOND_YUV_IMAGEREADER_STREAM) {
539a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    b1.addTarget(mYuv2ImageReader.getSurface());
540a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
541a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "  .. YUV2 on");
542a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
543a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
544a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (AFtrigger) {
545a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
546a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mCurrentCaptureSession.capture(b1.build(), mCaptureCallback, mOpsHandler);
547a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                b1.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
548a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
549a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mCurrentCaptureSession.setRepeatingRequest(b1.build(), mCaptureCallback, mOpsHandler);
550a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        } catch (CameraAccessException e) {
551a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.e(TAG, "Could not access camera for issuePreviewCaptureRequest.");
552a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
553a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
554a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
555a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    void runReprocessing() {
556a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mYuv1LastReceivedImage == null) {
557a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.e(TAG, "No YUV Image available.");
558a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            return;
559a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
560a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mImageWriter.queueInputImage(mYuv1LastReceivedImage);
561a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "  Sent YUV1 image to ImageWriter.queueInputImage()");
562a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        try {
563a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            CaptureRequest.Builder b1 = mCameraDevice.createReprocessCaptureRequest(mLastTotalCaptureResult);
5643855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala            // Todo: Read current orientation instead of just assuming device is in native orientation
5653855bb499fbfc073771fa951babfe1922d90ffc9Eino-Ville Talvala            b1.set(CaptureRequest.JPEG_ORIENTATION, mCameraInfoCache.sensorOrientation());
566a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.set(CaptureRequest.JPEG_QUALITY, (byte) 95);
5679736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            b1.set(CaptureRequest.NOISE_REDUCTION_MODE, mReprocessingNoiseMode);
5689736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            b1.set(CaptureRequest.EDGE_MODE, mReprocessingEdgeMode);
569a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            b1.addTarget(mJpegImageReader.getSurface());
570a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mCurrentCaptureSession.capture(b1.build(), mReprocessingCaptureCallback, mOpsHandler);
571a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mReprocessingRequestNanoTime = System.nanoTime();
572a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        } catch (CameraAccessException e) {
573a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.e(TAG, "Could not access camera for issuePreviewCaptureRequest.");
574a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
575a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mYuv1LastReceivedImage = null;
576a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        Log.v(TAG, "  Reprocessing request submitted.");
577a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
578a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
579a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
580a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    /*********************************
581a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     * onImageAvailable() processing *
582a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     *********************************/
583a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
584a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    ImageReader.OnImageAvailableListener mYuv1ImageListener =
585a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            new ImageReader.OnImageAvailableListener() {
586a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                @Override
587a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                public void onImageAvailable(ImageReader reader) {
588a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Image img = reader.acquireLatestImage();
589a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (img == null) {
590a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        Log.e(TAG, "Null image returned YUV1");
591a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        return;
592a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
593a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (mYuv1LastReceivedImage != null) {
594a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        mYuv1LastReceivedImage.close();
595a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
596a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mYuv1LastReceivedImage = img;
597a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (++mYuv1ImageCounter % LOG_NTH_FRAME == 0) {
598a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        Log.v(TAG, "YUV1 buffer available, Frame #=" + mYuv1ImageCounter + " w=" + img.getWidth() + " h=" + img.getHeight() + " time=" + img.getTimestamp());
599a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
600a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
601a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
602a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            };
603a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
604a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
605a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    ImageReader.OnImageAvailableListener mJpegImageListener =
606a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            new ImageReader.OnImageAvailableListener() {
607a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                @Override
608a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                public void onImageAvailable(ImageReader reader) {
609a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Image img = reader.acquireLatestImage();
610a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (img == null) {
611a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        Log.e(TAG, "Null image returned JPEG");
612a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        return;
613a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
614a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Image.Plane plane0 = img.getPlanes()[0];
615a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    final ByteBuffer buffer = plane0.getBuffer();
616a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    long dt = System.nanoTime() - mReprocessingRequestNanoTime;
617a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Log.v(TAG, String.format("JPEG buffer available, w=%d h=%d time=%d size=%d dt=%.1f ms  ISO=%d",
618a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            img.getWidth(), img.getHeight(), img.getTimestamp(), buffer.capacity(), 0.000001 * dt, mLastIso));
619a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    // Save JPEG on the utility thread,
620a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    final byte[] jpegBuf;
621a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (buffer.hasArray()) {
622a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        jpegBuf = buffer.array();
623a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    } else {
624a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        jpegBuf = new byte[buffer.capacity()];
625a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        buffer.get(jpegBuf);
626a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
627a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mMyCameraCallback.jpegAvailable(jpegBuf, img.getWidth(), img.getHeight());
628a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    img.close();
629a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
630a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    // take (reprocess) another picture right away if bursting.
631a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (mIsBursting) {
632a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        takePicture();
633a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
634a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
635a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            };
636a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
637a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
638a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    ImageReader.OnImageAvailableListener mYuv2ImageListener =
639a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            new ImageReader.OnImageAvailableListener() {
640a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                @Override
641a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                public void onImageAvailable(ImageReader reader) {
642a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Image img = reader.acquireLatestImage();
643a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (img == null) {
644a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        Log.e(TAG, "Null image returned YUV2");
645a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    } else {
646a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        if (++mYuv2ImageCounter % LOG_NTH_FRAME == 0) {
647a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            Log.v(TAG, "YUV2 buffer available, Frame #=" + mYuv2ImageCounter + " w=" + img.getWidth() + " h=" + img.getHeight() + " time=" + img.getTimestamp());
648a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        }
649a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        img.close();
650a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
651a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
652a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            };
653a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
654a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
655a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    ImageReader.OnImageAvailableListener mRawImageListener =
656a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            new ImageReader.OnImageAvailableListener() {
657a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                @Override
658a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                public void onImageAvailable(ImageReader reader) {
659a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    final Image img = reader.acquireLatestImage();
660a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    if (img == null) {
661a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        Log.e(TAG, "Null image returned RAW");
662a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    } else {
663a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        if (++mRawImageCounter % LOG_NTH_FRAME == 0) {
664a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            Image.Plane plane0 = img.getPlanes()[0];
665a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            final ByteBuffer buffer = plane0.getBuffer();
666a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                            Log.v(TAG, "Raw buffer available, Frame #=" + mRawImageCounter + "w=" + img.getWidth()
667a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                                    + " h=" + img.getHeight()
6683651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                                    + " format=" + CameraDeviceReport.getFormatName(img.getFormat())
669a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                                    + " time=" + img.getTimestamp()
670a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                                    + " size=" + buffer.capacity()
671a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                                    + " getRowStride()=" + plane0.getRowStride());
672a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        }
673a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                        img.close();
674a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    }
675a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
676a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            };
677a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
678a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    /*************************************
679a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     * CaptureResult metadata processing *
680a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     *************************************/
681a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
6823651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    private CameraCaptureSession.CaptureCallback mCaptureCallback = new LoggingCallbacks.SessionCaptureCallback() {
683a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        @Override
684a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
685a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (!mFirstFrameArrived) {
686a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mFirstFrameArrived = true;
687a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                long now = SystemClock.elapsedRealtime();
6883651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                long dt = now - CameraTimer.t0;
6893651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                long camera_dt = now - CameraTimer.t_session_go + CameraTimer.t_open_end - CameraTimer.t_open_start;
6903651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala                long repeating_req_dt = now - CameraTimer.t_burst;
691a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "App control to first frame: (" + dt + " ms)");
692a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                Log.v(TAG, "HAL request to first frame: (" + repeating_req_dt + " ms) " + " Total HAL wait: (" + camera_dt + " ms)");
693a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mMyCameraCallback.receivedFirstFrame();
694a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                mMyCameraCallback.performanceDataAvailable((int) dt, (int) camera_dt, null);
695a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
696a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            publishFrameData(result);
697a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            // Used for reprocessing.
698a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mLastTotalCaptureResult = result;
699a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            super.onCaptureCompleted(session, request, result);
700a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
701a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    };
702a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
703a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    // Reprocessing capture completed.
7043651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala    private CameraCaptureSession.CaptureCallback mReprocessingCaptureCallback = new LoggingCallbacks.SessionCaptureCallback() {
705a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        @Override
706a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
707a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "Reprocessing onCaptureCompleted()");
708a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
709a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    };
710a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
711a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static double SHORT_LOG_EXPOSURE = Math.log10(1000000000 / 10000); // 1/10000 second
712a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static double LONG_LOG_EXPOSURE = Math.log10(1000000000 / 10); // 1/10 second
713a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    public int FPS_CALC_LOOKBACK = 15;
714a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private LinkedList<Long> mFrameTimes = new LinkedList<Long>();
715a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
716a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private void publishFrameData(TotalCaptureResult result) {
717a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Faces.
718a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        final Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
719a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        NormalizedFace[] newFaces = new NormalizedFace[faces.length];
720a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (faces.length > 0) {
721a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int offX = mCameraInfoCache.faceOffsetX();
722a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int offY = mCameraInfoCache.faceOffsetY();
723a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int dX = mCameraInfoCache.activeAreaWidth() - 2 * offX;
724a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int dY = mCameraInfoCache.activeAreaHeight() - 2 * offY;
725a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (mCameraInfoCache.IS_NEXUS_6 && mCameraIsFront) {
726a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                // Front camera on Nexus 6 is currently 16 x 9 cropped to 4 x 3.
727a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                // TODO: Generalize this.
728a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                int cropOffset = dX / 8;
729a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                dX -= 2 * cropOffset;
730a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                offX += cropOffset;
731a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
732a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            int orientation = mCameraInfoCache.sensorOrientation();
733a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            for (int i = 0; i < faces.length; ++i) {
734a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                newFaces[i] = new NormalizedFace(faces[i], dX, dY, offX, offY);
735a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (mCameraIsFront && orientation == 90) {
736a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    newFaces[i].mirrorInY();
737a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
738a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (mCameraIsFront && orientation == 270) {
739a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    newFaces[i].mirrorInX();
740a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
741a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (!mCameraIsFront && orientation == 270) {
742a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    newFaces[i].mirrorInX();
743a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    newFaces[i].mirrorInY();
744a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
745a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
746a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
747a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
748a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Normalized lens and exposure coordinates.
749a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        double rm = Math.log10(result.get(CaptureResult.SENSOR_EXPOSURE_TIME));
750a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        float normExposure = (float) ((rm - SHORT_LOG_EXPOSURE) / (LONG_LOG_EXPOSURE - SHORT_LOG_EXPOSURE));
751a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        float normLensPos = (mCameraInfoCache.getDiopterHi() - result.get(CaptureResult.LENS_FOCUS_DISTANCE)) / (mCameraInfoCache.getDiopterHi() - mCameraInfoCache.getDiopterLow());
752a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mLastIso = result.get(CaptureResult.SENSOR_SENSITIVITY);
753a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
754a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Update frame arrival history.
755a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        mFrameTimes.add(result.get(CaptureResult.SENSOR_TIMESTAMP));
756a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mFrameTimes.size() > FPS_CALC_LOOKBACK) {
757a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mFrameTimes.removeFirst();
758a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
759a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
760a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Frame drop detector
761a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        {
762a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            float frameDuration = result.get(CaptureResult.SENSOR_FRAME_DURATION);
763a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            if (mFrameTimes.size() > 1) {
764a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                long dt = result.get(CaptureResult.SENSOR_TIMESTAMP) - mFrameTimes.get(mFrameTimes.size()-2);
765a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                if (dt > 3 * frameDuration / 2 && LOG_DROPPED_FRAMES) {
766a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    float drops = (dt * 1f / frameDuration) - 1f;
767a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    Log.e(TAG, String.format("dropped %.2f frames", drops));
768a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    mMyCameraCallback.performanceDataAvailable(null, null, drops);
769a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                }
770a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            }
771a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
772a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
773a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // FPS calc.
774a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        float fps = 0;
775a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mFrameTimes.size() > 1) {
776a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            long dt = mFrameTimes.getLast() - mFrameTimes.getFirst();
777a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            fps = (mFrameTimes.size() - 1) * 1000000000f / dt;
778a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            fps = (float) Math.floor(fps + 0.1); // round to nearest whole number, ish.
779a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
780a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
781a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        // Do callback.
782a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        if (mMyCameraCallback != null) {
783a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            mMyCameraCallback.frameDataAvailable(newFaces, normExposure, normLensPos, fps,
784a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                    (int) mLastIso, result.get(CaptureResult.CONTROL_AF_STATE), result.get(CaptureResult.CONTROL_AE_STATE), result.get(CaptureResult.CONTROL_AWB_STATE));
785a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        } else {
786a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            Log.v(TAG, "mMyCameraCallbacks is null!!.");
787a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
788a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
789a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
790a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    long mLastIso = 0;
791a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
792a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    /*********************
793a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     * UTILITY FUNCTIONS *
794a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala     *********************/
795a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
7969736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    /**
7979736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * Return the next mode after currentMode in supportedModes, wrapping to
7989736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * start of mode list if currentMode is last.  Returns currentMode if it is not found in
7999736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * supportedModes.
8009736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     *
8019736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * @param currentMode
8029736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * @param supportedModes
8039736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     * @return next mode after currentMode in supportedModes
8049736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala     */
8059736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    private int getNextMode(int currentMode, int[] supportedModes) {
8069736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        boolean getNext = false;
8079736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        for (int m : supportedModes) {
8089736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            if (getNext) {
8099736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                return m;
8109736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            }
8119736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            if (m == currentMode) {
8129736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala                getNext = true;
8139736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            }
8149736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        }
8159736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        if (getNext) {
8169736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            return supportedModes[0];
8179736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        }
8189736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        // Can't find mode in list
8199736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala        return currentMode;
8209736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala    }
8219736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala
822a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static String edgeModeToString(int mode) {
823a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        switch (mode) {
824a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.EDGE_MODE_OFF:
825a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "OFF";
826a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.EDGE_MODE_FAST:
827a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "FAST";
828a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.EDGE_MODE_HIGH_QUALITY:
829a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "HiQ";
8309736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            case CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG:
831a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "ZSL";
832a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
833a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        return Integer.toString(mode);
834a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
835a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala
836a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    private static String noiseModeToString(int mode) {
837a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        switch (mode) {
838a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.NOISE_REDUCTION_MODE_OFF:
839a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "OFF";
840a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.NOISE_REDUCTION_MODE_FAST:
841a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "FAST";
842a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala            case CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY:
843a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "HiQ";
8449736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            case CaptureRequest.NOISE_REDUCTION_MODE_MINIMAL:
845a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "MIN";
8469736d0f3038125c3c4b0cdeacbe18884a70805f2Eino-Ville Talvala            case CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG:
847a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala                return "ZSL";
848a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        }
849a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala        return Integer.toString(mode);
850a8a96dfce795a6621cdf7b890442fa5ed1252a55Eino-Ville Talvala    }
8513651aa3f8296eae150590b765fda1d87f49fb5b6Eino-Ville Talvala}
852