blob: 0627081225bb738b634f194acbbbf9b822b0fc6c [file] [log] [blame]
/*
* 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 / Camera 2 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.
*
* 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);
/**
* 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);
/**
* 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);
}
}