Codec2: pass block pools by ID

This highlighted a cfi bug so disabled cfi:

frameworks/av/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp:1237:15: runtime error:
control flow integrity check for type 'android::C2BlockPool' failed during virtual call
(vtable address 0x0078b2f659c0)
0x0078b2f659c0: note: invalid vtable in module /system/lib64/libstagefright_soft_c2avcdec.so
 00 00 00 00  98 a8 ef b2 78 00 00 00  f0 df f3 b2 78 00 00 00  00 e0 f3 b2 78 00 00 00  00 e0 f3 b2
              ^

Bug: 64121714
Test: unittest
Change-Id: I25d9c9d603e78c5043568cfb951d26aacea798a4
diff --git a/media/libstagefright/codec2/Android.bp b/media/libstagefright/codec2/Android.bp
index f79e058..311a20b 100644
--- a/media/libstagefright/codec2/Android.bp
+++ b/media/libstagefright/codec2/Android.bp
@@ -17,9 +17,9 @@
             "unsigned-integer-overflow",
             "signed-integer-overflow",
         ],
-        cfi: true,
+        cfi: false, // true,
         diag: {
-            cfi: true,
+            cfi: false, // true,
         },
     },
 
diff --git a/media/libstagefright/codec2/include/C2Config.h b/media/libstagefright/codec2/include/C2Config.h
index d4294c4..0568432 100644
--- a/media/libstagefright/codec2/include/C2Config.h
+++ b/media/libstagefright/codec2/include/C2Config.h
@@ -61,13 +61,15 @@
     kParamIndexMime,
     kParamIndexStreamCount,
     kParamIndexFormat,
+    kParamIndexBlockPools,
+
+    kParamIndexMaxVideoSizeHint,
+    kParamIndexVideoSizeTuning,
 
     // video info
 
     kParamIndexStructStart = 0x1,
     kParamIndexVideoSize,
-    kParamIndexMaxVideoSizeHint,
-    kParamIndexVideoSizeTuning,
 
     kParamIndexParamStart = 0x800,
 };
@@ -125,6 +127,8 @@
 
 typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexFormat> C2StreamFormatConfig;
 
+typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexBlockPools> C2PortBlockPoolsTuning;
+
 /*
    Component description fields:
 
diff --git a/media/libstagefright/codec2/vndk/C2Store.cpp b/media/libstagefright/codec2/vndk/C2Store.cpp
index 8413484..f8ddfef 100644
--- a/media/libstagefright/codec2/vndk/C2Store.cpp
+++ b/media/libstagefright/codec2/vndk/C2Store.cpp
@@ -16,6 +16,7 @@
 
 #include <C2AllocatorGralloc.h>
 #include <C2AllocatorIon.h>
+#include <C2BufferPriv.h>
 #include <C2Component.h>
 #include <C2PlatformSupport.h>
 
@@ -109,4 +110,35 @@
     return std::make_shared<C2PlatformAllocatorStore>();
 }
 
+C2Status GetCodec2BlockPool(
+        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool) {
+    pool->reset();
+    if (!component) {
+        return C2_BAD_VALUE;
+    }
+    // TODO support pre-registered block pools
+    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+    std::shared_ptr<C2Allocator> allocator;
+    C2Status res = C2_NOT_FOUND;
+
+    switch (id) {
+    case C2BlockPool::BASIC_LINEAR:
+        res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+        if (res == OK) {
+            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
+        }
+        break;
+    case C2BlockPool::BASIC_GRAPHIC:
+        res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
+        if (res == OK) {
+            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
+        }
+        break;
+    default:
+        break;
+    }
+    return res;
+}
+
 } // namespace android
\ No newline at end of file
diff --git a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
index 9402050..40bb548 100644
--- a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
@@ -25,9 +25,33 @@
 
 /**
  * Returns the platform allocator store.
+ * \retval nullptr if the platform allocator store could not be obtained
  */
 std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
 
+/**
+ * Retrieves a block pool for a component.
+ *
+ * \param id        the local ID of the block pool
+ * \param component the component using the block pool (must be non-null)
+ * \param pool      pointer to where the obtained block pool shall be stored on success. nullptr
+ *                  will be stored here on failure
+ *
+ * \retval C2_OK        the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the block pool does not exist
+ * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
+ *                      possible for basic pools)
+ * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
+ * \retval C2_REFUSED   no permission to complete any required allocation (this return value is only
+ *                      possible for basic pools)
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
+ *                      this return value is only possible for basic pools)
+ */
+C2Status GetCodec2BlockPool(
+        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool);
+
 } // namespace android
 
 #endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 3b2602d..5dcffd5 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -74,9 +74,9 @@
         misc_undefined: [
             "signed-integer-overflow",
         ],
-        cfi: true,
+        cfi: false, // true,
         diag: {
-            cfi: true,
+            cfi: false, // true,
         },
     },
 
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
index 7864f07..12eaff5 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
@@ -27,6 +27,8 @@
 #include "ih264d.h"
 #include "C2SoftAvcDec.h"
 
+#include <C2PlatformSupport.h>
+
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 #include <utils/misc.h>
@@ -275,6 +277,8 @@
     mMaxVideoSizeHint.mWidth = H264_MAX_FRAME_WIDTH;
     mMaxVideoSizeHint.mHeight = H264_MAX_FRAME_HEIGHT;
 
+    mOutputBlockPools = C2PortBlockPoolsTuning::output::alloc_unique({});
+
     auto insertParam = [&params = mParams] (C2Param *param) {
         params[restoreIndex(param)] = param;
     };
@@ -422,6 +426,8 @@
             false, "_video_size", &mVideoSize));
     mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
             false, "_max_video_size_hint", &mMaxVideoSizeHint));
+    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
+            false, "_output_block_pools", mOutputBlockPools.get()));
 }
 
 C2String C2SoftAvcDecIntf::getName() const {
@@ -443,6 +449,8 @@
 
         uint32_t index = restoreIndex(param);
         if (!mParams.count(index)) {
+            // TODO: add support for output-block-pools (this will be done when we move all
+            // config to shared ptr)
             continue;
         }
 
@@ -471,6 +479,13 @@
     C2Status err = C2_OK;
     for (C2Param *param : params) {
         uint32_t index = restoreIndex(param);
+        if (param->index() == mOutputBlockPools.get()->index()) {
+            // setting output block pools
+            mOutputBlockPools.reset(
+                    (C2PortBlockPoolsTuning::output *)C2Param::Copy(*param).release());
+            continue;
+        }
+
         if (mParams.count(index) == 0) {
             // We can't create C2SettingResult with no field, so just skipping in this case.
             err = C2_BAD_INDEX;
@@ -1211,7 +1226,19 @@
         // TODO: format & usage
         uint32_t format = HAL_PIXEL_FORMAT_YV12;
         C2MemoryUsage usage = { C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite };
-        (void) work->worklets.front()->allocators[0]->fetchGraphicBlock(
+        // TODO: lock access to interface
+        C2BlockPool::local_id_t poolId =
+            mIntf->mOutputBlockPools->flexCount() ?
+                    mIntf->mOutputBlockPools->m.mValues[0] : C2BlockPool::BASIC_GRAPHIC;
+        if (!mOutputBlockPool || mOutputBlockPool->getLocalId() != poolId) {
+            C2Status err = GetCodec2BlockPool(poolId, shared_from_this(), &mOutputBlockPool);
+            if (err != C2_OK) {
+                // TODO: trip
+            }
+        }
+        ALOGE("using allocator %u", mOutputBlockPool->getAllocatorId());
+
+        (void)mOutputBlockPool->fetchGraphicBlock(
                 mWidth, mHeight, format, usage, &mAllocatedBlock);
         ALOGE("provided (%dx%d) required (%dx%d)", mAllocatedBlock->width(), mAllocatedBlock->height(), mWidth, mHeight);
     }
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
index cc33083..41ccf39 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
@@ -118,6 +118,7 @@
     // TODO: C2StreamMimeConfig mInputStreamMime;
     // TODO: C2StreamMimeConfig mOutputStreamMime;
     C2StreamFormatConfig::input mInputStreamFormat;
+    std::unique_ptr<C2PortBlockPoolsTuning::output> mOutputBlockPools;
     C2StreamFormatConfig::output mOutputStreamFormat;
     C2VideoSizeStreamInfo::output mVideoSize;
     C2MaxVideoSizeHintPortSetting::input mMaxVideoSizeHint;
@@ -138,6 +139,7 @@
     std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
 
     void updateSupportedValues();
+    friend class C2SoftAvcDec;
 };
 
 class C2SoftAvcDec
@@ -191,6 +193,7 @@
 
     const std::shared_ptr<C2SoftAvcDecIntf> mIntf;
     const std::shared_ptr<C2ComponentListener> mListener;
+    std::shared_ptr<C2BlockPool> mOutputBlockPool;
 
     std::mutex mQueueLock;
     std::condition_variable mQueueCond;
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
index 51e1420..c7e1c82 100644
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ b/media/libstagefright/codecs/cmds/codec2.cpp
@@ -95,9 +95,7 @@
     sp<IProducerListener> mProducerListener;
 
     std::shared_ptr<C2Allocator> mAllocIon;
-    std::shared_ptr<C2Allocator> mAllocGralloc;
     std::shared_ptr<C2BlockPool> mLinearPool;
-    std::shared_ptr<C2BlockPool> mGraphicPool;
 
     std::mutex mQueueLock;
     std::condition_variable mQueueCondition;
@@ -145,10 +143,7 @@
 
     std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
     CHECK_EQ(store->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
-    CHECK_EQ(store->getAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mAllocGralloc), C2_OK);
-
     mLinearPool = std::make_shared<C2BasicLinearBlockPool>(mAllocIon);
-    mGraphicPool = std::make_shared<C2BasicGraphicBlockPool>(mAllocGralloc);
 
     mControl = mComposerClient->createSurface(
             String8("A Surface"),
@@ -214,6 +209,10 @@
     }
 
     std::shared_ptr<C2Component> component(std::make_shared<C2SoftAvcDec>("avc", 0, mListener));
+    std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
+        C2PortBlockPoolsTuning::output::alloc_unique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
+    std::vector<std::unique_ptr<C2SettingResult>> result;
+    (void)component->intf()->config_nb({pools.get()}, &result);
     component->start();
 
     for (int i = 0; i < 8; ++i) {
@@ -343,7 +342,6 @@
         work->input.buffers.emplace_back(new LinearBuffer(block));
         work->worklets.clear();
         work->worklets.emplace_back(new C2Worklet);
-        work->worklets.front()->allocators.emplace_back(mGraphicPool);
 
         std::list<std::unique_ptr<C2Work>> items;
         items.push_back(std::move(work));