blob: 476c3debc571ce9cd8bfcbedcb27f71b7d88a248 [file] [log] [blame]
Ruben Brunkfeb50af2014-05-09 19:58:49 -07001/*
2 * Copyright (C) 2014 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
17package android.hardware.camera2.legacy;
18
19import android.hardware.camera2.CaptureRequest;
Ruben Brunkef14da32014-06-24 16:06:54 -070020import android.util.Log;
Ruben Brunkfeb50af2014-05-09 19:58:49 -070021import android.view.Surface;
22
23import java.util.Collection;
24
Ruben Brunkd1f113d2014-07-11 11:46:20 -070025import static com.android.internal.util.Preconditions.*;
26
Ruben Brunkfeb50af2014-05-09 19:58:49 -070027/**
Ruben Brunke663cb772014-09-16 13:18:31 -070028 * Semi-immutable container for a single capture request and associated information,
29 * the only mutable characteristic of this container is whether or not is has been
30 * marked as "failed" using {@code #failRequest}.
Ruben Brunkfeb50af2014-05-09 19:58:49 -070031 */
32public class RequestHolder {
Ruben Brunkef14da32014-06-24 16:06:54 -070033 private static final String TAG = "RequestHolder";
Ruben Brunkfeb50af2014-05-09 19:58:49 -070034
35 private final boolean mRepeating;
36 private final CaptureRequest mRequest;
37 private final int mRequestId;
38 private final int mSubsequeceId;
39 private final long mFrameNumber;
Ruben Brunke663cb772014-09-16 13:18:31 -070040 private final int mNumJpegTargets;
41 private final int mNumPreviewTargets;
42 private volatile boolean mFailed = false;
Ruben Brunkfeb50af2014-05-09 19:58:49 -070043
Eino-Ville Talvala385f9e22016-03-31 16:47:14 -070044 private final Collection<Long> mJpegSurfaceIds;
45
Ruben Brunkd1f113d2014-07-11 11:46:20 -070046 /**
Ruben Brunkd1f113d2014-07-11 11:46:20 -070047 * A builder class for {@link RequestHolder} objects.
48 *
49 * <p>
50 * This allows per-request queries to be cached for repeating {@link CaptureRequest} objects.
51 * </p>
52 */
53 public final static class Builder {
54 private final int mRequestId;
55 private final int mSubsequenceId;
56 private final CaptureRequest mRequest;
57 private final boolean mRepeating;
Ruben Brunke663cb772014-09-16 13:18:31 -070058 private final int mNumJpegTargets;
59 private final int mNumPreviewTargets;
Ruben Brunk0fd198a2014-09-23 23:35:43 -070060 private final Collection<Long> mJpegSurfaceIds;
Ruben Brunkd1f113d2014-07-11 11:46:20 -070061
62 /**
63 * Construct a new {@link Builder} to generate {@link RequestHolder} objects.
64 *
65 * @param requestId the ID to set in {@link RequestHolder} objects.
66 * @param subsequenceId the sequence ID to set in {@link RequestHolder} objects.
67 * @param request the original {@link CaptureRequest} to set in {@link RequestHolder}
68 * objects.
69 * @param repeating {@code true} if the request is repeating.
70 */
71 public Builder(int requestId, int subsequenceId, CaptureRequest request,
Ruben Brunk0fd198a2014-09-23 23:35:43 -070072 boolean repeating, Collection<Long> jpegSurfaceIds) {
Ruben Brunkd1f113d2014-07-11 11:46:20 -070073 checkNotNull(request, "request must not be null");
74 mRequestId = requestId;
75 mSubsequenceId = subsequenceId;
76 mRequest = request;
77 mRepeating = repeating;
Ruben Brunk0fd198a2014-09-23 23:35:43 -070078 mJpegSurfaceIds = jpegSurfaceIds;
Ruben Brunke663cb772014-09-16 13:18:31 -070079 mNumJpegTargets = numJpegTargets(mRequest);
80 mNumPreviewTargets = numPreviewTargets(mRequest);
Ruben Brunkd1f113d2014-07-11 11:46:20 -070081 }
82
83 /**
Ruben Brunk0fd198a2014-09-23 23:35:43 -070084 * Returns true if the given surface requires jpeg buffers.
85 *
86 * @param s a {@link android.view.Surface} to check.
87 * @return true if the surface requires a jpeg buffer.
88 */
89 private boolean jpegType(Surface s)
90 throws LegacyExceptionUtils.BufferQueueAbandonedException {
91 return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
92 }
93
94 /**
95 * Returns true if the given surface requires non-jpeg buffer types.
96 *
97 * <p>
98 * "Jpeg buffer" refers to the buffers returned in the jpeg
99 * {@link android.hardware.Camera.PictureCallback}. Non-jpeg buffers are created using a tee
100 * of the preview stream drawn to the surface
101 * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
102 * equivalent methods.
103 * </p>
104 * @param s a {@link android.view.Surface} to check.
105 * @return true if the surface requires a non-jpeg buffer type.
106 */
107 private boolean previewType(Surface s)
108 throws LegacyExceptionUtils.BufferQueueAbandonedException {
109 return !jpegType(s);
110 }
111
112 /**
113 * Returns the number of surfaces targeted by the request that require jpeg buffers.
114 */
115 private int numJpegTargets(CaptureRequest request) {
116 int count = 0;
117 for (Surface s : request.getTargets()) {
118 try {
119 if (jpegType(s)) {
120 ++count;
121 }
122 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
123 Log.d(TAG, "Surface abandoned, skipping...", e);
124 }
125 }
126 return count;
127 }
128
129 /**
130 * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
131 */
132 private int numPreviewTargets(CaptureRequest request) {
133 int count = 0;
134 for (Surface s : request.getTargets()) {
135 try {
136 if (previewType(s)) {
137 ++count;
138 }
139 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
140 Log.d(TAG, "Surface abandoned, skipping...", e);
141 }
142 }
143 return count;
144 }
145
146 /**
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700147 * Build a new {@link RequestHolder} using with parameters generated from this
148 * {@link Builder}.
149 *
150 * @param frameNumber the {@code framenumber} to generate in the {@link RequestHolder}.
151 * @return a {@link RequestHolder} constructed with the {@link Builder}'s parameters.
152 */
153 public RequestHolder build(long frameNumber) {
154 return new RequestHolder(mRequestId, mSubsequenceId, mRequest, mRepeating, frameNumber,
Eino-Ville Talvala385f9e22016-03-31 16:47:14 -0700155 mNumJpegTargets, mNumPreviewTargets, mJpegSurfaceIds);
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700156 }
157 }
158
159 private RequestHolder(int requestId, int subsequenceId, CaptureRequest request,
Ruben Brunke663cb772014-09-16 13:18:31 -0700160 boolean repeating, long frameNumber, int numJpegTargets,
Eino-Ville Talvala385f9e22016-03-31 16:47:14 -0700161 int numPreviewTargets, Collection<Long> jpegSurfaceIds) {
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700162 mRepeating = repeating;
163 mRequest = request;
164 mRequestId = requestId;
165 mSubsequeceId = subsequenceId;
166 mFrameNumber = frameNumber;
Ruben Brunke663cb772014-09-16 13:18:31 -0700167 mNumJpegTargets = numJpegTargets;
168 mNumPreviewTargets = numPreviewTargets;
Eino-Ville Talvala385f9e22016-03-31 16:47:14 -0700169 mJpegSurfaceIds = jpegSurfaceIds;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700170 }
171
172 /**
173 * Return the request id for the contained {@link CaptureRequest}.
174 */
175 public int getRequestId() {
176 return mRequestId;
177 }
178
179 /**
180 * Returns true if the contained request is repeating.
181 */
182 public boolean isRepeating() {
183 return mRepeating;
184 }
185
186 /**
187 * Return the subsequence id for this request.
188 */
189 public int getSubsequeceId() {
190 return mSubsequeceId;
191 }
192
193 /**
194 * Returns the frame number for this request.
195 */
196 public long getFrameNumber() {
197 return mFrameNumber;
198 }
199
200 /**
201 * Returns the contained request.
202 */
203 public CaptureRequest getRequest() {
204 return mRequest;
205 }
206
207 /**
208 * Returns a read-only collection of the surfaces targeted by the contained request.
209 */
210 public Collection<Surface> getHolderTargets() {
211 return getRequest().getTargets();
212 }
213
214 /**
215 * Returns true if any of the surfaces targeted by the contained request require jpeg buffers.
216 */
217 public boolean hasJpegTargets() {
Ruben Brunke663cb772014-09-16 13:18:31 -0700218 return mNumJpegTargets > 0;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700219 }
220
221 /**
222 * Returns true if any of the surfaces targeted by the contained request require a
223 * non-jpeg buffer type.
224 */
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700225 public boolean hasPreviewTargets(){
Ruben Brunke663cb772014-09-16 13:18:31 -0700226 return mNumPreviewTargets > 0;
227 }
228
229 /**
230 * Return the number of jpeg-type surfaces targeted by this request.
231 */
232 public int numJpegTargets() {
233 return mNumJpegTargets;
234 }
235
236 /**
237 * Return the number of non-jpeg-type surfaces targeted by this request.
238 */
239 public int numPreviewTargets() {
240 return mNumPreviewTargets;
241 }
242
243 /**
Eino-Ville Talvala385f9e22016-03-31 16:47:14 -0700244 * Returns true if the given surface requires jpeg buffers.
245 *
246 * @param s a {@link android.view.Surface} to check.
247 * @return true if the surface requires a jpeg buffer.
248 */
249 public boolean jpegType(Surface s)
250 throws LegacyExceptionUtils.BufferQueueAbandonedException {
251 return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
252 }
253
254 /**
Ruben Brunke663cb772014-09-16 13:18:31 -0700255 * Mark this request as failed.
256 */
257 public void failRequest() {
258 Log.w(TAG, "Capture failed for request: " + getRequestId());
259 mFailed = true;
260 }
261
262 /**
263 * Return {@code true} if this request failed.
264 */
265 public boolean requestFailed() {
266 return mFailed;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700267 }
268
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700269}