codec2: add input/output allocator ID parameter

C2PortAllocatorsTuning is the parameter of component to indicate the allocator
ID of input/output buffers for CCodec to create block pools. When CCodec
creates remote output block pool, CCodec should config
C2PortBlockPoolsTuning::output as obtained block pool ID to the component.

Bug: 79392858
Test: CtsMediaTestCases android.media.cts.MediaPlayerTest#testLocalVideo_MP4_H264_480x360_500kbps_30fps_AAC_Stereo_128kbps_44110Hz
Change-Id: I144e6151ecbe43dc309e8c960c3ca1f26b5f81dc
diff --git a/C2VDAComponent.cpp b/C2VDAComponent.cpp
index dc95a96..2b3abde 100644
--- a/C2VDAComponent.cpp
+++ b/C2VDAComponent.cpp
@@ -45,6 +45,9 @@
     return static_cast<int32_t>(frameIndex.peeku() & 0x3FFFFFFF);
 }
 
+// Use basic graphic block pool/allocator as default.
+const C2BlockPool::local_id_t kDefaultOutputBlockPool = C2BlockPool::BASIC_GRAPHIC;
+
 const C2String kH264DecoderName = "c2.vda.avc.decoder";
 const C2String kVP8DecoderName = "c2.vda.vp8.decoder";
 const C2String kVP9DecoderName = "c2.vda.vp9.decoder";
@@ -111,7 +114,7 @@
                                  MEDIA_MIMETYPE_VIDEO_RAW))
                          .build());
 
-    struct Setter {
+    struct LocalSetter {
         static C2R SizeSetter(bool mayBlock, C2P<C2StreamPictureSizeInfo::output>& videoSize) {
             (void)mayBlock;
             // TODO: maybe apply block limit?
@@ -127,8 +130,31 @@
                                  C2F(mSize, width).inRange(minSize.width(), maxSize.width(), 16),
                                  C2F(mSize, height).inRange(minSize.height(), maxSize.height(), 16),
                          })
-                         .withSetter(Setter::SizeSetter)
+                         .withSetter(LocalSetter::SizeSetter)
                          .build());
+
+    C2Allocator::id_t inputAllocators[] = {C2PlatformAllocatorStore::ION};
+    C2Allocator::id_t outputAllocators[] = {C2PlatformAllocatorStore::GRALLOC};
+
+    addParameter(
+            DefineParam(mInputAllocatorIds, C2_PARAMKEY_INPUT_ALLOCATORS)
+                    .withConstValue(C2PortAllocatorsTuning::input::AllocShared(inputAllocators))
+                    .build());
+
+    addParameter(
+            DefineParam(mOutputAllocatorIds, C2_PARAMKEY_OUTPUT_ALLOCATORS)
+                    .withConstValue(C2PortAllocatorsTuning::output::AllocShared(outputAllocators))
+                    .build());
+
+    C2BlockPool::local_id_t outputBlockPools[] = {kDefaultOutputBlockPool};
+
+    addParameter(
+            DefineParam(mOutputBlockPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS)
+                    .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputBlockPools))
+                    .withFields({C2F(mOutputBlockPoolIds, m.values[0]).any(),
+                                 C2F(mOutputBlockPoolIds, m.values).inRange(0, 1)})
+                    .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps)
+                    .build());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -645,9 +671,8 @@
     // Allocate the output buffers.
     mVDAAdaptor->assignPictureBuffers(bufferCount);
 
-    // TODO: this is temporary, client should config block pool ID as a parameter.
-    C2BlockPool::local_id_t poolId = C2BlockPool::BASIC_GRAPHIC;
-
+    // Get block pool ID configured from the client.
+    auto poolId = mIntfImpl->getBlockPoolId();
     ALOGI("Using C2BlockPool ID = %" PRIu64 " for allocating output buffers", poolId);
     c2_status_t err;
     if (!mOutputBlockPool || mOutputBlockPool->getLocalId() != poolId) {
diff --git a/include/C2VDAComponent.h b/include/C2VDAComponent.h
index 266d60e..13d0b33 100644
--- a/include/C2VDAComponent.h
+++ b/include/C2VDAComponent.h
@@ -45,6 +45,7 @@
         // interfaces for C2VDAComponent
         c2_status_t status() const { return mInitStatus; }
         media::VideoCodecProfile getCodecProfile() const { return mCodecProfile; }
+        C2BlockPool::local_id_t getBlockPoolId() const { return mOutputBlockPoolIds->m.values[0]; }
 
     private:
         // The input format kind; should be C2FormatCompressed.
@@ -57,6 +58,12 @@
         std::shared_ptr<C2PortMediaTypeSetting::output> mOutputMediaType;
         // Decoded video size for output.
         std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+        // The suggested usage of input buffer allocator ID.
+        std::shared_ptr<C2PortAllocatorsTuning::input> mInputAllocatorIds;
+        // The suggested usage of output buffer allocator ID.
+        std::shared_ptr<C2PortAllocatorsTuning::output> mOutputAllocatorIds;
+        // Compnent uses this ID to fetch corresponding output block pool from platform.
+        std::shared_ptr<C2PortBlockPoolsTuning::output> mOutputBlockPoolIds;
 
         c2_status_t mInitStatus;
         media::VideoCodecProfile mCodecProfile;
diff --git a/tests/C2VDACompIntf_test.cpp b/tests/C2VDACompIntf_test.cpp
index ed9db32..6ed0753 100644
--- a/tests/C2VDACompIntf_test.cpp
+++ b/tests/C2VDACompIntf_test.cpp
@@ -6,11 +6,13 @@
 #define LOG_TAG "C2VDACompIntf_test"
 
 #include <C2VDAComponent.h>
-#include <SimpleInterfaceCommon.h>
+
+#include <C2PlatformSupport.h>
 
 #include <gtest/gtest.h>
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <limits>
 
@@ -27,6 +29,10 @@
 const char* MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
 const char* MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
 
+const C2Allocator::id_t kInputAllocators[] = {C2PlatformAllocatorStore::ION};
+const C2Allocator::id_t kOutputAllocators[] = {C2PlatformAllocatorStore::GRALLOC};
+const C2BlockPool::local_id_t kDefaultOutputBlockPool = C2BlockPool::BASIC_GRAPHIC;
+
 class C2VDACompIntfTest : public ::testing::Test {
 protected:
     C2VDACompIntfTest() {
@@ -321,6 +327,50 @@
             widthMin, widthMax, widthStep, heightMin, heightMax, heightStep));
 }
 
+TEST_F(C2VDACompIntfTest, TestInputAllocatorIds) {
+    std::shared_ptr<C2PortAllocatorsTuning::input> expected(
+            C2PortAllocatorsTuning::input::AllocShared(kInputAllocators));
+    std::shared_ptr<C2PortAllocatorsTuning::input> invalid(
+            C2PortAllocatorsTuning::input::AllocShared(kOutputAllocators));
+    TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
+}
+
+TEST_F(C2VDACompIntfTest, TestOutputAllocatorIds) {
+    std::shared_ptr<C2PortAllocatorsTuning::output> expected(
+            C2PortAllocatorsTuning::output::AllocShared(kOutputAllocators));
+    std::shared_ptr<C2PortAllocatorsTuning::output> invalid(
+            C2PortAllocatorsTuning::output::AllocShared(kInputAllocators));
+    TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
+}
+
+TEST_F(C2VDACompIntfTest, TestOutputBlockPoolIds) {
+    std::vector<std::unique_ptr<C2Param>> heapParams;
+    C2Param::Index index = C2PortBlockPoolsTuning::output::PARAM_TYPE;
+
+    // Query the param and check the default value.
+    ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
+    ASSERT_EQ(1u, heapParams.size());
+    C2BlockPool::local_id_t value = ((C2PortBlockPoolsTuning*)heapParams[0].get())->m.values[0];
+    ASSERT_EQ(kDefaultOutputBlockPool, value);
+
+    // Configure the param.
+    C2BlockPool::local_id_t configBlockPools[] = {C2BlockPool::PLATFORM_START + 1};
+    std::shared_ptr<C2PortBlockPoolsTuning::output> newParam(
+            C2PortBlockPoolsTuning::output::AllocShared(configBlockPools));
+
+    std::vector<C2Param*> params{newParam.get()};
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    ASSERT_EQ(C2_OK, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
+    EXPECT_EQ(0u, failures.size());
+
+    // Query the param again and check the value is as configured
+    heapParams.clear();
+    ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
+    ASSERT_EQ(1u, heapParams.size());
+    value = ((C2PortBlockPoolsTuning*)heapParams[0].get())->m.values[0];
+    ASSERT_EQ(configBlockPools[0], value);
+}
+
 TEST_F(C2VDACompIntfTest, TestUnsupportedParam) {
     C2ComponentTemporalInfo unsupportedParam;
     std::vector<C2Param*> stackParams{&unsupportedParam};