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