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.graphics.ImageFormat; 20 import android.os.Handler; 21 import android.os.Looper; 22 import android.os.Message; 23 import android.util.Log; 24 import android.view.Surface; 25 26 import dalvik.system.VMRuntime; 27 28 import java.lang.ref.WeakReference; 29 import java.nio.ByteBuffer; 30 import java.nio.ByteOrder; 31 import java.nio.NioUtils; 32 import java.util.List; 33 import java.util.concurrent.CopyOnWriteArrayList; 34 import java.util.concurrent.atomic.AtomicBoolean; 35 36 /** 37 * <p>The ImageReader class allows direct application access to image data 38 * rendered into a {@link android.view.Surface}</p> 39 * 40 * <p>Several Android media API classes accept Surface objects as targets to 41 * render to, including {@link MediaPlayer}, {@link MediaCodec}, 42 * {@link android.hardware.camera2.CameraDevice}, {@link ImageWriter} and 43 * {@link android.renderscript.Allocation RenderScript Allocations}. The image 44 * sizes and formats that can be used with each source vary, and should be 45 * checked in the documentation for the specific API.</p> 46 * 47 * <p>The image data is encapsulated in {@link Image} objects, and multiple such 48 * objects can be accessed at the same time, up to the number specified by the 49 * {@code maxImages} constructor parameter. New images sent to an ImageReader 50 * through its {@link Surface} are queued until accessed through the {@link #acquireLatestImage} 51 * or {@link #acquireNextImage} call. Due to memory limits, an image source will 52 * eventually stall or drop Images in trying to render to the Surface if the 53 * ImageReader does not obtain and release Images at a rate equal to the 54 * production rate.</p> 55 */ 56 public class ImageReader implements AutoCloseable { 57 58 /** 59 * Returned by nativeImageSetup when acquiring the image was successful. 60 */ 61 private static final int ACQUIRE_SUCCESS = 0; 62 /** 63 * Returned by nativeImageSetup when we couldn't acquire the buffer, 64 * because there were no buffers available to acquire. 65 */ 66 private static final int ACQUIRE_NO_BUFS = 1; 67 /** 68 * Returned by nativeImageSetup when we couldn't acquire the buffer 69 * because the consumer has already acquired {@maxImages} and cannot 70 * acquire more than that. 71 */ 72 private static final int ACQUIRE_MAX_IMAGES = 2; 73 74 /** 75 * <p> 76 * Create a new reader for images of the desired size and format. 77 * </p> 78 * <p> 79 * The {@code maxImages} parameter determines the maximum number of 80 * {@link Image} objects that can be be acquired from the 81 * {@code ImageReader} simultaneously. Requesting more buffers will use up 82 * more memory, so it is important to use only the minimum number necessary 83 * for the use case. 84 * </p> 85 * <p> 86 * The valid sizes and formats depend on the source of the image data. 87 * </p> 88 * <p> 89 * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created 90 * {@link ImageReader} will produce images that are not directly accessible 91 * by the application. The application can still acquire images from this 92 * {@link ImageReader}, and send them to the 93 * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via 94 * {@link ImageWriter} interface. However, the {@link Image#getPlanes() 95 * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE 96 * PRIVATE} format images. The application can check if an existing reader's 97 * format by calling {@link #getImageFormat()}. 98 * </p> 99 * <p> 100 * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader 101 * ImageReaders} are more efficient to use when application access to image 102 * data is not necessary, compared to ImageReaders using other format such 103 * as {@link ImageFormat#YUV_420_888 YUV_420_888}. 104 * </p> 105 * 106 * @param width The default width in pixels of the Images that this reader 107 * will produce. 108 * @param height The default height in pixels of the Images that this reader 109 * will produce. 110 * @param format The format of the Image that this reader will produce. This 111 * must be one of the {@link android.graphics.ImageFormat} or 112 * {@link android.graphics.PixelFormat} constants. Note that not 113 * all formats are supported, like ImageFormat.NV21. 114 * @param maxImages The maximum number of images the user will want to 115 * access simultaneously. This should be as small as possible to 116 * limit memory use. Once maxImages Images are obtained by the 117 * user, one of them has to be released before a new Image will 118 * become available for access through 119 * {@link #acquireLatestImage()} or {@link #acquireNextImage()}. 120 * Must be greater than 0. 121 * @see Image 122 */ 123 public static ImageReader newInstance(int width, int height, int format, int maxImages) { 124 return new ImageReader(width, height, format, maxImages); 125 } 126 127 /** 128 * @hide 129 */ 130 protected ImageReader(int width, int height, int format, int maxImages) { 131 mWidth = width; 132 mHeight = height; 133 mFormat = format; 134 mMaxImages = maxImages; 135 136 if (width < 1 || height < 1) { 137 throw new IllegalArgumentException( 138 "The image dimensions must be positive"); 139 } 140 if (mMaxImages < 1) { 141 throw new IllegalArgumentException( 142 "Maximum outstanding image count must be at least 1"); 143 } 144 145 if (format == ImageFormat.NV21) { 146 throw new IllegalArgumentException( 147 "NV21 format is not supported"); 148 } 149 150 mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat); 151 152 nativeInit(new WeakReference<ImageReader>(this), width, height, format, maxImages); 153 154 mSurface = nativeGetSurface(); 155 156 mIsReaderValid = true; 157 // Estimate the native buffer allocation size and register it so it gets accounted for 158 // during GC. Note that this doesn't include the buffers required by the buffer queue 159 // itself and the buffers requested by the producer. 160 // Only include memory for 1 buffer, since actually accounting for the memory used is 161 // complex, and 1 buffer is enough for the VM to treat the ImageReader as being of some 162 // size. 163 mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes( 164 width, height, format, /*buffer count*/ 1); 165 VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes); 166 } 167 168 /** 169 * The default width of {@link Image Images}, in pixels. 170 * 171 * <p>The width may be overridden by the producer sending buffers to this 172 * ImageReader's Surface. If so, the actual width of the images can be 173 * found using {@link Image#getWidth}.</p> 174 * 175 * @return the expected width of an Image 176 */ 177 public int getWidth() { 178 return mWidth; 179 } 180 181 /** 182 * The default height of {@link Image Images}, in pixels. 183 * 184 * <p>The height may be overridden by the producer sending buffers to this 185 * ImageReader's Surface. If so, the actual height of the images can be 186 * found using {@link Image#getHeight}.</p> 187 * 188 * @return the expected height of an Image 189 */ 190 public int getHeight() { 191 return mHeight; 192 } 193 194 /** 195 * The default {@link ImageFormat image format} of {@link Image Images}. 196 * 197 * <p>Some color formats may be overridden by the producer sending buffers to 198 * this ImageReader's Surface if the default color format allows. ImageReader 199 * guarantees that all {@link Image Images} acquired from ImageReader 200 * (for example, with {@link #acquireNextImage}) will have a "compatible" 201 * format to what was specified in {@link #newInstance}. 202 * As of now, each format is only compatible to itself. 203 * The actual format of the images can be found using {@link Image#getFormat}.</p> 204 * 205 * @return the expected format of an Image 206 * 207 * @see ImageFormat 208 */ 209 public int getImageFormat() { 210 return mFormat; 211 } 212 213 /** 214 * Maximum number of images that can be acquired from the ImageReader by any time (for example, 215 * with {@link #acquireNextImage}). 216 * 217 * <p>An image is considered acquired after it's returned by a function from ImageReader, and 218 * until the Image is {@link Image#close closed} to release the image back to the ImageReader. 219 * </p> 220 * 221 * <p>Attempting to acquire more than {@code maxImages} concurrently will result in the 222 * acquire function throwing a {@link IllegalStateException}. Furthermore, 223 * while the max number of images have been acquired by the ImageReader user, the producer 224 * enqueueing additional images may stall until at least one image has been released. </p> 225 * 226 * @return Maximum number of images for this ImageReader. 227 * 228 * @see Image#close 229 */ 230 public int getMaxImages() { 231 return mMaxImages; 232 } 233 234 /** 235 * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this 236 * {@code ImageReader}.</p> 237 * 238 * <p>Until valid image data is rendered into this {@link Surface}, the 239 * {@link #acquireNextImage} method will return {@code null}. Only one source 240 * can be producing data into this Surface at the same time, although the 241 * same {@link Surface} can be reused with a different API once the first source is 242 * disconnected from the {@link Surface}.</p> 243 * 244 * @return A {@link Surface} to use for a drawing target for various APIs. 245 */ 246 public Surface getSurface() { 247 return mSurface; 248 } 249 250 /** 251 * <p> 252 * Acquire the latest {@link Image} from the ImageReader's queue, dropping older 253 * {@link Image images}. Returns {@code null} if no new image is available. 254 * </p> 255 * <p> 256 * This operation will acquire all the images possible from the ImageReader, 257 * but {@link #close} all images that aren't the latest. This function is 258 * recommended to use over {@link #acquireNextImage} for most use-cases, as it's 259 * more suited for real-time processing. 260 * </p> 261 * <p> 262 * Note that {@link #getMaxImages maxImages} should be at least 2 for 263 * {@link #acquireLatestImage} to be any different than {@link #acquireNextImage} - 264 * discarding all-but-the-newest {@link Image} requires temporarily acquiring two 265 * {@link Image Images} at once. Or more generally, calling {@link #acquireLatestImage} 266 * with less than two images of margin, that is 267 * {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected. 268 * </p> 269 * <p> 270 * This operation will fail by throwing an {@link IllegalStateException} if 271 * {@code maxImages} have been acquired with {@link #acquireLatestImage} or 272 * {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage} 273 * calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between 274 * will exhaust the underlying queue. At such a time, {@link IllegalStateException} 275 * will be thrown until more images are 276 * released with {@link Image#close}. 277 * </p> 278 * 279 * @return latest frame of image data, or {@code null} if no image data is available. 280 * @throws IllegalStateException if too many images are currently acquired 281 */ 282 public Image acquireLatestImage() { 283 Image image = acquireNextImage(); 284 if (image == null) { 285 return null; 286 } 287 try { 288 for (;;) { 289 Image next = acquireNextImageNoThrowISE(); 290 if (next == null) { 291 Image result = image; 292 image = null; 293 return result; 294 } 295 image.close(); 296 image = next; 297 } 298 } finally { 299 if (image != null) { 300 image.close(); 301 } 302 } 303 } 304 305 /** 306 * Don't throw IllegalStateException if there are too many images acquired. 307 * 308 * @return Image if acquiring succeeded, or null otherwise. 309 * 310 * @hide 311 */ 312 public Image acquireNextImageNoThrowISE() { 313 SurfaceImage si = new SurfaceImage(mFormat); 314 return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null; 315 } 316 317 /** 318 * Attempts to acquire the next image from the underlying native implementation. 319 * 320 * <p> 321 * Note that unexpected failures will throw at the JNI level. 322 * </p> 323 * 324 * @param si A blank SurfaceImage. 325 * @return One of the {@code ACQUIRE_*} codes that determine success or failure. 326 * 327 * @see #ACQUIRE_MAX_IMAGES 328 * @see #ACQUIRE_NO_BUFS 329 * @see #ACQUIRE_SUCCESS 330 */ 331 private int acquireNextSurfaceImage(SurfaceImage si) { 332 synchronized (mCloseLock) { 333 // A null image will eventually be returned if ImageReader is already closed. 334 int status = ACQUIRE_NO_BUFS; 335 if (mIsReaderValid) { 336 status = nativeImageSetup(si); 337 } 338 339 switch (status) { 340 case ACQUIRE_SUCCESS: 341 si.mIsImageValid = true; 342 case ACQUIRE_NO_BUFS: 343 case ACQUIRE_MAX_IMAGES: 344 break; 345 default: 346 throw new AssertionError("Unknown nativeImageSetup return code " + status); 347 } 348 349 // Only keep track the successfully acquired image, as the native buffer is only mapped 350 // for such case. 351 if (status == ACQUIRE_SUCCESS) { 352 mAcquiredImages.add(si); 353 } 354 return status; 355 } 356 } 357 358 /** 359 * <p> 360 * Acquire the next Image from the ImageReader's queue. Returns {@code null} if 361 * no new image is available. 362 * </p> 363 * 364 * <p><i>Warning:</i> Consider using {@link #acquireLatestImage()} instead, as it will 365 * automatically release older images, and allow slower-running processing routines to catch 366 * up to the newest frame. Usage of {@link #acquireNextImage} is recommended for 367 * batch/background processing. Incorrectly using this function can cause images to appear 368 * with an ever-increasing delay, followed by a complete stall where no new images seem to 369 * appear. 370 * </p> 371 * 372 * <p> 373 * This operation will fail by throwing an {@link IllegalStateException} if 374 * {@code maxImages} have been acquired with {@link #acquireNextImage} or 375 * {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or 376 * {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without 377 * calling {@link Image#close} in-between will exhaust the underlying queue. At such a time, 378 * {@link IllegalStateException} will be thrown until more images are released with 379 * {@link Image#close}. 380 * </p> 381 * 382 * @return a new frame of image data, or {@code null} if no image data is available. 383 * @throws IllegalStateException if {@code maxImages} images are currently acquired 384 * @see #acquireLatestImage 385 */ 386 public Image acquireNextImage() { 387 // Initialize with reader format, but can be overwritten by native if the image 388 // format is different from the reader format. 389 SurfaceImage si = new SurfaceImage(mFormat); 390 int status = acquireNextSurfaceImage(si); 391 392 switch (status) { 393 case ACQUIRE_SUCCESS: 394 return si; 395 case ACQUIRE_NO_BUFS: 396 return null; 397 case ACQUIRE_MAX_IMAGES: 398 throw new IllegalStateException( 399 String.format( 400 "maxImages (%d) has already been acquired, " + 401 "call #close before acquiring more.", mMaxImages)); 402 default: 403 throw new AssertionError("Unknown nativeImageSetup return code " + status); 404 } 405 } 406 407 /** 408 * <p>Return the frame to the ImageReader for reuse.</p> 409 */ 410 private void releaseImage(Image i) { 411 if (! (i instanceof SurfaceImage) ) { 412 throw new IllegalArgumentException( 413 "This image was not produced by an ImageReader"); 414 } 415 SurfaceImage si = (SurfaceImage) i; 416 if (si.mIsImageValid == false) { 417 return; 418 } 419 420 if (si.getReader() != this || !mAcquiredImages.contains(i)) { 421 throw new IllegalArgumentException( 422 "This image was not produced by this ImageReader"); 423 } 424 425 si.clearSurfacePlanes(); 426 nativeReleaseImage(i); 427 si.mIsImageValid = false; 428 mAcquiredImages.remove(i); 429 } 430 431 /** 432 * Register a listener to be invoked when a new image becomes available 433 * from the ImageReader. 434 * 435 * @param listener 436 * The listener that will be run. 437 * @param handler 438 * The handler on which the listener should be invoked, or null 439 * if the listener should be invoked on the calling thread's looper. 440 * @throws IllegalArgumentException 441 * If no handler specified and the calling thread has no looper. 442 */ 443 public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) { 444 synchronized (mListenerLock) { 445 if (listener != null) { 446 Looper looper = handler != null ? handler.getLooper() : Looper.myLooper(); 447 if (looper == null) { 448 throw new IllegalArgumentException( 449 "handler is null but the current thread is not a looper"); 450 } 451 if (mListenerHandler == null || mListenerHandler.getLooper() != looper) { 452 mListenerHandler = new ListenerHandler(looper); 453 } 454 mListener = listener; 455 } else { 456 mListener = null; 457 mListenerHandler = null; 458 } 459 } 460 } 461 462 /** 463 * Callback interface for being notified that a new image is available. 464 * 465 * <p> 466 * The onImageAvailable is called per image basis, that is, callback fires for every new frame 467 * available from ImageReader. 468 * </p> 469 */ 470 public interface OnImageAvailableListener { 471 /** 472 * Callback that is called when a new image is available from ImageReader. 473 * 474 * @param reader the ImageReader the callback is associated with. 475 * @see ImageReader 476 * @see Image 477 */ 478 void onImageAvailable(ImageReader reader); 479 } 480 481 /** 482 * Free up all the resources associated with this ImageReader. 483 * 484 * <p> 485 * After calling this method, this ImageReader can not be used. Calling 486 * any methods on this ImageReader and Images previously provided by 487 * {@link #acquireNextImage} or {@link #acquireLatestImage} 488 * will result in an {@link IllegalStateException}, and attempting to read from 489 * {@link ByteBuffer ByteBuffers} returned by an earlier 490 * {@link Image.Plane#getBuffer Plane#getBuffer} call will 491 * have undefined behavior. 492 * </p> 493 */ 494 @Override 495 public void close() { 496 setOnImageAvailableListener(null, null); 497 if (mSurface != null) mSurface.release(); 498 499 /** 500 * Close all outstanding acquired images before closing the ImageReader. It is a good 501 * practice to close all the images as soon as it is not used to reduce system instantaneous 502 * memory pressure. CopyOnWrite list will use a copy of current list content. For the images 503 * being closed by other thread (e.g., GC thread), doubling the close call is harmless. For 504 * the image being acquired by other threads, mCloseLock is used to synchronize close and 505 * acquire operations. 506 */ 507 synchronized (mCloseLock) { 508 mIsReaderValid = false; 509 for (Image image : mAcquiredImages) { 510 image.close(); 511 } 512 mAcquiredImages.clear(); 513 514 nativeClose(); 515 516 if (mEstimatedNativeAllocBytes > 0) { 517 VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes); 518 mEstimatedNativeAllocBytes = 0; 519 } 520 } 521 } 522 523 /** 524 * Discard any free buffers owned by this ImageReader. 525 * 526 * <p> 527 * Generally, the ImageReader caches buffers for reuse once they have been 528 * allocated, for best performance. However, sometimes it may be important to 529 * release all the cached, unused buffers to save on memory. 530 * </p> 531 * <p> 532 * Calling this method will discard all free cached buffers. This does not include any buffers 533 * associated with Images acquired from the ImageReader, any filled buffers waiting to be 534 * acquired, and any buffers currently in use by the source rendering buffers into the 535 * ImageReader's Surface. 536 * <p> 537 * The ImageReader continues to be usable after this call, but may need to reallocate buffers 538 * when more buffers are needed for rendering. 539 * </p> 540 * @hide 541 */ 542 public void discardFreeBuffers() { 543 synchronized (mCloseLock) { 544 nativeDiscardFreeBuffers(); 545 } 546 } 547 548 @Override 549 protected void finalize() throws Throwable { 550 try { 551 close(); 552 } finally { 553 super.finalize(); 554 } 555 } 556 557 /** 558 * <p> 559 * Remove the ownership of this image from the ImageReader. 560 * </p> 561 * <p> 562 * After this call, the ImageReader no longer owns this image, and the image 563 * ownership can be transfered to another entity like {@link ImageWriter} 564 * via {@link ImageWriter#queueInputImage}. It's up to the new owner to 565 * release the resources held by this image. For example, if the ownership 566 * of this image is transfered to an {@link ImageWriter}, the image will be 567 * freed by the ImageWriter after the image data consumption is done. 568 * </p> 569 * <p> 570 * This method can be used to achieve zero buffer copy for use cases like 571 * {@link android.hardware.camera2.CameraDevice Camera2 API} PRIVATE and YUV 572 * reprocessing, where the application can select an output image from 573 * {@link ImageReader} and transfer this image directly to 574 * {@link ImageWriter}, where this image can be consumed by camera directly. 575 * For PRIVATE reprocessing, this is the only way to send input buffers to 576 * the {@link android.hardware.camera2.CameraDevice camera} for 577 * reprocessing. 578 * </p> 579 * <p> 580 * This is a package private method that is only used internally. 581 * </p> 582 * 583 * @param image The image to be detached from this ImageReader. 584 * @throws IllegalStateException If the ImageReader or image have been 585 * closed, or the has been detached, or has not yet been 586 * acquired. 587 */ 588 void detachImage(Image image) { 589 if (image == null) { 590 throw new IllegalArgumentException("input image must not be null"); 591 } 592 if (!isImageOwnedbyMe(image)) { 593 throw new IllegalArgumentException("Trying to detach an image that is not owned by" 594 + " this ImageReader"); 595 } 596 597 SurfaceImage si = (SurfaceImage) image; 598 si.throwISEIfImageIsInvalid(); 599 600 if (si.isAttachable()) { 601 throw new IllegalStateException("Image was already detached from this ImageReader"); 602 } 603 604 nativeDetachImage(image); 605 si.setDetached(true); 606 } 607 608 private boolean isImageOwnedbyMe(Image image) { 609 if (!(image instanceof SurfaceImage)) { 610 return false; 611 } 612 SurfaceImage si = (SurfaceImage) image; 613 return si.getReader() == this; 614 } 615 616 /** 617 * Called from Native code when an Event happens. 618 * 619 * This may be called from an arbitrary Binder thread, so access to the ImageReader must be 620 * synchronized appropriately. 621 */ 622 private static void postEventFromNative(Object selfRef) { 623 @SuppressWarnings("unchecked") 624 WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef; 625 final ImageReader ir = weakSelf.get(); 626 if (ir == null) { 627 return; 628 } 629 630 final Handler handler; 631 synchronized (ir.mListenerLock) { 632 handler = ir.mListenerHandler; 633 } 634 if (handler != null) { 635 handler.sendEmptyMessage(0); 636 } 637 } 638 639 private final int mWidth; 640 private final int mHeight; 641 private final int mFormat; 642 private final int mMaxImages; 643 private final int mNumPlanes; 644 private final Surface mSurface; 645 private int mEstimatedNativeAllocBytes; 646 647 private final Object mListenerLock = new Object(); 648 private final Object mCloseLock = new Object(); 649 private boolean mIsReaderValid = false; 650 private OnImageAvailableListener mListener; 651 private ListenerHandler mListenerHandler; 652 // Keep track of the successfully acquired Images. This need to be thread safe as the images 653 // could be closed by different threads (e.g., application thread and GC thread). 654 private List<Image> mAcquiredImages = new CopyOnWriteArrayList<Image>(); 655 656 /** 657 * This field is used by native code, do not access or modify. 658 */ 659 private long mNativeContext; 660 661 /** 662 * This custom handler runs asynchronously so callbacks don't get queued behind UI messages. 663 */ 664 private final class ListenerHandler extends Handler { 665 public ListenerHandler(Looper looper) { 666 super(looper, null, true /*async*/); 667 } 668 669 @Override 670 public void handleMessage(Message msg) { 671 OnImageAvailableListener listener; 672 synchronized (mListenerLock) { 673 listener = mListener; 674 } 675 676 // It's dangerous to fire onImageAvailable() callback when the ImageReader is being 677 // closed, as application could acquire next image in the onImageAvailable() callback. 678 boolean isReaderValid = false; 679 synchronized (mCloseLock) { 680 isReaderValid = mIsReaderValid; 681 } 682 if (listener != null && isReaderValid) { 683 listener.onImageAvailable(ImageReader.this); 684 } 685 } 686 } 687 688 private class SurfaceImage extends android.media.Image { 689 public SurfaceImage(int format) { 690 mFormat = format; 691 } 692 693 @Override 694 public void close() { 695 ImageReader.this.releaseImage(this); 696 } 697 698 public ImageReader getReader() { 699 return ImageReader.this; 700 } 701 702 @Override 703 public int getFormat() { 704 throwISEIfImageIsInvalid(); 705 int readerFormat = ImageReader.this.getImageFormat(); 706 // Assume opaque reader always produce opaque images. 707 mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat : 708 nativeGetFormat(readerFormat); 709 return mFormat; 710 } 711 712 @Override 713 public int getWidth() { 714 throwISEIfImageIsInvalid(); 715 int width; 716 switch(getFormat()) { 717 case ImageFormat.JPEG: 718 case ImageFormat.DEPTH_POINT_CLOUD: 719 case ImageFormat.RAW_PRIVATE: 720 width = ImageReader.this.getWidth(); 721 break; 722 default: 723 width = nativeGetWidth(); 724 } 725 return width; 726 } 727 728 @Override 729 public int getHeight() { 730 throwISEIfImageIsInvalid(); 731 int height; 732 switch(getFormat()) { 733 case ImageFormat.JPEG: 734 case ImageFormat.DEPTH_POINT_CLOUD: 735 case ImageFormat.RAW_PRIVATE: 736 height = ImageReader.this.getHeight(); 737 break; 738 default: 739 height = nativeGetHeight(); 740 } 741 return height; 742 } 743 744 @Override 745 public long getTimestamp() { 746 throwISEIfImageIsInvalid(); 747 return mTimestamp; 748 } 749 750 @Override 751 public void setTimestamp(long timestampNs) { 752 throwISEIfImageIsInvalid(); 753 mTimestamp = timestampNs; 754 } 755 756 @Override 757 public Plane[] getPlanes() { 758 throwISEIfImageIsInvalid(); 759 760 if (mPlanes == null) { 761 mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat); 762 } 763 // Shallow copy is fine. 764 return mPlanes.clone(); 765 } 766 767 @Override 768 protected final void finalize() throws Throwable { 769 try { 770 close(); 771 } finally { 772 super.finalize(); 773 } 774 } 775 776 @Override 777 boolean isAttachable() { 778 throwISEIfImageIsInvalid(); 779 return mIsDetached.get(); 780 } 781 782 @Override 783 ImageReader getOwner() { 784 throwISEIfImageIsInvalid(); 785 return ImageReader.this; 786 } 787 788 @Override 789 long getNativeContext() { 790 throwISEIfImageIsInvalid(); 791 return mNativeBuffer; 792 } 793 794 private void setDetached(boolean detached) { 795 throwISEIfImageIsInvalid(); 796 mIsDetached.getAndSet(detached); 797 } 798 799 private void clearSurfacePlanes() { 800 // Image#getPlanes may not be called before the image is closed. 801 if (mIsImageValid && mPlanes != null) { 802 for (int i = 0; i < mPlanes.length; i++) { 803 if (mPlanes[i] != null) { 804 mPlanes[i].clearBuffer(); 805 mPlanes[i] = null; 806 } 807 } 808 } 809 } 810 811 private class SurfacePlane extends android.media.Image.Plane { 812 // SurfacePlane instance is created by native code when SurfaceImage#getPlanes() is 813 // called 814 private SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer) { 815 mRowStride = rowStride; 816 mPixelStride = pixelStride; 817 mBuffer = buffer; 818 /** 819 * Set the byteBuffer order according to host endianness (native 820 * order), otherwise, the byteBuffer order defaults to 821 * ByteOrder.BIG_ENDIAN. 822 */ 823 mBuffer.order(ByteOrder.nativeOrder()); 824 } 825 826 @Override 827 public ByteBuffer getBuffer() { 828 throwISEIfImageIsInvalid(); 829 return mBuffer; 830 } 831 832 @Override 833 public int getPixelStride() { 834 SurfaceImage.this.throwISEIfImageIsInvalid(); 835 if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) { 836 throw new UnsupportedOperationException( 837 "getPixelStride is not supported for RAW_PRIVATE plane"); 838 } 839 return mPixelStride; 840 } 841 842 @Override 843 public int getRowStride() { 844 SurfaceImage.this.throwISEIfImageIsInvalid(); 845 if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) { 846 throw new UnsupportedOperationException( 847 "getRowStride is not supported for RAW_PRIVATE plane"); 848 } 849 return mRowStride; 850 } 851 852 private void clearBuffer() { 853 // Need null check first, as the getBuffer() may not be called before an image 854 // is closed. 855 if (mBuffer == null) { 856 return; 857 } 858 859 if (mBuffer.isDirect()) { 860 NioUtils.freeDirectBuffer(mBuffer); 861 } 862 mBuffer = null; 863 } 864 865 final private int mPixelStride; 866 final private int mRowStride; 867 868 private ByteBuffer mBuffer; 869 } 870 871 /** 872 * This field is used to keep track of native object and used by native code only. 873 * Don't modify. 874 */ 875 private long mNativeBuffer; 876 877 /** 878 * This field is set by native code during nativeImageSetup(). 879 */ 880 private long mTimestamp; 881 882 private SurfacePlane[] mPlanes; 883 private int mFormat = ImageFormat.UNKNOWN; 884 // If this image is detached from the ImageReader. 885 private AtomicBoolean mIsDetached = new AtomicBoolean(false); 886 887 private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, 888 int readerFormat); 889 private synchronized native int nativeGetWidth(); 890 private synchronized native int nativeGetHeight(); 891 private synchronized native int nativeGetFormat(int readerFormat); 892 } 893 894 private synchronized native void nativeInit(Object weakSelf, int w, int h, 895 int fmt, int maxImgs); 896 private synchronized native void nativeClose(); 897 private synchronized native void nativeReleaseImage(Image i); 898 private synchronized native Surface nativeGetSurface(); 899 private synchronized native int nativeDetachImage(Image i); 900 private synchronized native void nativeDiscardFreeBuffers(); 901 902 /** 903 * @return A return code {@code ACQUIRE_*} 904 * 905 * @see #ACQUIRE_SUCCESS 906 * @see #ACQUIRE_NO_BUFS 907 * @see #ACQUIRE_MAX_IMAGES 908 */ 909 private synchronized native int nativeImageSetup(Image i); 910 911 /** 912 * We use a class initializer to allow the native code to cache some 913 * field offsets. 914 */ 915 private static native void nativeClassInit(); 916 static { 917 System.loadLibrary("media_jni"); 918 nativeClassInit(); 919 } 920 } 921