diff --git a/media/codec2/hal/aidl/Android.bp b/media/codec2/hal/aidl/Android.bp
new file mode 100644
index 0000000..01cd354
--- /dev/null
+++ b/media/codec2/hal/aidl/Android.bp
@@ -0,0 +1,149 @@
+package {
+    default_applicable_licenses: ["frameworks_av_license"],
+}
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-aidl-client-defaults instead
+cc_library {
+    name: "libcodec2_aidl_client",
+
+    srcs: [
+        "ParamTypes.cpp",
+    ],
+
+    header_libs: [
+        "libcodec2_hal_common",
+        "libcodec2_internal", // private
+        "libgui_headers",
+    ],
+
+    shared_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.media.c2-V1-ndk",
+        "libbinder_ndk",
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libnativewindow",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "android.hardware.media.c2-V1-ndk",
+        "libcodec2",
+    ],
+}
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-defaults instead
+//cc_library {
+//    name: "libcodec2_hidl@1.0",
+//    vendor_available: true,
+//    min_sdk_version: "29",
+//    apex_available: [
+//        "//apex_available:platform",
+//        "com.android.media.swcodec",
+//    ],
+//
+//    defaults: ["hidl_defaults"],
+//
+//    srcs: [
+//        "Component.cpp",
+//        "ComponentInterface.cpp",
+//        "ComponentStore.cpp",
+//        "Configurable.cpp",
+//        "InputBufferManager.cpp",
+//        "InputSurface.cpp",
+//        "InputSurfaceConnection.cpp",
+//        "types.cpp",
+//    ],
+//
+//    header_libs: [
+//        "libbinder_headers",
+//        "libcodec2_hal_common",
+//        "libcodec2_internal", // private
+//        "libsystem_headers",
+//    ],
+//
+//    shared_libs: [
+//        "android.hardware.graphics.bufferqueue@1.0",
+//        "android.hardware.graphics.bufferqueue@2.0",
+//        "android.hardware.graphics.common@1.0",
+//        "android.hardware.media@1.0",
+//        "android.hardware.media.bufferpool@2.0",
+//        "android.hardware.media.c2@1.0",
+//        "android.hardware.media.omx@1.0",
+//        "libbase",
+//        "libcodec2",
+//        "libcodec2_vndk",
+//        "libcodec2_hidl_plugin_stub",
+//        "libcutils",
+//        "libhidlbase",
+//        "liblog",
+//        "libstagefright_bufferpool@2.0.1",
+//        "libstagefright_bufferqueue_helper_novndk",
+//        "libui",
+//        "libutils",
+//    ],
+//
+//    target: {
+//        vendor: {
+//            exclude_shared_libs: [
+//                "libstagefright_bufferqueue_helper_novndk",
+//                "libcodec2_hidl_plugin_stub",
+//            ],
+//            shared_libs: [
+//                "libstagefright_bufferqueue_helper",
+//                "libcodec2_hidl_plugin",
+//            ],
+//        },
+//        apex: {
+//            exclude_shared_libs: [
+//                "libcodec2_hidl_plugin",
+//                "libcodec2_hidl_plugin_stub",
+//            ],
+//        },
+//    },
+//
+//    export_include_dirs: [
+//        "include",
+//    ],
+//
+//    export_shared_lib_headers: [
+//        "android.hardware.media.c2@1.0",
+//        "libcodec2",
+//        "libcodec2_vndk",
+//        "libhidlbase",
+//        "libstagefright_bufferpool@2.0.1",
+//        "libui",
+//    ],
+//}
+//
+//// public dependency for Codec 2.0 HAL service implementations
+//cc_defaults {
+//    name: "libcodec2-hidl-defaults@1.0",
+//    defaults: ["libcodec2-impl-defaults"],
+//
+//    shared_libs: [
+//        "android.hardware.media.c2@1.0",
+//        "libcodec2_hidl@1.0",
+//    ],
+//}
+
+// public dependency for Codec 2.0 HAL client
+cc_defaults {
+    name: "libcodec2-aidl-client-defaults",
+    min_sdk_version: "34",
+    defaults: ["libcodec2-impl-defaults"],
+
+    shared_libs: [
+        "android.hardware.media.c2-V1-ndk",
+        "libcodec2_aidl_client",
+    ],
+}
diff --git a/media/codec2/hal/aidl/ParamTypes-specialization.h b/media/codec2/hal/aidl/ParamTypes-specialization.h
new file mode 100644
index 0000000..e409b34
--- /dev/null
+++ b/media/codec2/hal/aidl/ParamTypes-specialization.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
+#define CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
+
+#include <aidl/android/hardware/media/c2/FieldId.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValues.h>
+#include <aidl/android/hardware/media/c2/Params.h>
+#include <aidl/android/hardware/media/c2/Status.h>
+#include <codec2/common/ParamTypes.h>
+
+namespace android {
+
+using ::aidl::android::hardware::media::c2::FieldId;
+using ::aidl::android::hardware::media::c2::FieldSupportedValues;
+using ::aidl::android::hardware::media::c2::Params;
+using ::aidl::android::hardware::media::c2::Status;
+
+// {offset, size} -> FieldId
+template<>
+void SetFieldId(FieldId *d, uint32_t offset, uint32_t size);
+
+// FieldId -> offset
+template<>
+uint32_t GetOffsetFromFieldId(const FieldId &s);
+
+// FieldId -> size
+template<>
+uint32_t GetSizeFromFieldId(const FieldId &s);
+
+template<>
+void SetStatus(Status *dst, c2_status_t src);
+
+template<>
+c2_status_t GetStatus(const Status &status);
+
+// C2FieldSupportedValues -> FieldSupportedValues
+template<>
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s);
+
+// FieldSupportedValues -> C2FieldSupportedValues
+template<>
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s);
+
+template<>
+struct _ParamsBlobHelper<Params> { typedef std::vector<uint8_t> BlobType; };
+
+template<>
+const std::vector<uint8_t> &GetBlob<Params>(const Params &params);
+
+template<>
+std::vector<uint8_t> *GetBlob<Params>(Params *params);
+
+} // namespace android
+
+
+
+#endif  // CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
diff --git a/media/codec2/hal/aidl/ParamTypes.cpp b/media/codec2/hal/aidl/ParamTypes.cpp
index 319ba62..0a430f9 100644
--- a/media/codec2/hal/aidl/ParamTypes.cpp
+++ b/media/codec2/hal/aidl/ParamTypes.cpp
@@ -15,145 +15,84 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "Codec2-types"
+#define LOG_TAG "Codec2-AIDL-ParamTypes"
 #include <android-base/logging.h>
 
-#include <codec2/hidl/1.0/types.h>
-#include <media/stagefright/foundation/AUtils.h>
+#include <codec2/aidl/ParamTypes.h>
+#include <codec2/common/ParamTypes.h>
 
-#include <C2AllocatorIon.h>
-#include <C2AllocatorGralloc.h>
-#include <C2BlockInternal.h>
-#include <C2Buffer.h>
-#include <C2Component.h>
-#include <C2FenceFactory.h>
-#include <C2Param.h>
-#include <C2ParamInternal.h>
-#include <C2PlatformSupport.h>
-#include <C2Work.h>
-#include <util/C2ParamUtils.h>
-
-#include <algorithm>
-#include <functional>
-#include <iomanip>
-#include <unordered_map>
+#include "ParamTypes-specialization.h"
 
 namespace android {
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace utils {
 
-using ::android::hardware::Return;
-using ::android::hardware::media::bufferpool::BufferPoolData;
-using ::android::hardware::media::bufferpool::V2_0::BufferStatusMessage;
-using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
-using ::android::hardware::media::bufferpool::V2_0::implementation::
-        ClientManager;
-using ::android::hardware::media::bufferpool::V2_0::implementation::
-        TransactionId;
+using ::aidl::android::hardware::media::c2::FieldId;
+using ::aidl::android::hardware::media::c2::FieldSupportedValues;
+using ::aidl::android::hardware::media::c2::Params;
+using ::aidl::android::hardware::media::c2::Status;
+using ::aidl::android::hardware::media::c2::ValueRange;
 
-const char* asString(Status status, const char* def) {
-    return asString(static_cast<c2_status_t>(status), def);
+// {offset, size} -> FieldId
+template<>
+void SetFieldId(FieldId *d, uint32_t offset, uint32_t size) {
+    d->offset = offset;
+    d->sizeBytes = size;
 }
 
-namespace /* unnamed */ {
-
-template <typename EnumClass>
-typename std::underlying_type<EnumClass>::type underlying_value(
-        EnumClass x) {
-    return static_cast<typename std::underlying_type<EnumClass>::type>(x);
+// FieldId -> offset
+template<>
+uint32_t GetOffsetFromFieldId(const FieldId &s) {
+    return s.offset;
 }
 
-template <typename Common, typename DstVector, typename SrcVector>
-void copyVector(DstVector* d, const SrcVector& s) {
-    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
-            "DstVector's component size does not match Common");
-    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
-            "SrcVector's component size does not match Common");
-    d->resize(s.size());
-    std::copy(
-            reinterpret_cast<const Common*>(&s[0]),
-            reinterpret_cast<const Common*>(&s[0] + s.size()),
-            reinterpret_cast<Common*>(&(*d)[0]));
+// FieldId -> size
+template<>
+uint32_t GetSizeFromFieldId(const FieldId &s) {
+    return s.sizeBytes;
 }
 
-// C2ParamField -> ParamField
-bool objcpy(ParamField *d, const C2ParamField &s) {
-    d->index = static_cast<ParamIndex>(_C2ParamInspector::GetIndex(s));
-    d->fieldId.offset = static_cast<uint32_t>(_C2ParamInspector::GetOffset(s));
-    d->fieldId.size = static_cast<uint32_t>(_C2ParamInspector::GetSize(s));
-    return true;
+template<>
+void SetStatus(Status *dst, c2_status_t src) {
+    dst->status = src;
 }
 
-struct C2ParamFieldBuilder : public C2ParamField {
-    C2ParamFieldBuilder() : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
-    }
-    // ParamField -> C2ParamField
-    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
-            static_cast<uint32_t>(s.fieldId.offset),
-            static_cast<uint32_t>(s.fieldId.size)) {
-    }
-};
-
-// C2WorkOrdinalStruct -> WorkOrdinal
-bool objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
-    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
-    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
-    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
-    return true;
+template<>
+c2_status_t GetStatus(const Status &status) {
+    return static_cast<c2_status_t>(status.status);
 }
 
-// WorkOrdinal -> C2WorkOrdinalStruct
-bool objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
-    d->frameIndex = c2_cntr64_t(s.frameIndex);
-    d->timestamp = c2_cntr64_t(s.timestampUs);
-    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
-    return true;
-}
-
-// C2FieldSupportedValues::range's type -> ValueRange
-bool objcpy(
-        ValueRange* d,
-        const decltype(C2FieldSupportedValues::range)& s) {
-    d->min = static_cast<PrimitiveValue>(s.min.u64);
-    d->max = static_cast<PrimitiveValue>(s.max.u64);
-    d->step = static_cast<PrimitiveValue>(s.step.u64);
-    d->num = static_cast<PrimitiveValue>(s.num.u64);
-    d->denom = static_cast<PrimitiveValue>(s.denom.u64);
-    return true;
-}
+static constexpr FieldSupportedValues::Tag EMPTY = FieldSupportedValues::empty;
+static constexpr FieldSupportedValues::Tag RANGE = FieldSupportedValues::range;
+static constexpr FieldSupportedValues::Tag VALUES = FieldSupportedValues::values;
+static constexpr FieldSupportedValues::Tag FLAGS = FieldSupportedValues::flags;
 
 // C2FieldSupportedValues -> FieldSupportedValues
+template<>
 bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
     switch (s.type) {
     case C2FieldSupportedValues::EMPTY: {
-            d->empty(::android::hidl::safe_union::V1_0::Monostate{});
+            d->set<EMPTY>(true);
             break;
         }
     case C2FieldSupportedValues::RANGE: {
             ValueRange range{};
             if (!objcpy(&range, s.range)) {
                 LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
-                d->range(range);
+                d->set<RANGE>(range);
                 return false;
             }
-            d->range(range);
+            d->set<RANGE>(range);
             break;
         }
     case C2FieldSupportedValues::VALUES: {
-            hidl_vec<PrimitiveValue> values;
-            copyVector<uint64_t>(&values, s.values);
-            d->values(values);
+            std::vector<int64_t> values;
+            copyVector<int64_t>(&values, s.values);
+            d->set<VALUES>(values);
             break;
         }
     case C2FieldSupportedValues::FLAGS: {
-            hidl_vec<PrimitiveValue> flags;
-            copyVector<uint64_t>(&flags, s.values);
-            d->flags(flags);
+            std::vector<int64_t> flags;
+            copyVector<int64_t>(&flags, s.values);
+            d->set<FLAGS>(flags);
             break;
         }
     default:
@@ -165,42 +104,31 @@
     return true;
 }
 
-// ValueRange -> C2FieldSupportedValues::range's type
-bool objcpy(
-        decltype(C2FieldSupportedValues::range)* d,
-        const ValueRange& s) {
-    d->min.u64 = static_cast<uint64_t>(s.min);
-    d->max.u64 = static_cast<uint64_t>(s.max);
-    d->step.u64 = static_cast<uint64_t>(s.step);
-    d->num.u64 = static_cast<uint64_t>(s.num);
-    d->denom.u64 = static_cast<uint64_t>(s.denom);
-    return true;
-}
-
 // FieldSupportedValues -> C2FieldSupportedValues
+template<>
 bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
-    switch (s.getDiscriminator()) {
-    case FieldSupportedValues::hidl_discriminator::empty: {
+    switch (s.getTag()) {
+    case FieldSupportedValues::empty: {
             d->type = C2FieldSupportedValues::EMPTY;
             break;
         }
-    case FieldSupportedValues::hidl_discriminator::range: {
+    case FieldSupportedValues::range: {
             d->type = C2FieldSupportedValues::RANGE;
-            if (!objcpy(&d->range, s.range())) {
+            if (!objcpy(&d->range, s.get<RANGE>())) {
                 LOG(ERROR) << "Invalid FieldSupportedValues::range.";
                 return false;
             }
             d->values.resize(0);
             break;
         }
-    case FieldSupportedValues::hidl_discriminator::values: {
+    case FieldSupportedValues::values: {
             d->type = C2FieldSupportedValues::VALUES;
-            copyVector<uint64_t>(&d->values, s.values());
+            copyVector<uint64_t>(&d->values, s.get<VALUES>());
             break;
         }
-    case FieldSupportedValues::hidl_discriminator::flags: {
+    case FieldSupportedValues::flags: {
             d->type = C2FieldSupportedValues::FLAGS;
-            copyVector<uint64_t>(&d->values, s.flags());
+            copyVector<uint64_t>(&d->values, s.get<FLAGS>());
             break;
         }
     default:
@@ -210,1719 +138,171 @@
     return true;
 }
 
+template<>
+const std::vector<uint8_t> &GetBlob<Params>(const Params &params) {
+    return params.params;
+}
+
+template<>
+std::vector<uint8_t> *GetBlob<Params>(Params *params) {
+    return &params->params;
+}
+
+} // namespace android
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace utils {
+
+const char* asString(Status status, const char* def) {
+    return asString(static_cast<c2_status_t>(status.status), def);
+}
+
+namespace /* unnamed */ {
+
 } // unnamed namespace
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
-bool objcpy(
+bool ToAidl(
         FieldSupportedValuesQuery* d,
         const C2FieldSupportedValuesQuery& s) {
-    if (!objcpy(&d->field, s.field())) {
-        LOG(ERROR) << "Invalid C2FieldSupportedValuesQuery::field.";
-        return false;
-    }
-    switch (s.type()) {
-    case C2FieldSupportedValuesQuery::POSSIBLE:
-        d->type = FieldSupportedValuesQuery::Type::POSSIBLE;
-        break;
-    case C2FieldSupportedValuesQuery::CURRENT:
-        d->type = FieldSupportedValuesQuery::Type::CURRENT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2FieldSupportedValuesQuery::type_t "
-                   << "with underlying value " << underlying_value(s.type())
-                   << ".";
-        d->type = static_cast<FieldSupportedValuesQuery::Type>(s.type());
-    }
-    return true;
+    return ::android::objcpy(d, nullptr, s);
 }
 
 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
-bool objcpy(
+bool FromAidl(
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& s) {
-    C2FieldSupportedValuesQuery::type_t dType;
-    switch (s.type) {
-    case FieldSupportedValuesQuery::Type::POSSIBLE:
-        dType = C2FieldSupportedValuesQuery::POSSIBLE;
-        break;
-    case FieldSupportedValuesQuery::Type::CURRENT:
-        dType = C2FieldSupportedValuesQuery::CURRENT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized FieldSupportedValuesQuery::Type "
-                   << "with underlying value " << underlying_value(s.type)
-                   << ".";
-        dType = static_cast<C2FieldSupportedValuesQuery::type_t>(s.type);
-    }
-    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
-bool objcpy(
+bool ToAidl(
         FieldSupportedValuesQueryResult* d,
         const C2FieldSupportedValuesQuery& s) {
-    d->status = static_cast<Status>(s.status);
-    return objcpy(&d->values, s.values);
+    return ::android::objcpy(nullptr, d, s);
 }
 
 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
 // C2FieldSupportedValuesQuery
-bool objcpy(
+bool FromAidl(
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& sq,
         const FieldSupportedValuesQueryResult& sr) {
-    if (!objcpy(d, sq)) {
-        LOG(ERROR) << "Invalid FieldSupportedValuesQuery.";
-        return false;
-    }
-    d->status = static_cast<c2_status_t>(sr.status);
-    if (!objcpy(&d->values, sr.values)) {
-        LOG(ERROR) << "Invalid FieldSupportedValuesQueryResult::values.";
-        return false;
-    }
-    return true;
+    return ::android::objcpy(d, sq, sr);
 }
 
 // C2Component::Traits -> IComponentStore::ComponentTraits
-bool objcpy(
+bool ToAidl(
         IComponentStore::ComponentTraits *d,
         const C2Component::Traits &s) {
-    d->name = s.name;
-
-    switch (s.domain) {
-    case C2Component::DOMAIN_VIDEO:
-        d->domain = IComponentStore::ComponentTraits::Domain::VIDEO;
-        break;
-    case C2Component::DOMAIN_AUDIO:
-        d->domain = IComponentStore::ComponentTraits::Domain::AUDIO;
-        break;
-    case C2Component::DOMAIN_IMAGE:
-        d->domain = IComponentStore::ComponentTraits::Domain::IMAGE;
-        break;
-    case C2Component::DOMAIN_OTHER:
-        d->domain = IComponentStore::ComponentTraits::Domain::OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2Component::domain_t "
-                   << "with underlying value " << underlying_value(s.domain)
-                   << ".";
-        d->domain = static_cast<IComponentStore::ComponentTraits::Domain>(
-                s.domain);
-    }
-
-    switch (s.kind) {
-    case C2Component::KIND_DECODER:
-        d->kind = IComponentStore::ComponentTraits::Kind::DECODER;
-        break;
-    case C2Component::KIND_ENCODER:
-        d->kind = IComponentStore::ComponentTraits::Kind::ENCODER;
-        break;
-    case C2Component::KIND_OTHER:
-        d->kind = IComponentStore::ComponentTraits::Kind::OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2Component::kind_t "
-                   << "with underlying value " << underlying_value(s.kind)
-                   << ".";
-        d->kind = static_cast<IComponentStore::ComponentTraits::Kind>(
-                s.kind);
-    }
-
-    d->rank = static_cast<uint32_t>(s.rank);
-
-    d->mediaType = s.mediaType;
-
-    d->aliases.resize(s.aliases.size());
-    for (size_t ix = s.aliases.size(); ix > 0; ) {
-        --ix;
-        d->aliases[ix] = s.aliases[ix];
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
-bool objcpy(
+bool FromAidl(
         C2Component::Traits* d,
         const IComponentStore::ComponentTraits& s) {
-    d->name = s.name.c_str();
-
-    switch (s.domain) {
-    case IComponentStore::ComponentTraits::Domain::VIDEO:
-        d->domain = C2Component::DOMAIN_VIDEO;
-        break;
-    case IComponentStore::ComponentTraits::Domain::AUDIO:
-        d->domain = C2Component::DOMAIN_AUDIO;
-        break;
-    case IComponentStore::ComponentTraits::Domain::IMAGE:
-        d->domain = C2Component::DOMAIN_IMAGE;
-        break;
-    case IComponentStore::ComponentTraits::Domain::OTHER:
-        d->domain = C2Component::DOMAIN_OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized ComponentTraits::Domain "
-                   << "with underlying value " << underlying_value(s.domain)
-                   << ".";
-        d->domain = static_cast<C2Component::domain_t>(s.domain);
-    }
-
-    switch (s.kind) {
-    case IComponentStore::ComponentTraits::Kind::DECODER:
-        d->kind = C2Component::KIND_DECODER;
-        break;
-    case IComponentStore::ComponentTraits::Kind::ENCODER:
-        d->kind = C2Component::KIND_ENCODER;
-        break;
-    case IComponentStore::ComponentTraits::Kind::OTHER:
-        d->kind = C2Component::KIND_OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized ComponentTraits::Kind "
-                   << "with underlying value " << underlying_value(s.kind)
-                   << ".";
-        d->kind = static_cast<C2Component::kind_t>(s.kind);
-    }
-
-    d->rank = static_cast<C2Component::rank_t>(s.rank);
-    d->mediaType = s.mediaType.c_str();
-    d->aliases.resize(s.aliases.size());
-    for (size_t i = 0; i < s.aliases.size(); ++i) {
-        d->aliases[i] = s.aliases[i];
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
-namespace /* unnamed */ {
-
-// C2ParamFieldValues -> ParamFieldValues
-bool objcpy(ParamFieldValues *d, const C2ParamFieldValues &s) {
-    if (!objcpy(&d->paramOrField, s.paramOrField)) {
-        LOG(ERROR) << "Invalid C2ParamFieldValues::paramOrField.";
-        return false;
-    }
-    if (s.values) {
-        d->values.resize(1);
-        if (!objcpy(&d->values[0], *s.values)) {
-            LOG(ERROR) << "Invalid C2ParamFieldValues::values.";
-            return false;
-        }
-        return true;
-    }
-    d->values.resize(0);
-    return true;
-}
-
-// ParamFieldValues -> C2ParamFieldValues
-bool objcpy(C2ParamFieldValues *d, const ParamFieldValues &s) {
-    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
-    if (s.values.size() == 1) {
-        d->values = std::make_unique<C2FieldSupportedValues>();
-        if (!objcpy(d->values.get(), s.values[0])) {
-            LOG(ERROR) << "Invalid ParamFieldValues::values.";
-            return false;
-        }
-        return true;
-    } else if (s.values.size() == 0) {
-        d->values.reset();
-        return true;
-    }
-    LOG(ERROR) << "Invalid ParamFieldValues: "
-                  "Two or more FieldSupportedValues objects exist in "
-                  "ParamFieldValues. "
-                  "Only zero or one is allowed.";
-    return false;
-}
-
-} // unnamed namespace
-
 // C2SettingResult -> SettingResult
-bool objcpy(SettingResult *d, const C2SettingResult &s) {
-    switch (s.failure) {
-    case C2SettingResult::BAD_TYPE:
-        d->failure = SettingResult::Failure::BAD_TYPE;
-        break;
-    case C2SettingResult::BAD_PORT:
-        d->failure = SettingResult::Failure::BAD_PORT;
-        break;
-    case C2SettingResult::BAD_INDEX:
-        d->failure = SettingResult::Failure::BAD_INDEX;
-        break;
-    case C2SettingResult::READ_ONLY:
-        d->failure = SettingResult::Failure::READ_ONLY;
-        break;
-    case C2SettingResult::MISMATCH:
-        d->failure = SettingResult::Failure::MISMATCH;
-        break;
-    case C2SettingResult::BAD_VALUE:
-        d->failure = SettingResult::Failure::BAD_VALUE;
-        break;
-    case C2SettingResult::CONFLICT:
-        d->failure = SettingResult::Failure::CONFLICT;
-        break;
-    case C2SettingResult::UNSUPPORTED:
-        d->failure = SettingResult::Failure::UNSUPPORTED;
-        break;
-    case C2SettingResult::INFO_BAD_VALUE:
-        d->failure = SettingResult::Failure::INFO_BAD_VALUE;
-        break;
-    case C2SettingResult::INFO_CONFLICT:
-        d->failure = SettingResult::Failure::INFO_CONFLICT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2SettingResult::Failure "
-                   << "with underlying value " << underlying_value(s.failure)
-                   << ".";
-        d->failure = static_cast<SettingResult::Failure>(s.failure);
-    }
-    if (!objcpy(&d->field, s.field)) {
-        LOG(ERROR) << "Invalid C2SettingResult::field.";
-        return false;
-    }
-    d->conflicts.resize(s.conflicts.size());
-    size_t i = 0;
-    for (const C2ParamFieldValues& sConflict : s.conflicts) {
-        ParamFieldValues &dConflict = d->conflicts[i++];
-        if (!objcpy(&dConflict, sConflict)) {
-            LOG(ERROR) << "Invalid C2SettingResult::conflicts["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-    return true;
+bool ToAidl(SettingResult *d, const C2SettingResult &s) {
+    return ::android::objcpy(d, s);
 }
 
 // SettingResult -> std::unique_ptr<C2SettingResult>
-bool objcpy(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
-    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
-            .field = C2ParamFieldValues(C2ParamFieldBuilder()) });
-    if (!*d) {
-        LOG(ERROR) << "No memory for C2SettingResult.";
-        return false;
-    }
-
-    // failure
-    switch (s.failure) {
-    case SettingResult::Failure::BAD_TYPE:
-        (*d)->failure = C2SettingResult::BAD_TYPE;
-        break;
-    case SettingResult::Failure::BAD_PORT:
-        (*d)->failure = C2SettingResult::BAD_PORT;
-        break;
-    case SettingResult::Failure::BAD_INDEX:
-        (*d)->failure = C2SettingResult::BAD_INDEX;
-        break;
-    case SettingResult::Failure::READ_ONLY:
-        (*d)->failure = C2SettingResult::READ_ONLY;
-        break;
-    case SettingResult::Failure::MISMATCH:
-        (*d)->failure = C2SettingResult::MISMATCH;
-        break;
-    case SettingResult::Failure::BAD_VALUE:
-        (*d)->failure = C2SettingResult::BAD_VALUE;
-        break;
-    case SettingResult::Failure::CONFLICT:
-        (*d)->failure = C2SettingResult::CONFLICT;
-        break;
-    case SettingResult::Failure::UNSUPPORTED:
-        (*d)->failure = C2SettingResult::UNSUPPORTED;
-        break;
-    case SettingResult::Failure::INFO_BAD_VALUE:
-        (*d)->failure = C2SettingResult::INFO_BAD_VALUE;
-        break;
-    case SettingResult::Failure::INFO_CONFLICT:
-        (*d)->failure = C2SettingResult::INFO_CONFLICT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized SettingResult::Failure "
-                   << "with underlying value " << underlying_value(s.failure)
-                   << ".";
-        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failure);
-    }
-
-    // field
-    if (!objcpy(&(*d)->field, s.field)) {
-        LOG(ERROR) << "Invalid SettingResult::field.";
-        return false;
-    }
-
-    // conflicts
-    (*d)->conflicts.clear();
-    (*d)->conflicts.reserve(s.conflicts.size());
-    for (const ParamFieldValues& sConflict : s.conflicts) {
-        (*d)->conflicts.emplace_back(
-                C2ParamFieldValues{ C2ParamFieldBuilder(), nullptr });
-        if (!objcpy(&(*d)->conflicts.back(), sConflict)) {
-            LOG(ERROR) << "Invalid SettingResult::conflicts.";
-            return false;
-        }
-    }
-    return true;
+bool FromAidl(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
+    return ::android::objcpy(d, s);
 }
 
 // C2ParamDescriptor -> ParamDescriptor
-bool objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
-    d->index = static_cast<ParamIndex>(s.index());
-    d->attrib = static_cast<hidl_bitfield<ParamDescriptor::Attrib>>(
-            _C2ParamInspector::GetAttrib(s));
-    d->name = s.name();
-    copyVector<uint32_t>(&d->dependencies, s.dependencies());
-    return true;
+bool ToAidl(ParamDescriptor *d, const C2ParamDescriptor &s) {
+    return ::android::objcpy(d, s);
 }
 
 // ParamDescriptor -> C2ParamDescriptor
-bool objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
-    std::vector<C2Param::Index> dDependencies;
-    dDependencies.reserve(s.dependencies.size());
-    for (const ParamIndex& sDependency : s.dependencies) {
-        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
-    }
-    *d = std::make_shared<C2ParamDescriptor>(
-            C2Param::Index(static_cast<uint32_t>(s.index)),
-            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
-            C2String(s.name.c_str()),
-            std::move(dDependencies));
-    return true;
+bool FromAidl(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
+    return ::android::objcpy(d, s);
 }
 
 // C2StructDescriptor -> StructDescriptor
-bool objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
-    d->type = static_cast<ParamIndex>(s.coreIndex().coreIndex());
-    d->fields.resize(s.numFields());
-    size_t i = 0;
-    for (const auto& sField : s) {
-        FieldDescriptor& dField = d->fields[i++];
-        dField.fieldId.offset = static_cast<uint32_t>(
-                _C2ParamInspector::GetOffset(sField));
-        dField.fieldId.size = static_cast<uint32_t>(
-                _C2ParamInspector::GetSize(sField));
-        dField.type = static_cast<hidl_bitfield<FieldDescriptor::Type>>(
-                sField.type());
-        dField.extent = static_cast<uint32_t>(sField.extent());
-        dField.name = static_cast<hidl_string>(sField.name());
-        const auto& sNamedValues = sField.namedValues();
-        dField.namedValues.resize(sNamedValues.size());
-        size_t j = 0;
-        for (const auto& sNamedValue : sNamedValues) {
-            FieldDescriptor::NamedValue& dNamedValue = dField.namedValues[j++];
-            dNamedValue.name = static_cast<hidl_string>(sNamedValue.first);
-            dNamedValue.value = static_cast<PrimitiveValue>(
-                    sNamedValue.second.u64);
-        }
-    }
-    return true;
+bool ToAidl(StructDescriptor *d, const C2StructDescriptor &s) {
+    return ::android::objcpy(d, s);
 }
 
 // StructDescriptor -> C2StructDescriptor
-bool objcpy(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
-    C2Param::CoreIndex dIndex = C2Param::CoreIndex(static_cast<uint32_t>(s.type));
-    std::vector<C2FieldDescriptor> dFields;
-    dFields.reserve(s.fields.size());
-    for (const auto &sField : s.fields) {
-        C2FieldDescriptor dField = {
-            static_cast<uint32_t>(sField.type),
-            sField.extent,
-            sField.name,
-            sField.fieldId.offset,
-            sField.fieldId.size };
-        C2FieldDescriptor::NamedValuesType namedValues;
-        namedValues.reserve(sField.namedValues.size());
-        for (const auto& sNamedValue : sField.namedValues) {
-            namedValues.emplace_back(
-                sNamedValue.name,
-                C2Value::Primitive(static_cast<uint64_t>(sNamedValue.value)));
-        }
-        _C2ParamInspector::AddNamedValues(dField, std::move(namedValues));
-        dFields.emplace_back(dField);
-    }
-    *d = std::make_unique<C2StructDescriptor>(
-            _C2ParamInspector::CreateStructDescriptor(dIndex, std::move(dFields)));
-    return true;
+bool FromAidl(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
+    return ::android::objcpy(d, s);
 }
 
-namespace /* unnamed */ {
-
-// Find or add a hidl BaseBlock object from a given C2Handle* to a list and an
-// associated map.
-// Note: The handle is not cloned.
-bool _addBaseBlock(
-        uint32_t* index,
-        const C2Handle* handle,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!handle) {
-        LOG(ERROR) << "addBaseBlock called on a null C2Handle.";
-        return false;
-    }
-    auto it = baseBlockIndices->find(handle);
-    if (it != baseBlockIndices->end()) {
-        *index = it->second;
-    } else {
-        *index = baseBlocks->size();
-        baseBlockIndices->emplace(handle, *index);
-        baseBlocks->emplace_back();
-
-        BaseBlock &dBaseBlock = baseBlocks->back();
-        // This does not clone the handle.
-        dBaseBlock.nativeBlock(
-                reinterpret_cast<const native_handle_t*>(handle));
-
-    }
-    return true;
-}
-
-// Find or add a hidl BaseBlock object from a given BufferPoolData to a list and
-// an associated map.
-bool _addBaseBlock(
-        uint32_t* index,
-        const std::shared_ptr<BufferPoolData> bpData,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!bpData) {
-        LOG(ERROR) << "addBaseBlock called on a null BufferPoolData.";
-        return false;
-    }
-    auto it = baseBlockIndices->find(bpData.get());
-    if (it != baseBlockIndices->end()) {
-        *index = it->second;
-    } else {
-        *index = baseBlocks->size();
-        baseBlockIndices->emplace(bpData.get(), *index);
-        baseBlocks->emplace_back();
-
-        BaseBlock &dBaseBlock = baseBlocks->back();
-
-        if (bufferPoolSender) {
-            BufferStatusMessage pooledBlock;
-            ResultStatus bpStatus = bufferPoolSender->send(
-                    bpData,
-                    &pooledBlock);
-
-            if (bpStatus != ResultStatus::OK) {
-                LOG(ERROR) << "Failed to send buffer with BufferPool. Error: "
-                           << static_cast<int32_t>(bpStatus)
-                           << ".";
-                return false;
-            }
-            dBaseBlock.pooledBlock(pooledBlock);
-        }
-    }
-    return true;
-}
-
-bool addBaseBlock(
-        uint32_t* index,
-        const C2Handle* handle,
-        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!blockPoolData) {
-        // No BufferPoolData ==> NATIVE block.
-        return _addBaseBlock(
-                index, handle,
-                baseBlocks, baseBlockIndices);
-    }
-    switch (blockPoolData->getType()) {
-    case _C2BlockPoolData::TYPE_BUFFERPOOL: {
-            // BufferPoolData
-            std::shared_ptr<BufferPoolData> bpData;
-            if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData)
-                    || !bpData) {
-                LOG(ERROR) << "BufferPoolData unavailable in a block.";
-                return false;
-            }
-            return _addBaseBlock(
-                    index, bpData,
-                    bufferPoolSender, baseBlocks, baseBlockIndices);
-        }
-    case _C2BlockPoolData::TYPE_BUFFERQUEUE:
-        uint32_t gen;
-        uint64_t bqId;
-        int32_t bqSlot;
-        // Update handle if migration happened.
-        if (_C2BlockFactory::GetBufferQueueData(
-                blockPoolData, &gen, &bqId, &bqSlot)) {
-            android::MigrateNativeCodec2GrallocHandle(
-                    const_cast<native_handle_t*>(handle), gen, bqId, bqSlot);
-        }
-        return _addBaseBlock(
-                index, handle,
-                baseBlocks, baseBlockIndices);
-    default:
-        LOG(ERROR) << "Unknown C2BlockPoolData type.";
-        return false;
-    }
-}
-
-// C2Fence -> hidl_handle
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-bool objcpy(hidl_handle* d, const C2Fence& s) {
-    d->setTo(nullptr);
-    native_handle_t* handle = _C2FenceFactory::CreateNativeHandle(s);
-    if (handle) {
-        d->setTo(handle, true /* owns */);
-//  } else if (!s.ready()) {
-//      // TODO: we should wait for unmarshallable fences but this may not be
-//      // the best place for it. We can safely ignore here as at this time
-//      // all fences used here are marshallable.
-    }
-    return true;
-}
-
-// C2ConstLinearBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-bool objcpy(Block* d, const C2ConstLinearBlock& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    std::shared_ptr<const _C2BlockPoolData> bpData =
-            _C2BlockFactory::GetLinearBlockPoolData(s);
-    if (!addBaseBlock(&d->index, s.handle(), bpData,
-            bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid block data in C2ConstLinearBlock.";
-        return false;
-    }
-
-    // Create the metadata.
-    C2Hidl_RangeInfo dRangeInfo;
-    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
-    dRangeInfo.length = static_cast<uint32_t>(s.size());
-    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRangeInfo })) {
-        LOG(ERROR) << "Invalid range info in C2ConstLinearBlock.";
-        return false;
-    }
-
-    // Copy the fence
-    if (!objcpy(&d->fence, s.fence())) {
-        LOG(ERROR) << "Invalid C2ConstLinearBlock::fence.";
-        return false;
-    }
-    return true;
-}
-
-// C2ConstGraphicBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-bool objcpy(Block* d, const C2ConstGraphicBlock& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    std::shared_ptr<const _C2BlockPoolData> bpData =
-            _C2BlockFactory::GetGraphicBlockPoolData(s);
-    if (!addBaseBlock(&d->index, s.handle(), bpData,
-            bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid block data in C2ConstGraphicBlock.";
-        return false;
-    }
-
-    // Create the metadata.
-    C2Hidl_RectInfo dRectInfo;
-    C2Rect sRect = s.crop();
-    dRectInfo.left = static_cast<uint32_t>(sRect.left);
-    dRectInfo.top = static_cast<uint32_t>(sRect.top);
-    dRectInfo.width = static_cast<uint32_t>(sRect.width);
-    dRectInfo.height = static_cast<uint32_t>(sRect.height);
-    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRectInfo })) {
-        LOG(ERROR) << "Invalid rect info in C2ConstGraphicBlock.";
-        return false;
-    }
-
-    // Copy the fence
-    if (!objcpy(&d->fence, s.fence())) {
-        LOG(ERROR) << "Invalid C2ConstGraphicBlock::fence.";
-        return false;
-    }
-    return true;
-}
-
-// C2BufferData -> Buffer
-// This function only fills in d->blocks.
-bool objcpy(Buffer* d, const C2BufferData& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->blocks.resize(
-            s.linearBlocks().size() +
-            s.graphicBlocks().size());
-    size_t i = 0;
-    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        if (!objcpy(
-                &dBlock, linearBlock,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2BufferData::linearBlocks. "
-                       << "(Destination index = " << i - 1 << ".)";
-            return false;
-        }
-    }
-    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        if (!objcpy(
-                &dBlock, graphicBlock,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2BufferData::graphicBlocks. "
-                       << "(Destination index = " << i - 1 << ".)";
-            return false;
-        }
-    }
-    return true;
-}
-
-// C2Buffer -> Buffer
-bool objcpy(Buffer* d, const C2Buffer& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!createParamsBlob(&d->info, s.info())) {
-        LOG(ERROR) << "Invalid C2Buffer::info.";
-        return false;
-    }
-    if (!objcpy(d, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid C2Buffer::data.";
-        return false;
-    }
-    return true;
-}
-
-// C2InfoBuffer -> InfoBuffer
-bool objcpy(InfoBuffer* d, const C2InfoBuffer& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->index = static_cast<ParamIndex>(s.index());
-    Buffer& dBuffer = d->buffer;
-    if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid C2InfoBuffer::data";
-        return false;
-    }
-    return true;
-}
-
-// C2FrameData -> FrameData
-bool objcpy(FrameData* d, const C2FrameData& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->flags = static_cast<hidl_bitfield<FrameData::Flags>>(s.flags);
-    if (!objcpy(&d->ordinal, s.ordinal)) {
-        LOG(ERROR) << "Invalid C2FrameData::ordinal.";
-        return false;
-    }
-
-    d->buffers.resize(s.buffers.size());
-    size_t i = 0;
-    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
-        Buffer& dBuffer = d->buffers[i++];
-        if (!sBuffer) {
-            // A null (pointer to) C2Buffer corresponds to a Buffer with empty
-            // info and blocks.
-            dBuffer.info.resize(0);
-            dBuffer.blocks.resize(0);
-            continue;
-        }
-        if (!objcpy(
-                &dBuffer, *sBuffer,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2FrameData::buffers["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-
-    if (!createParamsBlob(&d->configUpdate, s.configUpdate)) {
-        LOG(ERROR) << "Invalid C2FrameData::configUpdate.";
-        return false;
-    }
-
-    d->infoBuffers.resize(s.infoBuffers.size());
-    i = 0;
-    for (const C2InfoBuffer& sInfoBuffer : s.infoBuffers) {
-        InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
-        if (!objcpy(&dInfoBuffer, sInfoBuffer,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-
-    return true;
-}
-
-} // unnamed namespace
-
-// DefaultBufferPoolSender's implementation
-
-DefaultBufferPoolSender::DefaultBufferPoolSender(
-        const sp<IClientManager>& receiverManager,
-        std::chrono::steady_clock::duration refreshInterval)
-    : mReceiverManager(receiverManager),
-      mRefreshInterval(refreshInterval) {
-}
-
-void DefaultBufferPoolSender::setReceiver(
-        const sp<IClientManager>& receiverManager,
-        std::chrono::steady_clock::duration refreshInterval) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (mReceiverManager != receiverManager) {
-        mReceiverManager = receiverManager;
-        mConnections.clear();
-    }
-    mRefreshInterval = refreshInterval;
-}
-
-ResultStatus DefaultBufferPoolSender::send(
-        const std::shared_ptr<BufferPoolData>& bpData,
-        BufferStatusMessage* bpMessage) {
-    int64_t connectionId = bpData->mConnectionId;
-    if (connectionId == 0) {
-        LOG(WARNING) << "registerSender -- invalid sender connection id (0).";
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (!mReceiverManager) {
-        LOG(ERROR) << "No access to receiver's BufferPool.";
-        return ResultStatus::NOT_FOUND;
-    }
-    if (!mSenderManager) {
-        mSenderManager = ClientManager::getInstance();
-        if (!mSenderManager) {
-            LOG(ERROR) << "Failed to retrieve local BufferPool ClientManager.";
-            return ResultStatus::CRITICAL_ERROR;
-        }
-    }
-
-    int64_t receiverConnectionId{0};
-    auto foundConnection = mConnections.find(connectionId);
-    bool isNewConnection = foundConnection == mConnections.end();
-    std::chrono::steady_clock::time_point now =
-            std::chrono::steady_clock::now();
-    if (isNewConnection ||
-            (now - foundConnection->second.lastSent > mRefreshInterval)) {
-        // Initialize the bufferpool connection.
-        ResultStatus rs =
-                mSenderManager->registerSender(mReceiverManager,
-                                               connectionId,
-                                               &receiverConnectionId);
-        if ((rs != ResultStatus::OK) && (rs != ResultStatus::ALREADY_EXISTS)) {
-            LOG(WARNING) << "registerSender -- returned error: "
-                         << static_cast<int32_t>(rs)
-                         << ".";
-            return rs;
-        } else if (receiverConnectionId == 0) {
-            LOG(WARNING) << "registerSender -- "
-                            "invalid receiver connection id (0).";
-            return ResultStatus::CRITICAL_ERROR;
-        } else {
-            if (isNewConnection) {
-                foundConnection = mConnections.try_emplace(
-                        connectionId, receiverConnectionId, now).first;
-            } else {
-                foundConnection->second.receiverConnectionId = receiverConnectionId;
-            }
-        }
-    } else {
-        receiverConnectionId = foundConnection->second.receiverConnectionId;
-    }
-
-    uint64_t transactionId;
-    int64_t timestampUs;
-    ResultStatus rs = mSenderManager->postSend(
-            receiverConnectionId, bpData, &transactionId, &timestampUs);
-    if (rs != ResultStatus::OK) {
-        LOG(ERROR) << "ClientManager::postSend -- returned error: "
-                   << static_cast<int32_t>(rs)
-                   << ".";
-        mConnections.erase(foundConnection);
-        return rs;
-    }
-    if (!bpMessage) {
-        LOG(ERROR) << "Null output parameter for BufferStatusMessage.";
-        mConnections.erase(foundConnection);
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    bpMessage->connectionId = receiverConnectionId;
-    bpMessage->bufferId = bpData->mId;
-    bpMessage->transactionId = transactionId;
-    bpMessage->timestampUs = timestampUs;
-    foundConnection->second.lastSent = now;
-    return rs;
-}
-
-// std::list<std::unique_ptr<C2Work>> -> WorkBundle
-bool objcpy(
-        WorkBundle* d,
-        const std::list<std::unique_ptr<C2Work>>& s,
-        BufferPoolSender* bufferPoolSender) {
-    // baseBlocks holds a list of BaseBlock objects that Blocks can refer to.
-    std::list<BaseBlock> baseBlocks;
-
-    // baseBlockIndices maps a raw pointer to native_handle_t or BufferPoolData
-    // inside baseBlocks to the corresponding index into baseBlocks. The keys
-    // (pointers) are used to identify blocks that have the same "base block" in
-    // s, a list of C2Work objects. Because baseBlocks will be copied into a
-    // hidl_vec eventually, the values of baseBlockIndices are zero-based
-    // integer indices instead of list iterators.
-    //
-    // Note that the pointers can be raw because baseBlockIndices has a shorter
-    // lifespan than all of base blocks.
-    std::map<const void*, uint32_t> baseBlockIndices;
-
-    d->works.resize(s.size());
-    size_t i = 0;
-    for (const std::unique_ptr<C2Work>& sWork : s) {
-        Work &dWork = d->works[i++];
-        if (!sWork) {
-            LOG(WARNING) << "Null C2Work encountered.";
-            continue;
-        }
-
-        // chain info is not in use currently.
-
-        // input
-        if (!objcpy(&dWork.input, sWork->input,
-                bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2Work::input.";
-            return false;
-        }
-
-        // worklets
-        if (sWork->worklets.size() == 0) {
-            LOG(DEBUG) << "Work with no worklets.";
-        } else {
-            // Parcel the worklets.
-            hidl_vec<Worklet> &dWorklets = dWork.worklets;
-            dWorklets.resize(sWork->worklets.size());
-            size_t j = 0;
-            for (const std::unique_ptr<C2Worklet>& sWorklet : sWork->worklets)
-            {
-                if (!sWorklet) {
-                    LOG(WARNING) << "Null C2Work::worklets["
-                                 << j << "].";
-                    continue;
-                }
-                Worklet &dWorklet = dWorklets[j++];
-
-                // component id
-                dWorklet.componentId = static_cast<uint32_t>(
-                        sWorklet->component);
-
-                // tunings
-                if (!createParamsBlob(&dWorklet.tunings, sWorklet->tunings)) {
-                    LOG(ERROR) << "Invalid C2Work::worklets["
-                               << j - 1 << "]->tunings.";
-                    return false;
-                }
-
-                // failures
-                dWorklet.failures.resize(sWorklet->failures.size());
-                size_t k = 0;
-                for (const std::unique_ptr<C2SettingResult>& sFailure :
-                        sWorklet->failures) {
-                    if (!sFailure) {
-                        LOG(WARNING) << "Null C2Work::worklets["
-                                     << j - 1 << "]->failures["
-                                     << k << "].";
-                        continue;
-                    }
-                    if (!objcpy(&dWorklet.failures[k++], *sFailure)) {
-                        LOG(ERROR) << "Invalid C2Work::worklets["
-                                   << j - 1 << "]->failures["
-                                   << k - 1 << "].";
-                        return false;
-                    }
-                }
-
-                // output
-                if (!objcpy(&dWorklet.output, sWorklet->output,
-                        bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
-                    LOG(ERROR) << "Invalid C2Work::worklets["
-                               << j - 1 << "]->output.";
-                    return false;
-                }
-            }
-        }
-
-        // worklets processed
-        dWork.workletsProcessed = sWork->workletsProcessed;
-
-        // result
-        dWork.result = static_cast<Status>(sWork->result);
-    }
-
-    // Copy std::list<BaseBlock> to hidl_vec<BaseBlock>.
-    {
-        d->baseBlocks.resize(baseBlocks.size());
-        size_t i = 0;
-        for (const BaseBlock& baseBlock : baseBlocks) {
-            d->baseBlocks[i++] = baseBlock;
-        }
-    }
-
-    return true;
-}
-
-namespace /* unnamed */ {
-
-struct C2BaseBlock {
-    enum type_t {
-        LINEAR,
-        GRAPHIC,
-    };
-    type_t type;
-    std::shared_ptr<C2LinearBlock> linear;
-    std::shared_ptr<C2GraphicBlock> graphic;
-};
-
-// hidl_handle -> C2Fence
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-bool objcpy(C2Fence* d, const hidl_handle& s) {
-    const native_handle_t* handle = s.getNativeHandle();
-    *d = _C2FenceFactory::CreateFromNativeHandle(handle);
-    return true;
-}
-
-// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
-bool createLinearBuffer(
-        std::shared_ptr<C2Buffer>* buffer,
-        const std::shared_ptr<C2LinearBlock>& block,
-        const std::vector<C2Param*>& meta,
-        const C2Fence& fence) {
-    // Check the block meta. It should have exactly 1 C2Info:
-    // C2Hidl_RangeInfo.
-    if ((meta.size() != 1) || !meta[0]) {
-        LOG(ERROR) << "Invalid C2LinearBlock::meta.";
-        return false;
-    }
-    if (meta[0]->size() != sizeof(C2Hidl_RangeInfo)) {
-        LOG(ERROR) << "Invalid range info in C2LinearBlock.";
-        return false;
-    }
-    C2Hidl_RangeInfo *rangeInfo =
-            reinterpret_cast<C2Hidl_RangeInfo*>(meta[0]);
-
-    // Create C2Buffer from C2LinearBlock.
-    *buffer = C2Buffer::CreateLinearBuffer(block->share(
-            rangeInfo->offset, rangeInfo->length,
-            fence));
-    if (!(*buffer)) {
-        LOG(ERROR) << "CreateLinearBuffer failed.";
-        return false;
-    }
-    return true;
-}
-
-// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
-bool createGraphicBuffer(
-        std::shared_ptr<C2Buffer>* buffer,
-        const std::shared_ptr<C2GraphicBlock>& block,
-        const std::vector<C2Param*>& meta,
-        const C2Fence& fence) {
-    // Check the block meta. It should have exactly 1 C2Info:
-    // C2Hidl_RectInfo.
-    if ((meta.size() != 1) || !meta[0]) {
-        LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
-        return false;
-    }
-    if (meta[0]->size() != sizeof(C2Hidl_RectInfo)) {
-        LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
-        return false;
-    }
-    C2Hidl_RectInfo *rectInfo =
-            reinterpret_cast<C2Hidl_RectInfo*>(meta[0]);
-
-    // Create C2Buffer from C2GraphicBlock.
-    *buffer = C2Buffer::CreateGraphicBuffer(block->share(
-            C2Rect(rectInfo->width, rectInfo->height).
-            at(rectInfo->left, rectInfo->top),
-            fence));
-    if (!(*buffer)) {
-        LOG(ERROR) << "CreateGraphicBuffer failed.";
-        return false;
-    }
-    return true;
-}
-
-// Buffer -> C2Buffer
-// Note: The native handles will be cloned.
-bool objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-    *d = nullptr;
-
-    // Currently, a non-null C2Buffer must contain exactly 1 block.
-    if (s.blocks.size() == 0) {
-        return true;
-    } else if (s.blocks.size() != 1) {
-        LOG(ERROR) << "Invalid Buffer: "
-                      "Currently, a C2Buffer must contain exactly 1 block.";
-        return false;
-    }
-
-    const Block &sBlock = s.blocks[0];
-    if (sBlock.index >= baseBlocks.size()) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].index: "
-                      "Array index out of range.";
-        return false;
-    }
-    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
-
-    // Parse meta.
-    std::vector<C2Param*> sBlockMeta;
-    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].meta.";
-        return false;
-    }
-
-    // Copy fence.
-    C2Fence dFence;
-    if (!objcpy(&dFence, sBlock.fence)) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].fence.";
-        return false;
-    }
-
-    // Construct a block.
-    switch (baseBlock.type) {
-    case C2BaseBlock::LINEAR:
-        if (!createLinearBuffer(d, baseBlock.linear, sBlockMeta, dFence)) {
-            LOG(ERROR) << "Invalid C2BaseBlock::linear.";
-            return false;
-        }
-        break;
-    case C2BaseBlock::GRAPHIC:
-        if (!createGraphicBuffer(d, baseBlock.graphic, sBlockMeta, dFence)) {
-            LOG(ERROR) << "Invalid C2BaseBlock::graphic.";
-            return false;
-        }
-        break;
-    default:
-        LOG(ERROR) << "Invalid C2BaseBlock::type.";
-        return false;
-    }
-
-    // Parse info
-    std::vector<C2Param*> params;
-    if (!parseParamsBlob(&params, s.info)) {
-        LOG(ERROR) << "Invalid Buffer::info.";
-        return false;
-    }
-    for (C2Param* param : params) {
-        if (param == nullptr) {
-            LOG(ERROR) << "Null param in Buffer::info.";
-            return false;
-        }
-        std::shared_ptr<C2Param> c2param{
-                C2Param::Copy(*param).release()};
-        if (!c2param) {
-            LOG(ERROR) << "Invalid param in Buffer::info.";
-            return false;
-        }
-        c2_status_t status =
-                (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
-        if (status != C2_OK) {
-            LOG(ERROR) << "C2Buffer::setInfo failed.";
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// InfoBuffer -> C2InfoBuffer
-bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-
-    // Currently, a non-null C2InfoBufer must contain exactly 1 block.
-    if (s.buffer.blocks.size() == 0) {
-        return true;
-    } else if (s.buffer.blocks.size() != 1) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer "
-                      "Currently, a C2InfoBuffer must contain exactly 1 block.";
-        return false;
-    }
-
-    const Block &sBlock = s.buffer.blocks[0];
-    if (sBlock.index >= baseBlocks.size()) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
-                      "Array index out of range.";
-        return false;
-    }
-    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
-
-    // Parse meta.
-    std::vector<C2Param*> sBlockMeta;
-    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
-        return false;
-    }
-
-    // Copy fence.
-    C2Fence dFence;
-    if (!objcpy(&dFence, sBlock.fence)) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
-        return false;
-    }
-
-    // Construct a block.
-    switch (baseBlock.type) {
-    case C2BaseBlock::LINEAR:
-        if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
-            sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
-            C2Hidl_RangeInfo *rangeInfo =
-                    reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
-            d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
-                    s.index,
-                    baseBlock.linear->share(
-                            rangeInfo->offset, rangeInfo->length, dFence)));
-            return true;
-        }
-        LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
-        break;
-    case C2BaseBlock::GRAPHIC:
-        // It's not used now
-        LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
-        break;
-    default:
-        LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
-        break;
-    }
-
-    return false;
-}
-
-// FrameData -> C2FrameData
-bool objcpy(C2FrameData* d, const FrameData& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
-    if (!objcpy(&d->ordinal, s.ordinal)) {
-        LOG(ERROR) << "Invalid FrameData::ordinal.";
-        return false;
-    }
-    d->buffers.clear();
-    d->buffers.reserve(s.buffers.size());
-    for (const Buffer& sBuffer : s.buffers) {
-        std::shared_ptr<C2Buffer> dBuffer;
-        if (!objcpy(&dBuffer, sBuffer, baseBlocks)) {
-            LOG(ERROR) << "Invalid FrameData::buffers.";
-            return false;
-        }
-        d->buffers.emplace_back(dBuffer);
-    }
-
-    std::vector<C2Param*> params;
-    if (!parseParamsBlob(&params, s.configUpdate)) {
-        LOG(ERROR) << "Invalid FrameData::configUpdate.";
-        return false;
-    }
-    d->configUpdate.clear();
-    for (C2Param* param : params) {
-        d->configUpdate.emplace_back(C2Param::Copy(*param));
-        if (!d->configUpdate.back()) {
-            LOG(ERROR) << "Unexpected error while parsing "
-                          "FrameData::configUpdate.";
-            return false;
-        }
-    }
-
-    d->infoBuffers.clear();
-    if (s.infoBuffers.size() == 0) {
-        // InfoBuffer is optional
-        return true;
-    }
-    d->infoBuffers.reserve(s.infoBuffers.size());
-    for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
-        if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
-            LOG(ERROR) << "Invalid Framedata::infoBuffers.";
-            return false;
-        }
-    }
-    return true;
-}
-
-// BaseBlock -> C2BaseBlock
-bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
-    switch (s.getDiscriminator()) {
-    case BaseBlock::hidl_discriminator::nativeBlock: {
-            if (s.nativeBlock() == nullptr) {
-                LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
-                return false;
-            }
-            native_handle_t* sHandle =
-                    native_handle_clone(s.nativeBlock());
-            if (sHandle == nullptr) {
-                LOG(ERROR) << "Null BaseBlock::nativeBlock.";
-                return false;
-            }
-            const C2Handle *sC2Handle =
-                    reinterpret_cast<const C2Handle*>(sHandle);
-
-            d->linear = _C2BlockFactory::CreateLinearBlock(sC2Handle);
-            if (d->linear) {
-                d->type = C2BaseBlock::LINEAR;
-                return true;
-            }
-
-            d->graphic = _C2BlockFactory::CreateGraphicBlock(sC2Handle);
-            if (d->graphic) {
-                d->type = C2BaseBlock::GRAPHIC;
-                return true;
-            }
-
-            LOG(ERROR) << "Unknown handle type in BaseBlock::nativeBlock.";
-            if (sHandle) {
-                native_handle_close(sHandle);
-                native_handle_delete(sHandle);
-            }
-            return false;
-        }
-    case BaseBlock::hidl_discriminator::pooledBlock: {
-            const BufferStatusMessage &bpMessage =
-                    s.pooledBlock();
-            sp<ClientManager> bp = ClientManager::getInstance();
-            std::shared_ptr<BufferPoolData> bpData;
-            native_handle_t *cHandle;
-            ResultStatus bpStatus = bp->receive(
-                    bpMessage.connectionId,
-                    bpMessage.transactionId,
-                    bpMessage.bufferId,
-                    bpMessage.timestampUs,
-                    &cHandle,
-                    &bpData);
-            if (bpStatus != ResultStatus::OK) {
-                LOG(ERROR) << "Failed to receive buffer from bufferpool -- "
-                           << "resultStatus = " << underlying_value(bpStatus)
-                           << ".";
-                return false;
-            } else if (!bpData) {
-                LOG(ERROR) << "No data in bufferpool transaction.";
-                return false;
-            }
-
-            d->linear = _C2BlockFactory::CreateLinearBlock(cHandle, bpData);
-            if (d->linear) {
-                d->type = C2BaseBlock::LINEAR;
-                return true;
-            }
-
-            d->graphic = _C2BlockFactory::CreateGraphicBlock(cHandle, bpData);
-            if (d->graphic) {
-                d->type = C2BaseBlock::GRAPHIC;
-                return true;
-            }
-            if (cHandle) {
-                // Though we got cloned handle, creating block failed.
-                native_handle_close(cHandle);
-                native_handle_delete(cHandle);
-            }
-
-            LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
-            return false;
-        }
-    default:
-        LOG(ERROR) << "Unrecognized BaseBlock's discriminator with "
-                   << "underlying value "
-                   << underlying_value(s.getDiscriminator()) << ".";
-        return false;
-    }
-}
-
-} // unnamed namespace
-
-// WorkBundle -> std::list<std::unique_ptr<C2Work>>
-bool objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
-    // Convert BaseBlocks to C2BaseBlocks.
-    std::vector<C2BaseBlock> dBaseBlocks(s.baseBlocks.size());
-    for (size_t i = 0; i < s.baseBlocks.size(); ++i) {
-        if (!objcpy(&dBaseBlocks[i], s.baseBlocks[i])) {
-            LOG(ERROR) << "Invalid WorkBundle::baseBlocks["
-                       << i << "].";
-            return false;
-        }
-    }
-
-    d->clear();
-    for (const Work& sWork : s.works) {
-        d->emplace_back(std::make_unique<C2Work>());
-        C2Work& dWork = *d->back();
-
-        // chain info is not in use currently.
-
-        // input
-        if (!objcpy(&dWork.input, sWork.input, dBaseBlocks)) {
-            LOG(ERROR) << "Invalid Work::input.";
-            return false;
-        }
-
-        // worklet(s)
-        dWork.worklets.clear();
-        for (const Worklet& sWorklet : sWork.worklets) {
-            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
-
-            // component id
-            dWorklet->component = static_cast<c2_node_id_t>(
-                    sWorklet.componentId);
-
-            // tunings
-            if (!copyParamsFromBlob(&dWorklet->tunings, sWorklet.tunings)) {
-                LOG(ERROR) << "Invalid Worklet::tunings";
-                return false;
-            }
-
-            // failures
-            dWorklet->failures.clear();
-            dWorklet->failures.reserve(sWorklet.failures.size());
-            for (const SettingResult& sFailure : sWorklet.failures) {
-                std::unique_ptr<C2SettingResult> dFailure;
-                if (!objcpy(&dFailure, sFailure)) {
-                    LOG(ERROR) << "Invalid Worklet::failures.";
-                    return false;
-                }
-                dWorklet->failures.emplace_back(std::move(dFailure));
-            }
-
-            // output
-            if (!objcpy(&dWorklet->output, sWorklet.output, dBaseBlocks)) {
-                LOG(ERROR) << "Invalid Worklet::output.";
-                return false;
-            }
-
-            dWork.worklets.emplace_back(std::move(dWorklet));
-        }
-
-        // workletsProcessed
-        dWork.workletsProcessed = sWork.workletsProcessed;
-
-        // result
-        dWork.result = static_cast<c2_status_t>(sWork.result);
-    }
-
-    return true;
-}
-
-constexpr size_t PARAMS_ALIGNMENT = 8;  // 64-bit alignment
-static_assert(PARAMS_ALIGNMENT % alignof(C2Param) == 0, "C2Param alignment mismatch");
-static_assert(PARAMS_ALIGNMENT % alignof(C2Info) == 0, "C2Param alignment mismatch");
-static_assert(PARAMS_ALIGNMENT % alignof(C2Tuning) == 0, "C2Param alignment mismatch");
-
 // Params -> std::vector<C2Param*>
-bool parseParamsBlob(std::vector<C2Param*> *params, const hidl_vec<uint8_t> &blob) {
-    // assuming blob is const here
-    size_t size = blob.size();
-    size_t ix = 0;
-    size_t old_ix = 0;
-    const uint8_t *data = blob.data();
-    C2Param *p = nullptr;
-
-    do {
-        p = C2ParamUtils::ParseFirst(data + ix, size - ix);
-        if (p) {
-            params->emplace_back(p);
-            old_ix = ix;
-            ix += p->size();
-            ix = align(ix, PARAMS_ALIGNMENT);
-            if (ix <= old_ix || ix > size) {
-                android_errorWriteLog(0x534e4554, "238083570");
-                break;
-            }
-        }
-    } while (p);
-
-    if (ix != size) {
-        LOG(ERROR) << "parseParamsBlob -- inconsistent sizes.";
-        return false;
-    }
-    return true;
+bool ParseParamsBlob(std::vector<C2Param*> *params, const Params &blob) {
+    return ::android::parseParamsBlob(params, blob);
 }
 
-namespace /* unnamed */ {
-
-/**
- * Concatenates a list of C2Params into a params blob. T is a container type
- * whose member type is compatible with C2Param*.
- *
- * \param[out] blob target blob
- * \param[in] params parameters to concatenate
- * \retval C2_OK if the blob was successfully created
- * \retval C2_BAD_VALUE if the blob was not successful created (this only
- *         happens if the parameters were not const)
- */
-template <typename T>
-bool _createParamsBlob(hidl_vec<uint8_t> *blob, const T &params) {
-    // assuming the parameter values are const
-    size_t size = 0;
-    for (const auto &p : params) {
-        if (!p) {
-            continue;
-        }
-        size += p->size();
-        size = align(size, PARAMS_ALIGNMENT);
-    }
-    blob->resize(size);
-    size_t ix = 0;
-    for (const auto &p : params) {
-        if (!p) {
-            continue;
-        }
-        // NEVER overwrite even if param values (e.g. size) changed
-        size_t paramSize = std::min(p->size(), size - ix);
-        std::copy(
-                reinterpret_cast<const uint8_t*>(&*p),
-                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
-                &(*blob)[ix]);
-        ix += paramSize;
-        ix = align(ix, PARAMS_ALIGNMENT);
-    }
-    blob->resize(ix);
-    if (ix != size) {
-        LOG(ERROR) << "createParamsBlob -- inconsistent sizes.";
-        return false;
-    }
-    return true;
-}
-
-/**
- * Parses a params blob and create a vector of new T objects that contain copies
- * of the params in the blob. T is C2Param or its compatible derived class.
- *
- * \param[out] params the resulting vector
- * \param[in] blob parameter blob to parse
- * \retval C2_OK if the full blob was parsed and params was constructed
- * \retval C2_BAD_VALUE otherwise
- */
-template <typename T>
-bool _copyParamsFromBlob(
-        std::vector<std::unique_ptr<T>>* params,
-        Params blob) {
-
-    std::vector<C2Param*> paramPointers;
-    if (!parseParamsBlob(&paramPointers, blob)) {
-        LOG(ERROR) << "copyParamsFromBlob -- failed to parse.";
-        return false;
-    }
-
-    params->resize(paramPointers.size());
-    size_t i = 0;
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            LOG(ERROR) << "copyParamsFromBlob -- null paramPointer.";
-            return false;
-        }
-        (*params)[i++].reset(reinterpret_cast<T*>(
-                C2Param::Copy(*paramPointer).release()));
-    }
-    return true;
-}
-
-} // unnamed namespace
-
 // std::vector<const C2Param*> -> Params
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<const C2Param*> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<C2Param*> -> Params
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<C2Param*> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::unique_ptr<C2Param>> -> Params
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::unique_ptr<C2Param>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::unique_ptr<C2Tuning>> -> Params
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::unique_ptr<C2Tuning>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::shared_ptr<const C2Info>> -> Params
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::shared_ptr<const C2Info>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // Params -> std::vector<std::unique_ptr<C2Param>>
-bool copyParamsFromBlob(
+bool CopyParamsFromBlob(
         std::vector<std::unique_ptr<C2Param>>* params,
         Params blob) {
-    return _copyParamsFromBlob(params, blob);
+    return ::android::_copyParamsFromBlob(params, blob);
 }
 
 // Params -> std::vector<std::unique_ptr<C2Tuning>>
-bool copyParamsFromBlob(
+bool CopyParamsFromBlob(
         std::vector<std::unique_ptr<C2Tuning>>* params,
         Params blob) {
-    return _copyParamsFromBlob(params, blob);
+    return ::android::_copyParamsFromBlob(params, blob);
 }
 
 // Params -> update std::vector<std::unique_ptr<C2Param>>
-bool updateParamsFromBlob(
+bool UpdateParamsFromBlob(
         const std::vector<C2Param*>& params,
         const Params& blob) {
-    std::unordered_map<uint32_t, C2Param*> index2param;
-    for (C2Param* const& param : params) {
-        if (!param) {
-            LOG(ERROR) << "updateParamsFromBlob -- null output param.";
-            return false;
-        }
-        if (index2param.find(param->index()) == index2param.end()) {
-            index2param.emplace(param->index(), param);
-        }
-    }
-
-    std::vector<C2Param*> paramPointers;
-    if (!parseParamsBlob(&paramPointers, blob)) {
-        LOG(ERROR) << "updateParamsFromBlob -- failed to parse.";
-        return false;
-    }
-
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            LOG(ERROR) << "updateParamsFromBlob -- null input param.";
-            return false;
-        }
-        decltype(index2param)::iterator i = index2param.find(
-                paramPointer->index());
-        if (i == index2param.end()) {
-            LOG(DEBUG) << "updateParamsFromBlob -- index "
-                       << paramPointer->index() << " not found. Skipping...";
-            continue;
-        }
-        if (!i->second->updateFrom(*paramPointer)) {
-            LOG(ERROR) << "updateParamsFromBlob -- size mismatch: "
-                       << params.size() << " vs " << paramPointer->size()
-                       << " (index = " << i->first << ").";
-            return false;
-        }
-    }
-    return true;
-}
-
-// Convert BufferPool ResultStatus to c2_status_t.
-c2_status_t toC2Status(ResultStatus rs) {
-    switch (rs) {
-    case ResultStatus::OK:
-        return C2_OK;
-    case ResultStatus::NO_MEMORY:
-        return C2_NO_MEMORY;
-    case ResultStatus::ALREADY_EXISTS:
-        return C2_DUPLICATE;
-    case ResultStatus::NOT_FOUND:
-        return C2_NOT_FOUND;
-    case ResultStatus::CRITICAL_ERROR:
-        return C2_CORRUPTED;
-    default:
-        LOG(WARNING) << "Unrecognized BufferPool ResultStatus: "
-                     << static_cast<int32_t>(rs) << ".";
-        return C2_CORRUPTED;
-    }
-}
-
-namespace /* unnamed */ {
-
-template <typename BlockProcessor>
-void forEachBlock(C2FrameData& frameData,
-                  BlockProcessor process) {
-    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
-        if (buffer) {
-            for (const C2ConstGraphicBlock& block :
-                    buffer->data().graphicBlocks()) {
-                process(block);
-            }
-        }
-    }
-}
-
-template <typename BlockProcessor>
-void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
-                  BlockProcessor process,
-                  bool processInput, bool processOutput) {
-    for (const std::unique_ptr<C2Work>& work : workList) {
-        if (!work) {
-            continue;
-        }
-        if (processInput) {
-            forEachBlock(work->input, process);
-        }
-        if (processOutput) {
-            for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
-                if (worklet) {
-                    forEachBlock(worklet->output,
-                                 process);
-                }
-            }
-        }
-    }
-}
-
-} // unnamed namespace
-
-bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::BeginTransferBlockToClient(data);
-        return true;
-    }
-    return false;
-}
-
-void beginTransferBufferQueueBlocks(
-        const std::list<std::unique_ptr<C2Work>>& workList,
-        bool processInput, bool processOutput) {
-    forEachBlock(workList, beginTransferBufferQueueBlock,
-                 processInput, processOutput);
-}
-
-bool endTransferBufferQueueBlock(
-        const C2ConstGraphicBlock& block,
-        bool transfer) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::EndTransferBlockToClient(data, transfer);
-        return true;
-    }
-    return false;
-}
-
-void endTransferBufferQueueBlocks(
-        const std::list<std::unique_ptr<C2Work>>& workList,
-        bool transfer,
-        bool processInput, bool processOutput) {
-    forEachBlock(workList,
-                 std::bind(endTransferBufferQueueBlock,
-                           std::placeholders::_1, transfer),
-                 processInput, processOutput);
-}
-
-bool displayBufferQueueBlock(const C2ConstGraphicBlock& block) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::DisplayBlockToBufferQueue(data);
-        return true;
-    }
-    return false;
+    return ::android::updateParamsFromBlob(params, blob);
 }
 
 }  // namespace utils
-}  // namespace V1_0
 }  // namespace c2
 }  // namespace media
 }  // namespace hardware
 }  // namespace android
-
+}  // namespace aidl
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h b/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h
index f111f81..ff69039 100644
--- a/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h
+++ b/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h
@@ -14,57 +14,29 @@
  * limitations under the License.
  */
 
-#ifndef CODEC2_HIDL_V1_0_UTILS_TYPES_H
-#define CODEC2_HIDL_V1_0_UTILS_TYPES_H
+#ifndef CODEC2_AIDL_UTILS_PARAM_TYPES_H
+#define CODEC2_AIDL_UTILS_PARAM_TYPES_H
 
-#include <bufferpool/ClientManager.h>
-#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
-#include <android/hardware/media/bufferpool/2.0/types.h>
-#include <android/hardware/media/c2/1.0/IComponentStore.h>
-#include <android/hardware/media/c2/1.0/types.h>
-#include <android/hidl/safe_union/1.0/types.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQuery.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.h>
+#include <aidl/android/hardware/media/c2/IComponentStore.h>
+#include <aidl/android/hardware/media/c2/ParamDescriptor.h>
+#include <aidl/android/hardware/media/c2/SettingResult.h>
+#include <aidl/android/hardware/media/c2/Status.h>
+#include <aidl/android/hardware/media/c2/StructDescriptor.h>
 
 #include <C2Component.h>
 #include <C2Param.h>
 #include <C2ParamDef.h>
-#include <C2Work.h>
 #include <util/C2Debug-base.h>
 
-#include <chrono>
-
-using namespace std::chrono_literals;
-
+namespace aidl {
 namespace android {
 namespace hardware {
 namespace media {
 namespace c2 {
-namespace V1_0 {
 namespace utils {
 
-using ::android::hardware::hidl_bitfield;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::status_t;
-using ::android::sp;
-using ::android::hardware::media::bufferpool::V2_0::implementation::
-        ConnectionId;
-
-// Types of metadata for Blocks.
-struct C2Hidl_Range {
-    uint32_t offset;
-    uint32_t length; // Do not use "size" because the name collides with C2Info::size().
-};
-typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo;
-
-struct C2Hidl_Rect {
-    uint32_t left;
-    uint32_t top;
-    uint32_t width;
-    uint32_t height;
-};
-typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo;
-
 // Make asString() and operator<< work with Status as well as c2_status_t.
 C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status);
 
@@ -74,169 +46,66 @@
  */
 
 // C2SettingResult -> SettingResult
-bool objcpy(
+bool ToAidl(
         SettingResult* d,
         const C2SettingResult& s);
 
 // SettingResult -> std::unique_ptr<C2SettingResult>
-bool objcpy(
+bool FromAidl(
         std::unique_ptr<C2SettingResult>* d,
         const SettingResult& s);
 
 // C2ParamDescriptor -> ParamDescriptor
-bool objcpy(
+bool ToAidl(
         ParamDescriptor* d,
         const C2ParamDescriptor& s);
 
 // ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
-bool objcpy(
+bool FromAidl(
         std::shared_ptr<C2ParamDescriptor>* d,
         const ParamDescriptor& s);
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
-bool objcpy(
+bool ToAidl(
         FieldSupportedValuesQuery* d,
         const C2FieldSupportedValuesQuery& s);
 
 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
-bool objcpy(
+bool FromAidl(
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& s);
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
-bool objcpy(
+bool ToAidl(
         FieldSupportedValuesQueryResult* d,
         const C2FieldSupportedValuesQuery& s);
 
 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
-bool objcpy(
+bool FromAidl(
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& sq,
         const FieldSupportedValuesQueryResult& sr);
 
 // C2Component::Traits -> ComponentTraits
-bool objcpy(
+bool ToAidl(
         IComponentStore::ComponentTraits* d,
         const C2Component::Traits& s);
 
 // ComponentTraits -> C2Component::Traits
-bool objcpy(
+bool FromAidl(
         C2Component::Traits* d,
         const IComponentStore::ComponentTraits& s);
 
 // C2StructDescriptor -> StructDescriptor
-bool objcpy(
+bool ToAidl(
         StructDescriptor* d,
         const C2StructDescriptor& s);
 
 // StructDescriptor -> C2StructDescriptor
-bool objcpy(
+bool FromAidl(
         std::unique_ptr<C2StructDescriptor>* d,
         const StructDescriptor& s);
 
-// Abstract class to be used in
-// objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
-struct BufferPoolSender {
-    typedef ::android::hardware::media::bufferpool::V2_0::
-            ResultStatus ResultStatus;
-    typedef ::android::hardware::media::bufferpool::V2_0::
-            BufferStatusMessage BufferStatusMessage;
-    typedef ::android::hardware::media::bufferpool::
-            BufferPoolData BufferPoolData;
-
-    /**
-     * Send bpData and return BufferStatusMessage that can be supplied to
-     * IClientManager::receive() in the receiving process.
-     *
-     * This function will be called from within the function
-     * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
-     *
-     * \param[in] bpData BufferPoolData identifying the buffer to send.
-     * \param[out] bpMessage BufferStatusMessage of the transaction. Information
-     *    inside \p bpMessage should be passed to the receiving process by some
-     *    other means so it can call receive() properly.
-     * \return ResultStatus value that determines the success of the operation.
-     *    (See the possible values of ResultStatus in
-     *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
-     */
-    virtual ResultStatus send(
-            const std::shared_ptr<BufferPoolData>& bpData,
-            BufferStatusMessage* bpMessage) = 0;
-
-    virtual ~BufferPoolSender() = default;
-};
-
-// Default implementation of BufferPoolSender.
-//
-// To use DefaultBufferPoolSender, the IClientManager instance of the receiving
-// process must be set before send() can operate. DefaultBufferPoolSender will
-// hold a strong reference to the IClientManager instance and use it to call
-// IClientManager::registerSender() to establish the bufferpool connection when
-// send() is called.
-struct DefaultBufferPoolSender : BufferPoolSender {
-    typedef ::android::hardware::media::bufferpool::V2_0::implementation::
-            ClientManager ClientManager;
-    typedef ::android::hardware::media::bufferpool::V2_0::
-            IClientManager IClientManager;
-
-    // Set the IClientManager instance of the receiving process and the refresh
-    // interval for the connection. The default interval is 4.5 seconds, which
-    // is slightly shorter than the amount of time the bufferpool will keep an
-    // inactive connection for.
-    DefaultBufferPoolSender(
-            const sp<IClientManager>& receiverManager = nullptr,
-            std::chrono::steady_clock::duration refreshInterval = 4500ms);
-
-    // Set the IClientManager instance of the receiving process and the refresh
-    // interval for the connection. The default interval is 4.5 seconds, which
-    // is slightly shorter than the amount of time the bufferpool will keep an
-    // inactive connection for.
-    void setReceiver(
-            const sp<IClientManager>& receiverManager,
-            std::chrono::steady_clock::duration refreshInterval = 4500ms);
-
-    // Implementation of BufferPoolSender::send(). send() will establish a
-    // bufferpool connection if needed, then send the bufferpool data over to
-    // the receiving process.
-    virtual ResultStatus send(
-            const std::shared_ptr<BufferPoolData>& bpData,
-            BufferStatusMessage* bpMessage) override;
-
-private:
-    std::mutex mMutex;
-    sp<ClientManager> mSenderManager;
-    sp<IClientManager> mReceiverManager;
-    std::chrono::steady_clock::duration mRefreshInterval;
-
-    struct Connection {
-        int64_t receiverConnectionId;
-        std::chrono::steady_clock::time_point lastSent;
-        Connection(int64_t receiverConnectionId,
-                   std::chrono::steady_clock::time_point lastSent)
-              : receiverConnectionId(receiverConnectionId),
-                lastSent(lastSent) {
-        }
-    };
-
-    // Map of connections.
-    //
-    // The key is the connection id. One sender-receiver pair may have multiple
-    // connections.
-    std::map<int64_t, Connection> mConnections;
-};
-
-// std::list<std::unique_ptr<C2Work>> -> WorkBundle
-// Note: If bufferpool will be used, bpSender must not be null.
-bool objcpy(
-        WorkBundle* d,
-        const std::list<std::unique_ptr<C2Work>>& s,
-        BufferPoolSender* bpSender = nullptr);
-
-// WorkBundle -> std::list<std::unique_ptr<C2Work>>
-bool objcpy(
-        std::list<std::unique_ptr<C2Work>>* d,
-        const WorkBundle& s);
-
 /**
  * Parses a params blob and returns C2Param pointers to its params. The pointers
  * point to locations inside the underlying buffer of \p blob. If \p blob is
@@ -247,9 +116,9 @@
  * \retval true if the full blob was parsed
  * \retval false otherwise
  */
-bool parseParamsBlob(
+bool ParseParamsBlob(
         std::vector<C2Param*> *params,
-        const hidl_vec<uint8_t> &blob);
+        const Params &blob);
 
 /**
  * Concatenates a list of C2Params into a params blob.
@@ -260,17 +129,17 @@
  * \retval false if the blob was not successful (this only happens if the
  *         parameters were not const)
  */
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<C2Param*> &params);
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::unique_ptr<C2Param>> &params);
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::shared_ptr<const C2Info>> &params);
-bool createParamsBlob(
-        hidl_vec<uint8_t> *blob,
+bool CreateParamsBlob(
+        Params *blob,
         const std::vector<std::unique_ptr<C2Tuning>> &params);
 
 /**
@@ -282,12 +151,12 @@
  * \retval true if the full blob was parsed and params was constructed
  * \retval false otherwise
  */
-bool copyParamsFromBlob(
+bool CopyParamsFromBlob(
         std::vector<std::unique_ptr<C2Param>>* params,
-        Params blob);
-bool copyParamsFromBlob(
+        const Params &blob);
+bool CopyParamsFromBlob(
         std::vector<std::unique_ptr<C2Tuning>>* params,
-        Params blob);
+        const Params &blob);
 
 /**
  * Parses a params blob and applies updates to params.
@@ -297,67 +166,15 @@
  * \retval true if the full blob was parsed and params was updated
  * \retval false otherwise
  */
-bool updateParamsFromBlob(
+bool UpdateParamsFromBlob(
         const std::vector<C2Param*>& params,
         const Params& blob);
 
-/**
- * Converts a BufferPool status value to c2_status_t.
- * \param BufferPool status
- * \return Corresponding c2_status_t
- */
-c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0::
-        ResultStatus rs);
-
-// BufferQueue-Based Block Operations
-// ==================================
-
-// Call before transferring block to other processes.
-//
-// The given block is ready to transfer to other processes. This will guarantee
-// the given block data is not mutated by bufferqueue migration.
-bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
-
-// Call beginTransferBufferQueueBlock() on blocks in the given workList.
-// processInput determines whether input blocks are yielded. processOutput
-// works similarly on output blocks. (The default value of processInput is
-// false while the default value of processOutput is true. This implies that in
-// most cases, only output buffers contain bufferqueue-based blocks.)
-void beginTransferBufferQueueBlocks(
-        const std::list<std::unique_ptr<C2Work>>& workList,
-        bool processInput = false,
-        bool processOutput = true);
-
-// Call after transferring block is finished and make sure that
-// beginTransferBufferQueueBlock() is called before.
-//
-// The transfer of given block is finished. If transfer is successful the given
-// block is not owned by process anymore. Since transfer is finished the given
-// block data is OK to mutate by bufferqueue migration after this call.
-bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
-                                 bool transfer);
-
-// Call endTransferBufferQueueBlock() on blocks in the given workList.
-// processInput determines whether input blocks are yielded. processOutput
-// works similarly on output blocks. (The default value of processInput is
-// false while the default value of processOutput is true. This implies that in
-// most cases, only output buffers contain bufferqueue-based blocks.)
-void endTransferBufferQueueBlocks(
-        const std::list<std::unique_ptr<C2Work>>& workList,
-        bool transfer,
-        bool processInput = false,
-        bool processOutput = true);
-
-// The given block is ready to be rendered. the given block is not owned by
-// process anymore. If migration is in progress, this returns false in order
-// not to render.
-bool displayBufferQueueBlock(const C2ConstGraphicBlock& block);
-
 }  // namespace utils
-}  // namespace V1_0
 }  // namespace c2
 }  // namespace media
 }  // namespace hardware
 }  // namespace android
+}  // namespace aidl
 
-#endif  // CODEC2_HIDL_V1_0_UTILS_TYPES_H
+#endif  // CODEC2_AIDL_UTILS_PARAM_TYPES_H
