1 /*
2  * Copyright (C) 2013 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 android.media;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SuppressLint;
23 import android.app.compat.CompatChanges;
24 import android.compat.annotation.ChangeId;
25 import android.compat.annotation.EnabledAfter;
26 import android.graphics.GraphicBuffer;
27 import android.graphics.ImageFormat;
28 import android.graphics.ImageFormat.Format;
29 import android.graphics.Rect;
30 import android.hardware.DataSpace;
31 import android.hardware.DataSpace.NamedDataSpace;
32 import android.hardware.HardwareBuffer;
33 import android.hardware.HardwareBuffer.Usage;
34 import android.hardware.SyncFence;
35 import android.hardware.camera2.MultiResolutionImageReader;
36 import android.os.Build;
37 import android.os.Handler;
38 import android.os.Looper;
39 import android.os.ParcelFileDescriptor;
40 import android.view.Surface;
41 
42 import dalvik.system.VMRuntime;
43 
44 import java.io.IOException;
45 import java.lang.ref.WeakReference;
46 import java.nio.ByteBuffer;
47 import java.nio.ByteOrder;
48 import java.nio.NioUtils;
49 import java.util.List;
50 import java.util.Objects;
51 import java.util.concurrent.CopyOnWriteArrayList;
52 import java.util.concurrent.Executor;
53 import java.util.concurrent.atomic.AtomicBoolean;
54 
55 /**
56  * <p>The ImageReader class allows direct application access to image data
57  * rendered into a {@link android.view.Surface}</p>
58  *
59  * <p>Several Android media API classes accept Surface objects as targets to
60  * render to, including {@link MediaPlayer}, {@link MediaCodec},
61  * {@link android.hardware.camera2.CameraDevice}, {@link ImageWriter} and
62  * {@link android.renderscript.Allocation RenderScript Allocations}. The image
63  * sizes and formats that can be used with each source vary, and should be
64  * checked in the documentation for the specific API.</p>
65  *
66  * <p>The image data is encapsulated in {@link Image} objects, and multiple such
67  * objects can be accessed at the same time, up to the number specified by the
68  * {@code maxImages} constructor parameter. New images sent to an ImageReader
69  * through its {@link Surface} are queued until accessed through the {@link #acquireLatestImage}
70  * or {@link #acquireNextImage} call. Due to memory limits, an image source will
71  * eventually stall or drop Images in trying to render to the Surface if the
72  * ImageReader does not obtain and release Images at a rate equal to the
73  * production rate.</p>
74  */
75 public class ImageReader implements AutoCloseable {
76 
77     /**
78      * Returned by nativeImageSetup when acquiring the image was successful.
79      */
80     private static final int ACQUIRE_SUCCESS = 0;
81     /**
82      * Returned by nativeImageSetup when we couldn't acquire the buffer,
83      * because there were no buffers available to acquire.
84      */
85     private static final int ACQUIRE_NO_BUFS = 1;
86     /**
87      * Returned by nativeImageSetup when we couldn't acquire the buffer
88      * because the consumer has already acquired {@maxImages} and cannot
89      * acquire more than that.
90      */
91     private static final int ACQUIRE_MAX_IMAGES = 2;
92 
93     /**
94      * <p>
95      * Flag to gate correct exception thrown by {@code #detachImage}.
96      * </p>
97      * <p>
98      * {@code #detachImage} is documented as throwing {@link java.lang.IllegalStateException} in
99      * the event of an error; a native helper method to this threw
100      * {@link java.lang.RuntimeException} if the surface was abandoned while detaching the
101      * {@code Image}.
102      * <p>
103      * This previously undocumented exception behavior continues through Android T.
104      * </p>
105      * <p>
106      * After Android T, the native helper method only throws {@code IllegalStateExceptions} in
107      * accordance with the documentation.
108      * </p>
109      * <p>
110      * {@code #detachImage} will now throw only ISEs if it runs into errors while detaching
111      * the image. Behavior on apps targeting API levels <= T remains unchanged.
112      * </p>
113      */
114     @ChangeId
115     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
116     private static final long DETACH_THROWS_ISE_ONLY = 236825255L;
117 
118     /**
119      * Cached value of {@link #DETACH_THROWS_ISE_ONLY} flag to prevent repeated calls when
120      * detaching image.
121      */
122     private final boolean mDetachThrowsIseOnly =
123             CompatChanges.isChangeEnabled(DETACH_THROWS_ISE_ONLY);
124 
125     /**
126      * <p>
127      * Create a new reader for images of the desired size and format.
128      * </p>
129      * <p>
130      * The {@code maxImages} parameter determines the maximum number of
131      * {@link Image} objects that can be be acquired from the
132      * {@code ImageReader} simultaneously. Requesting more buffers will use up
133      * more memory, so it is important to use only the minimum number necessary
134      * for the use case.
135      * </p>
136      * <p>
137      * The valid sizes and formats depend on the source of the image data.
138      * </p>
139      * <p>
140      * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created
141      * {@link ImageReader} will produce images that are not directly accessible
142      * by the application. The application can still acquire images from this
143      * {@link ImageReader}, and send them to the
144      * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via
145      * {@link ImageWriter} interface. However, the {@link Image#getPlanes()
146      * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE
147      * PRIVATE} format images. The application can check if an existing reader's
148      * format by calling {@link #getImageFormat()}.
149      * </p>
150      * <p>
151      * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader
152      * ImageReaders} are more efficient to use when application access to image
153      * data is not necessary, compared to ImageReaders using other format such
154      * as {@link ImageFormat#YUV_420_888 YUV_420_888}.
155      * </p>
156      *
157      * @param width The default width in pixels of the Images that this reader
158      *            will produce.
159      * @param height The default height in pixels of the Images that this reader
160      *            will produce.
161      * @param format The format of the Image that this reader will produce. This
162      *            must be one of the {@link android.graphics.ImageFormat} or
163      *            {@link android.graphics.PixelFormat} constants. Note that not
164      *            all formats are supported, like ImageFormat.NV21.
165      * @param maxImages The maximum number of images the user will want to
166      *            access simultaneously. This should be as small as possible to
167      *            limit memory use. Once maxImages Images are obtained by the
168      *            user, one of them has to be released before a new Image will
169      *            become available for access through
170      *            {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
171      *            Must be greater than 0.
172      * @see Image
173      */
newInstance( @ntRangefrom = 1) int width, @IntRange(from = 1) int height, @Format int format, @IntRange(from = 1) int maxImages)174     public static @NonNull ImageReader newInstance(
175             @IntRange(from = 1) int width,
176             @IntRange(from = 1) int height,
177             @Format             int format,
178             @IntRange(from = 1) int maxImages) {
179         // If the format is private don't default to USAGE_CPU_READ_OFTEN since it may not
180         // work, and is inscrutable anyway
181         return new ImageReader(width, height, format, maxImages,
182                 format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN, null);
183     }
184 
185     /**
186      * <p>
187      * Create a new reader for images of the desired size, format and consumer usage flag.
188      * </p>
189      * <p>
190      * The {@code maxImages} parameter determines the maximum number of {@link Image} objects that
191      * can be be acquired from the {@code ImageReader} simultaneously. Requesting more buffers will
192      * use up more memory, so it is important to use only the minimum number necessary for the use
193      * case.
194      * </p>
195      * <p>
196      * The valid sizes and formats depend on the source of the image data.
197      * </p>
198      * <p>
199      * The format and usage flag combination describes how the buffer will be used by
200      * consumer end-points. For example, if the application intends to send the images to
201      * {@link android.media.MediaCodec} or {@link android.media.MediaRecorder} for hardware video
202      * encoding, the format and usage flag combination needs to be
203      * {@link ImageFormat#PRIVATE PRIVATE} and {@link HardwareBuffer#USAGE_VIDEO_ENCODE}. When an
204      * {@link ImageReader} object is created with a valid size and such format/usage flag
205      * combination, the application can send the {@link Image images} to an {@link ImageWriter} that
206      * is created with the input {@link android.view.Surface} provided by the
207      * {@link android.media.MediaCodec} or {@link android.media.MediaRecorder}.
208      * </p>
209      * <p>
210      * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created {@link ImageReader}
211      * will produce images that are not directly accessible by the application. The application can
212      * still acquire images from this {@link ImageReader}, and send them to the
213      * {@link android.hardware.camera2.CameraDevice camera} for reprocessing, or to the
214      * {@link android.media.MediaCodec} / {@link android.media.MediaRecorder} for hardware video
215      * encoding via {@link ImageWriter} interface. However, the {@link Image#getPlanes()
216      * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE PRIVATE} format
217      * images. The application can check if an existing reader's format by calling
218      * {@link #getImageFormat()}.
219      * </p>
220      * <p>
221      * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader ImageReaders} are more
222      * efficient to use when application access to image data is not necessary, compared to
223      * ImageReaders using other format such as {@link ImageFormat#YUV_420_888 YUV_420_888}.
224      * </p>
225      * <p>
226      * Note that not all format and usage flag combinations are supported by the
227      * {@link ImageReader}. Below are the supported combinations by the {@link ImageReader}
228      * (assuming the consumer end-points support the such image consumption, e.g., hardware video
229      * encoding).
230      * <table>
231      * <tr>
232      *   <th>Format</th>
233      *   <th>Compatible usage flags</th>
234      * </tr>
235      * <tr>
236      *   <td>non-{@link android.graphics.ImageFormat#PRIVATE PRIVATE} formats defined by
237      *   {@link android.graphics.ImageFormat ImageFormat} or
238      *   {@link android.graphics.PixelFormat PixelFormat}</td>
239      *   <td>{@link HardwareBuffer#USAGE_CPU_READ_RARELY} or
240      *   {@link HardwareBuffer#USAGE_CPU_READ_OFTEN}</td>
241      * </tr>
242      * <tr>
243      *   <td>{@link android.graphics.ImageFormat#PRIVATE}</td>
244      *   <td>{@link HardwareBuffer#USAGE_VIDEO_ENCODE} or
245      *   {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
246      * </tr>
247      * </table>
248      * Using other combinations may result in {@link IllegalArgumentException}. Additionally,
249      * specifying {@link HardwareBuffer#USAGE_CPU_WRITE_RARELY} or
250      * {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} and writing to the ImageReader's buffers
251      * might break assumptions made by some producers, and should be used with caution.
252      * </p>
253      * <p>
254      * If the {@link ImageReader} is used as an output target for a {@link
255      * android.hardware.camera2.CameraDevice}, and if the usage flag contains
256      * {@link HardwareBuffer#USAGE_VIDEO_ENCODE}, the timestamps of the
257      * {@link Image images} produced by the {@link ImageReader} won't be in the same timebase as
258      * {@link android.os.SystemClock#elapsedRealtimeNanos}, even if
259      * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is
260      * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME}.
261      * Instead, the timestamps will be roughly in the same timebase as in
262      * {@link android.os.SystemClock#uptimeMillis}, so that A/V synchronization could work for
263      * video recording. In this case, the timestamps from the {@link ImageReader} with
264      * {@link HardwareBuffer#USAGE_VIDEO_ENCODE} usage flag may not be directly comparable with
265      * timestamps of other streams or capture result metadata.
266      * </p>
267      * @param width The default width in pixels of the Images that this reader will produce.
268      * @param height The default height in pixels of the Images that this reader will produce.
269      * @param format The format of the Image that this reader will produce. This must be one of the
270      *            {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
271      *            constants. Note that not all formats are supported, like ImageFormat.NV21.
272      * @param maxImages The maximum number of images the user will want to access simultaneously.
273      *            This should be as small as possible to limit memory use. Once maxImages Images are
274      *            obtained by the user, one of them has to be released before a new Image will
275      *            become available for access through {@link #acquireLatestImage()} or
276      *            {@link #acquireNextImage()}. Must be greater than 0.
277      * @param usage The intended usage of the images produced by this ImageReader. See the usages
278      *              on {@link HardwareBuffer} for a list of valid usage bits. See also
279      *              {@link HardwareBuffer#isSupported(int, int, int, int, long)} for checking
280      *              if a combination is supported. If it's not supported this will throw
281      *              an {@link IllegalArgumentException}.
282      * @see Image
283      * @see HardwareBuffer
284      */
newInstance( @ntRangefrom = 1) int width, @IntRange(from = 1) int height, @Format int format, @IntRange(from = 1) int maxImages, @Usage long usage)285     public static @NonNull ImageReader newInstance(
286             @IntRange(from = 1) int width,
287             @IntRange(from = 1) int height,
288             @Format             int format,
289             @IntRange(from = 1) int maxImages,
290             @Usage              long usage) {
291         // TODO: Check this - can't do it just yet because format support is different
292         // Unify formats! The only reliable way to validate usage is to just try it and see.
293 
294 //        if (!HardwareBuffer.isSupported(width, height, format, 1, usage)) {
295 //            throw new IllegalArgumentException("The given format=" + Integer.toHexString(format)
296 //                + " & usage=" + Long.toHexString(usage) + " is not supported");
297 //        }
298         return new ImageReader(width, height, format, maxImages, usage, /*parent*/ null);
299     }
300 
301      /**
302       * @hide
303       */
newInstance( @ntRangefrom = 1) int width, @IntRange(from = 1) int height, @Format int format, @IntRange(from = 1) int maxImages, @NonNull MultiResolutionImageReader parent)304      public static @NonNull ImageReader newInstance(
305             @IntRange(from = 1) int width,
306             @IntRange(from = 1) int height,
307             @Format             int format,
308             @IntRange(from = 1) int maxImages,
309             @NonNull            MultiResolutionImageReader parent) {
310         // If the format is private don't default to USAGE_CPU_READ_OFTEN since it may not
311         // work, and is inscrutable anyway
312         return new ImageReader(width, height, format, maxImages,
313                 format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN, parent);
314     }
315 
initializeImageReader(int width, int height, int imageFormat, int maxImages, long usage, int hardwareBufferFormat, int dataSpace)316     private void initializeImageReader(int width, int height, int imageFormat, int maxImages,
317             long usage, int hardwareBufferFormat, int dataSpace) {
318         if (width < 1 || height < 1) {
319             throw new IllegalArgumentException(
320                 "The image dimensions must be positive");
321         }
322 
323         if (maxImages < 1) {
324             throw new IllegalArgumentException(
325                 "Maximum outstanding image count must be at least 1");
326         }
327 
328         if (imageFormat == ImageFormat.NV21) {
329             throw new IllegalArgumentException(
330                 "NV21 format is not supported");
331         }
332 
333         nativeInit(new WeakReference<>(this), width, height, maxImages, usage,
334                 hardwareBufferFormat, dataSpace);
335 
336         mIsReaderValid = true;
337 
338         mSurface = nativeGetSurface();
339         // Estimate the native buffer allocation size and register it so it gets accounted for
340         // during GC. Note that this doesn't include the buffers required by the buffer queue
341         // itself and the buffers requested by the producer.
342         // Only include memory for 1 buffer, since actually accounting for the memory used is
343         // complex, and 1 buffer is enough for the VM to treat the ImageReader as being of some
344         // size.
345         mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(
346                 width, height, imageFormat, /*buffer count*/ 1);
347         VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
348     }
349 
ImageReader(int width, int height, int imageFormat, int maxImages, long usage, MultiResolutionImageReader parent)350     private ImageReader(int width, int height, int imageFormat, int maxImages, long usage,
351             MultiResolutionImageReader parent) {
352         mWidth = width;
353         mHeight = height;
354         mFormat = imageFormat;
355         mUsage = usage;
356         mMaxImages = maxImages;
357         mParent = parent;
358         // retrieve hal Format and hal dataspace from imageFormat
359         mHardwareBufferFormat = PublicFormatUtils.getHalFormat(mFormat);
360         mDataSpace = PublicFormatUtils.getHalDataspace(mFormat);
361         mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat);
362 
363         initializeImageReader(width, height, imageFormat, maxImages, usage, mHardwareBufferFormat,
364                 mDataSpace);
365     }
366 
ImageReader(int width, int height, int maxImages, long usage, MultiResolutionImageReader parent, int hardwareBufferFormat, int dataSpace)367     private ImageReader(int width, int height, int maxImages, long usage,
368             MultiResolutionImageReader parent, int hardwareBufferFormat, int dataSpace) {
369         mWidth = width;
370         mHeight = height;
371         mUsage = usage;
372         mMaxImages = maxImages;
373         mParent = parent;
374         mHardwareBufferFormat = hardwareBufferFormat;
375         mDataSpace = dataSpace;
376         mNumPlanes = ImageUtils.getNumPlanesForHardwareBufferFormat(mHardwareBufferFormat);
377         mFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
378 
379         initializeImageReader(width, height, mFormat, maxImages, usage, hardwareBufferFormat,
380                 dataSpace);
381     }
382 
383     /**
384      * The default width of {@link Image Images}, in pixels.
385      *
386      * <p>The width may be overridden by the producer sending buffers to this
387      * ImageReader's Surface. If so, the actual width of the images can be
388      * found using {@link Image#getWidth}.</p>
389      *
390      * @return the expected width of an Image
391      */
getWidth()392     public int getWidth() {
393         return mWidth;
394     }
395 
396     /**
397      * The default height of {@link Image Images}, in pixels.
398      *
399      * <p>The height may be overridden by the producer sending buffers to this
400      * ImageReader's Surface. If so, the actual height of the images can be
401      * found using {@link Image#getHeight}.</p>
402      *
403      * @return the expected height of an Image
404      */
getHeight()405     public int getHeight() {
406         return mHeight;
407     }
408 
409     /**
410      * The default {@link ImageFormat image format} of {@link Image Images}.
411      *
412      * <p>Some color formats may be overridden by the producer sending buffers to
413      * this ImageReader's Surface if the default color format allows. ImageReader
414      * guarantees that all {@link Image Images} acquired from ImageReader
415      * (for example, with {@link #acquireNextImage}) will have a "compatible"
416      * format to what was specified in {@link #newInstance}.
417      * As of now, each format is only compatible to itself.
418      * The actual format of the images can be found using {@link Image#getFormat}.</p>
419      *
420      * <p>Use this function if the ImageReader instance is created by factory method
421      * {@code newInstance} function or by builder pattern {@code ImageReader.Builder} and using
422      * {@link Builder#setImageFormat}.</p>
423      *
424      * @return the expected format of an Image
425      *
426      * @see ImageFormat
427      */
getImageFormat()428     public int getImageFormat() {
429         return mFormat;
430     }
431 
432     /**
433      * The default {@link HardwareBuffer} format of {@link Image Images}.
434      *
435      * <p>Use this function if the ImageReader instance is created by builder pattern
436      * {@code ImageReader.Builder} and using {@link Builder#setDefaultHardwareBufferFormat} and
437      * {@link Builder#setDefaultDataSpace}.</p>
438      *
439      * @return the expected {@link HardwareBuffer} format of an Image.
440      */
getHardwareBufferFormat()441     public @HardwareBuffer.Format int getHardwareBufferFormat() {
442         return mHardwareBufferFormat;
443     }
444 
445     /**
446      * The default dataspace of {@link Image Images}.
447      *
448      * <p>Use this function if the ImageReader instance is created by builder pattern
449      * {@code ImageReader.Builder} and {@link Builder#setDefaultDataSpace}.</p>
450      *
451      * @return the expected dataspace of an Image.
452      */
453     @SuppressLint("MethodNameUnits")
getDataSpace()454     public @NamedDataSpace int getDataSpace() {
455         return mDataSpace;
456     }
457 
458     /**
459      * Maximum number of images that can be acquired from the ImageReader by any time (for example,
460      * with {@link #acquireNextImage}).
461      *
462      * <p>An image is considered acquired after it's returned by a function from ImageReader, and
463      * until the Image is {@link Image#close closed} to release the image back to the ImageReader.
464      * </p>
465      *
466      * <p>Attempting to acquire more than {@code maxImages} concurrently will result in the
467      * acquire function throwing a {@link IllegalStateException}. Furthermore,
468      * while the max number of images have been acquired by the ImageReader user, the producer
469      * enqueueing additional images may stall until at least one image has been released. </p>
470      *
471      * @return Maximum number of images for this ImageReader.
472      *
473      * @see Image#close
474      */
getMaxImages()475     public int getMaxImages() {
476         return mMaxImages;
477     }
478 
479     /**
480      * The usage flag of images that can be produced by the ImageReader.
481      *
482      * @return The usage flag of the images for this ImageReader.
483      */
getUsage()484     public @Usage long getUsage() {
485         return mUsage;
486     }
487 
488     /**
489      * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
490      * {@code ImageReader}.</p>
491      *
492      * <p>Until valid image data is rendered into this {@link Surface}, the
493      * {@link #acquireNextImage} method will return {@code null}. Only one source
494      * can be producing data into this Surface at the same time, although the
495      * same {@link Surface} can be reused with a different API once the first source is
496      * disconnected from the {@link Surface}.</p>
497      *
498      * <p>Please note that holding on to the Surface object returned by this method is not enough
499      * to keep its parent ImageReader from being reclaimed. In that sense, a Surface acts like a
500      * {@link java.lang.ref.WeakReference weak reference} to the ImageReader that provides it.</p>
501      *
502      * @return A {@link Surface} to use for a drawing target for various APIs.
503      */
getSurface()504     public Surface getSurface() {
505         return mSurface;
506     }
507 
508     /**
509      * <p>
510      * Acquire the latest {@link Image} from the ImageReader's queue, dropping older
511      * {@link Image images}. Returns {@code null} if no new image is available.
512      * </p>
513      * <p>
514      * This operation will acquire all the images possible from the ImageReader,
515      * but {@link #close} all images that aren't the latest. This function is
516      * recommended to use over {@link #acquireNextImage} for most use-cases, as it's
517      * more suited for real-time processing.
518      * </p>
519      * <p>
520      * Note that {@link #getMaxImages maxImages} should be at least 2 for
521      * {@link #acquireLatestImage} to be any different than {@link #acquireNextImage} -
522      * discarding all-but-the-newest {@link Image} requires temporarily acquiring two
523      * {@link Image Images} at once. Or more generally, calling {@link #acquireLatestImage}
524      * with less than two images of margin, that is
525      * {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected.
526      * </p>
527      * <p>
528      * This operation will fail by throwing an {@link IllegalStateException} if
529      * {@code maxImages} have been acquired with {@link #acquireLatestImage} or
530      * {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage}
531      * calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between
532      * will exhaust the underlying queue. At such a time, {@link IllegalStateException}
533      * will be thrown until more images are
534      * released with {@link Image#close}.
535      * </p>
536      *
537      * @return latest frame of image data, or {@code null} if no image data is available.
538      * @throws IllegalStateException if too many images are currently acquired
539      */
acquireLatestImage()540     public Image acquireLatestImage() {
541         Image image = acquireNextImage();
542         if (image == null) {
543             return null;
544         }
545         try {
546             for (;;) {
547                 Image next = acquireNextImageNoThrowISE();
548                 if (next == null) {
549                     Image result = image;
550                     image = null;
551                     return result;
552                 }
553                 image.close();
554                 image = next;
555             }
556         } finally {
557             if (image != null) {
558                 image.close();
559             }
560             if (mParent != null) {
561                 mParent.flushOther(this);
562             }
563         }
564     }
565 
566     /**
567      * Don't throw IllegalStateException if there are too many images acquired.
568      *
569      * @return Image if acquiring succeeded, or null otherwise.
570      *
571      * @hide
572      */
acquireNextImageNoThrowISE()573     public Image acquireNextImageNoThrowISE() {
574         SurfaceImage si = new SurfaceImage(mFormat);
575         return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
576     }
577 
578     /**
579      * Attempts to acquire the next image from the underlying native implementation.
580      *
581      * <p>
582      * Note that unexpected failures will throw at the JNI level.
583      * </p>
584      *
585      * @param si A blank SurfaceImage.
586      * @return One of the {@code ACQUIRE_*} codes that determine success or failure.
587      *
588      * @see #ACQUIRE_MAX_IMAGES
589      * @see #ACQUIRE_NO_BUFS
590      * @see #ACQUIRE_SUCCESS
591      */
acquireNextSurfaceImage(SurfaceImage si)592     private int acquireNextSurfaceImage(SurfaceImage si) {
593         synchronized (mCloseLock) {
594             // A null image will eventually be returned if ImageReader is already closed.
595             int status = ACQUIRE_NO_BUFS;
596             if (mIsReaderValid) {
597                 status = nativeImageSetup(si);
598             }
599 
600             switch (status) {
601                 case ACQUIRE_SUCCESS:
602                     si.mIsImageValid = true;
603                 case ACQUIRE_NO_BUFS:
604                 case ACQUIRE_MAX_IMAGES:
605                     break;
606                 default:
607                     throw new AssertionError("Unknown nativeImageSetup return code " + status);
608             }
609 
610             // Only keep track the successfully acquired image, as the native buffer is only mapped
611             // for such case.
612             if (status == ACQUIRE_SUCCESS) {
613                 mAcquiredImages.add(si);
614             }
615             return status;
616         }
617     }
618 
619     /**
620      * <p>
621      * Acquire the next Image from the ImageReader's queue. Returns {@code null} if
622      * no new image is available.
623      * </p>
624      *
625      * <p><i>Warning:</i> Consider using {@link #acquireLatestImage()} instead, as it will
626      * automatically release older images, and allow slower-running processing routines to catch
627      * up to the newest frame. Usage of {@link #acquireNextImage} is recommended for
628      * batch/background processing. Incorrectly using this function can cause images to appear
629      * with an ever-increasing delay, followed by a complete stall where no new images seem to
630      * appear.
631      * </p>
632      *
633      * <p>
634      * This operation will fail by throwing an {@link IllegalStateException} if
635      * {@code maxImages} have been acquired with {@link #acquireNextImage} or
636      * {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or
637      * {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without
638      * calling {@link Image#close} in-between will exhaust the underlying queue. At such a time,
639      * {@link IllegalStateException} will be thrown until more images are released with
640      * {@link Image#close}.
641      * </p>
642      *
643      * @return a new frame of image data, or {@code null} if no image data is available.
644      * @throws IllegalStateException if {@code maxImages} images are currently acquired
645      * @see #acquireLatestImage
646      */
acquireNextImage()647     public Image acquireNextImage() {
648         // Initialize with reader format, but can be overwritten by native if the image
649         // format is different from the reader format.
650         SurfaceImage si;
651         si = new SurfaceImage(mFormat);
652         int status = acquireNextSurfaceImage(si);
653 
654         switch (status) {
655             case ACQUIRE_SUCCESS:
656                 return si;
657             case ACQUIRE_NO_BUFS:
658                 return null;
659             case ACQUIRE_MAX_IMAGES:
660                 throw new IllegalStateException(
661                         String.format(
662                                 "maxImages (%d) has already been acquired, " +
663                                 "call #close before acquiring more.", mMaxImages));
664             default:
665                 throw new AssertionError("Unknown nativeImageSetup return code " + status);
666         }
667     }
668 
669     /**
670      * <p>Return the frame to the ImageReader for reuse.</p>
671      *
672      * This method should only be called via {@link SurfaceImage#close} which ensures that image
673      * closing is atomic.
674      */
releaseImage(Image i)675     private void releaseImage(Image i) {
676         if (! (i instanceof SurfaceImage) ) {
677             throw new IllegalArgumentException(
678                 "This image was not produced by an ImageReader");
679         }
680         SurfaceImage si = (SurfaceImage) i;
681         if (si.mIsImageValid == false) {
682             return;
683         }
684 
685         if (si.getReader() != this || !mAcquiredImages.contains(i)) {
686             throw new IllegalArgumentException(
687                 "This image was not produced by this ImageReader");
688         }
689 
690         si.clearSurfacePlanes();
691         nativeReleaseImage(i);
692         si.mIsImageValid = false;
693         mAcquiredImages.remove(i);
694     }
695 
696     /**
697      * Register a listener to be invoked when a new image becomes available
698      * from the ImageReader.
699      *
700      * @param listener
701      *            The listener that will be run.
702      * @param handler
703      *            The handler on which the listener should be invoked, or null
704      *            if the listener should be invoked on the calling thread's looper.
705      * @throws IllegalArgumentException
706      *            If no handler specified and the calling thread has no looper.
707      */
setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler)708     public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
709         synchronized (mListenerLock) {
710             if (listener != null) {
711                 Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
712                 if (looper == null) {
713                     throw new IllegalArgumentException(
714                             "handler is null but the current thread is not a looper");
715                 }
716                 if (mListenerHandler == null || mListenerHandler.getLooper() != looper) {
717                     mListenerHandler = new ListenerHandler(looper);
718                     mListenerExecutor = new HandlerExecutor(mListenerHandler);
719                 }
720             } else {
721                 mListenerHandler = null;
722                 mListenerExecutor = null;
723             }
724             mListener = listener;
725         }
726     }
727 
728     /**
729      * Register a listener to be invoked when a new image becomes available
730      * from the ImageReader.
731      *
732      * @param listener
733      *            The listener that will be run.
734      * @param executor
735      *            The executor which will be used to invoke the listener.
736      * @throws IllegalArgumentException
737      *            If no handler specified and the calling thread has no looper.
738      *
739      * @hide
740      */
setOnImageAvailableListenerWithExecutor(@onNull OnImageAvailableListener listener, @NonNull Executor executor)741     public void setOnImageAvailableListenerWithExecutor(@NonNull OnImageAvailableListener listener,
742             @NonNull Executor executor) {
743         if (executor == null) {
744             throw new IllegalArgumentException("executor must not be null");
745         }
746 
747         synchronized (mListenerLock) {
748             mListenerExecutor = executor;
749             mListener = listener;
750         }
751     }
752 
753     /**
754      * Callback interface for being notified that a new image is available.
755      *
756      * <p>
757      * The onImageAvailable is called per image basis, that is, callback fires for every new frame
758      * available from ImageReader.
759      * </p>
760      */
761     public interface OnImageAvailableListener {
762         /**
763          * Callback that is called when a new image is available from ImageReader.
764          *
765          * @param reader the ImageReader the callback is associated with.
766          * @see ImageReader
767          * @see Image
768          */
onImageAvailable(ImageReader reader)769         void onImageAvailable(ImageReader reader);
770     }
771 
772     /**
773      * Free up all the resources associated with this ImageReader.
774      *
775      * <p>
776      * After calling this method, this ImageReader can not be used. Calling
777      * any methods on this ImageReader and Images previously provided by
778      * {@link #acquireNextImage} or {@link #acquireLatestImage}
779      * will result in an {@link IllegalStateException}, and attempting to read from
780      * {@link ByteBuffer ByteBuffers} returned by an earlier
781      * {@link Image.Plane#getBuffer Plane#getBuffer} call will
782      * have undefined behavior.
783      * </p>
784      */
785     @Override
close()786     public void close() {
787         setOnImageAvailableListener(null, null);
788         if (mSurface != null) mSurface.release();
789 
790         /**
791          * Close all outstanding acquired images before closing the ImageReader. It is a good
792          * practice to close all the images as soon as it is not used to reduce system instantaneous
793          * memory pressure. CopyOnWrite list will use a copy of current list content. For the images
794          * being closed by other thread (e.g., GC thread), doubling the close call is harmless. For
795          * the image being acquired by other threads, mCloseLock is used to synchronize close and
796          * acquire operations.
797          */
798         synchronized (mCloseLock) {
799             mIsReaderValid = false;
800             for (Image image : mAcquiredImages) {
801                 image.close();
802             }
803             mAcquiredImages.clear();
804 
805             nativeClose();
806 
807             if (mEstimatedNativeAllocBytes > 0) {
808                 VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
809                 mEstimatedNativeAllocBytes = 0;
810             }
811         }
812     }
813 
814     /**
815      * Discard any free buffers owned by this ImageReader.
816      *
817      * <p>
818      * Generally, the ImageReader caches buffers for reuse once they have been
819      * allocated, for best performance. However, sometimes it may be important to
820      * release all the cached, unused buffers to save on memory.
821      * </p>
822      * <p>
823      * Calling this method will discard all free cached buffers. This does not include any buffers
824      * associated with Images acquired from the ImageReader, any filled buffers waiting to be
825      * acquired, and any buffers currently in use by the source rendering buffers into the
826      * ImageReader's Surface.
827      * <p>
828      * The ImageReader continues to be usable after this call, but may need to reallocate buffers
829      * when more buffers are needed for rendering.
830      * </p>
831      */
discardFreeBuffers()832     public void discardFreeBuffers() {
833         synchronized (mCloseLock) {
834             nativeDiscardFreeBuffers();
835         }
836     }
837 
838     @Override
finalize()839     protected void finalize() throws Throwable {
840         try {
841             close();
842         } finally {
843             super.finalize();
844         }
845     }
846 
847     /**
848      * <p>
849      * Remove the ownership of this image from the ImageReader.
850      * </p>
851      * <p>
852      * After this call, the ImageReader no longer owns this image, and the image
853      * ownership can be transferred to another entity like {@link ImageWriter}
854      * via {@link ImageWriter#queueInputImage}. It's up to the new owner to
855      * release the resources held by this image. For example, if the ownership
856      * of this image is transferred to an {@link ImageWriter}, the image will be
857      * freed by the ImageWriter after the image data consumption is done.
858      * </p>
859      * <p>
860      * This method can be used to achieve zero buffer copy for use cases like
861      * {@link android.hardware.camera2.CameraDevice Camera2 API} PRIVATE and YUV
862      * reprocessing, where the application can select an output image from
863      * {@link ImageReader} and transfer this image directly to
864      * {@link ImageWriter}, where this image can be consumed by camera directly.
865      * For PRIVATE reprocessing, this is the only way to send input buffers to
866      * the {@link android.hardware.camera2.CameraDevice camera} for
867      * reprocessing.
868      * </p>
869      * <p>
870      * This is a package private method that is only used internally.
871      * </p>
872      *
873      * @param image The image to be detached from this ImageReader.
874      * @throws IllegalStateException If the ImageReader or image have been
875      *             closed, or the has been detached, or has not yet been
876      *             acquired.
877      * @throws RuntimeException If there is an error detaching {@code Image} from {@code Surface}.
878      *              {@code RuntimeException} is only thrown for applications targeting SDK <=
879      *              {@link android.os.Build.VERSION_CODES#TIRAMISU}.
880      *              For applications targeting SDK >
881      *              {@link android.os.Build.VERSION_CODES#TIRAMISU},
882      *              this method only throws {@code IllegalStateException}.
883      * @hide
884      */
detachImage(@ullable Image image)885     public void detachImage(@Nullable Image image) {
886         if (image == null) {
887            throw new IllegalArgumentException("input image must not be null");
888         }
889         if (!isImageOwnedbyMe(image)) {
890            throw new IllegalArgumentException("Trying to detach an image that is not owned by"
891                    + " this ImageReader");
892         }
893 
894         SurfaceImage si = (SurfaceImage) image;
895         si.throwISEIfImageIsInvalid();
896 
897         if (si.isAttachable()) {
898             throw new IllegalStateException("Image was already detached from this ImageReader");
899         }
900 
901         nativeDetachImage(image, mDetachThrowsIseOnly);
902         si.clearSurfacePlanes();
903         si.mPlanes = null;
904         si.setDetached(true);
905     }
906 
isImageOwnedbyMe(Image image)907     private boolean isImageOwnedbyMe(Image image) {
908         if (!(image instanceof SurfaceImage)) {
909             return false;
910         }
911         SurfaceImage si = (SurfaceImage) image;
912         return si.getReader() == this;
913     }
914 
915     /**
916      * Called from Native code when an Event happens.
917      *
918      * This may be called from an arbitrary Binder thread, so access to the ImageReader must be
919      * synchronized appropriately.
920      */
postEventFromNative(Object selfRef)921     private static void postEventFromNative(Object selfRef) {
922         @SuppressWarnings("unchecked")
923         WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef;
924         final ImageReader ir = weakSelf.get();
925         if (ir == null) {
926             return;
927         }
928 
929         final Executor executor;
930         final OnImageAvailableListener listener;
931         synchronized (ir.mListenerLock) {
932             executor = ir.mListenerExecutor;
933             listener = ir.mListener;
934         }
935         final boolean isReaderValid;
936         synchronized (ir.mCloseLock) {
937             isReaderValid = ir.mIsReaderValid;
938         }
939 
940         // It's dangerous to fire onImageAvailable() callback when the ImageReader
941         // is being closed, as application could acquire next image in the
942         // onImageAvailable() callback.
943         if (executor != null && listener != null && isReaderValid) {
944             executor.execute(new Runnable() {
945                 @Override
946                 public void run() {
947                     listener.onImageAvailable(ir);
948                 }
949             });
950         }
951     }
952 
953     /**
954      * Builder class for {@link ImageReader} objects.
955      */
956     public static final class Builder {
957         private int mWidth;
958         private int mHeight;
959         private int mMaxImages = 1;
960         private int mImageFormat = ImageFormat.UNKNOWN;
961         private int mHardwareBufferFormat = HardwareBuffer.RGBA_8888;
962         private int mDataSpace = DataSpace.DATASPACE_UNKNOWN;
963         private long mUsage = HardwareBuffer.USAGE_CPU_READ_OFTEN;
964         private boolean mUseLegacyImageFormat = false;
965 
966         /**
967          * Constructs a new builder for {@link ImageReader}.
968          *
969          * @param width The default width in pixels that will be passed to the producer.
970          *              May be overridden by the producer.
971          * @param height The default height in pixels that will be passed to the producer.
972          *              May be overridden by the producer.
973          * @see Image
974          */
Builder(@ntRangefrom = 1) int width, @IntRange(from = 1) int height)975         public Builder(@IntRange(from = 1) int width, @IntRange(from = 1) int height) {
976             mWidth = width;
977             mHeight = height;
978         }
979 
980         /**
981          * Set the maximal number of images.
982          *
983          * @param maxImages The maximum number of images the user will want to
984          *            access simultaneously. This should be as small as possible to
985          *            limit memory use. Default value is 1.
986          * @return the Builder instance with customized usage value.
987          */
setMaxImages(int maxImages)988         public @NonNull Builder setMaxImages(int maxImages) {
989             mMaxImages = maxImages;
990             return this;
991         }
992 
993         /**
994          * Set the consumer usage flag.
995          *
996          * @param usage The intended usage of the images consumed by this ImageReader.
997          *              See the usages on {@link HardwareBuffer} for a list of valid usage bits.
998          *              Default value is {@link HardwareBuffer#USAGE_CPU_READ_OFTEN}.
999          * @return the Builder instance with customized usage value.
1000          *
1001          * @see HardwareBuffer
1002          */
setUsage(@sage long usage)1003         public @NonNull Builder setUsage(@Usage long usage) {
1004             mUsage = usage;
1005             return this;
1006         }
1007 
1008         /**
1009          * Set the default image format passed by the producer. May be overridden by the producer.
1010          *
1011          * <p>{@link #setImageFormat} function replaces the combination of
1012          * {@link #setDefaultHardwareBufferFormat} and {@link #setDefaultDataSpace} functions.
1013          * Either this or these two functions must be called to initialize an {@code ImageReader}
1014          * instance.</p>
1015          *
1016          * @param imageFormat The format of the image that this reader will produce. This
1017          *                    must be one of the {@link android.graphics.ImageFormat} or
1018          *                   {@link android.graphics.PixelFormat} constants. Note that not
1019          *                   all formats are supported, like ImageFormat.NV21. The default value is
1020          *                   {@link ImageFormat#UNKNOWN}.
1021          * @return the builder instance with customized image format value.
1022          *
1023          * @see #setDefaultHardwareBufferFormat
1024          * @see #setDefaultDataSpace
1025          */
setImageFormat(@ormat int imageFormat)1026         public @NonNull Builder setImageFormat(@Format int imageFormat) {
1027             mImageFormat = imageFormat;
1028             mUseLegacyImageFormat = true;
1029             mHardwareBufferFormat = HardwareBuffer.RGBA_8888;
1030             mDataSpace = DataSpace.DATASPACE_UNKNOWN;
1031             return this;
1032         }
1033 
1034         /**
1035          * Set the default hardwareBuffer format passed by the producer.
1036          * May be overridden by the producer.
1037          *
1038          * <p>This function works together with {@link #setDefaultDataSpace} for an
1039          * {@link ImageReader} instance. Setting at least one of these two replaces
1040          * {@link #setImageFormat} function.</p>
1041          *
1042          * <p>The format of the Image can be overridden after {@link #setImageFormat} by calling
1043          * this function and then {@link #setDefaultDataSpace} functions.
1044          * <i>Warning:</i> Missing one of callings for initializing or overriding the format may
1045          * involve undefined behaviors.</p>
1046          *
1047          * @param hardwareBufferFormat The HardwareBuffer format of the image that this reader
1048          *                             will produce. The default value is
1049          *                             {@link HardwareBuffer#RGBA_8888 HardwareBuffer.RGBA_8888}.
1050          * @return the builder instance with customized hardwareBuffer value.
1051          *
1052          * @see #setDefaultDataSpace
1053          * @see #setImageFormat
1054          */
1055         @SuppressLint("MissingGetterMatchingBuilder")
setDefaultHardwareBufferFormat( @ardwareBuffer.Format int hardwareBufferFormat)1056         public @NonNull Builder setDefaultHardwareBufferFormat(
1057                 @HardwareBuffer.Format int hardwareBufferFormat) {
1058             mHardwareBufferFormat = hardwareBufferFormat;
1059             mUseLegacyImageFormat = false;
1060             mImageFormat = ImageFormat.UNKNOWN;
1061             return this;
1062         }
1063 
1064         /**
1065          * Set the default dataspace passed by the producer.
1066          * May be overridden by the producer.
1067          *
1068          * <p>This function works together with {@link #setDefaultHardwareBufferFormat} for an
1069          * {@link ImageReader} instance. Setting at least one of these two replaces
1070          * {@link #setImageFormat} function.</p>
1071          *
1072          * @param dataSpace The dataspace of the image that this reader will produce.
1073          *                  The default value is {@link DataSpace#DATASPACE_UNKNOWN}.
1074          * @return the builder instance with customized dataspace value.
1075          *
1076          * @see #setDefaultHardwareBufferFormat
1077          */
1078         @SuppressLint("MissingGetterMatchingBuilder")
setDefaultDataSpace(@amedDataSpace int dataSpace)1079         public @NonNull Builder setDefaultDataSpace(@NamedDataSpace int dataSpace) {
1080             mDataSpace = dataSpace;
1081             mUseLegacyImageFormat = false;
1082             mImageFormat = ImageFormat.UNKNOWN;
1083             return this;
1084         }
1085 
1086         /**
1087          * Builds a new ImageReader object.
1088          *
1089          * @return The new ImageReader object.
1090          */
build()1091         public @NonNull ImageReader build() {
1092             if (mUseLegacyImageFormat) {
1093                 return new ImageReader(mWidth, mHeight, mImageFormat, mMaxImages, mUsage, null);
1094             } else {
1095                 return new ImageReader(mWidth, mHeight, mMaxImages, mUsage, null,
1096                     mHardwareBufferFormat, mDataSpace);
1097             }
1098         }
1099     }
1100 
1101     private final int mWidth;
1102     private final int mHeight;
1103     private final int mFormat;
1104     private final long mUsage;
1105     private final int mMaxImages;
1106     private final int mNumPlanes;
1107     private Surface mSurface;
1108     private int mEstimatedNativeAllocBytes;
1109 
1110     private final Object mListenerLock = new Object();
1111     private final Object mCloseLock = new Object();
1112     private boolean mIsReaderValid = false;
1113     private OnImageAvailableListener mListener;
1114     private Executor mListenerExecutor;
1115     private ListenerHandler mListenerHandler;
1116     // Keep track of the successfully acquired Images. This need to be thread safe as the images
1117     // could be closed by different threads (e.g., application thread and GC thread).
1118     private List<Image> mAcquiredImages = new CopyOnWriteArrayList<>();
1119 
1120     // Applicable if this isn't a standalone ImageReader, but belongs to a
1121     // MultiResolutionImageReader.
1122     private final MultiResolutionImageReader mParent;
1123 
1124     private final int mHardwareBufferFormat;
1125 
1126     private final @NamedDataSpace int mDataSpace;
1127 
1128     /**
1129      * This field is used by native code, do not access or modify.
1130      */
1131     private long mNativeContext;
1132 
1133     /**
1134      * This custom handler runs asynchronously so callbacks don't get queued behind UI messages.
1135      */
1136     private final class ListenerHandler extends Handler {
ListenerHandler(Looper looper)1137         public ListenerHandler(Looper looper) {
1138             super(looper, null, true /*async*/);
1139         }
1140     }
1141 
1142     /**
1143      * An adapter {@link Executor} that posts all executed tasks onto the
1144      * given {@link Handler}.
1145      **/
1146     private final class HandlerExecutor implements Executor {
1147         private final Handler mHandler;
1148 
HandlerExecutor(@onNull Handler handler)1149         public HandlerExecutor(@NonNull Handler handler) {
1150             mHandler = Objects.requireNonNull(handler);
1151         }
1152 
1153         @Override
execute(Runnable command)1154         public void execute(Runnable command) {
1155             mHandler.post(command);
1156         }
1157     }
1158 
1159     private class SurfaceImage extends android.media.Image {
1160         private final Object mCloseLock = new Object();
1161 
SurfaceImage(int format)1162         public SurfaceImage(int format) {
1163             mFormat = format;
1164             mHardwareBufferFormat = ImageReader.this.mHardwareBufferFormat;
1165             mDataSpace = ImageReader.this.mDataSpace;
1166         }
1167 
1168         @Override
close()1169         public void close() {
1170             synchronized (this.mCloseLock) {
1171                 ImageReader.this.releaseImage(this);
1172             }
1173         }
1174 
getReader()1175         public ImageReader getReader() {
1176             return ImageReader.this;
1177         }
1178 
1179         @Override
getFormat()1180         public int getFormat() {
1181             throwISEIfImageIsInvalid();
1182             // update mFormat only if ImageReader is initialized by factory pattern.
1183             // if using builder pattern, mFormat has been updated upon initialization.
1184             // no need update here.
1185             int readerFormat = ImageReader.this.getImageFormat();
1186             // Assume opaque reader always produce opaque images.
1187             mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat :
1188                 nativeGetFormat(readerFormat);
1189             return mFormat;
1190         }
1191 
1192         @Override
getWidth()1193         public int getWidth() {
1194             throwISEIfImageIsInvalid();
1195             int width;
1196             switch(getFormat()) {
1197                 case ImageFormat.JPEG:
1198                 case ImageFormat.DEPTH_POINT_CLOUD:
1199                 case ImageFormat.RAW_PRIVATE:
1200                 case ImageFormat.DEPTH_JPEG:
1201                 case ImageFormat.HEIC:
1202                 case ImageFormat.JPEG_R:
1203                     width = ImageReader.this.getWidth();
1204                     break;
1205                 default:
1206                     width = nativeGetWidth();
1207             }
1208             return width;
1209         }
1210 
1211         @Override
getHeight()1212         public int getHeight() {
1213             throwISEIfImageIsInvalid();
1214             int height;
1215             switch(getFormat()) {
1216                 case ImageFormat.JPEG:
1217                 case ImageFormat.DEPTH_POINT_CLOUD:
1218                 case ImageFormat.RAW_PRIVATE:
1219                 case ImageFormat.DEPTH_JPEG:
1220                 case ImageFormat.HEIC:
1221                 case ImageFormat.JPEG_R:
1222                     height = ImageReader.this.getHeight();
1223                     break;
1224                 default:
1225                     height = nativeGetHeight();
1226             }
1227             return height;
1228         }
1229 
1230         @Override
getTimestamp()1231         public long getTimestamp() {
1232             throwISEIfImageIsInvalid();
1233             return mTimestamp;
1234         }
1235 
1236         @Override
getTransform()1237         public int getTransform() {
1238             throwISEIfImageIsInvalid();
1239             return mTransform;
1240         }
1241 
1242         @Override
getScalingMode()1243         public int getScalingMode() {
1244             throwISEIfImageIsInvalid();
1245             return mScalingMode;
1246         }
1247 
1248         @Override
getPlaneCount()1249         public int getPlaneCount() {
1250             throwISEIfImageIsInvalid();
1251             return ImageReader.this.mNumPlanes;
1252         }
1253 
1254         @Override
getFence()1255         public SyncFence getFence() throws IOException {
1256             throwISEIfImageIsInvalid();
1257             // duplicate ParcelFileDescriptor because native still retains the fence ownership.
1258             int fence = nativeGetFenceFd();
1259             if (fence != -1) {
1260                 return SyncFence.create(ParcelFileDescriptor.fromFd(nativeGetFenceFd()));
1261             } else {
1262                 return SyncFence.createEmpty();
1263             }
1264         }
1265 
1266         @Override
getHardwareBuffer()1267         public HardwareBuffer getHardwareBuffer() {
1268             throwISEIfImageIsInvalid();
1269             return nativeGetHardwareBuffer();
1270         }
1271 
1272         @Override
getDataSpace()1273         public @NamedDataSpace int getDataSpace() {
1274             throwISEIfImageIsInvalid();
1275             return mDataSpace;
1276         }
1277 
1278         @Override
setTimestamp(long timestampNs)1279         public void setTimestamp(long timestampNs) {
1280             throwISEIfImageIsInvalid();
1281             mTimestamp = timestampNs;
1282         }
1283 
1284         @Override
getPlanes()1285         public Plane[] getPlanes() {
1286             throwISEIfImageIsInvalid();
1287 
1288             if (mPlanes == null) {
1289                 mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes,
1290                         ImageReader.this.mHardwareBufferFormat, ImageReader.this.mUsage);
1291             }
1292             // Shallow copy is fine.
1293             return mPlanes.clone();
1294         }
1295 
1296         @Override
finalize()1297         protected final void finalize() throws Throwable {
1298             try {
1299                 close();
1300             } finally {
1301                 super.finalize();
1302             }
1303         }
1304 
1305         @Override
isAttachable()1306         public boolean isAttachable() {
1307             throwISEIfImageIsInvalid();
1308             return mIsDetached.get();
1309         }
1310 
1311         @Override
getOwner()1312         ImageReader getOwner() {
1313             throwISEIfImageIsInvalid();
1314             return ImageReader.this;
1315         }
1316 
1317         @Override
getNativeContext()1318         long getNativeContext() {
1319             throwISEIfImageIsInvalid();
1320             return mNativeBuffer;
1321         }
1322 
setDetached(boolean detached)1323         private void setDetached(boolean detached) {
1324             throwISEIfImageIsInvalid();
1325             mIsDetached.getAndSet(detached);
1326         }
1327 
clearSurfacePlanes()1328         private void clearSurfacePlanes() {
1329             // Image#getPlanes may not be called before the image is closed.
1330             if (mIsImageValid && mPlanes != null) {
1331                 for (int i = 0; i < mPlanes.length; i++) {
1332                     if (mPlanes[i] != null) {
1333                         mPlanes[i].clearBuffer();
1334                         mPlanes[i] = null;
1335                     }
1336                 }
1337             }
1338         }
1339 
1340         private class SurfacePlane extends android.media.Image.Plane {
1341             // SurfacePlane instance is created by native code when SurfaceImage#getPlanes() is
1342             // called
SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer)1343             private SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
1344                 mRowStride = rowStride;
1345                 mPixelStride = pixelStride;
1346                 mBuffer = buffer;
1347                 /**
1348                  * Set the byteBuffer order according to host endianness (native
1349                  * order), otherwise, the byteBuffer order defaults to
1350                  * ByteOrder.BIG_ENDIAN.
1351                  */
1352                 mBuffer.order(ByteOrder.nativeOrder());
1353             }
1354 
1355             @Override
getBuffer()1356             public ByteBuffer getBuffer() {
1357                 throwISEIfImageIsInvalid();
1358                 return mBuffer;
1359             }
1360 
1361             @Override
getPixelStride()1362             public int getPixelStride() {
1363                 SurfaceImage.this.throwISEIfImageIsInvalid();
1364                 if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
1365                     throw new UnsupportedOperationException(
1366                             "getPixelStride is not supported for RAW_PRIVATE plane");
1367                 }
1368                 return mPixelStride;
1369             }
1370 
1371             @Override
getRowStride()1372             public int getRowStride() {
1373                 SurfaceImage.this.throwISEIfImageIsInvalid();
1374                 if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
1375                     throw new UnsupportedOperationException(
1376                             "getRowStride is not supported for RAW_PRIVATE plane");
1377                 }
1378                 return mRowStride;
1379             }
1380 
clearBuffer()1381             private void clearBuffer() {
1382                 // Need null check first, as the getBuffer() may not be called before an image
1383                 // is closed.
1384                 if (mBuffer == null) {
1385                     return;
1386                 }
1387 
1388                 if (mBuffer.isDirect()) {
1389                     NioUtils.freeDirectBuffer(mBuffer);
1390                 }
1391                 mBuffer = null;
1392             }
1393 
1394             final private int mPixelStride;
1395             final private int mRowStride;
1396 
1397             private ByteBuffer mBuffer;
1398         }
1399 
1400         /**
1401          * This field is used to keep track of native object and used by native code only.
1402          * Don't modify.
1403          */
1404         private long mNativeBuffer;
1405 
1406         /**
1407          * These fields are set by native code during nativeImageSetup().
1408          */
1409         private long mTimestamp;
1410         private int mTransform;
1411         private int mScalingMode;
1412 
1413         private SurfacePlane[] mPlanes;
1414         private int mFormat = ImageFormat.UNKNOWN;
1415         private int mHardwareBufferFormat = HardwareBuffer.RGBA_8888;
1416         private int mDataSpace = DataSpace.DATASPACE_UNKNOWN;
1417         // If this image is detached from the ImageReader.
1418         private AtomicBoolean mIsDetached = new AtomicBoolean(false);
1419 
nativeCreatePlanes(int numPlanes, int hardwareBufferFormat, long readerUsage)1420         private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
1421                 int hardwareBufferFormat, long readerUsage);
nativeGetWidth()1422         private synchronized native int nativeGetWidth();
nativeGetHeight()1423         private synchronized native int nativeGetHeight();
nativeGetFormat(int readerFormat)1424         private synchronized native int nativeGetFormat(int readerFormat);
nativeGetFenceFd()1425         private synchronized native int nativeGetFenceFd();
nativeGetHardwareBuffer()1426         private synchronized native HardwareBuffer nativeGetHardwareBuffer();
1427     }
1428 
nativeInit(Object weakSelf, int w, int h, int maxImgs, long consumerUsage, int hardwareBufferFormat, int dataSpace)1429     private synchronized native void nativeInit(Object weakSelf, int w, int h, int maxImgs,
1430             long consumerUsage, int hardwareBufferFormat, int dataSpace);
nativeClose()1431     private synchronized native void nativeClose();
nativeReleaseImage(Image i)1432     private synchronized native void nativeReleaseImage(Image i);
nativeGetSurface()1433     private synchronized native Surface nativeGetSurface();
nativeDetachImage(Image i, boolean throwISEOnly)1434     private synchronized native int nativeDetachImage(Image i, boolean throwISEOnly);
nativeDiscardFreeBuffers()1435     private synchronized native void nativeDiscardFreeBuffers();
1436 
1437     /**
1438      * @return A return code {@code ACQUIRE_*}
1439      *
1440      * @see #ACQUIRE_SUCCESS
1441      * @see #ACQUIRE_NO_BUFS
1442      * @see #ACQUIRE_MAX_IMAGES
1443      */
nativeImageSetup(Image i)1444     private synchronized native int nativeImageSetup(Image i);
1445 
1446     /**
1447      * @hide
1448      */
1449     public static class ImagePlane extends android.media.Image.Plane {
ImagePlane(int rowStride, int pixelStride, ByteBuffer buffer)1450         private ImagePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
1451             mRowStride = rowStride;
1452             mPixelStride = pixelStride;
1453             mBuffer = buffer;
1454             /**
1455              * Set the byteBuffer order according to host endianness (native
1456              * order), otherwise, the byteBuffer order defaults to
1457              * ByteOrder.BIG_ENDIAN.
1458              */
1459             mBuffer.order(ByteOrder.nativeOrder());
1460         }
1461 
1462         @Override
getBuffer()1463         public ByteBuffer getBuffer() {
1464             return mBuffer;
1465         }
1466 
1467         @Override
getPixelStride()1468         public int getPixelStride() {
1469             return mPixelStride;
1470         }
1471 
1472         @Override
getRowStride()1473         public int getRowStride() {
1474             return mRowStride;
1475         }
1476 
1477         final private int mPixelStride;
1478         final private int mRowStride;
1479 
1480         private ByteBuffer mBuffer;
1481     }
1482 
1483     /**
1484      * @hide
1485      */
initializeImagePlanes(int numPlanes, GraphicBuffer buffer, int fenceFd, int format, long timestamp, int transform, int scalingMode, Rect crop)1486     public static ImagePlane[] initializeImagePlanes(int numPlanes,
1487             GraphicBuffer buffer, int fenceFd, int format, long timestamp, int transform,
1488             int scalingMode, Rect crop) {
1489 
1490         return nativeCreateImagePlanes(numPlanes, buffer, fenceFd, format, crop.left, crop.top,
1491                 crop.right, crop.bottom);
1492     }
1493 
nativeCreateImagePlanes(int numPlanes, GraphicBuffer buffer, int fenceFd, int format, int cropLeft, int cropTop, int cropRight, int cropBottom)1494     private synchronized static native ImagePlane[] nativeCreateImagePlanes(int numPlanes,
1495             GraphicBuffer buffer, int fenceFd, int format, int cropLeft, int cropTop,
1496             int cropRight, int cropBottom);
1497 
1498     /**
1499      * @hide
1500      */
unlockGraphicBuffer(GraphicBuffer buffer)1501     public static void unlockGraphicBuffer(GraphicBuffer buffer) {
1502         nativeUnlockGraphicBuffer(buffer);
1503     }
1504 
nativeUnlockGraphicBuffer(GraphicBuffer buffer)1505     private synchronized static native void nativeUnlockGraphicBuffer(GraphicBuffer buffer);
1506 
1507     /**
1508      * We use a class initializer to allow the native code to cache some
1509      * field offsets.
1510      */
nativeClassInit()1511     private static native void nativeClassInit();
1512     static {
1513         System.loadLibrary("media_jni");
nativeClassInit()1514         nativeClassInit();
1515     }
1516 }
1517