android.hardware.camera2 提供了访问android device上camera devices的接口
The android.hardware.camera2 package provides an interface to individual camera devices connected to an Android device. It replaces the deprecated {android.hardware.Camera}
android.hardware.camera2把camera device抽象为管道:接收request, 处理request, 输出结果 This package models a camera device as a pipeline, which? takes in input requests for capturing a single frame,? captures the single image per the request, and then? outputs one capture result metadata packet, plus a set of output image buffers for the request.? The requests are processed in-order, and multiple requests can be in flight at once. Since the camera device is a pipeline with multiple stages, having multiple requests in flight is required to maintain full framerate on most Android devices.
通过 android.hardware.camera2.CameraManager 枚举、查询、打开 camera devices To enumerate, query, and open available camera devices, obtain a {android.hardware.camera2.CameraManager} instance.
CameraCharacteristics描述 hardware device的静态属性,可用设置和输出参数 Individual {android.hardware.camera2.CameraDevice CameraDevices} provide a set of static property information that describes the hardware device and the available settings and output parameters for the device. This information is provided through the {android.hardware.camera2.CameraCharacteristics} object, and is available through { android.hardware.camera2.CameraManager#getCameraCharacteristics}
拍照或视频流:创建android.hardware.camera2.CameraCaptureSession 和 output Surfaces To capture or stream images from a camera device, the application must first create a {android.hardware.camera2.CameraCaptureSession camera capture session} with a set of output Surfaces for use with the camera device, with {android.hardware.camera2.CameraDevice#createCaptureSession}. 每个surface 提前配置size and format, 根据StreamConfigurationMap: (surface的参数: size and format) Each Surface has to be pre-configured with an {android.hardware.camera2.params.StreamConfigurationMap appropriate size and format} (if applicable) to match the sizes and formats available from the camera device. 获得surface的方法: A target Surface can be obtained from a variety of classes, including? {android.view.SurfaceView}, {android.graphics.SurfaceTexture} via {android.view.Surface#Surface(SurfaceTexture)}, {android.media.MediaCodec},? {android.media.MediaRecorder}, {android.renderscript.Allocation}, and? {android.media.ImageReader}.
一般而言,preview images发送到android.view.SurfaceView或者android.view.TextureView Generally, camera preview images are sent to {android.view.SurfaceView} or? {android.view.TextureView} (via its {android.graphics.SurfaceTexture}).?
Capture of JPEG images or RAW buffers: Capture of JPEG images or RAW buffers for {android.hardware.camera2.DngCreator} can be done with {android.media.ImageReader} with the {android.graphics.ImageFormat#JPEG} and { android.graphics.ImageFormat#RAW_SENSOR} formats. ?
Application-driven processing of camera data in RenderScript, OpenGL ES, or directly in managed or native code is best done through {android.renderscript.Allocation} with a YUV? {android.renderscript.Type}, {android.graphics.SurfaceTexture}, and {android.media.ImageReader} with a {android.graphics.ImageFormat#YUV_420_888} format, respectively. 应用需要构建一个CaptureRequest, CaptureRequest定义了需要的参数和 输出surface The application then needs to construct a {android.hardware.camera2.CaptureRequest},? which defines all the capture parameters needed by a camera device to capture a single image. The request also lists which of the configured output Surfaces should be used as targets for this capture.?
CaptureRequest.Builder: 构建CaptureRequest的方法 (CaptureRequest 参数) The CameraDevice has a{android.hardware.camera2.CameraDevice#createCaptureRequest factory method} for creating a {android.hardware.camera2.CaptureRequest.Builder request builder} for a given use case, which is optimized for the Android device the application is running on.
capture session处理request Once the request has been set up, it can be handed to the active capture session either for a one-shot {android.hardware.camera2.CameraCaptureSession#capture capture}? or for an endlessly { android.hardware.camera2.CameraCaptureSession#setRepeatingRequest repeating} use.? Both methods also have a variant that accepts a list of requests to use as a burst capture/repeating burst. Repeating requests have a lower priority than captures.
处理请求后,camera device 生成一个TotalCaptureResult object其中包含状态信息 After processing a request, the camera device will produce a { android.hardware.camera2.TotalCaptureResult} object, which contains information about the state of the camera device at time of capture, and the final settings used. These may vary somewhat from the request, if rounding or resolving contradictory parameters was necessary. camera device 发送一帧image data 到Surfaces The camera device will also send a frame of image data into each of the output {Surfaces} included in the request. These are produced asynchronously relative to the output CaptureResult, sometimes substantially later.
下面看下
CameraCaptureSession:
A configured capture session for a {CameraDevice}, used for capturing images from the camera.
A CameraCaptureSession is created by providing a set of target output surfaces to {CameraDevice#createCaptureSession createCaptureSession}.? Once created, the session is active until a new session is created by the camera device, or the camera device is closed.
//为什么实现为 callback(listener)是异步的 ?* Creating a session is an expensive operation and can take several hundred milliseconds, since ?* it requires configuring the camera device's internal pipelines and allocating memory buffers for ?* sending images to the desired targets. Therefore the setup is done asynchronously, and ?* {createCaptureSession} and ?* {createReprocessableCaptureSession} will ?* send the ready-to-use CameraCaptureSession to the provided listener's ?* {CameraCaptureSession.StateCallback#onConfigured onConfigured} callback. If configuration ?* cannot be completed, then the ?* {CameraCaptureSession.StateCallback#onConfigureFailed onConfigureFailed} is called, and the ?* session will not become active.
//capture request和session的关系,另外 capture request分为两类(repeating or non-repeating)? ?* Any capture requests (repeating or non-repeating) submitted before the session is ready will ?* be queued up and will begin capture once the session becomes ready. In case the session cannot be ?* configured and {onConfigureFailed} is called, all queued ?* capture requests are discarded.
// 只能有一个session? 如果新建一个session,之前的session自动 close? ?* If a new session is created by the camera device, then the previous session is closed, and its ?* associated {@link StateCallback#onClosed onClosed} callback will be invoked. ?All ?* of the session methods will throw an IllegalStateException if called once the session is ?* closed.
?* A closed session clears any repeating requests (as if {stopRepeating} had been called), ?* but will still complete all of its in-progress capture requests as normal, before a newly ?* created session takes over and reconfigures the camera device.
public abstract class CameraCaptureSession implements AutoCloseable {
? ? ?* <p>Pre-allocate all buffers for an output Surface.</p> ? ? ?* <p>Normally, the image buffers for a given output Surface are allocated on-demand, ? ? ?* to minimize startup latency and memory overhead.</p> ? ? ?* ? ? ?* <p>However, in some cases, it may be desirable for the buffers to be allocated before ? ? ?* any requests targeting the Surface are actually submitted to the device. Large buffers ? ? ?* may take some time to allocate, which can result in delays in submitting requests until ? ? ?* sufficient buffers are allocated to reach steady-state behavior. Such delays can cause ? ? ?* bursts to take longer than desired, or cause skips or stutters in preview output.</p> ? ? ?* ? ? ?* <p>The prepare() method can be used to perform this preallocation. It may only be called for ? ? ?* a given output Surface before that Surface is used as a target for a request. The number of ? ? ?* buffers allocated is the sum of the count needed by the consumer providing the output ? ? ?* Surface, and the maximum number needed by the camera device to fill its pipeline. Since this ? ? ?* may be a larger number than what is actually required for steady-state operation, using ? ? ?* prepare may result in higher memory consumption than the normal on-demand behavior results ? ? ?* in. Prepare() will also delay the time to first output to a given Surface, in exchange for ? ? ?* smoother frame rate once the allocation is complete.</p>
? ? ?public abstract void prepare(@NonNull Surface surface) throws CameraAccessException; ? ? ?public abstract void prepare(int maxCount, @NonNull Surface surface) throws CameraAccessException;
? ? /** ? ? ?* <p>Submit a request for an image to be captured by the camera device.</p> ? ? ?* ? ? ?* <p>The request defines all the parameters for capturing the single image, ? ? ?* including sensor, lens, flash, and post-processing settings.</p> ? ? ?*/ ? ? public abstract int capture(@NonNull CaptureRequest request, ? ? ? ? ? ? @Nullable CaptureCallback listener, @Nullable Handler handler) ? ? ? ? ? ? throws CameraAccessException;
? ? /** ? ? ?* <p>Submit a request for an image to be captured by the camera device.</p> ? ? ?* ? ? ?* <p>The behavior of this method matches that of ? ? ?* {#capture(CaptureRequest, CaptureCallback, Handler)}, ? ? ?* except that it uses {@link java.util.concurrent.Executor} as an argument ? ? ?* instead of {@link android.os.Handler}.</p> ? ? ?*/ ? ? public int captureSingleRequest(@NonNull CaptureRequest request, ? ? ? ? ? ? @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) ? ? ? ? ? ? throws CameraAccessException { ? ? ? ? throw new UnsupportedOperationException("Subclasses must override this method"); ? ? }
? ? /** ? ? ?* Submit a list of requests to be captured in sequence as a burst. The ? ? ?* burst will be captured in the minimum amount of time possible, and will ? ? ?* not be interleaved with requests submitted by other capture or repeat ? ? ?* calls. ? ? ?* <p>The main difference between this method and simply calling ? ? ?* {@link #capture} repeatedly is that this method guarantees that no ? ? ?* other requests will be interspersed with the burst.</p> ? ? ?*/ ? ? public abstract int captureBurst(@NonNull List<CaptureRequest> requests, ? ? ? ? ? ? @Nullable CaptureCallback listener, @Nullable Handler handler) ? ? ? ? ? ? throws CameraAccessException; ? ? public int captureBurstRequests(@NonNull List<CaptureRequest> requests, ? ? ? ? ? ? @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) ? ? ? ? ? ? throws CameraAccessException { ? ? ? ? throw new UnsupportedOperationException("Subclasses must override this method"); ? ? }
? ? /** ? ? ?* Request endlessly repeating capture of images by this capture session. ? ? ?* ? ? ?* <p>With this method, the camera device will continually capture images ? ? ?* using the settings in the provided {@link CaptureRequest}, at the maximum ? ? ?* rate possible.</p> ? ? ?* ? ? ?* <p>Repeating requests are a simple way for an application to maintain a ? ? ?* preview or other continuous stream of frames, without having to ? ? ?* continually submit identical requests through {@link #capture}.</p> ? ? ?* ? ? ?* <p>Repeat requests have lower priority than those submitted ? ? ?* through {@link #capture} or {@link #captureBurst}, so if ? ? ?* {@link #capture} is called when a repeating request is active, the ? ? ?* capture request will be processed before any further repeating ? ? ?* requests are processed.<p> ? ? public abstract int setRepeatingRequest(@NonNull CaptureRequest request, ? ? ? ? ? ? @Nullable CaptureCallback listener, @Nullable Handler handler) ? ? ? ? ? ? throws CameraAccessException; ? ? public int setSingleRepeatingRequest(@NonNull CaptureRequest request, ? ? ? ? ? ? @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) ? ? ? ? ? ? throws CameraAccessException { ? ? ? ? throw new UnsupportedOperationException("Subclasses must override this method"); ? ? }
? ? /** ? ? ?* A callback object for receiving updates about the state of a camera capture session. ? ? ?* ? ? ?*/ ? ? public static abstract class StateCallback { ?? ?public abstract void onConfigured(@NonNull CameraCaptureSession session); ?? ?onConfigureFailed(...); ?? ?onReady(...); ?? ?onActive(...); ?? ?onCaptureQueueEmpty(...); ? ? }
? ? /** ? ? ?* A callback object for tracking the progress of a {CaptureRequest} submitted to the ? ? ?* camera device. ? ? ?* ? ? ?* <p>This callback is invoked when a request triggers a capture to start, ? ? ?* and when the capture is complete. In case on an error capturing an image, ? ? ?* the error method is triggered instead of the completion method.</p> ? ? ?* ? ? ?* @see #capture ? ? ?* @see #captureBurst ? ? ?* @see #setRepeatingRequest ? ? ?* @see #setRepeatingBurst ? ? ?*/ ? ? public static abstract class CaptureCallback { ?? ?onCaptureStarted(); ?? ?onCapturePartial(); ?? ?onCaptureProgressed(); ?? ?onCaptureCompleted(); ?? ?onCaptureFailed(); ?? ?--- ? ? }
? ? /** ? ? ?* Close this capture session asynchronously. ? ? ?* ? ? ?* <p>Closing a session frees up the target output Surfaces of the session for reuse with either ? ? ?* a new session, or to other APIs that can draw to Surfaces.</p> ? ? ?* ? ? ?* Note that creating a new capture session with {CameraDevice#createCaptureSession} ? ? ?* will close any existing capture session automatically, and call the older session listener's ? ? ?* {StateCallback#onClosed} callback. Using {CameraDevice#createCaptureSession} ? ? ?* directly without closing is the recommended approach for quickly switching to a new session, ? ? ?* since unchanged target outputs can be reused more efficiently. ? ? ?* ? ? ?* Once a session is closed, all methods on it will throw an IllegalStateException, and any ? ? ?* repeating requests or bursts are stopped (as if { #stopRepeating()} was called). ? ? ?* However, any in-progress capture requests submitted to the session will be completed as ? ? ?* normal; once all captures have completed and the session has been torn down, ? ? ?* {StateCallback#onClosed} will be called.</p> ? ? ?* ? ? ?* Closing a session is idempotent; closing more than once has no effect.</p> ? ? ?*/ ? ? @Override ? ? public abstract void close();
}
/** ?* The base class for camera controls and information. ?* ?* <p> ?* This class defines the basic key/value map used for querying for camera ?* characteristics or capture results, and for setting camera request ?* parameters. ?* </p> ?* ?* <p> ?* All instances of CameraMetadata are immutable. The list of keys with {@link #getKeys()} ?* never changes, nor do the values returned by any key with {@code #get} throughout ?* the lifetime of the object. ?* </p> ?* ?* @see CameraDevice ?* @see CameraManager ?* @see CameraCharacteristics ?**/ public abstract class CameraMetadata<TKey> {
}
/** ?* An immutable package of settings and outputs needed to capture a single ?* image from the camera device. ?* ?* Contains the configuration for the capture hardware (sensor, lens, flash), ?* the processing pipeline, the control algorithms, and the output buffers. Also ?* contains the list of target Surfaces to send image data to for this ?* capture. ?* ?* <p>CaptureRequests can be created by using a { Builder} instance, ?* obtained by calling {CameraDevice#createCaptureRequest}</p> ?* ?* <p>CaptureRequests are given to {@link CameraCaptureSession#capture} or ?* {@link CameraCaptureSession#setRepeatingRequest} to capture images from a camera.</p> ?* ?* <p>Each request can specify a different subset of target Surfaces for the ?* camera to send the captured data to. All the surfaces used in a request must ?* be part of the surface list given to the last call to ?* {@link CameraDevice#createCaptureSession}, when the request is submitted to the ?* session.</p> ?* ?*? ?* <p>For example, a request meant for repeating preview might only include the ?* Surface for the preview SurfaceView or SurfaceTexture, while a ?* high-resolution still capture would also include a Surface from a ImageReader ?* configured for high-resolution JPEG images.</p> ?* ?* @see CameraCaptureSession#capture ?* @see CameraCaptureSession#setRepeatingRequest ?* @see CameraCaptureSession#captureBurst ?* @see CameraCaptureSession#setRepeatingBurst ?* @see CameraDevice#createCaptureRequest ?*/
public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> ? ? ? ? implements Parcelable {
? ? /** ? ? ?* A builder for capture requests. ? ? ?* ? ? ?* <p>To obtain a builder instance, use the ? ? ?* {@link CameraDevice#createCaptureRequest} method, which initializes the ? ? ?* request fields to one of the templates defined in {@link CameraDevice}. ? ? ?* ? ? ?* @see CameraDevice#createCaptureRequest ? ? ?* @see CameraDevice#TEMPLATE_PREVIEW ? ? ?* @see CameraDevice#TEMPLATE_RECORD ? ? ?* @see CameraDevice#TEMPLATE_STILL_CAPTURE ? ? ?* @see CameraDevice#TEMPLATE_VIDEO_SNAPSHOT ? ? ?* @see CameraDevice#TEMPLATE_MANUAL ? ? ?*/ ? ? public final static class Builder { ? ? ? ? private final CaptureRequest mRequest;
? ? ? ? public Builder(CameraMetadataNative template, boolean reprocess, ? ? ? ? ? ? ? ? int reprocessableSessionId, String logicalCameraId, ? ? ? ? ? ? ? ? Set<String> physicalCameraIdSet) { ? ? ? ? ? ? mRequest = new CaptureRequest(template, reprocess, reprocessableSessionId, ? ? ? ? ? ? ? ? ? ? logicalCameraId, physicalCameraIdSet); ? ? ? ? }
? ? ? ? public void addTarget(@NonNull Surface outputTarget) { ? ? ? ? ? ? mRequest.mSurfaceSet.add(outputTarget); ? ? ? ? } ? ? } }
/** ?* <p>The subset of the results of a single image capture from the image sensor.</p> ?* ?* <p>Contains a subset of the final configuration for the capture hardware (sensor, lens, ?* flash), the processing pipeline, the control algorithms, and the output ?* buffers.</p> ?* ?* <p>CaptureResults are produced by a {@link CameraDevice} after processing a ?* {CaptureRequest}. All properties listed for capture requests can also ?* be queried on the capture result, to determine the final values used for ?* capture. The result also includes additional metadata about the state of the ?* camera device during the capture.</p> ?* ?* <p>Not all properties returned by {CameraCharacteristics#getAvailableCaptureResultKeys()} ?* are necessarily available. Some results are {@link CaptureResult partial} and will ?* not have every key set. Only {TotalCaptureResult total} results are guaranteed to have ?* every key available that was enabled by the request. ?* ?* <p>{@link CaptureResult} objects are immutable.</p> ?* ?*/ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
}
|