Camera: add RAW_PRIVATE format

Also add necessary plumbing for RAW_PRIVATE to work for ImageReader.

Bug: 25596619
Change-Id: Ic90f3f44264ac46fae1fafbc27ac64b5319f0970
This commit is contained in:
Yin-Chia Yeh
2015-12-07 17:15:24 -08:00
parent 718e16ad57
commit 44581ff4db
11 changed files with 90 additions and 12 deletions

View File

@@ -11545,6 +11545,7 @@ package android.graphics {
field public static final int PRIVATE = 34; // 0x22
field public static final int RAW10 = 37; // 0x25
field public static final int RAW12 = 38; // 0x26
field public static final int RAW_PRIVATE = 36; // 0x24
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

View File

@@ -11888,6 +11888,7 @@ package android.graphics {
field public static final int PRIVATE = 34; // 0x22
field public static final int RAW10 = 37; // 0x25
field public static final int RAW12 = 38; // 0x26
field public static final int RAW_PRIVATE = 36; // 0x24
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

View File

@@ -11545,6 +11545,7 @@ package android.graphics {
field public static final int PRIVATE = 34; // 0x22
field public static final int RAW10 = 37; // 0x25
field public static final int RAW12 = 38; // 0x26
field public static final int RAW_PRIVATE = 36; // 0x24
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

View File

@@ -834,6 +834,7 @@ public final class StreamConfigurationMap {
* <ul>
* <li>{@link ImageFormat#JPEG JPEG}
* <li>{@link ImageFormat#RAW_SENSOR RAW16}
* <li>{@link ImageFormat#RAW_PRIVATE RAW_PRIVATE}
* </ul>
* </p>
*
@@ -1328,9 +1329,7 @@ public final class StreamConfigurationMap {
SparseIntArray map = getFormatsMap(output);
for (int j = 0; j < map.size(); j++) {
int format = map.keyAt(j);
if (format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
formats[i++] = imageFormatToPublic(format);
}
formats[i++] = imageFormatToPublic(format);
}
if (output) {
for (int j = 0; j < mDepthOutputFormats.size(); j++) {
@@ -1392,9 +1391,6 @@ public final class StreamConfigurationMap {
private int getPublicFormatCount(boolean output) {
SparseIntArray formatsMap = getFormatsMap(output);
int size = formatsMap.size();
if (formatsMap.indexOfKey(HAL_PIXEL_FORMAT_RAW_OPAQUE) >= 0) {
size -= 1;
}
if (output) {
size += mDepthOutputFormats.size();
}
@@ -1603,6 +1599,8 @@ public final class StreamConfigurationMap {
return "Y16";
case ImageFormat.RAW_SENSOR:
return "RAW_SENSOR";
case ImageFormat.RAW_PRIVATE:
return "RAW_PRIVATE";
case ImageFormat.RAW10:
return "RAW10";
case ImageFormat.DEPTH16:

View File

@@ -149,7 +149,9 @@ android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
case PublicFormat::DEPTH16:
return HAL_DATASPACE_DEPTH;
case PublicFormat::RAW_SENSOR:
case PublicFormat::RAW_PRIVATE:
case PublicFormat::RAW10:
case PublicFormat::RAW12:
return HAL_DATASPACE_ARBITRARY;
case PublicFormat::YUV_420_888:
case PublicFormat::NV21:
@@ -170,6 +172,7 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW12:
case HAL_PIXEL_FORMAT_YCbCr_420_888:
case HAL_PIXEL_FORMAT_YV12:
// Enums overlap in both name and value
@@ -177,6 +180,9 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
case HAL_PIXEL_FORMAT_RAW16:
// Name differs, though value is the same
return PublicFormat::RAW_SENSOR;
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
// Name differs, though value is the same
return PublicFormat::RAW_PRIVATE;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
// Name differs, though the value is the same
return PublicFormat::NV16;
@@ -212,7 +218,6 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
}
break;
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
// Not defined in public API
return PublicFormat::UNKNOWN;

View File

@@ -360,6 +360,17 @@ public class ImageFormat {
*/
public static final int RAW_SENSOR = 0x20;
/**
* <p>Private raw camera sensor image format, a single channel image with
* implementation depedent pixel layout.</p>
*
* <p>RAW_PRIVATE is a format for unprocessed raw image buffers coming from an
* image sensor. The actual structure of buffers of this format is
* implementation-dependent.</p>
*
*/
public static final int RAW_PRIVATE = 0x24;
/**
* <p>
* Android 10-bit raw format
@@ -748,6 +759,7 @@ public class ImageFormat {
case FLEX_RGB_888:
case FLEX_RGBA_8888:
case RAW_SENSOR:
case RAW_PRIVATE:
case RAW10:
case RAW12:
case DEPTH16:

View File

@@ -45,7 +45,9 @@ enum class PublicFormat {
RAW_SENSOR = 0x20,
PRIVATE = 0x22,
YUV_420_888 = 0x23,
RAW_PRIVATE = 0x24,
RAW10 = 0x25,
RAW12 = 0x26,
JPEG = 0x100,
DEPTH_POINT_CLOUD = 0x101,
YV12 = 0x32315659,

View File

@@ -141,6 +141,16 @@ public abstract class Image implements AutoCloseable {
* {@link android.hardware.camera2.CameraDevice CameraDevice}.
* </td>
* </tr>
* <tr>
* <td>{@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}</td>
* <td>1</td>
* <td>A single plane of raw sensor image data of private layout.
* The details of the layout is implementation specific. Row stride and
* pixel stride are undefined for this format. Calling {@link Plane#getRowStride()}
* or {@link Plane#getPixelStride()} on RAW_PRIVATE image will cause
* UnSupportedOperationException being thrown.
* </td>
* </tr>
* </table>
*
* @see android.graphics.ImageFormat
@@ -341,7 +351,13 @@ public abstract class Image implements AutoCloseable {
* <p>The row stride for this color plane, in bytes.</p>
*
* <p>This is the distance between the start of two consecutive rows of
* pixels in the image. The row stride is always greater than 0.</p>
* pixels in the image. Note that row stried is undefined for some formats
* such as
* {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
* and calling getRowStride on images of these formats will
* cause an UnsupportedOperationException being thrown.
* For formats where row stride is well defined, the row stride
* is always greater than 0.</p>
*/
public abstract int getRowStride();
/**
@@ -350,7 +366,12 @@ public abstract class Image implements AutoCloseable {
* <p>This is the distance between two consecutive pixel values in a row
* of pixels. It may be larger than the size of a single pixel to
* account for interleaved image data or padded formats.
* The pixel stride is always greater than 0.</p>
* Note that pixel stride is undefined for some formats such as
* {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
* and calling getPixelStride on images of these formats will
* cause an UnsupportedOperationException being thrown.
* For formats where pixel stride is well defined, the pixel stride
* is always greater than 0.</p>
*/
public abstract int getPixelStride();
/**

View File

@@ -570,7 +570,7 @@ public class ImageReader implements AutoCloseable {
nativeDetachImage(image);
si.setDetached(true);
}
}
private boolean isImageOwnedbyMe(Image image) {
if (!(image instanceof SurfaceImage)) {
@@ -675,6 +675,7 @@ public class ImageReader implements AutoCloseable {
switch(getFormat()) {
case ImageFormat.JPEG:
case ImageFormat.DEPTH_POINT_CLOUD:
case ImageFormat.RAW_PRIVATE:
width = ImageReader.this.getWidth();
break;
default:
@@ -690,6 +691,7 @@ public class ImageReader implements AutoCloseable {
switch(getFormat()) {
case ImageFormat.JPEG:
case ImageFormat.DEPTH_POINT_CLOUD:
case ImageFormat.RAW_PRIVATE:
height = ImageReader.this.getHeight();
break;
default:
@@ -791,12 +793,20 @@ public class ImageReader implements AutoCloseable {
@Override
public int getPixelStride() {
SurfaceImage.this.throwISEIfImageIsInvalid();
if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
throw new UnsupportedOperationException(
"getPixelStride is not supported for RAW_PRIVATE plane");
}
return mPixelStride;
}
@Override
public int getRowStride() {
SurfaceImage.this.throwISEIfImageIsInvalid();
if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
throw new UnsupportedOperationException(
"getRowStride is not supported for RAW_PRIVATE plane");
}
return mRowStride;
}

View File

@@ -57,6 +57,7 @@ class ImageUtils {
case ImageFormat.Y8:
case ImageFormat.Y16:
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW_PRIVATE:
case ImageFormat.RAW10:
case ImageFormat.RAW12:
case ImageFormat.DEPTH16:
@@ -98,6 +99,10 @@ class ImageUtils {
dst.getFormat() == ImageFormat.PRIVATE) {
throw new IllegalArgumentException("PRIVATE format images are not copyable");
}
if (src.getFormat() == ImageFormat.RAW_PRIVATE) {
throw new IllegalArgumentException(
"Copy of RAW_OPAQUE format has not been implemented");
}
if (!(dst.getOwner() instanceof ImageWriter)) {
throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
+ " the images from ImageWriter are writable");
@@ -193,7 +198,8 @@ class ImageUtils {
case ImageFormat.YV12:
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:
case ImageFormat.PRIVATE: // A really rough estimate because the real size is unknown.
case ImageFormat.RAW12:
case ImageFormat.PRIVATE: // A rough estimate because the real size is unknown.
estimatedBytePerPixel = 1.5;
break;
case ImageFormat.NV16:
@@ -201,6 +207,7 @@ class ImageUtils {
case ImageFormat.YUY2:
case ImageFormat.Y16:
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
case ImageFormat.DEPTH16:
estimatedBytePerPixel = 2.0;
break;
@@ -245,6 +252,7 @@ class ImageUtils {
case ImageFormat.Y16:
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW10:
case ImageFormat.RAW12:
return new Size(image.getWidth(), image.getHeight());
case ImageFormat.PRIVATE:
return new Size(0, 0);

View File

@@ -101,6 +101,8 @@ public:
void setOpaqueConsumer(const sp<BufferItemConsumer>& consumer) { mOpaqueConsumer = consumer; }
BufferItemConsumer* getOpaqueConsumer() { return mOpaqueConsumer.get(); }
// This is the only opaque format exposed in the ImageFormat public API.
// Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE
// (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here.
bool isOpaque() { return mFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; }
void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; }
@@ -470,7 +472,8 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
case HAL_PIXEL_FORMAT_BLOB:
// Used for JPEG data, height must be 1, width == size, single plane.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height);
ALOG_ASSERT(buffer->height == 1,
"JPEG should has height value one but got %d", buffer->height);
pData = buffer->data;
dataSize = Image_getJpegSize(buffer, usingRGBAOverride);
@@ -482,6 +485,14 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
pData = buffer->data;
dataSize = buffer->stride * buffer->height * bytesPerPixel;
break;
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
// Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
ALOG_ASSERT(buffer->height == 1,
"RAW_PRIVATE should has height value one but got %d", buffer->height);
pData = buffer->data;
dataSize = buffer->width;
break;
case HAL_PIXEL_FORMAT_RAW10:
// Single plane 10bpp bayer data.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
@@ -593,6 +604,10 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
pixelStride = 3;
break;
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
pixelStride = 0; // RAW OPAQUE doesn't have pixel stride
break;
default:
jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
"Pixel format: 0x%x is unsupported", fmt);
@@ -669,6 +684,10 @@ static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buff
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
rowStride = buffer->stride * 3;
break;
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
rowStride = 0; // RAW OPAQUE doesn't have row stride
break;
default:
ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt);
jniThrowException(env, "java/lang/UnsupportedOperationException",