Add preconditions for YUV formats.
Width and height need to be even and > 0 for the calculated dataSize to be valid. Test: test app crashes with a meaningful error message instead of an allocation failure. Bug: 163175419 Change-Id: Ibcce3e62f89b7d19d64e8a5efe792b35af6ab401
This commit is contained in:
@@ -140,6 +140,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
|
||||
fmt = applyFormatOverrides(fmt, containerFormat);
|
||||
switch (fmt) {
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_888:
|
||||
// Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
|
||||
if (buffer->width % 2 != 0) {
|
||||
ALOGE("YCbCr_420_888: width (%d) should be a multiple of 2", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height % 2 != 0) {
|
||||
ALOGE("YCbCr_420_888: height (%d) should be a multiple of 2", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->width <= 0) {
|
||||
ALOGE("YCbCr_420_888: width (%d) should be a > 0", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height <= 0) {
|
||||
ALOGE("YCbCr_420_888: height (%d) should be a > 0", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
pData =
|
||||
(idx == 0) ?
|
||||
buffer->data :
|
||||
@@ -160,6 +181,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
|
||||
break;
|
||||
// NV21
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
// Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
|
||||
if (buffer->width % 2 != 0) {
|
||||
ALOGE("YCrCb_420_SP: width (%d) should be a multiple of 2", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height % 2 != 0) {
|
||||
ALOGE("YCrCb_420_SP: height (%d) should be a multiple of 2", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->width <= 0) {
|
||||
ALOGE("YCrCb_420_SP: width (%d) should be a > 0", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height <= 0) {
|
||||
ALOGE("YCrCb_420_SP: height (%d) should be a > 0", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
cr = buffer->data + (buffer->stride * buffer->height);
|
||||
cb = cr + 1;
|
||||
// only map until last pixel
|
||||
@@ -178,6 +220,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
|
||||
rStride = buffer->width;
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
// Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
|
||||
if (buffer->width % 2 != 0) {
|
||||
ALOGE("YV12: width (%d) should be a multiple of 2", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height % 2 != 0) {
|
||||
ALOGE("YV12: height (%d) should be a multiple of 2", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->width <= 0) {
|
||||
ALOGE("YV12: width (%d) should be a > 0", buffer->width);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (buffer->height <= 0) {
|
||||
ALOGE("YV12: height (%d) should be a > 0", buffer->height);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
// Y and C stride need to be 16 pixel aligned.
|
||||
LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
|
||||
"Stride is not 16 pixel aligned %d", buffer->stride);
|
||||
@@ -344,6 +407,11 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
|
||||
int flexFormat = format;
|
||||
if (isPossiblyYUV(format)) {
|
||||
res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd);
|
||||
|
||||
if (res != OK) {
|
||||
ALOGW("lockAsyncYCbCr failed with error %d", res);
|
||||
}
|
||||
|
||||
pData = ycbcr.y;
|
||||
flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user