blob: 9b628fb72490a7d2b613614f54f78798d2f00924 [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
Ruben Brunkd1f113d2014-07-11 11:46:20 -070044 /**
Ruben Brunkd1f113d2014-07-11 11:46:20 -070045 * A builder class for {@link RequestHolder} objects.
46 *
47 * <p>
48 * This allows per-request queries to be cached for repeating {@link CaptureRequest} objects.
49 * </p>
50 */
51 public final static class Builder {
52 private final int mRequestId;
53 private final int mSubsequenceId;
54 private final CaptureRequest mRequest;
55 private final boolean mRepeating;
Ruben Brunke663cb772014-09-16 13:18:31 -070056 private final int mNumJpegTargets;
57 private final int mNumPreviewTargets;
Ruben Brunk0fd198a2014-09-23 23:35:43 -070058 private final Collection<Long> mJpegSurfaceIds;
Ruben Brunkd1f113d2014-07-11 11:46:20 -070059
60 /**
61 * Construct a new {@link Builder} to generate {@link RequestHolder} objects.
62 *
63 * @param requestId the ID to set in {@link RequestHolder} objects.
64 * @param subsequenceId the sequence ID to set in {@link RequestHolder} objects.
65 * @param request the original {@link CaptureRequest} to set in {@link RequestHolder}
66 * objects.
67 * @param repeating {@code true} if the request is repeating.
68 */
69 public Builder(int requestId, int subsequenceId, CaptureRequest request,
Ruben Brunk0fd198a2014-09-23 23:35:43 -070070 boolean repeating, Collection<Long> jpegSurfaceIds) {
Ruben Brunkd1f113d2014-07-11 11:46:20 -070071 checkNotNull(request, "request must not be null");
72 mRequestId = requestId;
73 mSubsequenceId = subsequenceId;
74 mRequest = request;
75 mRepeating = repeating;
Ruben Brunk0fd198a2014-09-23 23:35:43 -070076 mJpegSurfaceIds = jpegSurfaceIds;
Ruben Brunke663cb772014-09-16 13:18:31 -070077 mNumJpegTargets = numJpegTargets(mRequest);
78 mNumPreviewTargets = numPreviewTargets(mRequest);
Ruben Brunkd1f113d2014-07-11 11:46:20 -070079 }
80
81 /**
Ruben Brunk0fd198a2014-09-23 23:35:43 -070082 * Returns true if the given surface requires jpeg buffers.
83 *
84 * @param s a {@link android.view.Surface} to check.
85 * @return true if the surface requires a jpeg buffer.
86 */
87 private boolean jpegType(Surface s)
88 throws LegacyExceptionUtils.BufferQueueAbandonedException {
89 return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
90 }
91
92 /**
93 * Returns true if the given surface requires non-jpeg buffer types.
94 *
95 * <p>
96 * "Jpeg buffer" refers to the buffers returned in the jpeg
97 * {@link android.hardware.Camera.PictureCallback}. Non-jpeg buffers are created using a tee
98 * of the preview stream drawn to the surface
99 * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
100 * equivalent methods.
101 * </p>
102 * @param s a {@link android.view.Surface} to check.
103 * @return true if the surface requires a non-jpeg buffer type.
104 */
105 private boolean previewType(Surface s)
106 throws LegacyExceptionUtils.BufferQueueAbandonedException {
107 return !jpegType(s);
108 }
109
110 /**
111 * Returns the number of surfaces targeted by the request that require jpeg buffers.
112 */
113 private int numJpegTargets(CaptureRequest request) {
114 int count = 0;
115 for (Surface s : request.getTargets()) {
116 try {
117 if (jpegType(s)) {
118 ++count;
119 }
120 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
121 Log.d(TAG, "Surface abandoned, skipping...", e);
122 }
123 }
124 return count;
125 }
126
127 /**
128 * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
129 */
130 private int numPreviewTargets(CaptureRequest request) {
131 int count = 0;
132 for (Surface s : request.getTargets()) {
133 try {
134 if (previewType(s)) {
135 ++count;
136 }
137 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
138 Log.d(TAG, "Surface abandoned, skipping...", e);
139 }
140 }
141 return count;
142 }
143
144 /**
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700145 * Build a new {@link RequestHolder} using with parameters generated from this
146 * {@link Builder}.
147 *
148 * @param frameNumber the {@code framenumber} to generate in the {@link RequestHolder}.
149 * @return a {@link RequestHolder} constructed with the {@link Builder}'s parameters.
150 */
151 public RequestHolder build(long frameNumber) {
152 return new RequestHolder(mRequestId, mSubsequenceId, mRequest, mRepeating, frameNumber,
Ruben Brunke663cb772014-09-16 13:18:31 -0700153 mNumJpegTargets, mNumPreviewTargets);
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700154 }
155 }
156
157 private RequestHolder(int requestId, int subsequenceId, CaptureRequest request,
Ruben Brunke663cb772014-09-16 13:18:31 -0700158 boolean repeating, long frameNumber, int numJpegTargets,
159 int numPreviewTargets) {
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700160 mRepeating = repeating;
161 mRequest = request;
162 mRequestId = requestId;
163 mSubsequeceId = subsequenceId;
164 mFrameNumber = frameNumber;
Ruben Brunke663cb772014-09-16 13:18:31 -0700165 mNumJpegTargets = numJpegTargets;
166 mNumPreviewTargets = numPreviewTargets;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700167 }
168
169 /**
170 * Return the request id for the contained {@link CaptureRequest}.
171 */
172 public int getRequestId() {
173 return mRequestId;
174 }
175
176 /**
177 * Returns true if the contained request is repeating.
178 */
179 public boolean isRepeating() {
180 return mRepeating;
181 }
182
183 /**
184 * Return the subsequence id for this request.
185 */
186 public int getSubsequeceId() {
187 return mSubsequeceId;
188 }
189
190 /**
191 * Returns the frame number for this request.
192 */
193 public long getFrameNumber() {
194 return mFrameNumber;
195 }
196
197 /**
198 * Returns the contained request.
199 */
200 public CaptureRequest getRequest() {
201 return mRequest;
202 }
203
204 /**
205 * Returns a read-only collection of the surfaces targeted by the contained request.
206 */
207 public Collection<Surface> getHolderTargets() {
208 return getRequest().getTargets();
209 }
210
211 /**
212 * Returns true if any of the surfaces targeted by the contained request require jpeg buffers.
213 */
214 public boolean hasJpegTargets() {
Ruben Brunke663cb772014-09-16 13:18:31 -0700215 return mNumJpegTargets > 0;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700216 }
217
218 /**
219 * Returns true if any of the surfaces targeted by the contained request require a
220 * non-jpeg buffer type.
221 */
Ruben Brunkd1f113d2014-07-11 11:46:20 -0700222 public boolean hasPreviewTargets(){
Ruben Brunke663cb772014-09-16 13:18:31 -0700223 return mNumPreviewTargets > 0;
224 }
225
226 /**
227 * Return the number of jpeg-type surfaces targeted by this request.
228 */
229 public int numJpegTargets() {
230 return mNumJpegTargets;
231 }
232
233 /**
234 * Return the number of non-jpeg-type surfaces targeted by this request.
235 */
236 public int numPreviewTargets() {
237 return mNumPreviewTargets;
238 }
239
240 /**
241 * Mark this request as failed.
242 */
243 public void failRequest() {
244 Log.w(TAG, "Capture failed for request: " + getRequestId());
245 mFailed = true;
246 }
247
248 /**
249 * Return {@code true} if this request failed.
250 */
251 public boolean requestFailed() {
252 return mFailed;
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700253 }
254
Ruben Brunkfeb50af2014-05-09 19:58:49 -0700255}