ImageReader.java revision b2675542c2f414154125b534767ae0903fba581e
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 17package android.media; 18 19import android.view.Surface; 20import java.lang.AutoCloseable; 21 22/** 23 * <p>The ImageReader class allows direct application access to image data 24 * rendered into a {@link android.view.Surface}</p> 25 * 26 * <p>Several Android media API classes accept Surface objects as targets to 27 * render to, including {@link MediaPlayer}, {@link MediaCodec}, 28 * {@link android.hardware.photography.CameraDevice}, and 29 * {@link android.renderscript.Allocation RenderScript Allocations}. The image 30 * sizes and formats that can be used with each source vary, and should be 31 * checked in the documentation for the specific API.</p> 32 * 33 * <p>The image data is encapsulated in {@link Image} objects, and multiple such 34 * objects can be accessed at the same time, up to the number specified by the 35 * {@code maxImages} constructor parameter. New images sent to an ImageReader 36 * through its Surface are queued until accessed through the 37 * {@link #getNextImage} call. Due to memory limits, an image source will 38 * eventually stall or drop Images in trying to render to the Surface if the 39 * ImageReader does not obtain and release Images at a rate equal to the 40 * production rate.</p> 41 */ 42public final class ImageReader { 43 44 /** 45 * <p>Create a new reader for images of the desired size and format.</p> 46 * 47 * <p>The maxImages parameter determines the maximum number of {@link Image} 48 * objects that can be be acquired from the ImageReader 49 * simultaneously. Requesting more buffers will use up more memory, so it is 50 * important to use only the minimum number necessary for the use case.</p> 51 * 52 * <p>The valid sizes and formats depend on the source of the image 53 * data.</p> 54 * 55 * @param width the width in pixels of the Images that this reader will 56 * produce. 57 * @param height the height in pixels of the Images that this reader will 58 * produce. 59 * @param format the format of the Image that this reader will produce. This 60 * must be one of the {@link android.graphics.ImageFormat} constants. 61 * @param maxImages the maximum number of images the user will want to 62 * access simultaneously. This should be as small as possible to limit 63 * memory use. Once maxImages Images are obtained by the user, one of them 64 * has to be released before a new Image will become available for access 65 * through getImage(). Must be greater than 0. 66 * 67 * @see Image 68 */ 69 public ImageReader(int width, int height, int format, int maxImages) { 70 mWidth = width; 71 mHeight = height; 72 mFormat = format; 73 mMaxImages = maxImages; 74 75 if (width < 1 || height < 1) { 76 throw new IllegalArgumentException( 77 "The image dimensions must be positive"); 78 } 79 if (mMaxImages < 1) { 80 throw new IllegalArgumentException( 81 "Maximum outstanding image count must be at least 1"); 82 } 83 } 84 85 public int getWidth() { 86 return mWidth; 87 } 88 89 public int getHeight() { 90 return mHeight; 91 } 92 93 public int getImageFormat() { 94 return mFormat; 95 } 96 97 public int getMaxImages() { 98 return mMaxImages; 99 } 100 101 /** 102 * <p>Get a Surface that can be used to produce Images for this 103 * ImageReader.</p> 104 * 105 * <p>Until valid image data is rendered into this Surface, the 106 * {@link #getNextImage} method will return {@code null}. Only one source 107 * can be producing data into this Surface at the same time, although the 108 * same Surface can be reused with a different API once the first source is 109 * disconnected from the Surface.</p> 110 * 111 * @return A Surface to use for a drawing target for various APIs. 112 */ 113 public Surface getSurface() { 114 return null; 115 } 116 117 /** 118 * <p>Get the next Image from the ImageReader's queue. Returns {@code null} 119 * if no new image is available.</p> 120 * 121 * @return a new frame of image data, or {@code null} if no image data is 122 * available. 123 */ 124 public Image getNextImage() { 125 return null; 126 } 127 128 /** 129 * <p>Return the frame to the ImageReader for reuse.</p> 130 */ 131 public void releaseImage(Image i) { 132 if (! (i instanceof SurfaceImage) ) { 133 throw new IllegalArgumentException( 134 "This image was not produced by an ImageReader"); 135 } 136 SurfaceImage si = (SurfaceImage) i; 137 if (si.getReader() != this) { 138 throw new IllegalArgumentException( 139 "This image was not produced by this ImageReader"); 140 } 141 } 142 143 public void setOnImageAvailableListener(OnImageAvailableListener l) { 144 mImageListener = l; 145 } 146 147 public interface OnImageAvailableListener { 148 void onImageAvailable(ImageReader reader); 149 } 150 151 private final int mWidth; 152 private final int mHeight; 153 private final int mFormat; 154 private final int mMaxImages; 155 156 private OnImageAvailableListener mImageListener; 157 158 private class SurfaceImage extends android.media.Image { 159 public SurfaceImage() { 160 } 161 162 @Override 163 public void close() { 164 ImageReader.this.releaseImage(this); 165 } 166 167 public ImageReader getReader() { 168 return ImageReader.this; 169 } 170 } 171} 172