c2-codecs: handle stride correctly

Original change:
https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/1713931

The decoded data should be properly copied to the
client side, respecting the stride.

Bug: 188774534

Test:
atest android.mediav2.cts.CodecDecoderTest#testSimpleDecode
atest android.mediav2.cts.CodecDecoderTest#testReconfigure

Change-Id: I5a1dcc1cc085d2b04a8f4a57092fc0a0c9d2671c
Merged-In: I5a1dcc1cc085d2b04a8f4a57092fc0a0c9d2671c
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
index aaf5f87..7f95535 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
@@ -657,14 +657,6 @@
                 UnwrapNativeCodec2GrallocHandle(c2Handle);
             mHostColorBufferId = getColorBufferHandle(grallocHandle);
             DDD("found handle %d", mHostColorBufferId);
-        } else {
-            C2GraphicView wView = mOutBlock->map().get();
-            if (wView.error()) {
-                ALOGE("graphic view map failed %d", wView.error());
-                return C2_CORRUPTED;
-            }
-            mByteBuffer =
-                const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
         }
         DDD("provided (%dx%d) required (%dx%d)", mOutBlock->width(),
             mOutBlock->height(), ALIGN16(mWidth), mHeight);
@@ -737,22 +729,32 @@
     }
 }
 
-void C2GoldfishAvcDec::copyImageData(uint8_t *pBuffer, h264_image_t &img) {
+void C2GoldfishAvcDec::copyImageData(h264_image_t &img) {
     getVuiParams(img);
     if (mEnableAndroidNativeBuffers)
         return;
-    int myStride = mWidth;
-    for (int i = 0; i < mHeight; ++i) {
-        memcpy(pBuffer + i * myStride, img.data + i * mWidth, mWidth);
+
+    auto writeView = mOutBlock->map().get();
+    if (writeView.error()) {
+        ALOGE("graphic view map failed %d", writeView.error());
+        return;
     }
-    int Y = myStride * mHeight;
+    size_t dstYStride = writeView.layout().planes[C2PlanarLayout::PLANE_Y].rowInc;
+    size_t dstUVStride = writeView.layout().planes[C2PlanarLayout::PLANE_U].rowInc;
+
+    uint8_t *pYBuffer = const_cast<uint8_t *>(writeView.data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t *pUBuffer = const_cast<uint8_t *>(writeView.data()[C2PlanarLayout::PLANE_U]);
+    uint8_t *pVBuffer = const_cast<uint8_t *>(writeView.data()[C2PlanarLayout::PLANE_V]);
+
+    for (int i = 0; i < mHeight; ++i) {
+        memcpy(pYBuffer + i * dstYStride, img.data + i * mWidth, mWidth);
+    }
     for (int i = 0; i < mHeight / 2; ++i) {
-        memcpy(pBuffer + Y + i * myStride / 2,
+        memcpy(pUBuffer + i * dstUVStride,
                img.data + mWidth * mHeight + i * mWidth / 2, mWidth / 2);
     }
-    int UV = Y / 4;
     for (int i = 0; i < mHeight / 2; ++i) {
-        memcpy(pBuffer + Y + UV + i * myStride / 2,
+        memcpy(pVBuffer + i * dstUVStride,
                img.data + mWidth * mHeight * 5 / 4 + i * mWidth / 2,
                mWidth / 2);
     }
@@ -918,7 +920,7 @@
 
             DDD("got data %" PRIu64 " with pts %" PRIu64,  mPts2Index[mImg.pts], mImg.pts);
             mHeaderDecoded = true;
-            copyImageData(mByteBuffer, mImg);
+            copyImageData(mImg);
             finishWork(mPts2Index[mImg.pts], work);
             removePts(mImg.pts);
         } else {
@@ -985,7 +987,7 @@
         //        mImg = mContext->getImage();
         if (mImg.data != nullptr) {
             DDD("got data in drain mode %" PRIu64 " with pts %" PRIu64,  mPts2Index[mImg.pts], mImg.pts);
-            copyImageData(mByteBuffer, mImg);
+            copyImageData(mImg);
             finishWork(mPts2Index[mImg.pts], work);
             removePts(mImg.pts);
         } else {
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
index c726418..d906d02 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
@@ -99,9 +99,8 @@
     int mHostColorBufferId{-1};
 
     void getVuiParams(h264_image_t &img);
-    void copyImageData(uint8_t *pBuffer, h264_image_t &img);
+    void copyImageData(h264_image_t &img);
 
-    uint8_t *mByteBuffer{nullptr};
     h264_image_t mImg{};
     uint32_t mConsumedBytes{0};
     uint8_t *mInPBuffer{nullptr};