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