Snap for 12203851 from e278e7965d785080ae212d5ce26a44f74f25f31a to ks-qcom-24Q3-release

Change-Id: I068e9f87394f1c3cd9b3ed38e8c297dd15ec2a1e
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
index d77cba0..ef36b3d 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
@@ -723,7 +723,7 @@
         mOutBlock.reset();
     }
     if (!mOutBlock) {
-        const uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
+        const uint32_t format = HAL_PIXEL_FORMAT_YV12;
         const C2MemoryUsage usage = {(uint64_t)(BufferUsage::VIDEO_DECODER),
                                      C2MemoryUsage::CPU_WRITE | C2MemoryUsage::CPU_READ};
         c2_status_t err = pool->fetchGraphicBlock(ALIGN2(mWidth), mHeight,
diff --git a/system/codecs/c2/decoders/base/color_buffer_utils.cpp b/system/codecs/c2/decoders/base/color_buffer_utils.cpp
index 99563f4..94f9088 100644
--- a/system/codecs/c2/decoders/base/color_buffer_utils.cpp
+++ b/system/codecs/c2/decoders/base/color_buffer_utils.cpp
@@ -66,6 +66,24 @@
         }
     }
 
+    uint64_t getClientUsage(const std::shared_ptr<C2BlockPool> &pool) {
+        std::shared_ptr<C2GraphicBlock> myOutBlock;
+        const C2MemoryUsage usage = {0, 0};
+        const uint32_t format = HAL_PIXEL_FORMAT_YV12;
+        pool->fetchGraphicBlock(2, 2, format, usage, &myOutBlock);
+        auto myc2Handle = myOutBlock->handle();
+        native_handle_t *mygrallocHandle =
+        android::UnwrapNativeCodec2GrallocHandle(myc2Handle);
+        if (m_isMinigbm) {
+            cros_gralloc_handle const* cros_handle =
+                reinterpret_cast<cros_gralloc_handle const*>(mygrallocHandle);
+            return cros_handle->usage;
+        } else {
+            cb_handle_30_t* mycb = (cb_handle_30_t*)(mygrallocHandle);
+            return mycb->usage;
+        }
+    }
+
 private:
 
     bool getResInfo(native_handle_t const* handle,
@@ -119,15 +137,6 @@
 }
 
 uint64_t getClientUsage(const std::shared_ptr<C2BlockPool> &pool) {
-      std::shared_ptr<C2GraphicBlock> myOutBlock;
-      const C2MemoryUsage usage = {0, 0};
-      const uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
-      pool->fetchGraphicBlock(2, 2, format, usage, &myOutBlock);
-      auto myc2Handle = myOutBlock->handle();
-      native_handle_t *mygrallocHandle =
-      android::UnwrapNativeCodec2GrallocHandle(myc2Handle);
-      cb_handle_30_t* mycb = (cb_handle_30_t*)(mygrallocHandle);
-      ALOGV("%s %s %d: client usage 0x%x", __FILE__, __func__, __LINE__, mycb->usage);
-      return mycb->usage;
+    return getGlobals()->getClientUsage(pool);
 }
 
diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
index 81c07a8..922b837 100644
--- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
+++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
@@ -669,7 +669,7 @@
         mOutBlock.reset();
     }
     if (!mOutBlock) {
-        const uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
+        const uint32_t format = HAL_PIXEL_FORMAT_YV12;
         const C2MemoryUsage usage = {(uint64_t)(BufferUsage::VIDEO_DECODER),
                                      C2MemoryUsage::CPU_WRITE | C2MemoryUsage::CPU_READ};
         c2_status_t err = pool->fetchGraphicBlock(ALIGN2(mWidth), mHeight,
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
index 3809c9d..37c4a51 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
@@ -371,8 +371,12 @@
         if (me.v.matrix > C2Color::MATRIX_OTHER) {
             me.set().matrix = C2Color::MATRIX_OTHER;
         }
-        DDD("coded primaries %d coded range %d", me.set().primaries,
-            me.set().range);
+        DDD("%s %d coded color aspect range %d primaries/color %d transfer %d",
+                __func__, __LINE__,
+                (int)(me.v.range),
+                (int)(me.v.primaries),
+                (int)(me.v.transfer)
+                );
         return C2R::Ok();
     }
 
@@ -381,13 +385,31 @@
                        const C2P<C2StreamColorAspectsTuning::output> &def,
                        const C2P<C2StreamColorAspectsInfo::input> &coded) {
         (void)mayBlock;
-        (void)coded;
-        // just take default values, because vpx does not have those information
-        // in the frame.
-        me.set().range = def.v.range;
-        me.set().primaries = def.v.primaries;
-        me.set().transfer = def.v.transfer;
-        me.set().matrix = def.v.matrix;
+        // take default values for all unspecified fields, and coded values for
+        // specified ones
+        DDD("%s %d before update: color aspect range %d primaries/color %d transfer %d",
+                __func__, __LINE__,
+                (int)(me.v.range),
+                (int)(me.v.primaries),
+                (int)(me.v.transfer)
+                );
+        me.set().range =
+            coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+        me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
+                                 ? def.v.primaries
+                                 : coded.v.primaries;
+        me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
+                                ? def.v.transfer
+                                : coded.v.transfer;
+        me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix
+                                                               : coded.v.matrix;
+
+        DDD("%s %d after update: color aspect range %d primaries/color %d transfer %d",
+                __func__, __LINE__,
+                (int)(me.v.range),
+                (int)(me.v.primaries),
+                (int)(me.v.transfer)
+                );
         return C2R::Ok();
     }
 
@@ -566,10 +588,6 @@
     mMode = MODE_VP8;
 #endif
 
-    {
-        IntfImpl::Lock lock = mIntf->lock();
-        mColorAspects = mIntf->getDefaultColorAspects_l();
-    }
     mWidth = 320;
     mHeight = 240;
     mFrameParallelMode = false;
@@ -647,7 +665,21 @@
         createGraphicBuffer(block, C2Rect(mWidth, mHeight));
     {
         IntfImpl::Lock lock = mIntf->lock();
+#ifdef VP9
         buffer->setInfo(mIntf->getColorAspects_l());
+#else
+        std::shared_ptr<C2StreamColorAspectsInfo::output> tColorAspects =
+            std::make_shared<C2StreamColorAspectsInfo::output>
+            (C2StreamColorAspectsInfo::output(0u, m_range,
+                m_primaries, m_transfer,
+                m_matrix));
+        DDD("%s %d setting to index %d range %d primaries %d transfer %d",
+                __func__, __LINE__, (int)index,
+                (int)tColorAspects->range,
+                (int)tColorAspects->primaries,
+                (int)tColorAspects->transfer);
+        buffer->setInfo(tColorAspects);
+#endif
     }
 
     auto fillWork = [buffer, index,
@@ -731,18 +763,54 @@
         (int)work->input.ordinal.timestamp.peeku(),
         (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
 
-    // Software VP9 Decoder does not need the Codec Specific Data (CSD)
-    // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
-    // it was passed.
+    if (mMode == MODE_VP8) {
+        constexpr uint64_t ONE_SECOND_IN_MICRO_SECOND = 1000 * 1000;
+        // bug: 349159609
+        // note, vp8 does not have the FLAG_CODEC_CONFIG and the test
+        // android.mediav2.cts.DecoderDynamicColorAspectTest test still
+        // expects vp8 to pass. so this hack is to check the time stamp
+        // change to update the color aspect: too early or too late is
+        // a problem as it can cause mismatch of frame and coloraspect
+        DDD("%s %d vp8 last pts is %d current pts is %d",
+                __func__, __LINE__, mLastPts, (int) work->input.ordinal.timestamp.peeku());
+        if (mLastPts + ONE_SECOND_IN_MICRO_SECOND <= work->input.ordinal.timestamp.peeku()) {
+            codecConfig = true;
+            DDD("%s %d updated codecConfig to true", __func__, __LINE__);
+        } else {
+            DDD("%s %d keep codecConfig to false", __func__, __LINE__);
+        }
+        mLastPts = work->input.ordinal.timestamp.peeku();
+        if (mLastPts == 0) {
+            codecConfig = true;
+        }
+        if (codecConfig) {
+            IntfImpl::Lock lock = mIntf->lock();
+            std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects =
+            mIntf->getDefaultColorAspects_l();
+            m_primaries = defaultColorAspects->primaries;
+            m_range = defaultColorAspects->range;
+            m_transfer = defaultColorAspects->transfer;
+            m_matrix = defaultColorAspects->matrix;
+        }
+    }
+
     if (codecConfig) {
-        // Ignore CSD buffer for VP9.
+        {
+            IntfImpl::Lock lock = mIntf->lock();
+            std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects =
+                mIntf->getDefaultColorAspects_l();
+            lock.unlock();
+            C2StreamColorAspectsInfo::input codedAspects(0u, defaultColorAspects->range,
+                defaultColorAspects->primaries, defaultColorAspects->transfer,
+                defaultColorAspects->matrix);
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+        }
+
+        DDD("%s %d updated coloraspect due to codec config", __func__, __LINE__);
         if (mMode == MODE_VP9) {
             fillEmptyWork(work);
             return;
-        } else {
-            // Tolerate the CSD buffer for VP8. This is a workaround
-            // for b/28689536. continue
-            ALOGW("WARNING: Got CSD buffer for VP8. Continue");
         }
     }
 
@@ -784,30 +852,24 @@
     }
 }
 
-static void copyOutputBufferToYuvPlanarFrame(
-    uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
-    size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride,
-    size_t dstUVStride, uint32_t width, uint32_t height) {
-    uint8_t *dstStart = dst;
+static void copyOutputBufferToYuvPlanarFrame(C2GraphicView& writeView, const uint8_t* srcY,
+        const uint8_t* srcU, const uint8_t* srcV, uint32_t width, uint32_t height) {
 
-    for (size_t i = 0; i < height; ++i) {
-        memcpy(dst, srcY, width);
-        srcY += srcYStride;
-        dst += dstYStride;
+    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 < height; ++i) {
+        memcpy(pYBuffer + i * dstYStride, srcY + i * width, width);
     }
-
-    dst = dstStart + dstYStride * height;
-    for (size_t i = 0; i < height / 2; ++i) {
-        memcpy(dst, srcV, width / 2);
-        srcV += srcVStride;
-        dst += dstUVStride;
+    for (int i = 0; i < height / 2; ++i) {
+        memcpy(pUBuffer + i * dstUVStride, srcU + i * width / 2, width / 2);
     }
-
-    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
-    for (size_t i = 0; i < height / 2; ++i) {
-        memcpy(dst, srcU, width / 2);
-        srcU += srcUStride;
-        dst += dstUVStride;
+    for (int i = 0; i < height / 2; ++i) {
+        memcpy(pVBuffer + i * dstUVStride, srcV + i * width / 2, width / 2);
     }
 }
 
@@ -830,7 +892,7 @@
 
     // now get the block
     std::shared_ptr<C2GraphicBlock> block;
-    uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
+    uint32_t format = HAL_PIXEL_FORMAT_YV12;
     const C2MemoryUsage usage = {(uint64_t)(BufferUsage::VIDEO_DECODER),
                                  C2MemoryUsage::CPU_WRITE | C2MemoryUsage::CPU_READ};
 
@@ -944,13 +1006,12 @@
         if (img->fmt == VPX_IMG_FMT_I42016) {
             ALOGW("WARNING: not I42016 is not supported !!!");
         } else if (1) {
+            // the decoded frame is YUV420 from host
             const uint8_t *srcY = (const uint8_t *)mCtx->dst;
-            const uint8_t *srcV = srcY + mWidth * mHeight;
-            const uint8_t *srcU = srcV + mWidth * mHeight / 4;
+            const uint8_t *srcU = srcY + mWidth * mHeight;
+            const uint8_t *srcV = srcU + mWidth * mHeight / 4;
             // TODO: the following crashes
-            copyOutputBufferToYuvPlanarFrame(dst, srcY, srcU, srcV, srcYStride,
-                                             srcUStride, srcVStride, dstYStride,
-                                             dstUVStride, mWidth, mHeight);
+            copyOutputBufferToYuvPlanarFrame(wView, srcY, srcU, srcV, mWidth, mHeight);
             // memcpy(dst, srcY, mWidth * mHeight / 2);
         }
     }
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
index d08894e..ceb46bd 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
@@ -81,6 +81,14 @@
     bool mSignalledOutputEos;
     bool mSignalledError;
 
+    // this is VP8 only
+    uint64_t mLastPts { 0 };
+
+    C2Color::range_t m_range;
+    C2Color::primaries_t m_primaries;
+    C2Color::transfer_t m_transfer;
+    C2Color::matrix_t m_matrix;
+
     struct ConversionQueue {
         std::list<std::function<void()>> entries;
         Condition cond;