1 /*
2  * Copyright 2024 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.camera2.pipe.media
18 
19 import android.hardware.camera2.MultiResolutionImageReader
20 import android.media.ImageReader
21 import android.view.Surface
22 import androidx.camera.camera2.pipe.CameraStream
23 import androidx.camera.camera2.pipe.ImageSourceConfig
24 import androidx.camera.camera2.pipe.OutputId
25 import androidx.camera.camera2.pipe.StreamId
26 import androidx.camera.camera2.pipe.UnsafeWrapper
27 
28 /**
29  * An ImageSource produces images from a CameraStream via an [ImageSourceListener].
30  *
31  * This interface is an abstraction over [ImageReader] and [MultiResolutionImageReader] that is
32  * designed to eliminate several subtle and difficult to avoid pitfalls that can occur when using
33  * these classes directly.
34  *
35  * There are three common problems that occur when using an ImageReader with a camera:
36  * 1. Closing the ImageReader before all outstanding Images are closed. This can lead to memory
37  *    getting unexpectedly freed or overwritten, leading to corrupted outputs or difficult to
38  *    diagnose crashes. Implementations are expected to avoid this problem by waiting to close the
39  *    underlying ImageReader (after close has been called) until all images passed to the listener
40  *    have also been closed.
41  * 2. Acquiring too many images from an ImageReader (or failing to acquire images fast enough) can
42  *    either lead to IllegalStateExceptions when attempting to read images out, or it can lead to
43  *    stalling the Camera if images are not drained out fast enough. Implementations of this
44  *    interface are expected to internally account for the number of outstanding images and to read
45  *    and drop images that would otherwise exceed the maximum number of images.
46  * 3. Using ImageReader.acquireLatestImage skips an arbitrary number of images. While this is
47  *    primarily used to avoid stalling the camera, it also causes problems when attempting to
48  *    associate metadata from the camera and can lead to stalls later on. Since this can be solved
49  *    via #2, acquireLatestImage is not supported.
50  *
51  * Implementations are expected to be thread safe, and to associate each image with the [OutputId]
52  * it is associated with.
53  */
54 public interface ImageSource : UnsafeWrapper, AutoCloseable {
55     /** The graphics surface that the Camera produces images into. */
56     public val surface: Surface
57 
setListenernull58     public fun setListener(listener: ImageSourceListener)
59 }
60 
61 /** Listener for handling [ImageWrapper]s as they are produced. */
62 public fun interface ImageSourceListener {
63     /**
64      * Handle the next image from the [ImageSource]. Implementations *must* close the [image] when
65      * they are done with it. Receiving a null [image] indicates the that an image was produced, but
66      * that this image source is at capacity and that the image was dropped and closed to avoid
67      * stalling the camera.
68      */
69     public fun onImage(
70         streamId: StreamId,
71         outputId: OutputId,
72         outputTimestamp: Long,
73         image: ImageWrapper?
74     )
75 }
76 
77 /** Provider for creating an [ImageSource] based on an [ImageSourceConfig] */
78 public fun interface ImageSources {
createImageSourcenull79     public fun createImageSource(
80         cameraStream: CameraStream,
81         imageSourceConfig: ImageSourceConfig,
82     ): ImageSource
83 }
84