Add DEPTH image formats, support in ImageReader
- Add an explicit mapping between public ImageFormat/ PixelFormat enums and internal HAL format/dataspace. - Add DEPTH16 and DEPTH_POINT_CLOUD formats - Wire up mapping layer to ImageReader to support depth formats Change-Id: I8197eccef900cc91baddcfcb934ccd4d8c972eff
This commit is contained in:
committed by
Zhijun He
parent
981e056c01
commit
3dd5a398fd
@@ -10786,6 +10786,8 @@ package android.graphics {
|
||||
public class ImageFormat {
|
||||
ctor public ImageFormat();
|
||||
method public static int getBitsPerPixel(int);
|
||||
field public static final int DEPTH16 = 1144402265; // 0x44363159
|
||||
field public static final int DEPTH_POINT_CLOUD = 257; // 0x101
|
||||
field public static final int JPEG = 256; // 0x100
|
||||
field public static final int NV16 = 16; // 0x10
|
||||
field public static final int NV21 = 17; // 0x11
|
||||
|
||||
@@ -11092,6 +11092,8 @@ package android.graphics {
|
||||
public class ImageFormat {
|
||||
ctor public ImageFormat();
|
||||
method public static int getBitsPerPixel(int);
|
||||
field public static final int DEPTH16 = 1144402265; // 0x44363159
|
||||
field public static final int DEPTH_POINT_CLOUD = 257; // 0x101
|
||||
field public static final int JPEG = 256; // 0x100
|
||||
field public static final int NV16 = 16; // 0x10
|
||||
field public static final int NV21 = 17; // 0x11
|
||||
|
||||
@@ -129,6 +129,100 @@ jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,
|
||||
return surfaceObj;
|
||||
}
|
||||
|
||||
int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f) {
|
||||
|
||||
switch(f) {
|
||||
case JPEG:
|
||||
case DEPTH_POINT_CLOUD:
|
||||
return HAL_PIXEL_FORMAT_BLOB;
|
||||
case DEPTH16:
|
||||
return HAL_PIXEL_FORMAT_Y16;
|
||||
case RAW_SENSOR:
|
||||
return HAL_PIXEL_FORMAT_RAW16;
|
||||
default:
|
||||
// Most formats map 1:1
|
||||
return static_cast<int>(f);
|
||||
}
|
||||
}
|
||||
|
||||
android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
|
||||
PublicFormat f) {
|
||||
switch(f) {
|
||||
case JPEG:
|
||||
return HAL_DATASPACE_JFIF;
|
||||
case DEPTH_POINT_CLOUD:
|
||||
case DEPTH16:
|
||||
return HAL_DATASPACE_DEPTH;
|
||||
case RAW_SENSOR:
|
||||
case RAW10:
|
||||
return HAL_DATASPACE_ARBITRARY;
|
||||
case YUV_420_888:
|
||||
case NV21:
|
||||
case YV12:
|
||||
return HAL_DATASPACE_JFIF;
|
||||
default:
|
||||
// Most formats map to UNKNOWN
|
||||
return HAL_DATASPACE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
|
||||
int format, android_dataspace dataSpace) {
|
||||
switch(format) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
case HAL_PIXEL_FORMAT_RGB_888:
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
case HAL_PIXEL_FORMAT_Y8:
|
||||
case HAL_PIXEL_FORMAT_RAW10:
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
// Enums overlap in both name and value
|
||||
return static_cast<PublicFormat>(format);
|
||||
case HAL_PIXEL_FORMAT_RAW16:
|
||||
// Name differs, though value is the same
|
||||
return RAW_SENSOR;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
||||
// Name differs, though the value is the same
|
||||
return NV16;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
// Name differs, though the value is the same
|
||||
return NV21;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
||||
// Name differs, though the value is the same
|
||||
return YUY2;
|
||||
case HAL_PIXEL_FORMAT_Y16:
|
||||
// Dataspace-dependent
|
||||
switch (dataSpace) {
|
||||
case HAL_DATASPACE_DEPTH:
|
||||
return DEPTH16;
|
||||
default:
|
||||
// Assume non-depth Y16 is just Y16.
|
||||
return Y16;
|
||||
}
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_BLOB:
|
||||
// Dataspace-dependent
|
||||
switch (dataSpace) {
|
||||
case HAL_DATASPACE_DEPTH:
|
||||
return DEPTH_POINT_CLOUD;
|
||||
case HAL_DATASPACE_JFIF:
|
||||
return JPEG;
|
||||
default:
|
||||
// Assume otherwise-marked blobs are also JPEG
|
||||
return JPEG;
|
||||
}
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
|
||||
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
|
||||
// Not defined in public API
|
||||
return UNKNOWN;
|
||||
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static inline bool isSurfaceValid(const sp<Surface>& sur) {
|
||||
|
||||
@@ -355,6 +355,38 @@ public class ImageFormat {
|
||||
*/
|
||||
public static final int RAW10 = 0x25;
|
||||
|
||||
/**
|
||||
* Android dense depth image format.
|
||||
*
|
||||
* Each pixel is 16 bits, representing a depth ranging measurement from
|
||||
* a depth camera or similar sensor.
|
||||
*
|
||||
* <p>This format assumes
|
||||
* <ul>
|
||||
* <li>an even width</li>
|
||||
* <li>an even height</li>
|
||||
* <li>a horizontal stride multiple of 16 pixels</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <pre> y_size = stride * height </pre>
|
||||
*
|
||||
* When produced by a camera, the units are millimeters.
|
||||
*/
|
||||
public static final int DEPTH16 = 0x44363159;
|
||||
|
||||
/**
|
||||
* Android sparse depth point cloud format.
|
||||
*
|
||||
* <p>A variable-length list of 3D points, with each point represented
|
||||
* by a triple of floats.</p>
|
||||
*
|
||||
* <p>The number of points is {@code (size of the buffer in bytes) / 12}.
|
||||
*
|
||||
* The coordinate system and units depend on the source of the point cloud data.
|
||||
*/
|
||||
public static final int DEPTH_POINT_CLOUD = 0x101;
|
||||
|
||||
/**
|
||||
* Use this function to retrieve the number of bits per pixel of an
|
||||
* ImageFormat.
|
||||
@@ -376,6 +408,7 @@ public class ImageFormat {
|
||||
case Y8:
|
||||
return 8;
|
||||
case Y16:
|
||||
case DEPTH16:
|
||||
return 16;
|
||||
case NV21:
|
||||
return 12;
|
||||
@@ -412,6 +445,8 @@ public class ImageFormat {
|
||||
case YUV_420_888:
|
||||
case RAW_SENSOR:
|
||||
case RAW10:
|
||||
case DEPTH16:
|
||||
case DEPTH_POINT_CLOUD:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,33 @@ namespace android {
|
||||
class Surface;
|
||||
class IGraphicBufferProducer;
|
||||
|
||||
/**
|
||||
* Enum mirroring the public API definitions for image and pixel formats.
|
||||
* Some of these are hidden in the public API
|
||||
*
|
||||
* Keep up to date with android.graphics.ImageFormat and
|
||||
* android.graphics.PixelFormat
|
||||
*/
|
||||
enum PublicFormat {
|
||||
UNKNOWN = 0x0,
|
||||
RGBA_8888 = 0x1,
|
||||
RGBX_8888 = 0x2,
|
||||
RGB_888 = 0x3,
|
||||
RGB_565 = 0x4,
|
||||
NV16 = 0x10,
|
||||
NV21 = 0x11,
|
||||
YUY2 = 0x14,
|
||||
RAW_SENSOR = 0x20,
|
||||
YUV_420_888 = 0x23,
|
||||
RAW10 = 0x25,
|
||||
JPEG = 0x100,
|
||||
DEPTH_POINT_CLOUD = 0x101,
|
||||
YV12 = 0x32315659,
|
||||
Y8 = 0x20203859, // @hide
|
||||
Y16 = 0x20363159, // @hide
|
||||
DEPTH16 = 0x44363159
|
||||
};
|
||||
|
||||
/* Gets the underlying ANativeWindow for a Surface. */
|
||||
extern sp<ANativeWindow> android_view_Surface_getNativeWindow(
|
||||
JNIEnv* env, jobject surfaceObj);
|
||||
@@ -40,6 +67,21 @@ extern sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceO
|
||||
extern jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,
|
||||
const sp<IGraphicBufferProducer>& bufferProducer);
|
||||
|
||||
/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL
|
||||
* format */
|
||||
extern int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f);
|
||||
|
||||
/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL
|
||||
* dataspace */
|
||||
extern android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
|
||||
PublicFormat f);
|
||||
|
||||
/* Convert from HAL format, dataspace pair to
|
||||
* android.graphics.ImageFormat/PixelFormat.
|
||||
* For unknown/unspecified pairs, returns PublicFormat::UNKNOWN */
|
||||
extern PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
|
||||
int format, android_dataspace dataSpace);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _ANDROID_VIEW_SURFACE_H
|
||||
|
||||
@@ -483,6 +483,8 @@ public class ImageReader implements AutoCloseable {
|
||||
case ImageFormat.Y16:
|
||||
case ImageFormat.RAW_SENSOR:
|
||||
case ImageFormat.RAW10:
|
||||
case ImageFormat.DEPTH16:
|
||||
case ImageFormat.DEPTH_POINT_CLOUD:
|
||||
return 1;
|
||||
default:
|
||||
throw new UnsupportedOperationException(
|
||||
|
||||
@@ -95,6 +95,9 @@ public:
|
||||
void setBufferFormat(int format) { mFormat = format; }
|
||||
int getBufferFormat() { return mFormat; }
|
||||
|
||||
void setBufferDataspace(android_dataspace dataSpace) { mDataSpace = dataSpace; }
|
||||
android_dataspace getBufferDataspace() { return mDataSpace; }
|
||||
|
||||
void setBufferWidth(int width) { mWidth = width; }
|
||||
int getBufferWidth() { return mWidth; }
|
||||
|
||||
@@ -111,6 +114,7 @@ private:
|
||||
jobject mWeakThiz;
|
||||
jclass mClazz;
|
||||
int mFormat;
|
||||
android_dataspace mDataSpace;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
};
|
||||
@@ -263,29 +267,6 @@ static void Image_setBuffer(JNIEnv* env, jobject thiz,
|
||||
env->SetLongField(thiz, gSurfaceImageClassInfo.mLockedBuffer, reinterpret_cast<jlong>(buffer));
|
||||
}
|
||||
|
||||
// Some formats like JPEG defined with different values between android.graphics.ImageFormat and
|
||||
// graphics.h, need convert to the one defined in graphics.h here.
|
||||
static int Image_getPixelFormat(JNIEnv* env, int format)
|
||||
{
|
||||
int jpegFormat;
|
||||
jfieldID fid;
|
||||
|
||||
ALOGV("%s: format = 0x%x", __FUNCTION__, format);
|
||||
|
||||
jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat");
|
||||
ALOG_ASSERT(imageFormatClazz != NULL);
|
||||
|
||||
fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I");
|
||||
jpegFormat = env->GetStaticIntField(imageFormatClazz, fid);
|
||||
|
||||
// Translate the JPEG to BLOB for camera purpose.
|
||||
if (format == jpegFormat) {
|
||||
format = HAL_PIXEL_FORMAT_BLOB;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer, bool usingRGBAOverride)
|
||||
{
|
||||
ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
|
||||
@@ -483,7 +464,7 @@ static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* bu
|
||||
}
|
||||
|
||||
static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
|
||||
int32_t readerFormat)
|
||||
int32_t halReaderFormat)
|
||||
{
|
||||
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
|
||||
ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx);
|
||||
@@ -493,7 +474,7 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
|
||||
|
||||
int32_t fmt = buffer->flexFormat;
|
||||
|
||||
fmt = applyFormatOverrides(fmt, readerFormat);
|
||||
fmt = applyFormatOverrides(fmt, halReaderFormat);
|
||||
|
||||
switch (fmt) {
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
@@ -544,7 +525,7 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu
|
||||
}
|
||||
|
||||
static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
|
||||
int32_t readerFormat)
|
||||
int32_t halReaderFormat)
|
||||
{
|
||||
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
|
||||
ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0));
|
||||
@@ -554,7 +535,7 @@ static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buff
|
||||
|
||||
int32_t fmt = buffer->flexFormat;
|
||||
|
||||
fmt = applyFormatOverrides(fmt, readerFormat);
|
||||
fmt = applyFormatOverrides(fmt, halReaderFormat);
|
||||
|
||||
switch (fmt) {
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
@@ -683,11 +664,16 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz,
|
||||
{
|
||||
status_t res;
|
||||
int nativeFormat;
|
||||
android_dataspace nativeDataspace;
|
||||
|
||||
ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d",
|
||||
__FUNCTION__, width, height, format, maxImages);
|
||||
|
||||
nativeFormat = Image_getPixelFormat(env, format);
|
||||
PublicFormat publicFormat = static_cast<PublicFormat>(format);
|
||||
nativeFormat = android_view_Surface_mapPublicFormatToHalFormat(
|
||||
publicFormat);
|
||||
nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace(
|
||||
publicFormat);
|
||||
|
||||
sp<IGraphicBufferProducer> gbProducer;
|
||||
sp<IGraphicBufferConsumer> gbConsumer;
|
||||
@@ -711,10 +697,11 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz,
|
||||
consumer->setFrameAvailableListener(ctx);
|
||||
ImageReader_setNativeContext(env, thiz, ctx);
|
||||
ctx->setBufferFormat(nativeFormat);
|
||||
ctx->setBufferDataspace(nativeDataspace);
|
||||
ctx->setBufferWidth(width);
|
||||
ctx->setBufferHeight(height);
|
||||
|
||||
// Set the width/height/format to the CpuConsumer
|
||||
// Set the width/height/format/dataspace to the CpuConsumer
|
||||
res = consumer->setDefaultBufferSize(width, height);
|
||||
if (res != OK) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
@@ -726,6 +713,12 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz,
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Failed to set CpuConsumer buffer format");
|
||||
}
|
||||
res = consumer->setDefaultBufferDataSpace(nativeDataspace);
|
||||
if (res != OK) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Failed to set CpuConsumer buffer dataSpace");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ImageReader_close(JNIEnv* env, jobject thiz)
|
||||
@@ -885,6 +878,8 @@ static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
|
||||
static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int readerFormat)
|
||||
{
|
||||
int rowStride, pixelStride;
|
||||
PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat);
|
||||
|
||||
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
|
||||
|
||||
CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
|
||||
@@ -894,10 +889,11 @@ static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx, int
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
|
||||
}
|
||||
|
||||
readerFormat = Image_getPixelFormat(env, readerFormat);
|
||||
int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat(
|
||||
publicReaderFormat);
|
||||
|
||||
rowStride = Image_imageGetRowStride(env, buffer, idx, readerFormat);
|
||||
pixelStride = Image_imageGetPixelStride(env, buffer, idx, readerFormat);
|
||||
rowStride = Image_imageGetRowStride(env, buffer, idx, halReaderFormat);
|
||||
pixelStride = Image_imageGetPixelStride(env, buffer, idx, halReaderFormat);
|
||||
|
||||
jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz,
|
||||
gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride);
|
||||
@@ -910,6 +906,7 @@ static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int reade
|
||||
uint8_t *base = NULL;
|
||||
uint32_t size = 0;
|
||||
jobject byteBuffer;
|
||||
PublicFormat readerPublicFormat = static_cast<PublicFormat>(readerFormat);
|
||||
|
||||
ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
|
||||
|
||||
@@ -919,10 +916,11 @@ static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx, int reade
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
|
||||
}
|
||||
|
||||
readerFormat = Image_getPixelFormat(env, readerFormat);
|
||||
int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat(
|
||||
readerPublicFormat);
|
||||
|
||||
// Create byteBuffer from native buffer
|
||||
Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerFormat);
|
||||
Image_getLockedBufferInfo(env, buffer, idx, &base, &size, readerHalFormat);
|
||||
|
||||
if (size > static_cast<uint32_t>(INT32_MAX)) {
|
||||
// Byte buffer have 'int capacity', so check the range
|
||||
|
||||
Reference in New Issue
Block a user