Add support for 10-bit YUV P010 ImageFormat

Bug: 147711411
Test: Camera CTS
Change-Id: I44f61b44f1cc67e079417e72415a26c0793ab5e8
This commit is contained in:
Emilian Peev
2021-01-21 11:38:34 -08:00
parent 3f08df9fe9
commit fd37b04a35
4 changed files with 67 additions and 0 deletions

View File

@@ -15006,6 +15006,7 @@ package android.graphics {
field public static final int RGB_565 = 4; // 0x4
field public static final int UNKNOWN = 0; // 0x0
field public static final int Y8 = 538982489; // 0x20203859
field public static final int YCBCR_P010 = 54; // 0x36
field public static final int YUV_420_888 = 35; // 0x23
field public static final int YUV_422_888 = 39; // 0x27
field public static final int YUV_444_888 = 40; // 0x28

View File

@@ -174,6 +174,39 @@ public class ImageFormat {
*/
public static final int Y16 = 0x20363159;
/**
* <p>Android YUV P010 format.</p>
*
* P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
* followed immediately by a Wx(H/2) CbCr plane. Each sample is
* represented by a 16-bit little-endian value, with the lower 6 bits set
* to zero.
*
* <p>This format assumes
* <ul>
* <li>an even height</li>
* <li>a vertical stride equal to the height</li>
* </ul>
* </p>
*
* <pre> stride_in_bytes = stride * 2 </pre>
* <pre> y_size = stride_in_bytes * height </pre>
* <pre> cbcr_size = stride_in_bytes * (height / 2) </pre>
* <pre> cb_offset = y_size </pre>
* <pre> cr_offset = cb_offset + 2 </pre>
*
* <p>For example, the {@link android.media.Image} object can provide data
* in this format from a {@link android.hardware.camera2.CameraDevice}
* through a {@link android.media.ImageReader} object if this format is
* supported by {@link android.hardware.camera2.CameraDevice}.</p>
*
* @see android.media.Image
* @see android.media.ImageReader
* @see android.hardware.camera2.CameraDevice
*
*/
public static final int YCBCR_P010 = 0x36;
/**
* YCbCr format, used for video.
*
@@ -807,6 +840,8 @@ public class ImageFormat {
case RAW_DEPTH:
case RAW_SENSOR:
return 16;
case YCBCR_P010:
return 20;
case RAW_DEPTH10:
case RAW10:
return 10;
@@ -839,6 +874,7 @@ public class ImageFormat {
case YUV_420_888:
case YUV_422_888:
case YUV_444_888:
case YCBCR_P010:
case FLEX_RGB_888:
case FLEX_RGBA_8888:
case RAW_SENSOR:

View File

@@ -45,6 +45,7 @@ class ImageUtils {
case ImageFormat.YV12:
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:
case ImageFormat.YCBCR_P010:
return 3;
case ImageFormat.NV16:
return 2;
@@ -225,6 +226,7 @@ class ImageUtils {
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
case ImageFormat.DEPTH16:
case ImageFormat.YCBCR_P010:
estimatedBytePerPixel = 2.0;
break;
case PixelFormat.RGB_888:
@@ -244,6 +246,7 @@ class ImageUtils {
private static Size getEffectivePlaneSizeForImage(Image image, int planeIdx) {
switch (image.getFormat()) {
case ImageFormat.YCBCR_P010:
case ImageFormat.YV12:
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:

View File

@@ -69,6 +69,7 @@ bool isPossiblyYUV(PixelFormat format) {
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCBCR_P010:
return false;
case HAL_PIXEL_FORMAT_YV12:
@@ -261,6 +262,32 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
pStride = 1;
rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16);
break;
case HAL_PIXEL_FORMAT_YCBCR_P010:
if (buffer->height % 2 != 0) {
ALOGE("YCBCR_P010: height (%d) should be a multiple of 2", buffer->height);
return BAD_VALUE;
}
if (buffer->width <= 0) {
ALOGE("YCBCR_P010: width (%d) should be a > 0", buffer->width);
return BAD_VALUE;
}
if (buffer->height <= 0) {
ALOGE("YCBCR_P010: height (%d) should be a > 0", buffer->height);
return BAD_VALUE;
}
ySize = (buffer->stride * 2) * buffer->height;
cSize = ySize / 2;
pStride = (idx == 0) ? 2 : 4;
cb = buffer->data + ySize;
cr = cb + 2;
pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
dataSize = (idx == 0) ? ySize : cSize;
rStride = buffer->stride * 2;
break;
case HAL_PIXEL_FORMAT_Y8:
// Single plane, 8bpp.
LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);