diff options
author | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2017-09-15 17:58:39 -0400 |
commit | 10d07c88d69cc64f73a069163e7ea5ba2519a099 (patch) | |
tree | 8dbd149eb350320a29c3d10e7ad3201de1c5cbee /android/media/Image.java | |
parent | 677516fb6b6f207d373984757d3d9450474b6b00 (diff) | |
download | android-28-10d07c88d69cc64f73a069163e7ea5ba2519a099.tar.gz |
Import Android SDK Platform PI [4335822]
/google/data/ro/projects/android/fetch_artifact \
--bid 4335822 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4335822.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: Ic8f04be005a71c2b9abeaac754d8da8d6f9a2c32
Diffstat (limited to 'android/media/Image.java')
-rw-r--r-- | android/media/Image.java | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/android/media/Image.java b/android/media/Image.java new file mode 100644 index 00000000..fbe55614 --- /dev/null +++ b/android/media/Image.java @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import java.nio.ByteBuffer; +import java.lang.AutoCloseable; + +import android.graphics.Rect; + +/** + * <p>A single complete image buffer to use with a media source such as a + * {@link MediaCodec} or a + * {@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 Bitmap} class, + * Images are not directly usable as UI resources.</p> + * + * <p>Since Images are often directly produced or consumed by hardware + * components, they are a limited resource shared across the system, and should + * be closed as soon as they are no longer needed.</p> + * + * <p>For example, when using the {@link ImageReader} class to read out Images + * 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. When this happens, the function acquiring new Images will typically + * throw an {@link IllegalStateException}.</p> + * + * @see ImageReader + */ +public abstract class Image implements AutoCloseable { + /** + * @hide + */ + protected boolean mIsImageValid = false; + + /** + * @hide + */ + protected Image() { + } + + /** + * Throw IllegalStateException if the image is invalid (already closed). + * + * @hide + */ + protected void throwISEIfImageIsInvalid() { + if (!mIsImageValid) { + throw new IllegalStateException("Image is already closed"); + } + } + /** + * 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 ImageFormat}. The mapping between the + * formats and the planes is as follows: + * </p> + * + * <table> + * <tr> + * <th>Format</th> + * <th>Plane count</th> + * <th>Layout details</th> + * </tr> + * <tr> + * <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 BitmapFactory#decodeByteArray}. + * </td> + * </tr> + * <tr> + * <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 + * plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits. + * Each plane has its own row stride and pixel stride.</td> + * </tr> + * <tr> + * <td>{@link android.graphics.ImageFormat#YUV_422_888 YUV_422_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 the full height of the luminance + * plane (4:2:2 subsampling). Each pixel sample in each plane has 8 bits. + * Each plane has its own row stride and pixel stride.</td> + * </tr> + * <tr> + * <td>{@link android.graphics.ImageFormat#YUV_444_888 YUV_444_888}</td> + * <td>3</td> + * <td>A luminance plane followed by the Cb and Cr chroma planes. + * The chroma planes have the same width and height as that of the luminance + * plane (4:4:4 subsampling). Each pixel sample in each plane has 8 bits. + * Each plane has its own row stride and pixel stride.</td> + * </tr> + * <tr> + * <td>{@link android.graphics.ImageFormat#FLEX_RGB_888 FLEX_RGB_888}</td> + * <td>3</td> + * <td>A R (red) plane followed by the G (green) and B (blue) planes. + * All planes have the same widths and heights. + * Each pixel sample in each plane has 8 bits. + * Each plane has its own row stride and pixel stride.</td> + * </tr> + * <tr> + * <td>{@link android.graphics.ImageFormat#FLEX_RGBA_8888 FLEX_RGBA_8888}</td> + * <td>4</td> + * <td>A R (red) plane followed by the G (green), B (blue), and + * A (alpha) planes. All planes have the same widths and heights. + * Each pixel sample in each plane has 8 bits. + * Each plane has its own row stride and pixel stride.</td> + * </tr> + * <tr> + * <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 CameraDevice}. + * </td> + * </tr> + * <tr> + * <td>{@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}</td> + * <td>1</td> + * <td>A single plane of raw sensor image data of private layout. + * The details of the layout is implementation specific. Row stride and + * pixel stride are undefined for this format. Calling {@link Plane#getRowStride()} + * or {@link Plane#getPixelStride()} on RAW_PRIVATE image will cause + * UnSupportedOperationException being thrown. + * </td> + * </tr> + * </table> + * + * @see android.graphics.ImageFormat + */ + 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 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 abstract int getHeight(); + + /** + * Get the timestamp associated with this frame. + * <p> + * The timestamp is measured in nanoseconds, and is normally monotonically + * increasing. The timestamps for the images from different sources may have + * different timebases therefore may not be comparable. The specific meaning and + * timebase of the timestamp depend on the source providing images. See + * {@link android.hardware.Camera Camera}, + * {@link android.hardware.camera2.CameraDevice CameraDevice}, + * {@link MediaPlayer} and {@link MediaCodec} for more details. + * </p> + */ + public abstract long getTimestamp(); + + /** + * Set the timestamp associated with this frame. + * <p> + * The timestamp is measured in nanoseconds, and is normally monotonically + * increasing. The timestamps for the images from different sources may have + * different timebases therefore may not be comparable. The specific meaning and + * timebase of the timestamp depend on the source providing images. See + * {@link android.hardware.Camera Camera}, + * {@link android.hardware.camera2.CameraDevice CameraDevice}, + * {@link MediaPlayer} and {@link MediaCodec} for more details. + * </p> + * <p> + * For images dequeued from {@link ImageWriter} via + * {@link ImageWriter#dequeueInputImage()}, it's up to the application to + * set the timestamps correctly before sending them back to the + * {@link ImageWriter}, or the timestamp will be generated automatically when + * {@link ImageWriter#queueInputImage queueInputImage()} is called. + * </p> + * + * @param timestamp The timestamp to be set for this image. + */ + public void setTimestamp(long timestamp) { + throwISEIfImageIsInvalid(); + return; + } + + private Rect mCropRect; + + /** + * Get the crop rectangle associated with this frame. + * <p> + * The crop rectangle specifies the region of valid pixels in the image, + * using coordinates in the largest-resolution plane. + */ + public Rect getCropRect() { + throwISEIfImageIsInvalid(); + + if (mCropRect == null) { + return new Rect(0, 0, getWidth(), getHeight()); + } else { + return new Rect(mCropRect); // return a copy + } + } + + /** + * Set the crop rectangle associated with this frame. + * <p> + * The crop rectangle specifies the region of valid pixels in the image, + * using coordinates in the largest-resolution plane. + */ + public void setCropRect(Rect cropRect) { + throwISEIfImageIsInvalid(); + + if (cropRect != null) { + cropRect = new Rect(cropRect); // make a copy + if (!cropRect.intersect(0, 0, getWidth(), getHeight())) { + cropRect.setEmpty(); + } + } + mCropRect = cropRect; + } + + /** + * Get the array of pixel planes for this Image. The number of planes is + * determined by the format of the Image. The application will get an empty + * array if the image format is {@link android.graphics.ImageFormat#PRIVATE + * PRIVATE}, because the image pixel data is not directly accessible. The + * application can check the image format by calling + * {@link Image#getFormat()}. + */ + public abstract Plane[] getPlanes(); + + /** + * 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 + * or write to {@link ByteBuffer ByteBuffers} returned by an earlier + * {@link Plane#getBuffer} call will have undefined behavior. If the image + * was obtained from {@link ImageWriter} via + * {@link ImageWriter#dequeueInputImage()}, after calling this method, any + * image data filled by the application will be lost and the image will be + * returned to {@link ImageWriter} for reuse. Images given to + * {@link ImageWriter#queueInputImage queueInputImage()} are automatically + * closed. + * </p> + */ + @Override + public abstract void close(); + + /** + * <p> + * Check if the image can be attached to a new owner (e.g. {@link ImageWriter}). + * </p> + * <p> + * This is a package private method that is only used internally. + * </p> + * + * @return true if the image is attachable to a new owner, false if the image is still attached + * to its current owner, or the image is a stand-alone image and is not attachable to + * a new owner. + */ + boolean isAttachable() { + throwISEIfImageIsInvalid(); + + return false; + } + + /** + * <p> + * Get the owner of the {@link Image}. + * </p> + * <p> + * The owner of an {@link Image} could be {@link ImageReader}, {@link ImageWriter}, + * {@link MediaCodec} etc. This method returns the owner that produces this image, or null + * if the image is stand-alone image or the owner is unknown. + * </p> + * <p> + * This is a package private method that is only used internally. + * </p> + * + * @return The owner of the Image. + */ + Object getOwner() { + throwISEIfImageIsInvalid(); + + return null; + } + + /** + * Get native context (buffer pointer) associated with this image. + * <p> + * This is a package private method that is only used internally. It can be + * used to get the native buffer pointer and passed to native, which may be + * passed to {@link ImageWriter#attachAndQueueInputImage} to avoid a reverse + * JNI call. + * </p> + * + * @return native context associated with this Image. + */ + long getNativeContext() { + throwISEIfImageIsInvalid(); + + return 0; + } + + /** + * <p>A single color plane of image data.</p> + * + * <p>The number and meaning of the planes in an Image are determined by the + * format of the Image.</p> + * + * <p>Once the Image has been closed, any access to the the plane's + * ByteBuffer will fail.</p> + * + * @see #getFormat + */ + public static abstract class Plane { + /** + * @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. Note that row stried is undefined for some formats + * such as + * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}, + * and calling getRowStride on images of these formats will + * cause an UnsupportedOperationException being thrown. + * For formats where row stride is well defined, the row stride + * is always greater than 0.</p> + */ + 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. + * Note that pixel stride is undefined for some formats such as + * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}, + * and calling getPixelStride on images of these formats will + * cause an UnsupportedOperationException being thrown. + * For formats where pixel stride is well defined, the pixel stride + * is always greater than 0.</p> + */ + public abstract int getPixelStride(); + /** + * <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> + * + * <p>For raw formats, each plane is only guaranteed to contain data + * up to the last pixel in the last row. In other words, the stride + * after the last row may not be mapped into the buffer. This is a + * necessary requirement for any interleaved format.</p> + * + * @return the byte buffer containing the image data for this plane. + */ + public abstract ByteBuffer getBuffer(); + } + +} |