summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--graphics/java/android/graphics/ImageFormat.java124
-rw-r--r--media/java/android/media/ImageReader.java1
-rw-r--r--media/jni/android_media_ImageReader.cpp20
4 files changed, 143 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt
index 312f20db44c0..2d656aa2a397 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10493,6 +10493,7 @@ package android.graphics {
field public static final int JPEG = 256; // 0x100
field public static final int NV16 = 16; // 0x10
field public static final int NV21 = 17; // 0x11
+ field public static final int RAW10 = 37; // 0x25
field public static final int RAW_SENSOR = 32; // 0x20
field public static final int RGB_565 = 4; // 0x4
field public static final int UNKNOWN = 0; // 0x0
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index fe53a17c4712..28fd7ba4c8d3 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -211,6 +211,127 @@ public class ImageFormat {
public static final int RAW_SENSOR = 0x20;
/**
+ * <p>
+ * Android 10-bit raw format
+ * </p>
+ * <p>
+ * This is a single-plane, 10-bit per pixel, densely packed, unprocessed
+ * format, usually representing raw Bayer-pattern images coming from an image
+ * sensor.
+ * </p>
+ * <p>
+ * In an image buffer with this format, starting from the first pixel, each
+ * 4 consecutive pixels are packed into 5 bytes (40 bits). Each one of the
+ * first 4 bytes contains the top 8 bits of each pixel, The fifth byte
+ * contains the 2 least significant bits of the 4 pixels, the exact layout
+ * data for each 4 consecutive pixels is illustrated below (Pi[j] stands for
+ * the jth bit of the ith pixel):
+ * </p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center"></th>
+ * <th align="center">bit 7</th>
+ * <th align="center">bit 6</th>
+ * <th align="center">bit 5</th>
+ * <th align="center">bit 4</th>
+ * <th align="center">bit 3</th>
+ * <th align="center">bit 2</th>
+ * <th align="center">bit 1</th>
+ * <th align="center">bit 0</th>
+ * </tr>
+ * </thead> <tbody>
+ * <tr>
+ * <td align="center">Byte 0:</td>
+ * <td align="center">P0[9]</td>
+ * <td align="center">P0[8]</td>
+ * <td align="center">P0[7]</td>
+ * <td align="center">P0[6]</td>
+ * <td align="center">P0[5]</td>
+ * <td align="center">P0[4]</td>
+ * <td align="center">P0[3]</td>
+ * <td align="center">P0[2]</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Byte 1:</td>
+ * <td align="center">P1[9]</td>
+ * <td align="center">P1[8]</td>
+ * <td align="center">P1[7]</td>
+ * <td align="center">P1[6]</td>
+ * <td align="center">P1[5]</td>
+ * <td align="center">P1[4]</td>
+ * <td align="center">P1[3]</td>
+ * <td align="center">P1[2]</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Byte 2:</td>
+ * <td align="center">P2[9]</td>
+ * <td align="center">P2[8]</td>
+ * <td align="center">P2[7]</td>
+ * <td align="center">P2[6]</td>
+ * <td align="center">P2[5]</td>
+ * <td align="center">P2[4]</td>
+ * <td align="center">P2[3]</td>
+ * <td align="center">P2[2]</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Byte 3:</td>
+ * <td align="center">P3[9]</td>
+ * <td align="center">P3[8]</td>
+ * <td align="center">P3[7]</td>
+ * <td align="center">P3[6]</td>
+ * <td align="center">P3[5]</td>
+ * <td align="center">P3[4]</td>
+ * <td align="center">P3[3]</td>
+ * <td align="center">P3[2]</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Byte 4:</td>
+ * <td align="center">P3[1]</td>
+ * <td align="center">P3[0]</td>
+ * <td align="center">P2[1]</td>
+ * <td align="center">P2[0]</td>
+ * <td align="center">P1[1]</td>
+ * <td align="center">P1[0]</td>
+ * <td align="center">P0[1]</td>
+ * <td align="center">P0[0]</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ * <p>
+ * This format assumes
+ * <ul>
+ * <li>a width multiple of 4 pixels</li>
+ * <li>an even height</li>
+ * </ul>
+ * </p>
+ *
+ * <pre>
+ * size = width * height * 10 / 8
+ * </pre>
+ * <p>
+ * Since this is a densely packed format, the pixel and row stride are always
+ * 0. The application must use the pixel data layout defined in above table
+ * to access data.
+ * </p>
+ *
+ * <p>
+ * For example, the {@link android.media.Image} object can provide data in
+ * this format from a {@link android.hardware.camera2.CameraDevice} (if supported)
+ * through a {@link android.media.ImageReader} object. The
+ * {@link android.media.Image#getPlanes() Image#getPlanes()} will return a
+ * single plane containing the pixel data. The pixel stride and row stride
+ * are always 0 in {@link android.media.Image.Plane#getPixelStride()} and
+ * {@link android.media.Image.Plane#getRowStride()} respectively.
+ * </p>
+ *
+ * @see android.media.Image
+ * @see android.media.ImageReader
+ * @see android.hardware.camera2.CameraDevice
+ */
+ public static final int RAW10 = 0x25;
+
+ /**
* Raw bayer format used for images, which is 10 bit precision samples
* stored in 16 bit words. The filter pattern is RGGB. Whether this format
* is supported by the camera hardware can be determined by
@@ -250,6 +371,8 @@ public class ImageFormat {
return 16;
case BAYER_RGGB:
return 16;
+ case RAW10:
+ return 10;
}
return -1;
}
@@ -276,6 +399,7 @@ public class ImageFormat {
case NV21:
case YUV_420_888:
case RAW_SENSOR:
+ case RAW10:
return true;
}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 1bd32c4c976c..6e1b80aeee73 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -477,6 +477,7 @@ public class ImageReader implements AutoCloseable {
case ImageFormat.Y8:
case ImageFormat.Y16:
case ImageFormat.RAW_SENSOR:
+ case ImageFormat.RAW10:
return 1;
default:
throw new UnsupportedOperationException(
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index ad7ee7ad091e..35317e1c51e0 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -267,7 +267,7 @@ static void Image_setBuffer(JNIEnv* env, jobject thiz,
// graphics.h, need convert to the one defined in graphics.h here.
static int Image_getPixelFormat(JNIEnv* env, int format)
{
- int jpegFormat, rawSensorFormat;
+ int jpegFormat;
jfieldID fid;
ALOGV("%s: format = 0x%x", __FUNCTION__, format);
@@ -413,6 +413,16 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
pData = buffer->data;
dataSize = buffer->stride * buffer->height * bytesPerPixel;
break;
+ case HAL_PIXEL_FORMAT_RAW10:
+ // Single plane 10bpp bayer data.
+ ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+ LOG_ALWAYS_FATAL_IF(buffer->width % 4,
+ "Width is not multiple of 4 %d", buffer->width);
+ LOG_ALWAYS_FATAL_IF(buffer->height % 2,
+ "Height is not even %d", buffer->height);
+ pData = buffer->data;
+ dataSize = buffer->width * buffer->height * 10 / 8;
+ break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
// Single plane, 32bpp.
@@ -470,7 +480,9 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
pixelStride = 1;
break;
case HAL_PIXEL_FORMAT_BLOB:
- // Used for JPEG data, single plane, row and pixel strides are 0
+ case HAL_PIXEL_FORMAT_RAW10:
+ // Blob is used for JPEG data, RAW10 is used for 10-bit raw data, they are
+ // single plane, row and pixel strides are 0.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
pixelStride = 0;
break;
@@ -523,7 +535,9 @@ static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buff
rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16);
break;
case HAL_PIXEL_FORMAT_BLOB:
- // Used for JPEG data, single plane, row and pixel strides are 0
+ case HAL_PIXEL_FORMAT_RAW10:
+ // Blob is used for JPEG data, RAW10 is used for 10-bit raw data, they are
+ // single plane, row and pixel strides are 0.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
rowStride = 0;
break;