1 /*
2  * Copyright 2021 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.extensions.impl.advanced;
18 
19 import android.annotation.SuppressLint;
20 import android.content.Context;
21 import android.hardware.camera2.CameraCharacteristics;
22 import android.hardware.camera2.CaptureRequest;
23 import android.view.Surface;
24 
25 import java.util.Map;
26 
27 /**
28  * Interface for activating extension sessions.
29  *
30  * <p><pre>
31  * The flow of a extension session.
32  * (1) {@link #initSession}: CameraX prepares streams configuration for creating
33  *     CameraCaptureSession. Output surfaces for Preview, ImageCapture and ImageAnalysis are passed
34  *     in and vendor is responsible for outputting the results to these surfaces.
35  *
36  * (2) {@link #onCaptureSessionStart}: It is called after CameraCaptureSession is configured.
37  *     A {@link RequestProcessorImpl} is passed for vendor to send repeating requests and
38  *     single requests.
39  *
40  * (3) {@link #startRepeating}:  CameraX will call this method to start the repeating request
41  *     after CameraCaptureSession is called.  Vendor should start the repeating request by
42  *     {@link RequestProcessorImpl}. Vendor can also update the repeating request at other
43  *     time other than in this method.
44  *
45  * (4) {@link #setParameters(Map)}: The passed parameters will be attached to the repeating request
46  *     and single requests but vendor can choose to apply some of them only.
47  *
48  * (5) {@link #startCapture(CaptureCallback)}: It is called when apps want to
49  *     start a multi-frame image capture.  {@link CaptureCallback} will be called
50  *     to report the statue and the output image will be written to the capture output surface
51  *     specified in {@link #initSession}.
52  *
53  * (5) {@link #onCaptureSessionEnd}: It is called right BEFORE CameraCaptureSession.close() is
54  *     called.
55  *
56  * (6) {@link #deInitSession}: called when CameraCaptureSession is destroyed
57  * </pre>
58  */
59 @SuppressLint("UnknownNullness")
60 public interface SessionProcessorImpl {
61     /**
62      * Notify to start the session for the extension. This is where the use case is started and
63      * would be able to allocate resources here. After onInit() is called, the camera ID,
64      * cameraCharacteristics and context will not change until deInitSession() has been called.
65      *
66      * <p>CameraX specifies the output surface configurations for preview, image capture and image
67      * analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which consists of a
68      * list of {@link Camera2OutputConfigImpl} and session parameters. The
69      * {@link Camera2SessionConfigImpl} will be used to configure the
70      * CameraCaptureSession.
71      *
72      * <p>OEM is responsible for outputting correct camera images output to these output surfaces.
73      * OEM can have the following options to enable the output:
74      * <pre>
75      * (1) Add these output surfaces in CameraCaptureSession directly using
76      * {@link Camera2OutputConfigImplBuilder#newSurfaceConfig(Surface)} }. Processing
77      * may be done in HAL.
78      *
79      * (2) Use surface sharing with other surface by calling
80      * {@link Camera2OutputConfigImplBuilder#addSurfaceSharingOutputConfig(Camera2OutputConfigImpl)}
81      * to add the output surface to the other {@link Camera2OutputConfigImpl}.
82      *
83      * (3) Process output from other surfaces (RAW, YUV..) and write the result to the output
84      * surface. The output surface won't be contained in the returned
85      * {@link Camera2SessionConfigImpl}.
86      * </pre>
87      *
88      * <p>To ensure the preview, image capture and image analysis are working properly, OEM is
89      * responsible for setting corresponding {@link Camera2OutputConfigImpl.UsageType} in the
90      * {@link Camera2OutputConfigImpl}. CameraX will examine if all usage types
91      * (USAGE_PREVIEW/USAGE_CAPTURE/USAGE_ANALYSIS) can be found in the returned
92      * {@link Camera2SessionConfigImpl} and throws an {@link IllegalArgumentException} if some
93      * usage type is not found.
94      *
95      * <p>{@link Camera2OutputConfigImplBuilder} and {@link Camera2SessionConfigImplBuilder}
96      * implementations are provided in the stub for OEM to construct the
97      * {@link Camera2OutputConfigImpl} and {@link Camera2SessionConfigImpl} instances.
98      *
99      * @param previewSurfaceConfig       output surface for preview
100      * @param imageCaptureSurfaceConfig  output surface for image capture.
101      * @param imageAnalysisSurfaceConfig an optional output config for image analysis
102      *                                   (YUV_420_888).
103      * @return a {@link Camera2SessionConfigImpl} consisting of a list of
104      * {@link Camera2OutputConfigImpl}
105      * and session parameters which will decide the
106      * {@link android.hardware.camera2.params.SessionConfiguration} for configuring the
107      * CameraCaptureSession. Please note that the OutputConfiguration list may not be part of any
108      * supported or mandatory stream combination BUT OEM must ensure this list will always
109      * produce a valid camera capture session.
110      */
initSession( String cameraId, Map<String, CameraCharacteristics> cameraCharacteristicsMap, Context context, OutputSurfaceImpl previewSurfaceConfig, OutputSurfaceImpl imageCaptureSurfaceConfig, OutputSurfaceImpl imageAnalysisSurfaceConfig)111     Camera2SessionConfigImpl initSession(
112             String cameraId,
113             Map<String, CameraCharacteristics> cameraCharacteristicsMap,
114             Context context,
115             OutputSurfaceImpl previewSurfaceConfig,
116             OutputSurfaceImpl imageCaptureSurfaceConfig,
117             OutputSurfaceImpl imageAnalysisSurfaceConfig);
118 
119     /**
120      * Notify to de-initialize the extension. This callback will be invoked after unbind. After
121      * onDeInit() was called, it is expected that the camera ID, cameraCharacteristics will
122      * no longer hold and tear down any resources allocated for this extension. Aborts all pending
123      * captures.
124      */
deInitSession()125     void deInitSession();
126 
127     /**
128      * CameraX / Camera2 would call these API’s to pass parameters from the app to the OEM. It’s
129      * expected that the OEM would (eventually) update the repeating request if the keys are
130      * supported. Setting a value to null explicitly un-sets the value.
131      */
setParameters(Map<CaptureRequest.Key<?>, Object> parameters)132     void setParameters(Map<CaptureRequest.Key<?>, Object> parameters);
133 
134     /**
135      * This will be invoked once after the {@link android.hardware.camera2.CameraCaptureSession}
136      * has been created. {@link RequestProcessorImpl} is passed for OEM to submit single
137      * requests or set repeating requests. This ExtensionRequestProcessor will be valid to use
138      * until onCaptureSessionEnd is called.
139      */
onCaptureSessionStart(RequestProcessorImpl requestProcessor)140     void onCaptureSessionStart(RequestProcessorImpl requestProcessor);
141 
142     /**
143      * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
144      * closed. {@link RequestProcessorImpl} passed in onCaptureSessionStart will no longer
145      * accept any requests after onCaptureSessionEnd() returns.
146      */
onCaptureSessionEnd()147     void onCaptureSessionEnd();
148 
149     /**
150      * Starts the repeating request after CameraCaptureSession is called. Vendor should start the
151      * repeating request by {@link RequestProcessorImpl}. Vendor can also update the
152      * repeating request at time other than in this method.
153      *
154      * @param callback a callback to report the status.
155      * @return the id of the capture sequence.
156      */
startRepeating(CaptureCallback callback)157     int startRepeating(CaptureCallback callback);
158 
159     /**
160      * Stop the repeating request. To prevent OEM from not calling stopRepeating, CameraX will
161      * first stop repeating of current CameraCaptureSession and call this API to signal OEM that
162      * all repeating request should stopped and calling
163      * {@link RequestProcessorImpl#setRepeating(RequestProcessorImpl.Request)} will simply do
164      * nothing.
165      */
stopRepeating()166     void stopRepeating();
167 
168     /**
169      * Start a multi-frame capture.
170      *
171      * When the capture is completed, {@link CaptureCallback#onCaptureSequenceCompleted}
172      * is called and {@code OnImageAvailableListener#onImageAvailable}
173      * will also be called on the ImageReader that creates the image capture output surface.
174      *
175      * <p>Only one capture can perform at a time. Starting a capture when another capture is running
176      * will cause onCaptureFailed to be called immediately.
177      *
178      * @param callback a callback to report the status.
179      * @return the id of the capture sequence.
180      */
startCapture(CaptureCallback callback)181     int startCapture(CaptureCallback callback);
182 
183     /**
184      * Abort capture tasks.
185      */
abortCapture(int captureSequenceId)186     void abortCapture(int captureSequenceId);
187 
188     /**
189      * Callback for notifying the status of {@link #startCapture(CaptureCallback)} and
190      * {@link #startRepeating(CaptureCallback)}.
191      */
192     interface CaptureCallback {
193         /**
194          * This method is called when the camera device has started capturing the initial input
195          * image.
196          *
197          * For a multi-frame capture, the method is called when the
198          * CameraCaptureSession.CaptureCallback onCaptureStarted of first frame is called and its
199          * timestamp is directly forwarded to timestamp parameter of
200          * this method.
201          *
202          * @param captureSequenceId id of the current capture sequence
203          * @param timestamp         the timestamp at start of capture for repeating
204          *                          request or the timestamp at start of capture of the
205          *                          first frame in a multi-frame capture, in nanoseconds.
206          */
onCaptureStarted(int captureSequenceId, long timestamp)207         void onCaptureStarted(int captureSequenceId, long timestamp);
208 
209         /**
210          * This method is called when an image (or images in case of multi-frame
211          * capture) is captured and device-specific extension processing is triggered.
212          *
213          * @param captureSequenceId id of the current capture sequence
214          */
onCaptureProcessStarted(int captureSequenceId)215         void onCaptureProcessStarted(int captureSequenceId);
216 
217         /**
218          * This method is called instead of
219          * {@link #onCaptureProcessStarted} when the camera device failed
220          * to produce the required input for the device-specific extension. The
221          * cause could be a failed camera capture request, a failed
222          * capture result or dropped camera frame.
223          *
224          * @param captureSequenceId id of the current capture sequence
225          */
onCaptureFailed(int captureSequenceId)226         void onCaptureFailed(int captureSequenceId);
227 
228         /**
229          * This method is called independently of the others in the CaptureCallback, when a capture
230          * sequence finishes.
231          *
232          * <p>In total, there will be at least one
233          * {@link #onCaptureProcessStarted}/{@link #onCaptureFailed}
234          * invocation before this callback is triggered. If the capture
235          * sequence is aborted before any requests have begun processing,
236          * {@link #onCaptureSequenceAborted} is invoked instead.</p>
237          *
238          * @param captureSequenceId id of the current capture sequence
239          */
onCaptureSequenceCompleted(int captureSequenceId)240         void onCaptureSequenceCompleted(int captureSequenceId);
241 
242         /**
243          * This method is called when a capture sequence aborts.
244          *
245          * @param captureSequenceId id of the current capture sequence
246          */
onCaptureSequenceAborted(int captureSequenceId)247         void onCaptureSequenceAborted(int captureSequenceId);
248     }
249 }
250