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