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