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.cts;
18 
19 import java.nio.ByteBuffer;
20 import java.lang.AutoCloseable;
21 
22 import android.graphics.Rect;
23 
24 /**
25  * <p>A single complete image buffer to use with a media source such as a
26  * {@link MediaCodec} or a
27  * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
28  *
29  * <p>This class allows for efficient direct application access to the pixel
30  * data of the CodecImage through one or more
31  * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
32  * {@link Plane} that describes the layout of the pixel data in that plane. Due
33  * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class,
34  * Images are not directly usable as UI resources.</p>
35  *
36  * <p>Since Images are often directly produced or consumed by hardware
37  * components, they are a limited resource shared across the system, and should
38  * be closed as soon as they are no longer needed.</p>
39  *
40  * <p>For example, when using the {@link ImageReader} class to read out Images
41  * from various media sources, not closing old CodecImage objects will prevent the
42  * availability of new Images once
43  * {@link ImageReader#getMaxImages the maximum outstanding image count} is
44  * reached. When this happens, the function acquiring new Images will typically
45  * throw an {@link IllegalStateException}.</p>
46  *
47  * @see ImageReader
48  */
49 public abstract class CodecImage implements AutoCloseable {
50     /**
51      * Get the format for this image. This format determines the number of
52      * ByteBuffers needed to represent the image, and the general layout of the
53      * pixel data in each in ByteBuffer.
54      *
55      * <p>
56      * The format is one of the values from
57      * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the
58      * formats and the planes is as follows:
59      * </p>
60      *
61      * <table>
62      * <tr>
63      *   <th>Format</th>
64      *   <th>Plane count</th>
65      *   <th>Layout details</th>
66      * </tr>
67      * <tr>
68      *   <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td>
69      *   <td>1</td>
70      *   <td>Compressed data, so row and pixel strides are 0. To uncompress, use
71      *      {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
72      *   </td>
73      * </tr>
74      * <tr>
75      *   <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td>
76      *   <td>3</td>
77      *   <td>A luminance plane followed by the Cb and Cr chroma planes.
78      *     The chroma planes have half the width and height of the luminance
79      *     plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits.
80      *     Each plane has its own row stride and pixel stride.</td>
81      * </tr>
82      * <tr>
83      *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td>
84      *   <td>1</td>
85      *   <td>A single plane of raw sensor image data, with 16 bits per color
86      *     sample. The details of the layout need to be queried from the source of
87      *     the raw sensor data, such as
88      *     {@link android.hardware.camera2.CameraDevice CameraDevice}.
89      *   </td>
90      * </tr>
91      * </table>
92      *
93      * @see android.graphics.ImageFormat
94      */
getFormat()95     public abstract int getFormat();
96 
97     /**
98      * The width of the image in pixels. For formats where some color channels
99      * are subsampled, this is the width of the largest-resolution plane.
100      */
getWidth()101     public abstract int getWidth();
102 
103     /**
104      * The height of the image in pixels. For formats where some color channels
105      * are subsampled, this is the height of the largest-resolution plane.
106      */
getHeight()107     public abstract int getHeight();
108 
109     /**
110      * Get the timestamp associated with this frame.
111      * <p>
112      * The timestamp is measured in nanoseconds, and is monotonically
113      * increasing. However, the zero point and whether the timestamp can be
114      * compared against other sources of time or images depend on the source of
115      * this image.
116      * </p>
117      */
getTimestamp()118     public abstract long getTimestamp();
119 
120     private Rect mCropRect;
121 
122     /**
123      * Get the crop rectangle associated with this frame.
124      * <p>
125      * The crop rectangle specifies the region of valid pixels in the image,
126      * using coordinates in the largest-resolution plane.
127      */
getCropRect()128     public Rect getCropRect() {
129         if (mCropRect == null) {
130             return new Rect(0, 0, getWidth(), getHeight());
131         } else {
132             return new Rect(mCropRect); // return a copy
133         }
134     }
135 
136     /**
137      * Set the crop rectangle associated with this frame.
138      * <p>
139      * The crop rectangle specifies the region of valid pixels in the image,
140      * using coordinates in the largest-resolution plane.
141      */
setCropRect(Rect cropRect)142     public void setCropRect(Rect cropRect) {
143         if (cropRect != null) {
144             cropRect = new Rect(cropRect);  // make a copy
145             cropRect.intersect(0, 0, getWidth(), getHeight());
146         }
147         mCropRect = cropRect;
148     }
149 
150     /**
151      * Get the array of pixel planes for this CodecImage. The number of planes is
152      * determined by the format of the CodecImage.
153      */
getPlanes()154     public abstract Plane[] getPlanes();
155 
156     /**
157      * Free up this frame for reuse.
158      * <p>
159      * After calling this method, calling any methods on this {@code CodecImage} will
160      * result in an {@link IllegalStateException}, and attempting to read from
161      * {@link ByteBuffer ByteBuffers} returned by an earlier
162      * {@link Plane#getBuffer} call will have undefined behavior.
163      * </p>
164      */
165     @Override
close()166     public abstract void close();
167 
168     /**
169      * <p>A single color plane of image data.</p>
170      *
171      * <p>The number and meaning of the planes in an CodecImage are determined by the
172      * format of the CodecImage.</p>
173      *
174      * <p>Once the CodecImage has been closed, any access to the the plane's
175      * ByteBuffer will fail.</p>
176      *
177      * @see #getFormat
178      */
179     public static abstract class Plane {
180         /**
181          * <p>The row stride for this color plane, in bytes.</p>
182          *
183          * <p>This is the distance between the start of two consecutive rows of
184          * pixels in the image. The row stride is always greater than 0.</p>
185          */
getRowStride()186         public abstract int getRowStride();
187         /**
188          * <p>The distance between adjacent pixel samples, in bytes.</p>
189          *
190          * <p>This is the distance between two consecutive pixel values in a row
191          * of pixels. It may be larger than the size of a single pixel to
192          * account for interleaved image data or padded formats.
193          * The pixel stride is always greater than 0.</p>
194          */
getPixelStride()195         public abstract int getPixelStride();
196         /**
197          * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer}
198          * containing the frame data.</p>
199          *
200          * <p>In particular, the buffer returned will always have
201          * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so
202          * the underlying data could be mapped as a pointer in JNI without doing
203          * any copies with {@code GetDirectBufferAddress}.</p>
204          *
205          * @return the byte buffer containing the image data for this plane.
206          */
getBuffer()207         public abstract ByteBuffer getBuffer();
208     }
209 
210 }
211