1 /*
2  * Copyright (C) 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 
17 package android.hardware.camera2.impl;
18 
19 import android.hardware.camera2.CameraCaptureSession;
20 import android.hardware.camera2.CaptureRequest;
21 import android.hardware.camera2.utils.SubmitInfo;
22 
23 import java.util.List;
24 
25 /**
26  * This class holds a capture ID and its expected last regular, zslStill, and reprocess
27  * frame number.
28  */
29 public class RequestLastFrameNumbersHolder {
30     // request ID
31     private final int mRequestId;
32     // The last regular frame number for this request ID. It's
33     // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no regular request.
34     private final long mLastRegularFrameNumber;
35     // The last reprocess frame number for this request ID. It's
36     // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no reprocess request.
37     private final long mLastReprocessFrameNumber;
38     // The last ZSL still capture frame number for this request ID. It's
39     // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no zsl request.
40     private final long mLastZslStillFrameNumber;
41     // Whether the sequence is completed. (only consider capture result)
42     private boolean mSequenceCompleted;
43     // Whether the inflight request is completed. (consider result, buffers, and notifies)
44     private boolean mInflightCompleted;
45 
46     /**
47      * Create a request-last-frame-numbers holder with a list of requests, request ID, and
48      * the last frame number returned by camera service.
49      */
RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo)50     public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo) {
51         long lastRegularFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
52         long lastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
53         long lastZslStillFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
54         long frameNumber = requestInfo.getLastFrameNumber();
55 
56         if (requestInfo.getLastFrameNumber() < requestList.size() - 1) {
57             throw new IllegalArgumentException(
58                     "lastFrameNumber: " + requestInfo.getLastFrameNumber() +
59                     " should be at least " + (requestList.size() - 1) + " for the number of " +
60                     " requests in the list: " + requestList.size());
61         }
62 
63         // find the last regular, zslStill, and reprocess frame number
64         for (int i = requestList.size() - 1; i >= 0; i--) {
65             CaptureRequest request = requestList.get(i);
66             int requestType = request.getRequestType();
67             if (requestType == CaptureRequest.REQUEST_TYPE_REPROCESS
68                     && lastReprocessFrameNumber ==
69                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
70                 lastReprocessFrameNumber = frameNumber;
71             } else if (requestType == CaptureRequest.REQUEST_TYPE_ZSL_STILL
72                     && lastZslStillFrameNumber ==
73                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
74                 lastZslStillFrameNumber = frameNumber;
75             } else if (requestType == CaptureRequest.REQUEST_TYPE_REGULAR
76                     && lastRegularFrameNumber ==
77                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
78                 lastRegularFrameNumber = frameNumber;
79             }
80 
81             if (lastReprocessFrameNumber != CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
82                     && lastZslStillFrameNumber !=
83                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
84                     && lastRegularFrameNumber !=
85                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
86                 break;
87             }
88 
89             frameNumber--;
90         }
91 
92         mLastRegularFrameNumber = lastRegularFrameNumber;
93         mLastReprocessFrameNumber = lastReprocessFrameNumber;
94         mLastZslStillFrameNumber = lastZslStillFrameNumber;
95         mRequestId = requestInfo.getRequestId();
96         mSequenceCompleted = false;
97         mInflightCompleted = false;
98     }
99 
100     /**
101      * Create a request-last-frame-numbers holder with a request ID and last regular/ZslStill
102      * frame number.
103      */
RequestLastFrameNumbersHolder(int requestId, long lastFrameNumber, int[] repeatingRequestTypes)104     RequestLastFrameNumbersHolder(int requestId, long lastFrameNumber,
105             int[] repeatingRequestTypes) {
106         long lastRegularFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
107         long lastZslStillFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
108 
109         if (repeatingRequestTypes == null) {
110             throw new IllegalArgumentException(
111                     "repeatingRequest list must not be null");
112         }
113         if (lastFrameNumber < repeatingRequestTypes.length - 1) {
114             throw new IllegalArgumentException(
115                     "lastFrameNumber: " + lastFrameNumber + " should be at least "
116                     + (repeatingRequestTypes.length - 1)
117                     + " for the number of requests in the list: "
118                     + repeatingRequestTypes.length);
119         }
120 
121         long frameNumber = lastFrameNumber;
122         for (int i = repeatingRequestTypes.length - 1; i >= 0; i--) {
123             if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_ZSL_STILL
124                     && lastZslStillFrameNumber ==
125                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
126                 lastZslStillFrameNumber = frameNumber;
127             } else if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_REGULAR
128                     && lastRegularFrameNumber ==
129                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
130                 lastRegularFrameNumber = frameNumber;
131             }
132 
133             if (lastZslStillFrameNumber != CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
134                     && lastRegularFrameNumber !=
135                     CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
136                 break;
137             }
138 
139             frameNumber--;
140         }
141 
142         mLastRegularFrameNumber = lastRegularFrameNumber;
143         mLastZslStillFrameNumber = lastZslStillFrameNumber;
144         mLastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
145         mRequestId = requestId;
146         mSequenceCompleted = false;
147         mInflightCompleted = false;
148     }
149 
150     /**
151      * Return the last regular frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
152      * it contains no regular request.
153      */
getLastRegularFrameNumber()154     public long getLastRegularFrameNumber() {
155         return mLastRegularFrameNumber;
156     }
157 
158     /**
159      * Return the last reprocess frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
160      * it contains no reprocess request.
161      */
getLastReprocessFrameNumber()162     public long getLastReprocessFrameNumber() {
163         return mLastReprocessFrameNumber;
164     }
165 
166     /**
167      * Return the last ZslStill frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
168      * it contains no Zsl request.
169      */
getLastZslStillFrameNumber()170     public long getLastZslStillFrameNumber() {
171         return mLastZslStillFrameNumber;
172     }
173 
174     /**
175      * Return the last frame number overall.
176      */
getLastFrameNumber()177     public long getLastFrameNumber() {
178         return Math.max(mLastZslStillFrameNumber,
179                 Math.max(mLastRegularFrameNumber, mLastReprocessFrameNumber));
180     }
181 
182     /**
183      * Return the request ID.
184      */
getRequestId()185     public int getRequestId() {
186         return mRequestId;
187     }
188 
189     /**
190      * Return whether the capture sequence is completed.
191      */
isSequenceCompleted()192     public boolean isSequenceCompleted() {
193         return mSequenceCompleted;
194     }
195 
196     /**
197      * Mark the capture sequence as completed.
198      */
markSequenceCompleted()199     public void markSequenceCompleted() {
200         mSequenceCompleted = true;
201     }
202 
203     /**
204      * Return whether the inflight capture is completed.
205      */
isInflightCompleted()206     public boolean isInflightCompleted() {
207         return mInflightCompleted;
208     }
209 
210     /**
211      * Mark the inflight capture as completed.
212      */
markInflightCompleted()213     public void markInflightCompleted() {
214         mInflightCompleted = true;
215     }
216 
217 }
218 
219