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