1 /* 2 * Copyright 2023 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 17 package androidx.camera.core; 18 19 import org.jspecify.annotations.NonNull; 20 21 import java.util.Objects; 22 23 /** 24 * An immutable representation of the estimated duration an image capture will take 25 * capturing and processing the current scene according to the scene's lighting condition and/or 26 * camera configuration. 27 * 28 * <p>The latency estimate is produced by {@link ImageCapture#getRealtimeCaptureLatencyEstimate()}. 29 * 30 * <p>The estimate is comprised of two components: {@link #getCaptureLatencyMillis()}, 31 * {@link #getProcessingLatencyMillis()}. 32 */ 33 public class ImageCaptureLatencyEstimate { 34 /** The capture latency is unsupported or undefined */ 35 public static final long UNDEFINED_CAPTURE_LATENCY = -1; 36 37 /** The processing latency is unsupported or undefined */ 38 public static final long UNDEFINED_PROCESSING_LATENCY = -1; 39 40 /** The image capture latency estimate is unsupported or undefined */ 41 public static final @NonNull ImageCaptureLatencyEstimate UNDEFINED_IMAGE_CAPTURE_LATENCY = 42 new ImageCaptureLatencyEstimate(UNDEFINED_CAPTURE_LATENCY, 43 UNDEFINED_PROCESSING_LATENCY); 44 45 private final long mCaptureLatencyMillis; 46 private final long mProcessingLatencyMillis; 47 private final long mTotalCaptureLatencyMillis; 48 49 /** 50 * Created by {@link ImageCapture#getRealtimeCaptureLatencyEstimate()} when querying for the 51 * current realtime latency estimate. This can also be used for testing. It is not necessary to 52 * explicitly construct this in any other scenario. 53 * 54 * @param captureLatencyMillis The estimated duration in milliseconds from when the camera 55 * begins capturing frames to the moment the camera has completed 56 * capturing frames. 57 * @param processingLatencyMillis The estimated duration in milliseconds from when the 58 * processing begins until the processing has completed and the 59 * final processed capture is available. 60 */ ImageCaptureLatencyEstimate(long captureLatencyMillis, long processingLatencyMillis)61 public ImageCaptureLatencyEstimate(long captureLatencyMillis, long processingLatencyMillis) { 62 mCaptureLatencyMillis = captureLatencyMillis; 63 mProcessingLatencyMillis = processingLatencyMillis; 64 mTotalCaptureLatencyMillis = computeTotalCaptureLatencyMillis(captureLatencyMillis, 65 processingLatencyMillis); 66 } 67 68 /** 69 * Returns the estimated duration in milliseconds from when the camera begins capturing 70 * frames to the moment the camera has completed capturing frames. If this estimate is not 71 * supported or not available then it will be {@link #UNDEFINED_CAPTURE_LATENCY}. 72 */ getCaptureLatencyMillis()73 public long getCaptureLatencyMillis() { 74 return mCaptureLatencyMillis; 75 } 76 77 /** 78 * Returns the estimated duration in milliseconds from when the processing begins until the 79 * processing has completed and the final processed capture is available. If this estimate is 80 * not supported or not available then it will be {@link #UNDEFINED_PROCESSING_LATENCY}. 81 */ getProcessingLatencyMillis()82 public long getProcessingLatencyMillis() { 83 return mProcessingLatencyMillis; 84 } 85 86 /** 87 * Returns the total estimated capture duration in milliseconds. This includes time spent in 88 * capturing and processing. 89 * 90 * <p>If either the capture latency or processing latency is undefined then the total estimate 91 * is {@link #UNDEFINED_CAPTURE_LATENCY}. 92 */ getTotalCaptureLatencyMillis()93 public long getTotalCaptureLatencyMillis() { 94 return mTotalCaptureLatencyMillis; 95 } 96 97 @Override equals(Object o)98 public boolean equals(Object o) { 99 if (this == o) return true; 100 if (!(o instanceof ImageCaptureLatencyEstimate)) return false; 101 ImageCaptureLatencyEstimate that = (ImageCaptureLatencyEstimate) o; 102 return mCaptureLatencyMillis == that.getCaptureLatencyMillis() 103 && mProcessingLatencyMillis == that.getProcessingLatencyMillis() 104 && mTotalCaptureLatencyMillis == that.getTotalCaptureLatencyMillis(); 105 } 106 107 @Override hashCode()108 public int hashCode() { 109 return Objects.hash(mCaptureLatencyMillis, mProcessingLatencyMillis, 110 mTotalCaptureLatencyMillis); 111 } 112 113 @Override toString()114 public @NonNull String toString() { 115 return "captureLatencyMillis=" + mCaptureLatencyMillis 116 + ", processingLatencyMillis=" + mProcessingLatencyMillis 117 + ", totalCaptureLatencyMillis=" + mTotalCaptureLatencyMillis; 118 } 119 computeTotalCaptureLatencyMillis(long captureLatencyMillis, long processingLatencyMillis)120 private long computeTotalCaptureLatencyMillis(long captureLatencyMillis, 121 long processingLatencyMillis) { 122 if (captureLatencyMillis == UNDEFINED_PROCESSING_LATENCY 123 || processingLatencyMillis == UNDEFINED_CAPTURE_LATENCY) { 124 return UNDEFINED_CAPTURE_LATENCY; 125 } 126 return captureLatencyMillis + processingLatencyMillis; 127 } 128 } 129