Add YV12 YUV format support to GrallocConsumer.
Bug: 26219828
Change-Id: I92532b08e54920efbf04278c5a52650833f8d5b1
diff --git a/rsGrallocConsumer.cpp b/rsGrallocConsumer.cpp
index 4d3c5dd..d00453d 100644
--- a/rsGrallocConsumer.cpp
+++ b/rsGrallocConsumer.cpp
@@ -162,16 +162,73 @@
//mAlloc->scalingMode = b.mScalingMode;
//mAlloc->frameNumber = b.mFrameNumber;
+ // For YUV Allocations, we need to populate the drvState with details of how
+ // the data is layed out.
+ // RenderScript requests a buffer in the YCbCr_420_888 format.
+ // The Camera HAL can return a buffer of YCbCr_420_888 or YV12, regardless
+ // of the requested format.
+ // mHal.state.yuv contains the requested format,
+ // mGraphicBuffer->getPixelFormat() is the returned format.
if (mAlloc[idx]->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
- mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
+ const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
+ const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
- mAlloc[idx]->mHal.drvState.lod[0].stride = ycbcr.ystride;
- mAlloc[idx]->mHal.drvState.lod[1].stride = ycbcr.cstride;
- mAlloc[idx]->mHal.drvState.lod[2].stride = ycbcr.cstride;
+ if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
+ HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ const int cWidth = yWidth / 2;
+ const int cHeight = yHeight / 2;
- mAlloc[idx]->mHal.drvState.yuv.shift = 1;
- mAlloc[idx]->mHal.drvState.yuv.step = ycbcr.chroma_step;
+ mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
+ mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
+
+ mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = ycbcr.y;
+ mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
+ mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
+
+ mAlloc[idx]->mHal.drvState.lod[0].stride = ycbcr.ystride;
+ mAlloc[idx]->mHal.drvState.lod[1].stride = ycbcr.cstride;
+ mAlloc[idx]->mHal.drvState.lod[2].stride = ycbcr.cstride;
+
+ mAlloc[idx]->mHal.drvState.yuv.shift = 1;
+ mAlloc[idx]->mHal.drvState.yuv.step = ycbcr.chroma_step;
+ mAlloc[idx]->mHal.drvState.lodCount = 3;
+ } else if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
+ HAL_PIXEL_FORMAT_YV12) {
+ // For YV12, the data layout is Y, followed by Cr, followed by Cb;
+ // for YCbCr_420_888, it's Y, followed by Cb, followed by Cr.
+ // RenderScript assumes lod[0] is Y, lod[1] is Cb, and lod[2] is Cr.
+ const int cWidth = yWidth / 2;
+ const int cHeight = yHeight / 2;
+
+ mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
+ mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
+
+ size_t yStride = rsRound(yWidth *
+ mAlloc[idx]->mHal.state.type->getElementSizeBytes(), 16);
+ size_t cStride = rsRound(yStride >> 1, 16);
+
+ uint8_t *yPtr = (uint8_t *)mAlloc[idx]->mHal.drvState.lod[0].mallocPtr;
+ uint8_t *crPtr = yPtr + yStride * yHeight;
+ uint8_t *cbPtr = crPtr + cStride * cHeight;
+
+ mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = cbPtr;
+ mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = crPtr;
+
+ mAlloc[idx]->mHal.drvState.lod[0].stride = yStride;
+ mAlloc[idx]->mHal.drvState.lod[1].stride = cStride;
+ mAlloc[idx]->mHal.drvState.lod[2].stride = cStride;
+
+ mAlloc[idx]->mHal.drvState.yuv.shift = 1;
+ mAlloc[idx]->mHal.drvState.yuv.step = 1;
+ mAlloc[idx]->mHal.drvState.lodCount = 3;
+ } else {
+ ALOGD("Unrecognized format: %d",
+ mSlots[buf].mGraphicBuffer->getPixelFormat());
+ }
}
return OK;