summaryrefslogtreecommitdiff
path: root/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
blob: 8dbfadc2f70ee290db410d0c2c0569f5e9a79eda (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.camera.extensions.impl.advanced;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.util.Pair;
import android.view.Surface;

import java.util.Map;

/**
 * Interface for creating Camera2 CameraCaptureSessions with extension enabled based on
 * advanced vendor implementation.
 *
 * <p><pre>
 * The flow of a extension session is shown below:
 * (1) {@link #initSession}: CameraX prepares streams configuration for creating
 *     CameraCaptureSession. Output surfaces for Preview, ImageCapture and ImageAnalysis are passed
 *     in and vendor is responsible for outputting the results to these surfaces.
 *
 * (2) {@link #onCaptureSessionStart}: It is called after CameraCaptureSession is configured.
 *     A {@link RequestProcessorImpl} is passed for vendor to send repeating requests and
 *     single requests.
 *
 * (3) {@link #startRepeating}:  CameraX will call this method to start the repeating request
 *     after CameraCaptureSession is called. Vendor should start the repeating request by
 *     {@link RequestProcessorImpl}. Vendor can also update the repeating request if needed later.
 *
 * (4) {@link #setParameters(Map)}: The passed parameters will be attached to the repeating request
 *     and single requests but vendor can choose to apply some of them only.
 *
 * (5) {@link #startCapture(CaptureCallback)}: It is called when apps want to
 *     start a multi-frame image capture.  {@link CaptureCallback} will be called
 *     to report the status and the output image will be written to the capture output surface
 *     specified in {@link #initSession}.
 *
 * (5) {@link #onCaptureSessionEnd}: It is called right BEFORE CameraCaptureSession.close() is
 *     called.
 *
 * (6) {@link #deInitSession}: called when CameraCaptureSession is closed.
 * </pre>
 */
@SuppressLint("UnknownNullness")
public interface SessionProcessorImpl {
    /**
     * Initializes the session for the extension. This is where the OEMs allocate resources for
     * preparing a CameraCaptureSession. After initSession() is called, the camera ID,
     * cameraCharacteristics and context will not change until deInitSession() has been called.
     *
     * <p>CameraX / Camera2 specifies the output surface configurations for preview using
     * {@link OutputSurfaceConfigurationImpl#getPreviewOutputSurface}, image capture using
     * {@link OutputSurfaceConfigurationImpl#getImageCaptureOutputSurface}, and image analysis
     * [optional] using {@link OutputSurfaceConfigurationImpl#getImageAnalysisOutputSurface}.
     * And OEM returns a {@link Camera2SessionConfigImpl} which consists of a list of
     * {@link Camera2OutputConfigImpl} and session parameters. The {@link Camera2SessionConfigImpl}
     * will be used to configure the CameraCaptureSession.
     *
     * <p>OEM is responsible for outputting correct camera images output to these output surfaces.
     * OEM can have the following options to enable the output:
     * <pre>
     * (1) Add these output surfaces in CameraCaptureSession directly using
     * {@link Camera2OutputConfigImplBuilder#newSurfaceConfig(Surface)} }. Processing is done in
     * HAL.
     *
     * (2) Use surface sharing with other surface by calling
     * {@link Camera2OutputConfigImplBuilder#addSurfaceSharingOutputConfig(Camera2OutputConfigImpl)}
     * to add the output surface to the other {@link Camera2OutputConfigImpl}.
     *
     * (3) Process output from other surfaces (RAW, YUV..) and write the result to the output
     * surface. The output surface won't be contained in the returned
     * {@link Camera2SessionConfigImpl}.
     * </pre>
     *
     * <p>{@link Camera2OutputConfigImplBuilder} and {@link Camera2SessionConfigImplBuilder}
     * implementations are provided in the stub for OEM to construct the
     * {@link Camera2OutputConfigImpl} and {@link Camera2SessionConfigImpl} instances.
     *
     * @param surfaceConfigs contains output surfaces for preview, image capture, and an
     *                       optional output config for image analysis (YUV_420_888).
     * @return a {@link Camera2SessionConfigImpl} consisting of a list of
     * {@link Camera2OutputConfigImpl} and session parameters which will decide the
     * {@link android.hardware.camera2.params.SessionConfiguration} for configuring the
     * CameraCaptureSession. Please note that the OutputConfiguration list may not be part of any
     * supported or mandatory stream combination BUT OEM must ensure this list will always
     * produce a valid camera capture session.
     *
     * @since 1.4
     */
    Camera2SessionConfigImpl initSession(
            String cameraId,
            Map<String, CameraCharacteristics> cameraCharacteristicsMap,
            Context context,
            OutputSurfaceConfigurationImpl surfaceConfigs);

    /**
     * Initializes the session for the extension. This is where the OEMs allocate resources for
     * preparing a CameraCaptureSession. After initSession() is called, the camera ID,
     * cameraCharacteristics and context will not change until deInitSession() has been called.
     *
     * <p>CameraX / Camera2 specifies the output surface configurations for preview, image capture
     * and image analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which
     * consists of a list of {@link Camera2OutputConfigImpl} and session parameters. The
     * {@link Camera2SessionConfigImpl} will be used to configure the CameraCaptureSession.
     *
     * <p>OEM is responsible for outputting correct camera images output to these output surfaces.
     * OEM can have the following options to enable the output:
     * <pre>
     * (1) Add these output surfaces in CameraCaptureSession directly using
     * {@link Camera2OutputConfigImplBuilder#newSurfaceConfig(Surface)} }. Processing is done in
     * HAL.
     *
     * (2) Use surface sharing with other surface by calling
     * {@link Camera2OutputConfigImplBuilder#addSurfaceSharingOutputConfig(Camera2OutputConfigImpl)}
     * to add the output surface to the other {@link Camera2OutputConfigImpl}.
     *
     * (3) Process output from other surfaces (RAW, YUV..) and write the result to the output
     * surface. The output surface won't be contained in the returned
     * {@link Camera2SessionConfigImpl}.
     * </pre>
     *
     * <p>{@link Camera2OutputConfigImplBuilder} and {@link Camera2SessionConfigImplBuilder}
     * implementations are provided in the stub for OEM to construct the
     * {@link Camera2OutputConfigImpl} and {@link Camera2SessionConfigImpl} instances.
     *
     * @param previewSurfaceConfig       output surface for preview
     * @param imageCaptureSurfaceConfig  output surface for image capture.
     * @param imageAnalysisSurfaceConfig an optional output config for image analysis
     *                                   (YUV_420_888).
     * @return a {@link Camera2SessionConfigImpl} consisting of a list of
     * {@link Camera2OutputConfigImpl} and session parameters which will decide the
     * {@link android.hardware.camera2.params.SessionConfiguration} for configuring the
     * CameraCaptureSession. Please note that the OutputConfiguration list may not be part of any
     * supported or mandatory stream combination BUT OEM must ensure this list will always
     * produce a valid camera capture session.
     */
    Camera2SessionConfigImpl initSession(
            String cameraId,
            Map<String, CameraCharacteristics> cameraCharacteristicsMap,
            Context context,
            OutputSurfaceImpl previewSurfaceConfig,
            OutputSurfaceImpl imageCaptureSurfaceConfig,
            OutputSurfaceImpl imageAnalysisSurfaceConfig);

    /**
     * Notify to de-initialize the extension. This callback will be invoked after
     * CameraCaptureSession is closed. After onDeInit() was called, it is expected that the
     * camera ID, cameraCharacteristics will no longer hold and tear down any resources allocated
     * for this extension. Aborts all pending captures.
     */
    void deInitSession();

    /**
     * CameraX / Camera2 would call these API’s to pass parameters from the app to the OEM. It’s
     * expected that the OEM would (eventually) update the repeating request if the keys are
     * supported. Setting a value to null explicitly un-sets the value.
     */
    void setParameters(Map<CaptureRequest.Key<?>, Object> parameters);

    /**
     * CameraX / Camera2 will call this interface in response to client requests involving
     * the output preview surface. Typical examples include requests that include AF/AE triggers.
     * Extensions can disregard any capture request keys that were not advertised in
     * {@link AdvancedExtenderImpl#getAvailableCaptureRequestKeys}.
     *
     * @param triggers Capture request key value map.
     * @param callback a callback to report the status.
     * @return the id of the capture sequence.
     *
     * @throws IllegalArgumentException If there are no valid settings that can be applied
     *
     * @since 1.3
     */
    int startTrigger(Map<CaptureRequest.Key<?>, Object> triggers, CaptureCallback callback);

    /**
     * This will be invoked once after the {@link android.hardware.camera2.CameraCaptureSession}
     * has been created. {@link RequestProcessorImpl} is passed for OEM to submit single
     * requests or set repeating requests. This ExtensionRequestProcessor will be valid to use
     * until onCaptureSessionEnd is called.
     */
    void onCaptureSessionStart(RequestProcessorImpl requestProcessor);

    /**
     * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
     * closed. {@link RequestProcessorImpl} passed in onCaptureSessionStart will no longer
     * accept any requests after onCaptureSessionEnd() returns.
     */
    void onCaptureSessionEnd();

    /**
     * Starts the repeating request after CameraCaptureSession is called. Vendor should start the
     * repeating request by {@link RequestProcessorImpl}. Vendor can also update the
     * repeating request when needed later.
     *
     * @param callback a callback to report the status.
     * @return the id of the capture sequence.
     */
    int startRepeating(CaptureCallback callback);

    /**
     * Stop the repeating request. To prevent OEM from not calling stopRepeating, CameraX will
     * first stop the repeating request of current CameraCaptureSession and call this API to signal
     * OEM that the repeating request was stopped and going forward calling
     * {@link RequestProcessorImpl#setRepeating} will simply do nothing.
     */
    void stopRepeating();

    /**
     * Start a multi-frame capture with a postview. {@link #startCapture(CaptureCallback)}
     * will be used for captures without a postview request.
     *
     * Postview will be available before the capture. Upon postview completion,
     * {@code OnImageAvailableListener#onImageAvailable} will be called on the ImageReader
     * that creates the postview output surface. When the capture is completed,
     * {@link CaptureCallback#onCaptureSequenceCompleted} is called and
     * {@code OnImageAvailableListener#onImageAvailable} will also be called on the ImageReader
     * that creates the image capture output surface.
     *
     * <p>Only one capture can perform at a time. Starting a capture when another capture is
     * running will cause onCaptureFailed to be called immediately.
     *
     * @param callback a callback to report the status.
     * @return the id of the capture sequence.
     * @since 1.4
     */
    int startCaptureWithPostview(CaptureCallback callback);

    /**
     * Start a multi-frame capture.
     *
     * When the capture is completed, {@link CaptureCallback#onCaptureSequenceCompleted}
     * is called and {@code OnImageAvailableListener#onImageAvailable}
     * will also be called on the ImageReader that creates the image capture output surface.
     *
     * <p>Only one capture can perform at a time. Starting a capture when another capture is running
     * will cause onCaptureFailed to be called immediately.
     *
     * @param callback a callback to report the status.
     * @return the id of the capture sequence.
     */
    int startCapture(CaptureCallback callback);

    /**
     * Abort all capture tasks.
     */
    void abortCapture(int captureSequenceId);

    /**
     * Returns the dynamically calculated capture latency pair in milliseconds.
     *
     * <p>In contrast to {@link AdvancedExtenderImpl#getEstimatedCaptureLatencyRange} this method is
     * guaranteed to be called after {@link #onCaptureSessionStart}.
     * The measurement is expected to take in to account dynamic parameters such as the current
     * scene, the state of 3A algorithms, the state of internal HW modules and return a more
     * accurate assessment of the still capture latency.</p>
     *
     * @return pair that includes the estimated input frame/frames camera capture latency as the
     * first field. This is the time between {@link #onCaptureStarted} and
     * {@link #onCaptureProcessStarted}. The second field value includes the estimated
     * post-processing latency. This is the time between {@link #onCaptureProcessStarted} until
     * the processed frame returns back to the client registered surface.
     * Both first and second values will be in milliseconds. The total still capture latency will be
     * the sum of both the first and second values of the pair.
     * The pair is expected to be null if the dynamic latency estimation is not supported.
     * If clients have not configured a still capture output, then this method can also return a
     * null pair.
     * @since 1.4
     */
    Pair<Long, Long> getRealtimeCaptureLatency();

    /**
     * Callback for notifying the status of {@link #startCapture(CaptureCallback)} and
     * {@link #startRepeating(CaptureCallback)}.
     */
    interface CaptureCallback {
        /**
         * This method is called when the camera device has started capturing the initial input
         * image.
         *
         * For a multi-frame capture, the method is called when the
         * CameraCaptureSession.CaptureCallback onCaptureStarted of first frame is called and its
         * timestamp is directly forwarded to timestamp parameter of
         * this method.
         *
         * @param captureSequenceId id of the current capture sequence
         * @param timestamp         the timestamp at start of capture for repeating
         *                          request or the timestamp at start of capture of the
         *                          first frame in a multi-frame capture, in nanoseconds.
         */
        void onCaptureStarted(int captureSequenceId, long timestamp);

        /**
         * This method is called when an image (or images in case of multi-frame
         * capture) is captured and device-specific extension processing is triggered.
         *
         * @param captureSequenceId id of the current capture sequence
         */
        void onCaptureProcessStarted(int captureSequenceId);

        /**
         * This method is called instead of
         * {@link #onCaptureProcessStarted} when the camera device failed
         * to produce the required input for the device-specific extension. The
         * cause could be a failed camera capture request, a failed
         * capture result or dropped camera frame.
         *
         * @param captureSequenceId id of the current capture sequence
         */
        void onCaptureFailed(int captureSequenceId);

        /**
         * This method is called independently of the others in the CaptureCallback, when a capture
         * sequence finishes.
         *
         * <p>In total, there will be at least one
         * {@link #onCaptureProcessStarted}/{@link #onCaptureFailed}
         * invocation before this callback is triggered. If the capture
         * sequence is aborted before any requests have begun processing,
         * {@link #onCaptureSequenceAborted} is invoked instead.</p>
         *
         * @param captureSequenceId id of the current capture sequence
         */
        void onCaptureSequenceCompleted(int captureSequenceId);

        /**
         * This method is called when a capture sequence aborts.
         *
         * @param captureSequenceId id of the current capture sequence
         */
        void onCaptureSequenceAborted(int captureSequenceId);

        /**
         * Capture result callback that needs to be called when the process capture results are
         * ready as part of frame post-processing.
         *
         * This callback will fire after {@link #onCaptureStarted}, {@link #onCaptureProcessStarted}
         * and before {@link #onCaptureSequenceCompleted}. The callback is not expected to fire
         * in case of capture failure  {@link #onCaptureFailed} or capture abort
         * {@link #onCaptureSequenceAborted}.
         *
         * @param timestamp            The timestamp at start of capture. The same timestamp value
         *                             passed to {@link #onCaptureStarted}.
         * @param captureSequenceId    the capture id of the request that generated the capture
         *                             results. This is the return value of either
         *                             {@link #startRepeating} or {@link #startCapture}.
         * @param result               Map containing the supported capture results. Do note
         *                             that if results 'android.jpeg.quality' and
         *                             'android.jpeg.orientation' are present in the process
         *                             capture input results, then the values must also be passed
         *                             as part of this callback. Both Camera2 and CameraX guarantee
         *                             that those two settings and results are always supported and
         *                             applied by the corresponding framework.
         */
        void onCaptureCompleted(long timestamp, int captureSequenceId,
                Map<CaptureResult.Key, Object> result);

        /**
         * Capture progress callback that needs to be called when the process capture is
         * ongoing and includes the estimated progress of the processing.
         *
         * <p>Extensions must ensure that they always call this callback with monotonically
         * increasing values.</p>
         *
         * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
         * callback is expected to be called once when processing is done with value 100.</p>
         *
         * @param progress             Value between 0 and 100.
         * @since 1.4
         */
        void onCaptureProcessProgressed(int progress);
    }
}