Loading api/current.txt +14 −7 Original line number Diff line number Diff line Loading @@ -12334,7 +12334,7 @@ package android.media { field public static final int EULER_Z = 2; // 0x2 } public abstract interface Image implements java.lang.AutoCloseable { public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public abstract int getFormat(); method public abstract int getHeight(); Loading @@ -12343,23 +12343,30 @@ package android.media { method public abstract int getWidth(); } public static abstract interface Image.Plane { public static abstract class Image.Plane { method public abstract java.nio.ByteBuffer getBuffer(); method public abstract int getPixelStride(); method public abstract int getRowStride(); } public final class ImageReader implements java.lang.AutoCloseable { ctor public ImageReader(int, int, int, int); public class ImageReader implements java.lang.AutoCloseable { method public android.media.Image acquireLatestImage() throws android.media.ImageReader.MaxImagesAcquiredException; method public android.media.Image acquireNextImage() throws android.media.ImageReader.MaxImagesAcquiredException; method public void close(); method public int getHeight(); method public int getImageFormat(); method public int getMaxImages(); method public android.media.Image getNextImage(); method public android.view.Surface getSurface(); method public int getWidth(); method public void releaseImage(android.media.Image); method public void setImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); method public static android.media.ImageReader newInstance(int, int, int, int); method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); } public static class ImageReader.MaxImagesAcquiredException extends java.lang.Exception { ctor public ImageReader.MaxImagesAcquiredException(); ctor public ImageReader.MaxImagesAcquiredException(java.lang.String); ctor public ImageReader.MaxImagesAcquiredException(java.lang.String, java.lang.Throwable); ctor public ImageReader.MaxImagesAcquiredException(java.lang.Throwable); } public static abstract interface ImageReader.OnImageAvailableListener { core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java +10 −14 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.Image; import android.media.ImageReader; import android.media.ImageReader.MaxImagesAcquiredException; import android.os.Bundle; import android.os.Handler; import android.os.Looper; Loading Loading @@ -83,8 +84,8 @@ public class VirtualDisplayTest extends AndroidTestCase { mImageReaderLock.lock(); try { mImageReader = new ImageReader(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2); mImageReader.setImageAvailableListener(mImageListener, mHandler); mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2); mImageReader.setOnImageAvailableListener(mImageListener, mHandler); mSurface = mImageReader.getSurface(); } finally { mImageReaderLock.unlock(); Loading Loading @@ -409,19 +410,11 @@ public class VirtualDisplayTest extends AndroidTestCase { } Log.d(TAG, "New image available from virtual display."); Image image = reader.getNextImage(); // Get the latest buffer. Image image = reader.acquireLatestImage(); if (image != null) { try { // Get the latest buffer. for (;;) { Image nextImage = reader.getNextImage(); if (nextImage == null) { break; } reader.releaseImage(image); image = nextImage; } // Scan for colors. int color = scanImage(image); synchronized (this) { Loading @@ -431,9 +424,12 @@ public class VirtualDisplayTest extends AndroidTestCase { } } } finally { reader.releaseImage(image); image.close(); } } } catch (MaxImagesAcquiredException e) { // We should never try to consume more buffers than maxImages. throw new IllegalStateException(e); } finally { mImageReaderLock.unlock(); } Loading media/java/android/media/Image.java +63 −34 Original line number Diff line number Diff line Loading @@ -16,20 +16,19 @@ package android.media; import android.graphics.ImageFormat; import java.nio.ByteBuffer; import java.lang.AutoCloseable; /** * <p>A single complete image buffer to use with a media source such as a * {@link MediaCodec} or a * {@link android.hardware.camera2.CameraDevice}.</p> * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p> * * <p>This class allows for efficient direct application access to the pixel * data of the Image through one or more * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a * {@link Plane} that describes the layout of the pixel data in that plane. Due * to this direct access, and unlike the {@link android.graphics.Bitmap} class, * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class, * Images are not directly usable as as UI resources.</p> * * <p>Since Images are often directly produced or consumed by hardware Loading @@ -40,19 +39,29 @@ import java.lang.AutoCloseable; * from various media sources, not closing old Image objects will prevent the * availability of new Images once * {@link ImageReader#getMaxImages the maximum outstanding image count} is * reached.</p> * reached. When this happens, the function acquiring new Images will typically * throw a * {@link ImageReader.MaxImagesAcquiredException MaxImagesAcquiredException}.</p> * * @see ImageReader */ public interface Image extends AutoCloseable { public abstract class Image implements AutoCloseable { /** * @hide */ protected Image() { } /** * Get the format for this image. This format determines the number of * ByteBuffers needed to represent the image, and the general layout of the * pixel data in each in ByteBuffer. * * <p> * The format is one of the values from * {@link android.graphics.ImageFormat}. The mapping between the formats and * the planes is as follows: * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the * formats and the planes is as follows: * </p> * * <table> * <tr> Loading @@ -61,13 +70,14 @@ public interface Image extends AutoCloseable { * <th>Layout details</th> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#JPEG}</td> * <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td> * <td>1</td> * <td>Compressed data, so row and pixel strides are 0. To uncompress, use * {@link android.graphics.BitmapFactory#decodeByteArray}.</td> * {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}. * </td> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#YUV_420_888}</td> * <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td> * <td>3</td> * <td>A luminance plane followed by the Cb and Cr chroma planes. * The chroma planes have half the width and height of the luminance Loading @@ -75,53 +85,60 @@ public interface Image extends AutoCloseable { * Each plane has its own row stride and pixel stride.</td> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td> * <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td> * <td>1</td> * <td>A single plane of raw sensor image data, with 16 bits per color * sample. The details of the layout need to be queried from the source of * the raw sensor data, such as * {@link android.hardware.camera2.CameraDevice}. * {@link android.hardware.camera2.CameraDevice CameraDevice}. * </td> * </tr> * </table> * * @see android.graphics.ImageFormat */ public int getFormat(); public abstract int getFormat(); /** * The width of the image in pixels. For formats where some color channels * are subsampled, this is the width of the largest-resolution plane. */ public int getWidth(); public abstract int getWidth(); /** * The height of the image in pixels. For formats where some color channels * are subsampled, this is the height of the largest-resolution plane. */ public int getHeight(); public abstract int getHeight(); /** * Get the timestamp associated with this frame. The timestamp is measured * in nanoseconds, and is monotonically increasing. However, the zero point * and whether the timestamp can be compared against other sources of time * or images depend on the source of this image. * Get the timestamp associated with this frame. * <p> * The timestamp is measured in nanoseconds, and is monotonically * increasing. However, the zero point and whether the timestamp can be * compared against other sources of time or images depend on the source of * this image. * </p> */ public long getTimestamp(); public abstract long getTimestamp(); /** * Get the array of pixel planes for this Image. The number of planes is * determined by the format of the Image. */ public Plane[] getPlanes(); public abstract Plane[] getPlanes(); /** * Free up this frame for reuse. After calling this method, calling any * methods on this Image will result in an IllegalStateException, and * attempting to read from ByteBuffers returned by an earlier * {@code Plane#getBuffer} call will have undefined behavior. * Free up this frame for reuse. * <p> * After calling this method, calling any methods on this {@code Image} will * result in an {@link IllegalStateException}, and attempting to read from * {@link ByteBuffer ByteBuffers} returned by an earlier * {@link Plane#getBuffer} call will have undefined behavior. * </p> */ public void close(); @Override public abstract void close(); /** * <p>A single color plane of image data.</p> Loading @@ -134,29 +151,41 @@ public interface Image extends AutoCloseable { * * @see #getFormat */ public interface Plane { public static abstract class Plane { /** * <p>The row stride for this color plane, in bytes. * @hide */ protected Plane() { } /** * <p>The row stride for this color plane, in bytes.</p> * * <p>This is the distance between the start of two consecutive rows of * pixels in the image.</p> * pixels in the image. The row stride is always greater than 0.</p> */ public int getRowStride(); public abstract int getRowStride(); /** * <p>The distance between adjacent pixel samples, in bytes.</p> * * <p>This is the distance between two consecutive pixel values in a row * of pixels. It may be larger than the size of a single pixel to * account for interleaved image data or padded formats.</p> * account for interleaved image data or padded formats. * The pixel stride is always greater than 0.</p> */ public int getPixelStride(); public abstract int getPixelStride(); /** * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers} * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer} * containing the frame data.</p> * * <p>In particular, the buffer returned will always have * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so * the underlying data could be mapped as a pointer in JNI without doing * any copies with {@code GetDirectBufferAddress}.</p> * * @return the byte buffer containing the image data for this plane. */ public ByteBuffer getBuffer(); public abstract ByteBuffer getBuffer(); } } media/java/android/media/ImageReader.java +238 −59 File changed.Preview size limit exceeded, changes collapsed. Show changes media/jni/android_media_ImageReader.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -43,8 +43,8 @@ using namespace android; static const char* const OutOfResourcesException = "android/view/Surface$OutOfResourcesException"; static const char* const MaxImagesAcquiredException = "android/media/ImageReader$MaxImagesAcquiredException"; enum { IMAGE_READER_MAX_NUM_PLANES = 3, Loading Loading @@ -700,7 +700,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz, if (buffer == NULL) { ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" " maxImages buffers"); jniThrowException(env, OutOfResourcesException, jniThrowException(env, MaxImagesAcquiredException, "Too many outstanding images, close existing images" " to be able to acquire more."); return false; Loading @@ -709,7 +709,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz, if (res != NO_ERROR) { if (res != BAD_VALUE /*no buffers*/) { if (res == NOT_ENOUGH_DATA) { jniThrowException(env, OutOfResourcesException, jniThrowException(env, MaxImagesAcquiredException, "Too many outstanding images, close existing images" " to be able to acquire more."); } else { Loading Loading
api/current.txt +14 −7 Original line number Diff line number Diff line Loading @@ -12334,7 +12334,7 @@ package android.media { field public static final int EULER_Z = 2; // 0x2 } public abstract interface Image implements java.lang.AutoCloseable { public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public abstract int getFormat(); method public abstract int getHeight(); Loading @@ -12343,23 +12343,30 @@ package android.media { method public abstract int getWidth(); } public static abstract interface Image.Plane { public static abstract class Image.Plane { method public abstract java.nio.ByteBuffer getBuffer(); method public abstract int getPixelStride(); method public abstract int getRowStride(); } public final class ImageReader implements java.lang.AutoCloseable { ctor public ImageReader(int, int, int, int); public class ImageReader implements java.lang.AutoCloseable { method public android.media.Image acquireLatestImage() throws android.media.ImageReader.MaxImagesAcquiredException; method public android.media.Image acquireNextImage() throws android.media.ImageReader.MaxImagesAcquiredException; method public void close(); method public int getHeight(); method public int getImageFormat(); method public int getMaxImages(); method public android.media.Image getNextImage(); method public android.view.Surface getSurface(); method public int getWidth(); method public void releaseImage(android.media.Image); method public void setImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); method public static android.media.ImageReader newInstance(int, int, int, int); method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); } public static class ImageReader.MaxImagesAcquiredException extends java.lang.Exception { ctor public ImageReader.MaxImagesAcquiredException(); ctor public ImageReader.MaxImagesAcquiredException(java.lang.String); ctor public ImageReader.MaxImagesAcquiredException(java.lang.String, java.lang.Throwable); ctor public ImageReader.MaxImagesAcquiredException(java.lang.Throwable); } public static abstract interface ImageReader.OnImageAvailableListener {
core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java +10 −14 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.Image; import android.media.ImageReader; import android.media.ImageReader.MaxImagesAcquiredException; import android.os.Bundle; import android.os.Handler; import android.os.Looper; Loading Loading @@ -83,8 +84,8 @@ public class VirtualDisplayTest extends AndroidTestCase { mImageReaderLock.lock(); try { mImageReader = new ImageReader(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2); mImageReader.setImageAvailableListener(mImageListener, mHandler); mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2); mImageReader.setOnImageAvailableListener(mImageListener, mHandler); mSurface = mImageReader.getSurface(); } finally { mImageReaderLock.unlock(); Loading Loading @@ -409,19 +410,11 @@ public class VirtualDisplayTest extends AndroidTestCase { } Log.d(TAG, "New image available from virtual display."); Image image = reader.getNextImage(); // Get the latest buffer. Image image = reader.acquireLatestImage(); if (image != null) { try { // Get the latest buffer. for (;;) { Image nextImage = reader.getNextImage(); if (nextImage == null) { break; } reader.releaseImage(image); image = nextImage; } // Scan for colors. int color = scanImage(image); synchronized (this) { Loading @@ -431,9 +424,12 @@ public class VirtualDisplayTest extends AndroidTestCase { } } } finally { reader.releaseImage(image); image.close(); } } } catch (MaxImagesAcquiredException e) { // We should never try to consume more buffers than maxImages. throw new IllegalStateException(e); } finally { mImageReaderLock.unlock(); } Loading
media/java/android/media/Image.java +63 −34 Original line number Diff line number Diff line Loading @@ -16,20 +16,19 @@ package android.media; import android.graphics.ImageFormat; import java.nio.ByteBuffer; import java.lang.AutoCloseable; /** * <p>A single complete image buffer to use with a media source such as a * {@link MediaCodec} or a * {@link android.hardware.camera2.CameraDevice}.</p> * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p> * * <p>This class allows for efficient direct application access to the pixel * data of the Image through one or more * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a * {@link Plane} that describes the layout of the pixel data in that plane. Due * to this direct access, and unlike the {@link android.graphics.Bitmap} class, * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class, * Images are not directly usable as as UI resources.</p> * * <p>Since Images are often directly produced or consumed by hardware Loading @@ -40,19 +39,29 @@ import java.lang.AutoCloseable; * from various media sources, not closing old Image objects will prevent the * availability of new Images once * {@link ImageReader#getMaxImages the maximum outstanding image count} is * reached.</p> * reached. When this happens, the function acquiring new Images will typically * throw a * {@link ImageReader.MaxImagesAcquiredException MaxImagesAcquiredException}.</p> * * @see ImageReader */ public interface Image extends AutoCloseable { public abstract class Image implements AutoCloseable { /** * @hide */ protected Image() { } /** * Get the format for this image. This format determines the number of * ByteBuffers needed to represent the image, and the general layout of the * pixel data in each in ByteBuffer. * * <p> * The format is one of the values from * {@link android.graphics.ImageFormat}. The mapping between the formats and * the planes is as follows: * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the * formats and the planes is as follows: * </p> * * <table> * <tr> Loading @@ -61,13 +70,14 @@ public interface Image extends AutoCloseable { * <th>Layout details</th> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#JPEG}</td> * <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td> * <td>1</td> * <td>Compressed data, so row and pixel strides are 0. To uncompress, use * {@link android.graphics.BitmapFactory#decodeByteArray}.</td> * {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}. * </td> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#YUV_420_888}</td> * <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td> * <td>3</td> * <td>A luminance plane followed by the Cb and Cr chroma planes. * The chroma planes have half the width and height of the luminance Loading @@ -75,53 +85,60 @@ public interface Image extends AutoCloseable { * Each plane has its own row stride and pixel stride.</td> * </tr> * <tr> * <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td> * <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td> * <td>1</td> * <td>A single plane of raw sensor image data, with 16 bits per color * sample. The details of the layout need to be queried from the source of * the raw sensor data, such as * {@link android.hardware.camera2.CameraDevice}. * {@link android.hardware.camera2.CameraDevice CameraDevice}. * </td> * </tr> * </table> * * @see android.graphics.ImageFormat */ public int getFormat(); public abstract int getFormat(); /** * The width of the image in pixels. For formats where some color channels * are subsampled, this is the width of the largest-resolution plane. */ public int getWidth(); public abstract int getWidth(); /** * The height of the image in pixels. For formats where some color channels * are subsampled, this is the height of the largest-resolution plane. */ public int getHeight(); public abstract int getHeight(); /** * Get the timestamp associated with this frame. The timestamp is measured * in nanoseconds, and is monotonically increasing. However, the zero point * and whether the timestamp can be compared against other sources of time * or images depend on the source of this image. * Get the timestamp associated with this frame. * <p> * The timestamp is measured in nanoseconds, and is monotonically * increasing. However, the zero point and whether the timestamp can be * compared against other sources of time or images depend on the source of * this image. * </p> */ public long getTimestamp(); public abstract long getTimestamp(); /** * Get the array of pixel planes for this Image. The number of planes is * determined by the format of the Image. */ public Plane[] getPlanes(); public abstract Plane[] getPlanes(); /** * Free up this frame for reuse. After calling this method, calling any * methods on this Image will result in an IllegalStateException, and * attempting to read from ByteBuffers returned by an earlier * {@code Plane#getBuffer} call will have undefined behavior. * Free up this frame for reuse. * <p> * After calling this method, calling any methods on this {@code Image} will * result in an {@link IllegalStateException}, and attempting to read from * {@link ByteBuffer ByteBuffers} returned by an earlier * {@link Plane#getBuffer} call will have undefined behavior. * </p> */ public void close(); @Override public abstract void close(); /** * <p>A single color plane of image data.</p> Loading @@ -134,29 +151,41 @@ public interface Image extends AutoCloseable { * * @see #getFormat */ public interface Plane { public static abstract class Plane { /** * <p>The row stride for this color plane, in bytes. * @hide */ protected Plane() { } /** * <p>The row stride for this color plane, in bytes.</p> * * <p>This is the distance between the start of two consecutive rows of * pixels in the image.</p> * pixels in the image. The row stride is always greater than 0.</p> */ public int getRowStride(); public abstract int getRowStride(); /** * <p>The distance between adjacent pixel samples, in bytes.</p> * * <p>This is the distance between two consecutive pixel values in a row * of pixels. It may be larger than the size of a single pixel to * account for interleaved image data or padded formats.</p> * account for interleaved image data or padded formats. * The pixel stride is always greater than 0.</p> */ public int getPixelStride(); public abstract int getPixelStride(); /** * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers} * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer} * containing the frame data.</p> * * <p>In particular, the buffer returned will always have * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so * the underlying data could be mapped as a pointer in JNI without doing * any copies with {@code GetDirectBufferAddress}.</p> * * @return the byte buffer containing the image data for this plane. */ public ByteBuffer getBuffer(); public abstract ByteBuffer getBuffer(); } }
media/java/android/media/ImageReader.java +238 −59 File changed.Preview size limit exceeded, changes collapsed. Show changes
media/jni/android_media_ImageReader.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -43,8 +43,8 @@ using namespace android; static const char* const OutOfResourcesException = "android/view/Surface$OutOfResourcesException"; static const char* const MaxImagesAcquiredException = "android/media/ImageReader$MaxImagesAcquiredException"; enum { IMAGE_READER_MAX_NUM_PLANES = 3, Loading Loading @@ -700,7 +700,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz, if (buffer == NULL) { ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" " maxImages buffers"); jniThrowException(env, OutOfResourcesException, jniThrowException(env, MaxImagesAcquiredException, "Too many outstanding images, close existing images" " to be able to acquire more."); return false; Loading @@ -709,7 +709,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz, if (res != NO_ERROR) { if (res != BAD_VALUE /*no buffers*/) { if (res == NOT_ENOUGH_DATA) { jniThrowException(env, OutOfResourcesException, jniThrowException(env, MaxImagesAcquiredException, "Too many outstanding images, close existing images" " to be able to acquire more."); } else { Loading