Loading media/java/android/media/ImageReader.java +14 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.os.Looper; import android.os.Message; import android.view.Surface; import dalvik.system.VMRuntime; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.ByteOrder; Loading Loading @@ -148,6 +150,13 @@ public class ImageReader implements AutoCloseable { nativeInit(new WeakReference<ImageReader>(this), width, height, format, maxImages); mSurface = nativeGetSurface(); // Estimate the native buffer allocation size and register it so it gets accounted for // during GC. Note that this doesn't include the buffers required by the buffer queue // itself and the buffers requested by the producer. mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(width, height, format, maxImages); VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes); } /** Loading Loading @@ -467,6 +476,10 @@ public class ImageReader implements AutoCloseable { setOnImageAvailableListener(null, null); if (mSurface != null) mSurface.release(); nativeClose(); if (mEstimatedNativeAllocBytes > 0) { VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes); mEstimatedNativeAllocBytes = 0; } } @Override Loading Loading @@ -606,6 +619,7 @@ public class ImageReader implements AutoCloseable { private final int mMaxImages; private final int mNumPlanes; private final Surface mSurface; private int mEstimatedNativeAllocBytes; private final Object mListenerLock = new Object(); private OnImageAvailableListener mListener; Loading media/java/android/media/ImageUtils.java +56 −0 Original line number Diff line number Diff line Loading @@ -119,4 +119,60 @@ class ImageUtils { dstBuffer.rewind(); } } /** * Return the estimated native allocation size in bytes based on width, height, format, * and number of images. * * <p>This is a very rough estimation and should only be used for native allocation * registration in VM so it can be accounted for during GC.</p> * * @param width The width of the images. * @param height The height of the images. * @param format The format of the images. * @param numImages The number of the images. */ public static int getEstimatedNativeAllocBytes(int width, int height, int format, int numImages) { double estimatedBytePerPixel; switch (format) { // 10x compression from RGB_888 case ImageFormat.JPEG: case ImageFormat.DEPTH_POINT_CLOUD: estimatedBytePerPixel = 0.3; break; case ImageFormat.Y8: estimatedBytePerPixel = 1.0; break; case ImageFormat.RAW10: estimatedBytePerPixel = 1.25; break; case ImageFormat.YV12: case ImageFormat.YUV_420_888: case ImageFormat.NV21: case ImageFormat.PRIVATE: // A really rough estimate because the real size is unknown. estimatedBytePerPixel = 1.5; break; case ImageFormat.NV16: case PixelFormat.RGB_565: case ImageFormat.YUY2: case ImageFormat.Y16: case ImageFormat.RAW_SENSOR: case ImageFormat.DEPTH16: estimatedBytePerPixel = 2.0; break; case PixelFormat.RGB_888: estimatedBytePerPixel = 3.0; break; case PixelFormat.RGBA_8888: case PixelFormat.RGBX_8888: estimatedBytePerPixel = 4.0; break; default: throw new UnsupportedOperationException( String.format("Invalid format specified %d", format)); } return (int)(width * height * estimatedBytePerPixel * numImages); } } Loading
media/java/android/media/ImageReader.java +14 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.os.Looper; import android.os.Message; import android.view.Surface; import dalvik.system.VMRuntime; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.ByteOrder; Loading Loading @@ -148,6 +150,13 @@ public class ImageReader implements AutoCloseable { nativeInit(new WeakReference<ImageReader>(this), width, height, format, maxImages); mSurface = nativeGetSurface(); // Estimate the native buffer allocation size and register it so it gets accounted for // during GC. Note that this doesn't include the buffers required by the buffer queue // itself and the buffers requested by the producer. mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(width, height, format, maxImages); VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes); } /** Loading Loading @@ -467,6 +476,10 @@ public class ImageReader implements AutoCloseable { setOnImageAvailableListener(null, null); if (mSurface != null) mSurface.release(); nativeClose(); if (mEstimatedNativeAllocBytes > 0) { VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes); mEstimatedNativeAllocBytes = 0; } } @Override Loading Loading @@ -606,6 +619,7 @@ public class ImageReader implements AutoCloseable { private final int mMaxImages; private final int mNumPlanes; private final Surface mSurface; private int mEstimatedNativeAllocBytes; private final Object mListenerLock = new Object(); private OnImageAvailableListener mListener; Loading
media/java/android/media/ImageUtils.java +56 −0 Original line number Diff line number Diff line Loading @@ -119,4 +119,60 @@ class ImageUtils { dstBuffer.rewind(); } } /** * Return the estimated native allocation size in bytes based on width, height, format, * and number of images. * * <p>This is a very rough estimation and should only be used for native allocation * registration in VM so it can be accounted for during GC.</p> * * @param width The width of the images. * @param height The height of the images. * @param format The format of the images. * @param numImages The number of the images. */ public static int getEstimatedNativeAllocBytes(int width, int height, int format, int numImages) { double estimatedBytePerPixel; switch (format) { // 10x compression from RGB_888 case ImageFormat.JPEG: case ImageFormat.DEPTH_POINT_CLOUD: estimatedBytePerPixel = 0.3; break; case ImageFormat.Y8: estimatedBytePerPixel = 1.0; break; case ImageFormat.RAW10: estimatedBytePerPixel = 1.25; break; case ImageFormat.YV12: case ImageFormat.YUV_420_888: case ImageFormat.NV21: case ImageFormat.PRIVATE: // A really rough estimate because the real size is unknown. estimatedBytePerPixel = 1.5; break; case ImageFormat.NV16: case PixelFormat.RGB_565: case ImageFormat.YUY2: case ImageFormat.Y16: case ImageFormat.RAW_SENSOR: case ImageFormat.DEPTH16: estimatedBytePerPixel = 2.0; break; case PixelFormat.RGB_888: estimatedBytePerPixel = 3.0; break; case PixelFormat.RGBA_8888: case PixelFormat.RGBX_8888: estimatedBytePerPixel = 4.0; break; default: throw new UnsupportedOperationException( String.format("Invalid format specified %d", format)); } return (int)(width * height * estimatedBytePerPixel * numImages); } }