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