Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | package androidx.camera.extensions.impl; |
| 17 | |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 18 | import static android.hardware.camera2.CameraMetadata.CONTROL_AE_MODE_OFF; |
| 19 | |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 20 | import android.annotation.SuppressLint; |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 21 | import android.content.Context; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 22 | import android.hardware.camera2.CameraCharacteristics; |
| 23 | import android.hardware.camera2.CaptureRequest; |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 24 | import android.hardware.camera2.CaptureResult; |
Franklin Wu | c84b18f | 2019-04-29 15:45:44 -0700 | [diff] [blame] | 25 | import android.hardware.camera2.TotalCaptureResult; |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 26 | import android.hardware.camera2.params.SessionConfiguration; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 27 | import android.media.Image; |
| 28 | import android.media.ImageWriter; |
| 29 | import android.os.Build; |
| 30 | import android.util.Log; |
Franklin Wu | c84b18f | 2019-04-29 15:45:44 -0700 | [diff] [blame] | 31 | import android.util.Pair; |
Charcoal Chen | 4eeaeb2 | 2021-04-14 10:28:52 +0800 | [diff] [blame] | 32 | import android.util.Range; |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 33 | import android.util.Size; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 34 | import android.view.Surface; |
| 35 | |
TY Chang | d1057c8 | 2019-05-21 15:26:44 +0800 | [diff] [blame] | 36 | import androidx.annotation.NonNull; |
| 37 | import androidx.annotation.Nullable; |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 38 | import androidx.annotation.RequiresApi; |
TY Chang | d1057c8 | 2019-05-21 15:26:44 +0800 | [diff] [blame] | 39 | |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 40 | import java.nio.ByteBuffer; |
| 41 | import java.util.ArrayList; |
Scott Nien | 73f4d38 | 2023-11-30 22:30:08 +0800 | [diff] [blame] | 42 | import java.util.Collections; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 43 | import java.util.List; |
| 44 | import java.util.Map; |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 45 | import java.util.concurrent.Executor; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 46 | import java.util.concurrent.TimeUnit; |
| 47 | |
| 48 | /** |
| 49 | * Implementation for HDR image capture use case. |
| 50 | * |
| 51 | * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers |
| 52 | * don't need to implement this, unless this is used for related testing usage. |
Franklin Wu | 99529cb | 2019-10-07 11:35:44 -0700 | [diff] [blame] | 53 | * |
| 54 | * @since 1.0 |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 55 | */ |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 56 | @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 57 | @SuppressLint("UnknownNullness") |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 58 | public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { |
| 59 | private static final String TAG = "HdrImageCaptureExtender"; |
| 60 | private static final int UNDER_STAGE_ID = 0; |
| 61 | private static final int NORMAL_STAGE_ID = 1; |
| 62 | private static final int OVER_STAGE_ID = 2; |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 63 | private static final int SESSION_STAGE_ID = 101; |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 64 | private static final long UNDER_EXPOSURE_TIME = TimeUnit.MILLISECONDS.toNanos(8); |
| 65 | private static final long NORMAL_EXPOSURE_TIME = TimeUnit.MILLISECONDS.toNanos(16); |
| 66 | private static final long OVER_EXPOSURE_TIME = TimeUnit.MILLISECONDS.toNanos(32); |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 67 | private HdrImageCaptureExtenderCaptureProcessorImpl mCaptureProcessor = null; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 68 | |
| 69 | public HdrImageCaptureExtenderImpl() { |
| 70 | } |
| 71 | |
| 72 | @Override |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 73 | public void init(@NonNull String cameraId, |
| 74 | @NonNull CameraCharacteristics cameraCharacteristics) { |
Franklin Wu | db1062c | 2019-04-23 18:22:35 -0700 | [diff] [blame] | 75 | } |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 76 | |
| 77 | @Override |
TY Chang | d1057c8 | 2019-05-21 15:26:44 +0800 | [diff] [blame] | 78 | public boolean isExtensionAvailable(@NonNull String cameraId, |
| 79 | @Nullable CameraCharacteristics cameraCharacteristics) { |
Charcoal Chen | 2f4582e | 2022-11-24 15:20:25 +0800 | [diff] [blame] | 80 | // Return false to skip tests since old devices do not support extensions. |
| 81 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 82 | return false; |
| 83 | } |
| 84 | |
| 85 | if (cameraCharacteristics == null) { |
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | Range<Long> exposureTimeRange = |
| 90 | cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); |
| 91 | |
| 92 | if (exposureTimeRange == null || !exposureTimeRange.contains( |
| 93 | Range.create(UNDER_EXPOSURE_TIME, OVER_EXPOSURE_TIME))) { |
| 94 | return false; |
| 95 | } |
| 96 | |
| 97 | // The device needs to support CONTROL_AE_MODE_OFF for the testing CaptureStages |
| 98 | int[] availableAeModes = |
| 99 | cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES); |
| 100 | |
| 101 | if (availableAeModes != null) { |
| 102 | for (int mode : availableAeModes) { |
| 103 | if (mode == CONTROL_AE_MODE_OFF) { |
| 104 | return true; |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | return false; |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 110 | } |
| 111 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 112 | @NonNull |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 113 | @Override |
| 114 | public List<CaptureStageImpl> getCaptureStages() { |
| 115 | // Under exposed capture stage |
| 116 | SettableCaptureStage captureStageUnder = new SettableCaptureStage(UNDER_STAGE_ID); |
| 117 | // Turn off AE so that ISO sensitivity can be controlled |
| 118 | captureStageUnder.addCaptureRequestParameters(CaptureRequest.CONTROL_AE_MODE, |
| 119 | CaptureRequest.CONTROL_AE_MODE_OFF); |
| 120 | captureStageUnder.addCaptureRequestParameters(CaptureRequest.SENSOR_EXPOSURE_TIME, |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 121 | UNDER_EXPOSURE_TIME); |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 122 | |
| 123 | // Normal exposed capture stage |
| 124 | SettableCaptureStage captureStageNormal = new SettableCaptureStage(NORMAL_STAGE_ID); |
| 125 | captureStageNormal.addCaptureRequestParameters(CaptureRequest.SENSOR_EXPOSURE_TIME, |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 126 | NORMAL_EXPOSURE_TIME); |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 127 | |
| 128 | // Over exposed capture stage |
| 129 | SettableCaptureStage captureStageOver = new SettableCaptureStage(OVER_STAGE_ID); |
| 130 | captureStageOver.addCaptureRequestParameters(CaptureRequest.SENSOR_EXPOSURE_TIME, |
charcoalchen | eec786f5 | 2021-08-20 09:19:40 +0800 | [diff] [blame] | 131 | OVER_EXPOSURE_TIME); |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 132 | |
| 133 | List<CaptureStageImpl> captureStages = new ArrayList<>(); |
| 134 | captureStages.add(captureStageUnder); |
| 135 | captureStages.add(captureStageNormal); |
| 136 | captureStages.add(captureStageOver); |
| 137 | return captureStages; |
| 138 | } |
| 139 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 140 | |
| 141 | @Nullable |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 142 | @Override |
| 143 | public CaptureProcessorImpl getCaptureProcessor() { |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 144 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 145 | mCaptureProcessor = new HdrImageCaptureExtenderCaptureProcessorImpl(); |
| 146 | return mCaptureProcessor; |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 147 | } else { |
| 148 | return new NoOpCaptureProcessorImpl(); |
| 149 | } |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 150 | } |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 151 | |
| 152 | @Override |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 153 | public void onInit(@NonNull String cameraId, |
| 154 | @NonNull CameraCharacteristics cameraCharacteristics, |
| 155 | @NonNull Context context) { |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 156 | } |
| 157 | |
| 158 | @Override |
| 159 | public void onDeInit() { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 160 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && mCaptureProcessor != null) { |
| 161 | mCaptureProcessor.release(); |
| 162 | } |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 163 | } |
| 164 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 165 | @Nullable |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 166 | @Override |
| 167 | public CaptureStageImpl onPresetSession() { |
Charcoal Chen | 43a574e | 2021-03-19 14:27:05 +0800 | [diff] [blame] | 168 | // The CaptureRequest parameters will be set via SessionConfiguration#setSessionParameters |
| 169 | // (CaptureRequest) which only supported from API level 28. |
| 170 | if (Build.VERSION.SDK_INT < 28) { |
| 171 | return null; |
| 172 | } |
| 173 | |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 174 | SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID); |
| 175 | return captureStage; |
| 176 | } |
| 177 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 178 | @Nullable |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 179 | @Override |
| 180 | public CaptureStageImpl onEnableSession() { |
| 181 | SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID); |
| 182 | return captureStage; |
| 183 | } |
| 184 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 185 | @Nullable |
WenHung_Teng | 6a22abb | 2019-04-30 16:57:34 +0800 | [diff] [blame] | 186 | @Override |
| 187 | public CaptureStageImpl onDisableSession() { |
| 188 | SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID); |
| 189 | return captureStage; |
| 190 | } |
| 191 | |
| 192 | @Override |
| 193 | public int getMaxCaptureStage() { |
| 194 | return 4; |
| 195 | } |
| 196 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 197 | @Nullable |
charcoalchen | 9429b07 | 2019-08-21 10:48:46 +0800 | [diff] [blame] | 198 | @Override |
| 199 | public List<Pair<Integer, Size[]>> getSupportedResolutions() { |
| 200 | return null; |
| 201 | } |
| 202 | |
Charcoal Chen | 4eeaeb2 | 2021-04-14 10:28:52 +0800 | [diff] [blame] | 203 | @Nullable |
| 204 | @Override |
| 205 | public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { |
| 206 | return new Range<>(300L, 1000L); |
| 207 | } |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 208 | |
| 209 | @RequiresApi(23) |
| 210 | static final class HdrImageCaptureExtenderCaptureProcessorImpl implements CaptureProcessorImpl { |
| 211 | private ImageWriter mImageWriter; |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 212 | @Override |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 213 | public void onOutputSurface(@NonNull Surface surface, int imageFormat) { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 214 | mImageWriter = ImageWriter.newInstance(surface, 2); |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 215 | } |
| 216 | |
| 217 | @Override |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 218 | public void process(@NonNull Map<Integer, Pair<Image, TotalCaptureResult>> results) { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 219 | process(results, null, null); |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | @Override |
| 223 | public void process(@NonNull Map<Integer, Pair<Image, TotalCaptureResult>> results, |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 224 | @Nullable ProcessResultImpl resultCallback, @Nullable Executor executor) { |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 225 | Log.d(TAG, "Started HDR CaptureProcessor"); |
| 226 | |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 227 | Executor executorForCallback = executor != null ? executor : (cmd) -> cmd.run(); |
| 228 | |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 229 | // Check for availability of all requested images |
| 230 | if (!results.containsKey(UNDER_STAGE_ID)) { |
| 231 | Log.w(TAG, |
| 232 | "Unable to process since images does not contain " |
| 233 | + "underexposed image."); |
| 234 | return; |
| 235 | } |
| 236 | |
| 237 | if (!results.containsKey(NORMAL_STAGE_ID)) { |
| 238 | Log.w(TAG, |
| 239 | "Unable to process since images does not contain normal " |
| 240 | + "exposed image."); |
| 241 | return; |
| 242 | } |
| 243 | |
| 244 | if (!results.containsKey(OVER_STAGE_ID)) { |
| 245 | Log.w(TAG, |
| 246 | "Unable to process since images does not contain " |
| 247 | + "overexposed image."); |
| 248 | return; |
| 249 | } |
| 250 | |
| 251 | // Do processing of images, our placeholder logic just copies the first |
| 252 | // Image into the output buffer. |
| 253 | List<Pair<Image, TotalCaptureResult>> imageDataPairs = new ArrayList<>( |
| 254 | results.values()); |
| 255 | Image outputImage = mImageWriter.dequeueInputImage(); |
| 256 | |
| 257 | // Do processing here |
| 258 | // The sample here simply returns the normal image result |
| 259 | Image normalImage = imageDataPairs.get(NORMAL_STAGE_ID).first; |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 260 | if (outputImage.getWidth() != normalImage.getWidth() |
| 261 | || outputImage.getHeight() != normalImage.getHeight()) { |
| 262 | throw new IllegalStateException(String.format("input image " |
| 263 | + "resolution [%d, %d] not the same as the " |
| 264 | + "output image[%d, %d]", normalImage.getWidth(), |
| 265 | normalImage.getHeight(), outputImage.getWidth(), |
| 266 | outputImage.getHeight())); |
| 267 | } |
| 268 | |
| 269 | try { |
| 270 | // copy y plane |
| 271 | Image.Plane inYPlane = normalImage.getPlanes()[0]; |
| 272 | Image.Plane outYPlane = outputImage.getPlanes()[0]; |
| 273 | ByteBuffer inYBuffer = inYPlane.getBuffer(); |
| 274 | ByteBuffer outYBuffer = outYPlane.getBuffer(); |
| 275 | int inYPixelStride = inYPlane.getPixelStride(); |
| 276 | int inYRowStride = inYPlane.getRowStride(); |
| 277 | int outYPixelStride = outYPlane.getPixelStride(); |
| 278 | int outYRowStride = outYPlane.getRowStride(); |
| 279 | for (int x = 0; x < outputImage.getHeight(); x++) { |
| 280 | for (int y = 0; y < outputImage.getWidth(); y++) { |
| 281 | int inIndex = x * inYRowStride + y * inYPixelStride; |
| 282 | int outIndex = x * outYRowStride + y * outYPixelStride; |
| 283 | outYBuffer.put(outIndex, inYBuffer.get(inIndex)); |
| 284 | } |
| 285 | } |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 286 | // Copy UV |
| 287 | for (int i = 1; i < 3; i++) { |
| 288 | Image.Plane inPlane = normalImage.getPlanes()[i]; |
| 289 | Image.Plane outPlane = outputImage.getPlanes()[i]; |
| 290 | ByteBuffer inBuffer = inPlane.getBuffer(); |
| 291 | ByteBuffer outBuffer = outPlane.getBuffer(); |
| 292 | int inPixelStride = inPlane.getPixelStride(); |
| 293 | int inRowStride = inPlane.getRowStride(); |
| 294 | int outPixelStride = outPlane.getPixelStride(); |
| 295 | int outRowStride = outPlane.getRowStride(); |
| 296 | // UV are half width compared to Y |
| 297 | for (int x = 0; x < outputImage.getHeight() / 2; x++) { |
| 298 | for (int y = 0; y < outputImage.getWidth() / 2; y++) { |
| 299 | int inIndex = x * inRowStride + y * inPixelStride; |
| 300 | int outIndex = x * outRowStride + y * outPixelStride; |
| 301 | byte b = inBuffer.get(inIndex); |
| 302 | outBuffer.put(outIndex, b); |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | } catch (IllegalStateException e) { |
| 307 | Log.e(TAG, "Error accessing the Image: " + e); |
| 308 | // Since something went wrong, don't try to queue up the image. |
| 309 | // Instead let the Image writing get dropped. |
| 310 | return; |
| 311 | } |
| 312 | |
| 313 | mImageWriter.queueInputImage(outputImage); |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 314 | |
| 315 | TotalCaptureResult captureResult = results.get(NORMAL_STAGE_ID).second; |
| 316 | |
| 317 | if (resultCallback != null) { |
| 318 | executorForCallback.execute( |
| 319 | () -> resultCallback.onCaptureCompleted( |
| 320 | captureResult.get(CaptureResult.SENSOR_TIMESTAMP), |
| 321 | getFilteredResults(captureResult))); |
| 322 | } |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 323 | |
| 324 | Log.d(TAG, "Completed HDR CaptureProcessor"); |
| 325 | } |
| 326 | |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 327 | @SuppressWarnings("unchecked") |
| 328 | private List<Pair<CaptureResult.Key, Object>> getFilteredResults( |
| 329 | TotalCaptureResult captureResult) { |
| 330 | List<Pair<CaptureResult.Key, Object>> list = new ArrayList<>(); |
| 331 | for (CaptureResult.Key key : captureResult.getKeys()) { |
| 332 | list.add(new Pair<>(key, captureResult.get(key))); |
| 333 | } |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 334 | |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 335 | return list; |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 336 | } |
| 337 | |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 338 | |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 339 | @Override |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 340 | public void onResolutionUpdate(@NonNull Size size) { |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 341 | |
| 342 | } |
| 343 | |
| 344 | @Override |
| 345 | public void onImageFormatUpdate(int imageFormat) { |
| 346 | |
| 347 | } |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 348 | |
| 349 | @Override |
| 350 | public void onPostviewOutputSurface(@NonNull Surface surface) { |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 351 | } |
| 352 | |
| 353 | @Override |
| 354 | public void onResolutionUpdate(@NonNull Size size, @NonNull Size postviewSize) { |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 355 | onResolutionUpdate(size); |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 356 | } |
| 357 | |
| 358 | @Override |
| 359 | public void processWithPostview( |
| 360 | @NonNull Map<Integer, Pair<Image, TotalCaptureResult>> results, |
| 361 | @NonNull ProcessResultImpl resultCallback, @Nullable Executor executor) { |
Scott Nien | 1b14822 | 2023-08-31 17:31:40 +0800 | [diff] [blame] | 362 | Log.d(TAG, "processWithPostview"); |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 363 | process(results, resultCallback, executor); |
| 364 | } |
| 365 | |
| 366 | public void release() { |
| 367 | if (mImageWriter != null) { |
| 368 | mImageWriter.close(); |
| 369 | } |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 370 | } |
Trevor McGuire | e0327b2 | 2021-09-22 22:59:57 -0700 | [diff] [blame] | 371 | } |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 372 | |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 373 | @NonNull |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 374 | @Override |
| 375 | public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { |
| 376 | return null; |
| 377 | } |
| 378 | |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 379 | @Override |
| 380 | public int onSessionType() { |
| 381 | return SessionConfiguration.SESSION_REGULAR; |
| 382 | } |
| 383 | |
| 384 | @Nullable |
| 385 | @Override |
| 386 | public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(@NonNull Size captureSize) { |
Scott Nien | 73f4d38 | 2023-11-30 22:30:08 +0800 | [diff] [blame] | 387 | return Collections.emptyList(); |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 388 | } |
| 389 | |
| 390 | @Override |
| 391 | public boolean isCaptureProcessProgressAvailable() { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 392 | return false; |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 393 | } |
| 394 | |
| 395 | @Nullable |
| 396 | @Override |
| 397 | public Pair<Long, Long> getRealtimeCaptureLatency() { |
| 398 | return null; |
| 399 | } |
| 400 | |
| 401 | @Override |
| 402 | public boolean isPostviewAvailable() { |
Scott Nien | c849f2a | 2023-10-27 14:39:56 +0800 | [diff] [blame] | 403 | return false; |
Scott Nien | 76a0ba3 | 2023-08-11 16:10:22 +0800 | [diff] [blame] | 404 | } |
| 405 | |
Alan Viverette | 40eb907 | 2022-06-22 14:24:52 -0400 | [diff] [blame] | 406 | @NonNull |
Scott Nien | b44f077 | 2022-05-01 10:28:56 +0800 | [diff] [blame] | 407 | @Override |
| 408 | public List<CaptureResult.Key> getAvailableCaptureResultKeys() { |
| 409 | return null; |
| 410 | } |
Franklin Wu | 30c76f6 | 2019-04-15 16:03:23 -0700 | [diff] [blame] | 411 | } |