16d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/*
26d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Copyright 2016 The Android Open Source Project
36d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
46d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Licensed under the Apache License, Version 2.0 (the "License");
56d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * you may not use this file except in compliance with the License.
66d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * You may obtain a copy of the License at
76d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
86d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *      http://www.apache.org/licenses/LICENSE-2.0
96d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Unless required by applicable law or agreed to in writing, software
116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * distributed under the License is distributed on an "AS IS" BASIS,
126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * See the License for the specific language governing permissions and
146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * limitations under the License.
156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpackage com.android.mediaframeworktest.stress;
186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.blocking.BlockingSessionCallback;
206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.Camera2SurfaceViewTestCase;
216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestUtils;
226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.StaticMetadata;
236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.ImageFormat;
256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraDevice;
266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureFailure;
276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureRequest;
286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureResult;
296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.TotalCaptureResult;
306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.params.InputConfiguration;
316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.Image;
326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.ImageReader;
336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.ImageWriter;
346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log;
356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Size;
366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Surface;
376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.ArrayList;
396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.Arrays;
406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.List;
416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.EXIF_TEST_DATA;
436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS;
446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback;
456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener;
466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageWriterListener;
476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.configureReprocessableCameraSession;
486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.dumpFile;
496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getAscendingOrderSizes;
506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage;
516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.makeImageReader;
526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.setJpegKeys;
536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.verifyJpegKeys;
546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Tests for Reprocess API.</p>
576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * adb shell am instrument \
596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e class \
606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    com.android.mediaframeworktest.stress.Camera2StillCaptureTest#Camera2ReprocessCaptureTest \
6184789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim *    -e iterations 1 \
626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e waitIntervalMs 1000 \
636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e resultToFile false \
646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -r -w com.android.mediaframeworktest/.Camera2InstrumentationTestRunner
656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class Camera2ReprocessCaptureTest extends Camera2SurfaceViewTestCase  {
676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String TAG = "ReprocessCaptureTest";
686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int CAPTURE_TIMEOUT_FRAMES = 100;
716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int CAPTURE_TIMEOUT_MS = 3000;
726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS = 1000;
736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int CAPTURE_TEMPLATE = CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG;
746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int ZSL_TEMPLATE = CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG;
756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int NUM_REPROCESS_TEST_LOOP = 3;
766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int NUM_REPROCESS_CAPTURES = 3;
776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int NUM_REPROCESS_BURST = 3;
786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private int mDumpFrameCount = 0;
796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // The image reader for the first regular capture
816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageReader mFirstImageReader;
826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // The image reader for the reprocess capture
836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageReader mSecondImageReader;
846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // A flag indicating whether the regular capture and the reprocess capture share the same image
856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // reader. If it's true, mFirstImageReader should be used for regular and reprocess outputs.
866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean mShareOneImageReader;
876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private SimpleImageReaderListener mFirstImageReaderListener;
886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private SimpleImageReaderListener mSecondImageReaderListener;
896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private Surface mInputSurface;
906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageWriter mImageWriter;
916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private SimpleImageWriterListener mImageWriterListener;
926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private enum CaptureTestCase {
946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SINGLE_SHOT,
956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        BURST,
966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        MIXED_BURST,
976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ABORT_CAPTURE,
986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TIMESTAMPS,
996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        JPEG_EXIF,
1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        REQUEST_KEYS,
1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test YUV_420_888 -> JPEG with maximal supported sizes
1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testBasicYuvToJpegReprocessing() throws Exception {
1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (String id : mCameraIds) {
1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (!isYuvReprocessSupported(id)) {
1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                continue;
1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Test iteration starts...
11384789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim            for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
11484789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                Log.v(TAG, String.format("Reprocessing YUV to JPEG: %d/%d", iteration + 1,
11584789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                        getIterationCount()));
1166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // YUV_420_888 -> JPEG must be supported.
1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testBasicReprocessing(id, ImageFormat.YUV_420_888, ImageFormat.JPEG);
11884789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Thread.sleep(getTestWaitIntervalMs());
1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test OPAQUE -> JPEG with maximal supported sizes
1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testBasicOpaqueToJpegReprocessing() throws Exception {
1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (String id : mCameraIds) {
1296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (!isOpaqueReprocessSupported(id)) {
1306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                continue;
1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Test iteration starts...
13484789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim            for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
13584789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                Log.v(TAG, String.format("Reprocessing OPAQUE to JPEG: %d/%d", iteration + 1,
13684789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                        getIterationCount()));
1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // OPAQUE -> JPEG must be supported.
1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testBasicReprocessing(id, ImageFormat.PRIVATE, ImageFormat.JPEG);
13984789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Thread.sleep(getTestWaitIntervalMs());
1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test all supported size and format combinations with preview.
1486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testReprocessingSizeFormatWithPreview() throws Exception {
1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (String id : mCameraIds) {
1516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
1526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                continue;
1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // open Camera device
1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                openDevice(id);
1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Test iteration starts...
16084789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.v(TAG, String.format("Reprocessing size format with preview: %d/%d",
16284789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                            iteration + 1, getIterationCount()));
1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    testReprocessingAllCombinations(id, mOrderedPreviewSizes.get(0),
1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            CaptureTestCase.SINGLE_SHOT);
16584789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Thread.sleep(getTestWaitIntervalMs());
1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
1686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } finally {
1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeDevice();
1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test burst captures mixed with regular and reprocess captures with and without preview.
1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testMixedBurstReprocessing() throws Exception {
1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (String id : mCameraIds) {
1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                continue;
1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // open Camera device
1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                openDevice(id);
1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Test iteration starts...
18884789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.v(TAG, String.format("Reprocessing mixed burst with or without preview: "
19084789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                            + "%d/%d", iteration + 1, getIterationCount()));
1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    // no preview
1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    testReprocessingAllCombinations(id, /*previewSize*/null,
1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            CaptureTestCase.MIXED_BURST);
1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    // with preview
1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    testReprocessingAllCombinations(id, mOrderedPreviewSizes.get(0),
1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            CaptureTestCase.MIXED_BURST);
19784789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Thread.sleep(getTestWaitIntervalMs());
1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } finally {
2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeDevice();
2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test the input format and output format with the largest input and output sizes.
2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testBasicReprocessing(String cameraId, int inputFormat,
2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int reprocessOutputFormat) throws Exception {
2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            openDevice(cameraId);
2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            testReprocessingMaxSizes(cameraId, inputFormat, reprocessOutputFormat,
2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    /* previewSize */null, CaptureTestCase.SINGLE_SHOT);
2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeDevice();
2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test the input format and output format with the largest input and output sizes for a
2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * certain test case.
2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessingMaxSizes(String cameraId, int inputFormat,
2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int reprocessOutputFormat, Size previewSize, CaptureTestCase captureTestCase)
2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws Exception {
2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxInputSize = getMaxSize(inputFormat, StaticMetadata.StreamDirection.Input);
2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxReprocessOutputSize =
2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                getMaxSize(reprocessOutputFormat, StaticMetadata.StreamDirection.Output);
2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        switch (captureTestCase) {
2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case SINGLE_SHOT:
2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testReprocess(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        reprocessOutputFormat, previewSize, NUM_REPROCESS_CAPTURES);
2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case ABORT_CAPTURE:
2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testReprocessAbort(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        reprocessOutputFormat);
2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case TIMESTAMPS:
2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testReprocessTimestamps(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        reprocessOutputFormat);
2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case JPEG_EXIF:
2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testReprocessJpegExif(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize);
2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case REQUEST_KEYS:
2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                testReprocessRequestKeys(cameraId, maxInputSize, inputFormat,
2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        maxReprocessOutputSize, reprocessOutputFormat);
2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            default:
2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                throw new IllegalArgumentException("Invalid test case");
2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test all input format, input size, output format, and output size combinations.
2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessingAllCombinations(String cameraId, Size previewSize,
2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureTestCase captureTestCase) throws Exception {
2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int[] supportedInputFormats =
2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int inputFormat : supportedInputFormats) {
2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size[] supportedInputSizes =
2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mStaticInfo.getAvailableSizesForFormatChecked(inputFormat,
2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    StaticMetadata.StreamDirection.Input);
2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (Size inputSize : supportedInputSizes) {
2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                int[] supportedReprocessOutputFormats =
2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mStaticInfo.getValidOutputFormatsForInput(inputFormat);
2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Size[] supportedReprocessOutputSizes =
2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            mStaticInfo.getAvailableSizesForFormatChecked(reprocessOutputFormat,
2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            StaticMetadata.StreamDirection.Output);
2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    for (Size reprocessOutputSize : supportedReprocessOutputSizes) {
2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        switch (captureTestCase) {
2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            case SINGLE_SHOT:
2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                testReprocess(cameraId, inputSize, inputFormat,
2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        NUM_REPROCESS_CAPTURES);
2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                break;
2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            case BURST:
2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                testReprocessBurst(cameraId, inputSize, inputFormat,
2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        NUM_REPROCESS_BURST);
2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                break;
2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            case MIXED_BURST:
2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                testReprocessMixedBurst(cameraId, inputSize, inputFormat,
2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                        NUM_REPROCESS_BURST);
2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                break;
2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            default:
2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                throw new IllegalArgumentException("Invalid test case");
2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        }
2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test burst that is mixed with regular and reprocess capture requests.
3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessMixedBurst(String cameraId, Size inputSize, int inputFormat,
3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numBurst) throws Exception {
3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessMixedBurst: cameraId: " + cameraId + " inputSize: " +
3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    " previewSize: " + previewSize + " numBurst: " + numBurst);
3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean enablePreview = (previewSize != null);
3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageResultHolder[] imageResultHolders = new ImageResultHolder[0];
3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // totalNumBurst = number of regular burst + number of reprocess burst.
3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int totalNumBurst = numBurst * 2;
3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                updatePreviewSurface(previewSize);
3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mPreviewSurface = null;
3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                totalNumBurst);
3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(mPreviewSurface, /*numImageWriterImages*/numBurst);
3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                startPreview(mPreviewSurface);
3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Prepare an array of booleans indicating each capture's type (regular or reprocess)
3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            boolean[] isReprocessCaptures = new boolean[totalNumBurst];
3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < totalNumBurst; i++) {
3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if ((i & 1) == 0) {
3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    isReprocessCaptures[i] = true;
3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                } else {
3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    isReprocessCaptures[i] = false;
3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            imageResultHolders = doMixedReprocessBurstCapture(isReprocessCaptures);
3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (ImageResultHolder holder : imageResultHolders) {
3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Image reprocessedImage = holder.getImage();
3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult result = holder.getTotalCaptureResult();
3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectImageProperties("testReprocessMixedBurst", reprocessedImage,
3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputFormat, reprocessOutputSize,
3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            result.get(CaptureResult.SENSOR_TIMESTAMP));
3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (DEBUG) {
3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputFormat));
3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    dumpImage(reprocessedImage,
3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            "/testReprocessMixedBurst_camera" + cameraId + "_" + mDumpFrameCount);
3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mDumpFrameCount++;
3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (ImageResultHolder holder : imageResultHolders) {
3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                holder.getImage().close();
3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test burst of reprocess capture requests.
3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessBurst(String cameraId, Size inputSize, int inputFormat,
3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numBurst) throws Exception {
3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessBurst: cameraId: " + cameraId + " inputSize: " +
3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    " previewSize: " + previewSize + " numBurst: " + numBurst);
3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean enablePreview = (previewSize != null);
3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageResultHolder[] imageResultHolders = new ImageResultHolder[0];
3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                updatePreviewSurface(previewSize);
3966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
3976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mPreviewSurface = null;
3986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
4016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                numBurst);
4026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(mPreviewSurface, numBurst);
4036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
4056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                startPreview(mPreviewSurface);
4066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            imageResultHolders = doReprocessBurstCapture(numBurst);
4096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (ImageResultHolder holder : imageResultHolders) {
4106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Image reprocessedImage = holder.getImage();
4116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult result = holder.getTotalCaptureResult();
4126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectImageProperties("testReprocessBurst", reprocessedImage,
4146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputFormat, reprocessOutputSize,
4156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            result.get(CaptureResult.SENSOR_TIMESTAMP));
4166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (DEBUG) {
4186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
4196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
4206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
4216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputFormat));
4226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    dumpImage(reprocessedImage,
4236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            "/testReprocessBurst_camera" + cameraId + "_" + mDumpFrameCount);
4246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mDumpFrameCount++;
4256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
4266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
4286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (ImageResultHolder holder : imageResultHolders) {
4296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                holder.getImage().close();
4306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
4326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
4336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
4376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test a sequences of reprocess capture requests.
4386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocess(String cameraId, Size inputSize, int inputFormat,
4406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
4416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numReprocessCaptures) throws Exception {
4426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
4436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocess: cameraId: " + cameraId + " inputSize: " +
4446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
4456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
4466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    " previewSize: " + previewSize);
4476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean enablePreview = (previewSize != null);
4506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
4526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
4536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                updatePreviewSurface(previewSize);
4546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
4556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mPreviewSurface = null;
4566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
4596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    /*maxImages*/1);
4606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(mPreviewSurface, /*numImageWriterImages*/1);
4616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (enablePreview) {
4636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                startPreview(mPreviewSurface);
4646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < numReprocessCaptures; i++) {
4676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageResultHolder imageResultHolder = null;
4686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                try {
4706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    imageResultHolder = doReprocessCapture();
4716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Image reprocessedImage = imageResultHolder.getImage();
4726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    TotalCaptureResult result = imageResultHolder.getTotalCaptureResult();
4736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mCollector.expectImageProperties("testReprocess", reprocessedImage,
4756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            reprocessOutputFormat, reprocessOutputSize,
4766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            result.get(CaptureResult.SENSOR_TIMESTAMP));
4776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (DEBUG) {
4796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
4806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
4816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
4826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                reprocessOutputFormat));
4836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        dumpImage(reprocessedImage,
4856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                "/testReprocess_camera" + cameraId + "_" + mDumpFrameCount);
4866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mDumpFrameCount++;
4876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
4886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                } finally {
4896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (imageResultHolder != null) {
4906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        imageResultHolder.getImage().close();
4916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
4926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
4936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
4956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
4966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
4976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test aborting a burst reprocess capture and multiple single reprocess captures.
5026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessAbort(String cameraId, Size inputSize, int inputFormat,
5046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
5056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
5066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessAbort: cameraId: " + cameraId + " inputSize: " +
5076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
5086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
5096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
5126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
5136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    NUM_REPROCESS_CAPTURES);
5146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(/*previewSurface*/null, NUM_REPROCESS_CAPTURES);
5156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Test two cases: submitting reprocess requests one by one and in a burst.
5176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            boolean submitInBursts[] = {false, true};
5186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (boolean submitInBurst : submitInBursts) {
5196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Prepare reprocess capture requests.
5206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ArrayList<CaptureRequest> reprocessRequests =
5216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        new ArrayList<>(NUM_REPROCESS_CAPTURES);
5226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
5246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
5256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            /*inputResult*/null);
5266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mImageWriter.queueInputImage(
5286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
5296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
5306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    builder.addTarget(getReprocessOutputImageReader().getSurface());
5316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessRequests.add(builder.build());
5326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
5356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Submit reprocess capture requests.
5376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (submitInBurst) {
5386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
5396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                } else {
5406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    for (CaptureRequest request : reprocessRequests) {
5416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mSession.capture(request, captureCallback, mHandler);
5426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
5436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Abort after getting the first result
5466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult reprocessResult =
5476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        captureCallback.getTotalCaptureResultForRequest(reprocessRequests.get(0),
5486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        CAPTURE_TIMEOUT_FRAMES);
5496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mSession.abortCaptures();
5506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Wait until the session is ready again.
5526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mSessionListener.getStateWaiter().waitForState(
5536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        BlockingSessionCallback.SESSION_READY, SESSION_CLOSE_TIMEOUT_MS);
5546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Gather all failed requests.
5566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ArrayList<CaptureFailure> failures =
5576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        captureCallback.getCaptureFailures(NUM_REPROCESS_CAPTURES - 1);
5586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ArrayList<CaptureRequest> failedRequests = new ArrayList<>();
5596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (CaptureFailure failure : failures) {
5606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    failedRequests.add(failure.getRequest());
5616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // For each request that didn't fail must have a valid result.
5646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (int i = 1; i < reprocessRequests.size(); i++) {
5656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest request = reprocessRequests.get(i);
5666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (!failedRequests.contains(request)) {
5676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        captureCallback.getTotalCaptureResultForRequest(request,
5686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                CAPTURE_TIMEOUT_FRAMES);
5696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
5706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Drain the image reader listeners.
5736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mFirstImageReaderListener.drain();
5746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (!mShareOneImageReader) {
5756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mSecondImageReaderListener.drain();
5766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Make sure all input surfaces are released.
5796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
5806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
5816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
5836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
5846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
5856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
5866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test timestamps for reprocess requests. Reprocess request's shutter timestamp, result's
5916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * sensor timestamp, and output image's timestamp should match the reprocess input's timestamp.
5926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessTimestamps(String cameraId, Size inputSize, int inputFormat,
5946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
5956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
5966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessTimestamps: cameraId: " + cameraId + " inputSize: " +
5976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
5986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
5996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
6026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
6036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    NUM_REPROCESS_CAPTURES);
6046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(/*previewSurface*/null, NUM_REPROCESS_CAPTURES);
6056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Prepare reprocess capture requests.
6076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(NUM_REPROCESS_CAPTURES);
6086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ArrayList<Long> expectedTimestamps = new ArrayList<>(NUM_REPROCESS_CAPTURES);
6096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
6116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
6126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        /*inputResult*/null);
6136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mImageWriter.queueInputImage(
6156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
6166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
6176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder.addTarget(getReprocessOutputImageReader().getSurface());
6186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                reprocessRequests.add(builder.build());
6196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Reprocess result's timestamp should match input image's timestamp.
6206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                expectedTimestamps.add(result.get(CaptureResult.SENSOR_TIMESTAMP));
6216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Submit reprocess requests.
6246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
6256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
6266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Verify we get the expected timestamps.
6286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < reprocessRequests.size(); i++) {
6296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                captureCallback.waitForCaptureStart(reprocessRequests.get(i),
6306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        expectedTimestamps.get(i), CAPTURE_TIMEOUT_FRAMES);
6316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            TotalCaptureResult[] reprocessResults =
6346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
6356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CAPTURE_TIMEOUT_FRAMES);
6366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < expectedTimestamps.size(); i++) {
6386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Verify the result timestamps match the input image's timestamps.
6396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                long expected = expectedTimestamps.get(i);
6406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                long timestamp = reprocessResults[i].get(CaptureResult.SENSOR_TIMESTAMP);
6416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                assertEquals("Reprocess result timestamp (" + timestamp + ") doesn't match input " +
6426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        "image's timestamp (" + expected + ")", expected, timestamp);
6436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Verify the reprocess output image timestamps match the input image's timestamps.
6456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
6466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                timestamp = image.getTimestamp();
6476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                image.close();
6486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                assertEquals("Reprocess output timestamp (" + timestamp + ") doesn't match input " +
6506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        "image's timestamp (" + expected + ")", expected, timestamp);
6516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Make sure all input surfaces are released.
6546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
6556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
6566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
6586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
6596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
6606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
6646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test JPEG tags for reprocess requests. Reprocess result's JPEG tags and JPEG image's tags
6656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * match reprocess request's JPEG tags.
6666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
6676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessJpegExif(String cameraId, Size inputSize, int inputFormat,
6686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize) throws Exception {
6696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
6706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessJpegExif: cameraId: " + cameraId + " inputSize: " +
6716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
6726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize);
6736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size[] thumbnailSizes = mStaticInfo.getAvailableThumbnailSizesChecked();
6766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size[] testThumbnailSizes = new Size[EXIF_TEST_DATA.length];
6776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Arrays.fill(testThumbnailSizes, thumbnailSizes[thumbnailSizes.length - 1]);
6786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Make sure thumbnail size (0, 0) is covered.
6796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        testThumbnailSizes[0] = new Size(0, 0);
6806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
6826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, ImageFormat.JPEG,
6836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    EXIF_TEST_DATA.length);
6846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(/*previewSurface*/null, EXIF_TEST_DATA.length);
6856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Prepare reprocess capture requests.
6876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(EXIF_TEST_DATA.length);
6886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
6906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
6916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        /*inputResult*/null);
6926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mImageWriter.queueInputImage(
6936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
6946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
6966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder.addTarget(getReprocessOutputImageReader().getSurface());
6976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // set jpeg keys
6996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                setJpegKeys(builder, EXIF_TEST_DATA[i], testThumbnailSizes[i], mCollector);
7006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                reprocessRequests.add(builder.build());
7016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Submit reprocess requests.
7046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
7056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
7066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            TotalCaptureResult[] reprocessResults =
7086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
7096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CAPTURE_TIMEOUT_FRAMES);
7106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
7126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Verify output image's and result's JPEG EXIF data.
7136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
7146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                verifyJpegKeys(image, reprocessResults[i], reprocessOutputSize,
7156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        testThumbnailSizes[i], EXIF_TEST_DATA[i], mStaticInfo, mCollector);
7166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                image.close();
7176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
7206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
7216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
7226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
7286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test the following keys in reprocess results match the keys in reprocess requests:
7296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *   1. EDGE_MODE
7306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *   2. NOISE_REDUCTION_MODE
7316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *   3. REPROCESS_EFFECTIVE_EXPOSURE_FACTOR (only for YUV reprocess)
7326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
7336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void testReprocessRequestKeys(String cameraId, Size inputSize, int inputFormat,
7346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
7356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
7366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "testReprocessRequestKeys: cameraId: " + cameraId + " inputSize: " +
7376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
7386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
7396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final Integer[] EDGE_MODES = {CaptureRequest.EDGE_MODE_FAST,
7426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.EDGE_MODE_HIGH_QUALITY, CaptureRequest.EDGE_MODE_OFF,
7436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG};
7446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final Integer[] NR_MODES = {CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY,
7456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.NOISE_REDUCTION_MODE_OFF,
7466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
7476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.NOISE_REDUCTION_MODE_FAST};
7486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final Float[] EFFECTIVE_EXP_FACTORS = {null, 1.0f, 2.5f, 4.0f};
7496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int numFrames = EDGE_MODES.length;
7506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
7526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
7536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    numFrames);
7546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setupReprocessableSession(/*previewSurface*/null, numFrames);
7556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Prepare reprocess capture requests.
7576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(numFrames);
7586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < numFrames; i++) {
7606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
7616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        /*inputResult*/null);
7626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mImageWriter.queueInputImage(
7636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
7646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
7666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder.addTarget(getReprocessOutputImageReader().getSurface());
7676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Set reprocess request keys
7696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder.set(CaptureRequest.EDGE_MODE, EDGE_MODES[i]);
7706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder.set(CaptureRequest.NOISE_REDUCTION_MODE, NR_MODES[i]);
7716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (inputFormat == ImageFormat.YUV_420_888) {
7726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    builder.set(CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR,
7736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            EFFECTIVE_EXP_FACTORS[i]);
7746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
7756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                reprocessRequests.add(builder.build());
7766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Submit reprocess requests.
7796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
7806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
7816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            TotalCaptureResult[] reprocessResults =
7836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
7846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CAPTURE_TIMEOUT_FRAMES);
7856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < numFrames; i++) {
7876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Verify result's keys
7886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Integer resultEdgeMode = reprocessResults[i].get(CaptureResult.EDGE_MODE);
7896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Integer resultNoiseReductionMode =
7906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        reprocessResults[i].get(CaptureResult.NOISE_REDUCTION_MODE);
7916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                assertEquals("Reprocess result edge mode (" + resultEdgeMode +
7936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        ") doesn't match requested edge mode (" + EDGE_MODES[i] + ")",
7946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        resultEdgeMode, EDGE_MODES[i]);
7956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                assertEquals("Reprocess result noise reduction mode (" + resultNoiseReductionMode +
7966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        ") doesn't match requested noise reduction mode (" +
7976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        NR_MODES[i] + ")", resultNoiseReductionMode,
7986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        NR_MODES[i]);
7996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (inputFormat == ImageFormat.YUV_420_888) {
8016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Float resultEffectiveExposureFactor = reprocessResults[i].get(
8026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
8036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    assertEquals("Reprocess effective exposure factor (" +
8046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            resultEffectiveExposureFactor + ") doesn't match requested " +
8056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            "effective exposure factor (" + EFFECTIVE_EXP_FACTORS[i] + ")",
8066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            resultEffectiveExposureFactor, EFFECTIVE_EXP_FACTORS[i]);
8076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
8086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
8096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
8106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeReprossibleSession();
8116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            closeImageReaders();
8126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
8166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Set up two image readers: one for regular capture (used for reprocess input) and one for
8176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * reprocess capture.
8186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
8196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void setupImageReaders(Size inputSize, int inputFormat, Size reprocessOutputSize,
8206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int reprocessOutputFormat, int maxImages) {
8216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mShareOneImageReader = false;
8236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // If the regular output and reprocess output have the same size and format,
8246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // they can share one image reader.
8256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (inputFormat == reprocessOutputFormat &&
8266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                inputSize.equals(reprocessOutputSize)) {
8276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            maxImages *= 2;
8286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mShareOneImageReader = true;
8296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // create an ImageReader for the regular capture
8316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mFirstImageReaderListener = new SimpleImageReaderListener();
8326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mFirstImageReader = makeImageReader(inputSize, inputFormat, maxImages,
8336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mFirstImageReaderListener, mHandler);
8346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!mShareOneImageReader) {
8366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // create an ImageReader for the reprocess capture
8376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSecondImageReaderListener = new SimpleImageReaderListener();
8386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSecondImageReader = makeImageReader(reprocessOutputSize, reprocessOutputFormat,
8396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    maxImages, mSecondImageReaderListener, mHandler);
8406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
8446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Close two image readers.
8456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
8466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void closeImageReaders() {
8476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CameraTestUtils.closeImageReader(mFirstImageReader);
8486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mFirstImageReader = null;
8496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CameraTestUtils.closeImageReader(mSecondImageReader);
8506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSecondImageReader = null;
8516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
8546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Get the ImageReader for reprocess output.
8556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
8566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageReader getReprocessOutputImageReader() {
8576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mShareOneImageReader) {
8586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mFirstImageReader;
8596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
8606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mSecondImageReader;
8616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private SimpleImageReaderListener getReprocessOutputImageReaderListener() {
8656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mShareOneImageReader) {
8666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mFirstImageReaderListener;
8676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
8686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mSecondImageReaderListener;
8696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
8736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Set up a reprocessable session and create an ImageWriter with the sessoin's input surface.
8746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
8756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void setupReprocessableSession(Surface previewSurface, int numImageWriterImages)
8766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws Exception {
8776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // create a reprocessable capture session
8786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<Surface> outSurfaces = new ArrayList<Surface>();
8796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        outSurfaces.add(mFirstImageReader.getSurface());
8806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!mShareOneImageReader) {
8816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outSurfaces.add(mSecondImageReader.getSurface());
8826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (previewSurface != null) {
8846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outSurfaces.add(previewSurface);
8856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        InputConfiguration inputConfig = new InputConfiguration(mFirstImageReader.getWidth(),
8886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mFirstImageReader.getHeight(), mFirstImageReader.getImageFormat());
8896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        String inputConfigString = inputConfig.toString();
8906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
8916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "InputConfiguration: " + inputConfigString);
8926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
8936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertTrue(String.format("inputConfig is wrong: %dx%d format %d. Expect %dx%d format %d",
8946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                inputConfig.getWidth(), inputConfig.getHeight(), inputConfig.getFormat(),
8956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mFirstImageReader.getWidth(), mFirstImageReader.getHeight(),
8966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mFirstImageReader.getImageFormat()),
8976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                inputConfig.getWidth() == mFirstImageReader.getWidth() &&
8986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                inputConfig.getHeight() == mFirstImageReader.getHeight() &&
8996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                inputConfig.getFormat() == mFirstImageReader.getImageFormat());
9006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSessionListener = new BlockingSessionCallback();
9026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession = configureReprocessableCameraSession(mCamera, inputConfig, outSurfaces,
9036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mSessionListener, mHandler);
9046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // create an ImageWriter
9066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mInputSurface = mSession.getInputSurface();
9076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mImageWriter = ImageWriter.newInstance(mInputSurface,
9086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                numImageWriterImages);
9096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mImageWriterListener = new SimpleImageWriterListener(mImageWriter);
9116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mImageWriter.setOnImageReleasedListener(mImageWriterListener, mHandler);
9126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
9136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
9156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Close the reprocessable session and ImageWriter.
9166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
9176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void closeReprossibleSession() {
9186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mInputSurface = null;
9196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mSession != null) {
9216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.close();
9226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession = null;
9236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mImageWriter != null) {
9266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mImageWriter.close();
9276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mImageWriter = null;
9286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
9306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
9326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Do one reprocess capture.
9336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
9346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageResultHolder doReprocessCapture() throws Exception {
9356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return doReprocessBurstCapture(/*numBurst*/1)[0];
9366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
9376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
9396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Do a burst of reprocess captures.
9406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
9416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageResultHolder[] doReprocessBurstCapture(int numBurst) throws Exception {
9426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean[] isReprocessCaptures = new boolean[numBurst];
9436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < numBurst; i++) {
9446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            isReprocessCaptures[i] = true;
9456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return doMixedReprocessBurstCapture(isReprocessCaptures);
9486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
9496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
9516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Do a burst of captures that are mixed with regular and reprocess captures.
9526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
9536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param isReprocessCaptures An array whose elements indicate whether it's a reprocess capture
9546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                            request. If the element is true, it represents a reprocess capture
9556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                            request. If the element is false, it represents a regular capture
9566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                            request. The size of the array is the number of capture requests
9576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                            in the burst.
9586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
9596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private ImageResultHolder[] doMixedReprocessBurstCapture(boolean[] isReprocessCaptures)
9606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws Exception {
9616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (isReprocessCaptures == null || isReprocessCaptures.length <= 0) {
9626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("isReprocessCaptures must have at least 1 capture.");
9636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean hasReprocessRequest = false;
9666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean hasRegularRequest = false;
9676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TotalCaptureResult[] results = new TotalCaptureResult[isReprocessCaptures.length];
9696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < isReprocessCaptures.length; i++) {
9706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // submit a capture and get the result if this entry is a reprocess capture.
9716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (isReprocessCaptures[i]) {
9726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                results[i] = submitCaptureRequest(mFirstImageReader.getSurface(),
9736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        /*inputResult*/null);
9746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mImageWriter.queueInputImage(
9756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
9766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                hasReprocessRequest = true;
9776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
9786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                hasRegularRequest = true;
9796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
9806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Surface[] outputSurfaces = new Surface[isReprocessCaptures.length];
9836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < isReprocessCaptures.length; i++) {
9846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outputSurfaces[i] = getReprocessOutputImageReader().getSurface();
9856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
9866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TotalCaptureResult[] finalResults = submitMixedCaptureBurstRequest(outputSurfaces, results);
9886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
9896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageResultHolder[] holders = new ImageResultHolder[isReprocessCaptures.length];
9906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < isReprocessCaptures.length; i++) {
9916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
9926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (hasReprocessRequest && hasRegularRequest) {
9936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // If there are mixed requests, images and results may not be in the same order.
9946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (int j = 0; j < finalResults.length; j++) {
9956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (finalResults[j] != null &&
9966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            finalResults[j].get(CaptureResult.SENSOR_TIMESTAMP) ==
9976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            image.getTimestamp()) {
9986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        holders[i] = new ImageResultHolder(image, finalResults[j]);
9996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        finalResults[j] = null;
10006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        break;
10016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
10026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
10036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                assertNotNull("Cannot find a result matching output image's timestamp: " +
10056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        image.getTimestamp(), holders[i]);
10066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
10076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // If no mixed requests, images and results should be in the same order.
10086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                holders[i] = new ImageResultHolder(image, finalResults[i]);
10096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
10106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
10116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return holders;
10136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
10146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
10166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Start preview without a listener.
10176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
10186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void startPreview(Surface previewSurface) throws Exception {
10196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder builder = mCamera.createCaptureRequest(ZSL_TEMPLATE);
10206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        builder.addTarget(previewSurface);
10216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(builder.build(), null, mHandler);
10226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
10236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
10256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Issue a capture request and return the result. If inputResult is null, it's a regular
10266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * request. Otherwise, it's a reprocess request.
10276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
10286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private TotalCaptureResult submitCaptureRequest(Surface output,
10296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            TotalCaptureResult inputResult) throws Exception {
10306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Surface[] outputs = new Surface[1];
10316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        outputs[0] = output;
10326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TotalCaptureResult[] inputResults = new TotalCaptureResult[1];
10336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        inputResults[0] = inputResult;
10346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return submitMixedCaptureBurstRequest(outputs, inputResults)[0];
10366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
10376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
10396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Submit a burst request mixed with regular and reprocess requests.
10406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
10416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param outputs An array of output surfaces. One output surface will be used in one request
10426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                so the length of the array is the number of requests in a burst request.
10436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param inputResults An array of input results. If it's null, all requests are regular
10446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                     requests. If an element is null, that element represents a regular
10456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                     request. If an element if not null, that element represents a reprocess
10466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                     request.
10476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
10486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
10496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private TotalCaptureResult[] submitMixedCaptureBurstRequest(Surface[] outputs,
10506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            TotalCaptureResult[] inputResults) throws Exception {
10516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (outputs == null || outputs.length <= 0) {
10526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("outputs must have at least 1 surface");
10536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else if (inputResults != null && inputResults.length != outputs.length) {
10546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("The lengths of outputs and inputResults " +
10556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "don't match");
10566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
10576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int numReprocessCaptures = 0;
10596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
10606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ArrayList<CaptureRequest> captureRequests = new ArrayList<>(outputs.length);
10616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Prepare a list of capture requests. Whether it's a regular or reprocess capture request
10636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // is based on inputResults array.
10646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < outputs.length; i++) {
10656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest.Builder builder;
10666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            boolean isReprocess = (inputResults != null && inputResults[i] != null);
10676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (isReprocess) {
10686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder = mCamera.createReprocessCaptureRequest(inputResults[i]);
10696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                numReprocessCaptures++;
10706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
10716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                builder = mCamera.createCaptureRequest(CAPTURE_TEMPLATE);
10726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
10736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            builder.addTarget(outputs[i]);
10746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest request = builder.build();
10756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            assertTrue("Capture request reprocess type " + request.isReprocess() + " is wrong.",
10766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                request.isReprocess() == isReprocess);
10776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            captureRequests.add(request);
10796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
10806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (captureRequests.size() == 1) {
10826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.capture(captureRequests.get(0), captureCallback, mHandler);
10836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
10846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.captureBurst(captureRequests, captureCallback, mHandler);
10856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
10866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
10876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TotalCaptureResult[] results;
10886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (numReprocessCaptures == 0 || numReprocessCaptures == outputs.length) {
10896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            results = new TotalCaptureResult[outputs.length];
10906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // If the requests are not mixed, they should come in order.
10916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (int i = 0; i < results.length; i++){
10926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                results[i] = captureCallback.getTotalCaptureResultForRequest(
10936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        captureRequests.get(i), CAPTURE_TIMEOUT_FRAMES);
10946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
10956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
10966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // If the requests are mixed, they may not come in order.
10976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            results = captureCallback.getTotalCaptureResultsForRequests(
10986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    captureRequests, CAPTURE_TIMEOUT_FRAMES * captureRequests.size());
10996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // make sure all input surfaces are released.
11026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < numReprocessCaptures; i++) {
11036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
11046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return results;
11076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private Size getMaxSize(int format, StaticMetadata.StreamDirection direction) {
11106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size[] sizes = mStaticInfo.getAvailableSizesForFormatChecked(format, direction);
11116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return getAscendingOrderSizes(Arrays.asList(sizes), /*ascending*/false).get(0);
11126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean isYuvReprocessSupported(String cameraId) throws Exception {
11156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return isReprocessSupported(cameraId, ImageFormat.YUV_420_888);
11166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean isOpaqueReprocessSupported(String cameraId) throws Exception {
11196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return isReprocessSupported(cameraId, ImageFormat.PRIVATE);
11206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void dumpImage(Image image, String name) {
11236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        String filename = DEBUG_FILE_NAME_BASE + name;
11246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        switch(image.getFormat()) {
11256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case ImageFormat.JPEG:
11266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                filename += ".jpg";
11276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
11286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case ImageFormat.NV16:
11296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case ImageFormat.NV21:
11306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case ImageFormat.YUV_420_888:
11316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                filename += ".yuv";
11326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
11336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            default:
11346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                filename += "." + image.getFormat();
11356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
11366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Log.d(TAG, "dumping an image to " + filename);
11396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        dumpFile(filename , getDataFromImage(image));
11406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
11436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * A class that holds an Image and a TotalCaptureResult.
11446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
11456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static class ImageResultHolder {
11466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        private final Image mImage;
11476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        private final TotalCaptureResult mResult;
11486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        public ImageResultHolder(Image image, TotalCaptureResult result) {
11506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mImage = image;
11516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mResult = result;
11526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        public Image getImage() {
11556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mImage;
11566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
11586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        public TotalCaptureResult getTotalCaptureResult() {
11596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return mResult;
11606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
11616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
11626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim}
1163