diff --git a/media/codec2/hidl/plugin/Android.bp b/media/codec2/hidl/plugin/Android.bp
new file mode 100644
index 0000000..4708b12
--- /dev/null
+++ b/media/codec2/hidl/plugin/Android.bp
@@ -0,0 +1,66 @@
+cc_library_headers {
+    name: "libcodec2_hidl_plugin_headers",
+    vendor_available: true,
+    export_include_dirs: [
+        "include",
+    ],
+}
+
+cc_library {
+    name: "libcodec2_hidl_plugin_stub",
+
+    srcs: [
+        "DefaultFilterPlugin.cpp",
+        "FilterWrapperStub.cpp",
+    ],
+
+    header_libs: [
+        "libcodec2_internal", // private
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "liblog",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+        "internal",
+    ],
+
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+}
+
+cc_library {
+    name: "libcodec2_hidl_plugin",
+    vendor: true,
+
+    srcs: [
+        "DefaultFilterPlugin.cpp",
+        "FilterWrapper.cpp",
+    ],
+
+    header_libs: [
+        "libcodec2_internal", // private
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "liblog",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+        "internal",
+    ],
+}
diff --git a/media/codec2/hidl/plugin/DefaultFilterPlugin.cpp b/media/codec2/hidl/plugin/DefaultFilterPlugin.cpp
new file mode 100644
index 0000000..cd1bcb0
--- /dev/null
+++ b/media/codec2/hidl/plugin/DefaultFilterPlugin.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2020 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-DefaultFilterPlugin"
+#include <android-base/logging.h>
+
+#include <set>
+
+#include <dlfcn.h>
+
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+
+#include <codec2/hidl/plugin/FilterPlugin.h>
+
+#include <DefaultFilterPlugin.h>
+#include <FilterWrapper.h>
+
+namespace android {
+
+DefaultFilterPlugin::DefaultFilterPlugin(const char *pluginPath)
+    : mInit(NO_INIT),
+      mHandle(nullptr),
+      mDestroyPlugin(nullptr),
+      mPlugin(nullptr) {
+    mHandle = dlopen(pluginPath, RTLD_NOW | RTLD_NODELETE);
+    if (!mHandle) {
+        LOG(DEBUG) << "FilterPlugin: no plugin detected";
+        return;
+    }
+    GetFilterPluginVersionFunc getVersion =
+        (GetFilterPluginVersionFunc)dlsym(mHandle, "GetFilterPluginVersion");
+    if (!getVersion) {
+        LOG(WARNING) << "FilterPlugin: GetFilterPluginVersion undefined";
+        return;
+    }
+    int32_t version = getVersion();
+    if (version != FilterPlugin_V1::VERSION) {
+        LOG(WARNING) << "FilterPlugin: unrecognized version (" << version << ")";
+        return;
+    }
+    CreateFilterPluginFunc createPlugin =
+        (CreateFilterPluginFunc)dlsym(mHandle, "CreateFilterPlugin");
+    if (!createPlugin) {
+        LOG(WARNING) << "FilterPlugin: CreateFilterPlugin undefined";
+        return;
+    }
+    mDestroyPlugin =
+        (DestroyFilterPluginFunc)dlsym(mHandle, "DestroyFilterPlugin");
+    if (!mDestroyPlugin) {
+        LOG(WARNING) << "FilterPlugin: DestroyFilterPlugin undefined";
+        return;
+    }
+    mPlugin = (FilterPlugin_V1 *)createPlugin();
+    if (!mPlugin) {
+        LOG(WARNING) << "FilterPlugin: CreateFilterPlugin returned nullptr";
+        return;
+    }
+    mStore = mPlugin->getComponentStore();
+    if (!mStore) {
+        LOG(WARNING) << "FilterPlugin: FilterPlugin_V1::getComponentStore returned nullptr";
+        return;
+    }
+    mInit = OK;
+}
+
+DefaultFilterPlugin::~DefaultFilterPlugin() {
+    if (mHandle) {
+        if (mDestroyPlugin && mPlugin) {
+            mDestroyPlugin(mPlugin);
+            mPlugin = nullptr;
+        }
+        dlclose(mHandle);
+        mHandle = nullptr;
+        mDestroyPlugin = nullptr;
+    }
+}
+
+bool DefaultFilterPlugin::describe(C2String name, FilterWrapper::Descriptor *desc) {
+    if (mInit != OK) {
+        return false;
+    }
+    return mPlugin->describe(name, desc);
+}
+
+bool DefaultFilterPlugin::isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf) {
+    if (mInit != OK) {
+        return false;
+    }
+    return mPlugin->isFilteringEnabled(intf);
+}
+
+}  // namespace android
diff --git a/media/codec2/hidl/plugin/FilterWrapper.cpp b/media/codec2/hidl/plugin/FilterWrapper.cpp
new file mode 100644
index 0000000..0b38bc1
--- /dev/null
+++ b/media/codec2/hidl/plugin/FilterWrapper.cpp
@@ -0,0 +1,921 @@
+/*
+ * Copyright 2020 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-FilterWrapper"
+#include <android-base/logging.h>
+
+#include <set>
+#include <sstream>
+
+#include <dlfcn.h>
+
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+
+#include <codec2/hidl/plugin/FilterPlugin.h>
+
+#include <FilterWrapper.h>
+
+namespace android {
+
+namespace {
+
+// Indices that the last filter in the chain should consume.
+static constexpr uint32_t kTypesForLastFilter[] = {
+    // In case we have an output surface, we want to use the block pool
+    // backed by the output surface for the output buffer going to the client.
+    C2PortBlockPoolsTuning::output::PARAM_TYPE,
+};
+
+class WrappedDecoderInterface : public C2ComponentInterface {
+public:
+    WrappedDecoderInterface(
+            std::shared_ptr<C2ComponentInterface> intf,
+            std::vector<FilterWrapper::Component> &&filters)
+        : mIntf(intf) {
+        takeFilters(std::move(filters));
+    }
+
+    ~WrappedDecoderInterface() override = default;
+
+    void takeFilters(std::vector<FilterWrapper::Component> &&filters) {
+        std::unique_lock lock(mMutex);
+        std::vector<std::unique_ptr<C2Param>> lastFilterParams;
+        if (!mFilters.empty()) {
+            std::vector<C2Param::Index> indices;
+            std::vector<std::shared_ptr<C2ParamDescriptor>> paramDescs;
+            c2_status_t err = mFilters.back().intf->querySupportedParams_nb(&paramDescs);
+            if (err != C2_OK) {
+                LOG(WARNING) << "WrappedDecoderInterface: " << mFilters.back().traits.name
+                        << " returned error for querySupportedParams_nb; err=" << err;
+                paramDescs.clear();
+            }
+            for (const std::shared_ptr<C2ParamDescriptor> &paramDesc : paramDescs) {
+                C2Param::Index index = paramDesc->index();
+                if (std::count(
+                            std::begin(kTypesForLastFilter),
+                            std::end(kTypesForLastFilter),
+                            index.type()) != 0) {
+                    if (index.forStream()) {
+                        // querySupportedParams does not return per-stream params.
+                        // We only support stream-0 for now.
+                        index = index.withStream(0u);
+                    }
+                    indices.push_back(index);
+                }
+            }
+            if (!indices.empty()) {
+                mFilters.back().intf->query_vb({}, indices, C2_MAY_BLOCK, &lastFilterParams);
+            }
+        }
+
+        // TODO: documentation
+        mFilters = std::move(filters);
+        mTypeToIndexForQuery.clear();
+        mTypeToIndexForConfig.clear();
+        for (size_t i = 0; i < mFilters.size(); ++i) {
+            if (i == 0) {
+                transferParams_l(mIntf, mFilters[0].intf, C2_MAY_BLOCK);
+            } else {
+                transferParams_l(mFilters[i - 1].intf, mFilters[i].intf, C2_MAY_BLOCK);
+            }
+            for (C2Param::Type type : mFilters[i].desc.controlParams) {
+                mTypeToIndexForQuery[type.type()] = i;
+                mTypeToIndexForConfig[type.type() & ~C2Param::CoreIndex::IS_REQUEST_FLAG] = i;
+            }
+            for (C2Param::Type type : mFilters[i].desc.affectedParams) {
+                mTypeToIndexForQuery[type.type()] = i;
+            }
+        }
+        if (!mFilters.empty()) {
+            for (uint32_t type : kTypesForLastFilter) {
+                mTypeToIndexForQuery[type] = mFilters.size() - 1;
+                mTypeToIndexForConfig[type & ~C2Param::CoreIndex::IS_REQUEST_FLAG] =
+                    mFilters.size() - 1;
+            }
+            if (!lastFilterParams.empty()) {
+                std::vector<C2Param *> paramPtrs(lastFilterParams.size());
+                std::transform(
+                        lastFilterParams.begin(),
+                        lastFilterParams.end(),
+                        paramPtrs.begin(),
+                        [](const std::unique_ptr<C2Param> &param) {
+                            return param.get();
+                        });
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                mFilters.back().intf->config_vb(paramPtrs, C2_MAY_BLOCK, &failures);
+            }
+        }
+    }
+
+    C2String getName() const override { return mIntf->getName(); }
+
+    c2_node_id_t getId() const override { return mIntf->getId(); }
+
+    c2_status_t query_vb(
+            const std::vector<C2Param *> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
+        std::unique_lock lock(mMutex);
+        std::list<C2Param *> stackParamsList(stackParams.size());
+        std::copy_n(stackParams.begin(), stackParams.size(), stackParamsList.begin());
+        heapParams->clear();
+        c2_status_t result = C2_OK;
+        // TODO: loop optimization
+        for (size_t i = 0; i < mFilters.size(); ++i) {
+            // Filter stack params according to mTypeToIndexForQuery
+            std::vector<C2Param *> stackParamsForFilter;
+            for (auto it = stackParamsList.begin(); it != stackParamsList.end(); ) {
+                C2Param *param = *it;
+                uint32_t type = param->type().type();
+                auto it2 = mTypeToIndexForQuery.find(type);
+                if (it2 == mTypeToIndexForQuery.end() || it2->second != i) {
+                    ++it;
+                    continue;
+                }
+                stackParamsForFilter.push_back(param);
+                it = stackParamsList.erase(it);
+            }
+            // Filter heap params according to mTypeToIndexForQuery
+            std::vector<C2Param::Index> heapParamIndicesForFilter;
+            for (size_t j = 0; j < heapParamIndices.size(); ++j) {
+                uint32_t type = heapParamIndices[j].type();
+                auto it = mTypeToIndexForQuery.find(type);
+                if (it == mTypeToIndexForQuery.end() || it->second != i) {
+                    continue;
+                }
+                heapParamIndicesForFilter.push_back(heapParamIndices[j]);
+            }
+            std::vector<std::unique_ptr<C2Param>> heapParamsForFilter;
+            const std::shared_ptr<C2ComponentInterface> &filter = mFilters[i].intf;
+            c2_status_t err = filter->query_vb(
+                    stackParamsForFilter, heapParamIndicesForFilter, mayBlock,
+                    &heapParamsForFilter);
+            if (err != C2_OK && err != C2_BAD_INDEX) {
+                LOG(WARNING) << "WrappedDecoderInterface: " << filter->getName()
+                        << " returned error for query_vb; err=" << err;
+                result = err;
+                continue;
+            }
+            heapParams->insert(
+                    heapParams->end(),
+                    std::make_move_iterator(heapParamsForFilter.begin()),
+                    std::make_move_iterator(heapParamsForFilter.end()));
+        }
+
+        std::vector<C2Param *> stackParamsForIntf;
+        std::copy_n(stackParamsList.begin(), stackParamsList.size(), stackParamsForIntf.begin());
+
+        // Gather heap params that did not get queried from the filter interfaces above.
+        // These need to be queried from the decoder interface.
+        std::vector<C2Param::Index> heapParamIndicesForIntf;
+        for (size_t j = 0; j < heapParamIndices.size(); ++j) {
+            uint32_t type = heapParamIndices[j].type();
+            if (mTypeToIndexForQuery.find(type) != mTypeToIndexForQuery.end()) {
+                continue;
+            }
+            heapParamIndicesForIntf.push_back(heapParamIndices[j]);
+        }
+
+        std::vector<std::unique_ptr<C2Param>> heapParamsForIntf;
+        c2_status_t err = mIntf->query_vb(
+                stackParamsForIntf, heapParamIndicesForIntf, mayBlock, &heapParamsForIntf);
+        if (err != C2_OK) {
+            LOG(err == C2_BAD_INDEX ? VERBOSE : WARNING)
+                    << "WrappedDecoderInterface: " << mIntf->getName()
+                    << " returned error for query_vb; err=" << err;
+            result = err;
+        }
+
+        // TODO: params needs to preserve the order
+        heapParams->insert(
+                heapParams->end(),
+                std::make_move_iterator(heapParamsForIntf.begin()),
+                std::make_move_iterator(heapParamsForIntf.end()));
+
+        return result;
+    }
+
+    c2_status_t config_vb(
+            const std::vector<C2Param *> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
+        std::unique_lock lock(mMutex);
+        c2_status_t result = C2_OK;
+        std::vector<C2Param *> paramsForIntf;
+        for (C2Param* param : params) {
+            auto it = mTypeToIndexForConfig.find(param->type().type());
+            if (it != mTypeToIndexForConfig.end()) {
+                continue;
+            }
+            paramsForIntf.push_back(param);
+        }
+        c2_status_t err = mIntf->config_vb(paramsForIntf, mayBlock, failures);
+        if (err != C2_OK) {
+            LOG(err == C2_BAD_INDEX ? VERBOSE : WARNING)
+                    << "WrappedDecoderInterface: " << mIntf->getName()
+                    << " returned error for config_vb; err=" << err;
+            result = err;
+        }
+        for (size_t i = 0; i < mFilters.size(); ++i) {
+            if (i == 0) {
+                transferParams_l(mIntf, mFilters[0].intf, mayBlock);
+            } else {
+                transferParams_l(mFilters[i - 1].intf, mFilters[i].intf, mayBlock);
+            }
+            const std::shared_ptr<C2ComponentInterface> &filter = mFilters[i].intf;
+            std::vector<std::unique_ptr<C2SettingResult>> filterFailures;
+            std::vector<C2Param *> paramsForFilter;
+            for (C2Param* param : params) {
+                auto it = mTypeToIndexForConfig.find(param->type().type());
+                if (it != mTypeToIndexForConfig.end() && it->second != i) {
+                    continue;
+                }
+                paramsForFilter.push_back(param);
+            }
+            c2_status_t err = filter->config_vb(paramsForFilter, mayBlock, &filterFailures);
+            if (err != C2_OK) {
+                LOG(err == C2_BAD_INDEX ? VERBOSE : WARNING)
+                        << "WrappedDecoderInterface: " << filter->getName()
+                        << " returned error for config_vb; err=" << err;
+                result = err;
+            }
+        }
+
+        return result;
+    }
+
+    c2_status_t createTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
+    c2_status_t releaseTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
+
+    c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override {
+        std::unique_lock lock(mMutex);
+        c2_status_t result = mIntf->querySupportedParams_nb(params);
+        if (result != C2_OK) {
+            LOG(WARNING) << "WrappedDecoderInterface: " << mIntf->getName()
+                    << " returned error for querySupportedParams_nb; err=" << result;
+            return result;
+        }
+        // TODO: optimization idea --- pre-compute at takeFilter().
+        for (const FilterWrapper::Component &filter : mFilters) {
+            std::vector<std::shared_ptr<C2ParamDescriptor>> filterParams;
+            c2_status_t err = filter.intf->querySupportedParams_nb(&filterParams);
+            if (err != C2_OK) {
+                LOG(WARNING) << "WrappedDecoderInterface: " << filter.intf->getName()
+                        << " returned error for querySupportedParams_nb; err=" << result;
+                result = err;
+                continue;
+            }
+            for (const std::shared_ptr<C2ParamDescriptor> &paramDesc : filterParams) {
+                if (std::count(
+                        filter.desc.controlParams.begin(),
+                        filter.desc.controlParams.end(),
+                        paramDesc->index().type()) == 0) {
+                    continue;
+                }
+                params->push_back(paramDesc);
+            }
+        }
+        return result;
+    }
+
+    c2_status_t querySupportedValues_vb(
+            std::vector<C2FieldSupportedValuesQuery> &fields,
+            c2_blocking_t mayBlock) const override {
+        std::unique_lock lock(mMutex);
+        c2_status_t result = mIntf->querySupportedValues_vb(fields, mayBlock);
+        if (result != C2_OK && result != C2_BAD_INDEX) {
+            LOG(WARNING) << "WrappedDecoderInterface: " << mIntf->getName()
+                    << " returned error for querySupportedParams_nb; err=" << result;
+            return result;
+        }
+        for (const FilterWrapper::Component &filter : mFilters) {
+            std::vector<C2FieldSupportedValuesQuery> filterFields;
+            std::vector<size_t> indices;
+            for (size_t i = 0; i < fields.size(); ++i) {
+                const C2FieldSupportedValuesQuery &field = fields[i];
+                uint32_t type = C2Param::Index(_C2ParamInspector::GetIndex(field.field())).type();
+                if (std::count(
+                        filter.desc.controlParams.begin(),
+                        filter.desc.controlParams.end(),
+                        type) == 0) {
+                    continue;
+                }
+                filterFields.push_back(field);
+                indices.push_back(i);
+            }
+            c2_status_t err = filter.intf->querySupportedValues_vb(filterFields, mayBlock);
+            if (err != C2_OK && err != C2_BAD_INDEX) {
+                LOG(WARNING) << "WrappedDecoderInterface: " << filter.intf->getName()
+                        << " returned error for querySupportedParams_nb; err=" << result;
+                result = err;
+                continue;
+            }
+            for (size_t i = 0; i < filterFields.size(); ++i) {
+                fields[indices[i]] = filterFields[i];
+            }
+        }
+        return result;
+    }
+
+private:
+    mutable std::mutex mMutex;
+    std::shared_ptr<C2ComponentInterface> mIntf;
+    std::vector<FilterWrapper::Component> mFilters;
+    std::map<uint32_t, size_t> mTypeToIndexForQuery;
+    std::map<uint32_t, size_t> mTypeToIndexForConfig;
+
+    c2_status_t transferParams_l(
+            const std::shared_ptr<C2ComponentInterface> &curr,
+            const std::shared_ptr<C2ComponentInterface> &next,
+            c2_blocking_t mayBlock) {
+        // NOTE: this implementation is preliminary --- it could change once
+        // we define what parameters needs to be propagated in component chaining.
+        std::vector<std::shared_ptr<C2ParamDescriptor>> paramDescs;
+        c2_status_t err = next->querySupportedParams_nb(&paramDescs);
+        if (err != C2_OK) {
+            LOG(DEBUG) << "WrappedDecoderInterface: " << next->getName()
+                    << " returned error for querySupportedParams_nb; err=" << err;
+            return err;
+        }
+        // Find supported input params from the next interface and flip direction
+        // so they become output params.
+        std::vector<C2Param::Index> indices;
+        for (const std::shared_ptr<C2ParamDescriptor> &paramDesc : paramDescs) {
+            C2Param::Index index = paramDesc->index();
+            if (!index.forInput() || paramDesc->isReadOnly()) {
+                continue;
+            }
+            if (index.forStream()) {
+                uint32_t stream = index.stream();
+                index = index.withPort(true /* output */).withStream(stream);
+            } else {
+                index = index.withPort(true /* output */);
+            }
+            indices.push_back(index);
+        }
+        // Query those output params from the current interface
+        std::vector<std::unique_ptr<C2Param>> heapParams;
+        err = curr->query_vb({}, indices, mayBlock, &heapParams);
+        if (err != C2_OK && err != C2_BAD_INDEX) {
+            LOG(DEBUG) << "WrappedDecoderInterface: " << curr->getName()
+                    << " returned error for query_vb; err=" << err;
+            return err;
+        }
+        // Flip the direction of the queried params, so they become input parameters.
+        // Configure the next interface with the params.
+        std::vector<C2Param *> configParams;
+        for (size_t i = 0; i < heapParams.size(); ++i) {
+            if (heapParams[i]->forStream()) {
+                heapParams[i] = C2Param::CopyAsStream(
+                        *heapParams[i], false /* output */, heapParams[i]->stream());
+            } else {
+                heapParams[i] = C2Param::CopyAsPort(*heapParams[i], false /* output */);
+            }
+            configParams.push_back(heapParams[i].get());
+        }
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        err = next->config_vb(configParams, mayBlock, &failures);
+        if (err != C2_OK && err != C2_BAD_INDEX) {
+            LOG(DEBUG) << "WrappedDecoderInterface: " << next->getName()
+                    << " returned error for config_vb; err=" << err;
+            return err;
+        }
+        return C2_OK;
+    }
+};
+
+class WrappedDecoder : public C2Component, public std::enable_shared_from_this<WrappedDecoder> {
+public:
+    WrappedDecoder(
+            std::shared_ptr<C2Component> comp,
+            std::vector<FilterWrapper::Component> &&filters,
+            std::weak_ptr<FilterWrapper> filterWrapper)
+        : mComp(comp), mFilters(std::move(filters)), mFilterWrapper(filterWrapper) {
+        std::vector<FilterWrapper::Component> filtersDup(mFilters);
+        mIntf = std::make_shared<WrappedDecoderInterface>(
+                comp->intf(), std::move(filtersDup));
+    }
+
+    ~WrappedDecoder() override = default;
+
+    std::shared_ptr<C2ComponentInterface> intf() override { return mIntf; }
+
+    c2_status_t setListener_vb(
+            const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override {
+        if (listener) {
+            setListenerInternal(mFilters, listener, mayBlock);
+        } else {
+            mComp->setListener_vb(nullptr, mayBlock);
+            for (FilterWrapper::Component &filter : mFilters) {
+                filter.comp->setListener_vb(nullptr, mayBlock);
+            }
+        }
+        mListener = listener;
+        return C2_OK;
+    }
+
+    c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override {
+        return mComp->queue_nb(items);
+    }
+
+    c2_status_t announce_nb(const std::vector<C2WorkOutline> &) override {
+        return C2_OMITTED;
+    }
+
+    c2_status_t flush_sm(
+            flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override {
+        c2_status_t result = mComp->flush_sm(mode, flushedWork);
+        std::list<std::unique_ptr<C2Work>> filterFlushedWork;
+        for (FilterWrapper::Component filter : mRunningFilters) {
+            c2_status_t err = filter.comp->flush_sm(mode, &filterFlushedWork);
+            if (err != C2_OK) {
+                result = err;
+            }
+            flushedWork->splice(flushedWork->end(), filterFlushedWork);
+        }
+        return result;
+    }
+
+    c2_status_t drain_nb(drain_mode_t mode) override {
+        // TODO: simplify using comp->drain_nb(mode)
+        switch (mode) {
+        case DRAIN_COMPONENT_WITH_EOS: {
+            std::unique_ptr<C2Work> eosWork{new C2Work};
+            eosWork->input.flags = C2FrameData::FLAG_END_OF_STREAM;
+            eosWork->worklets.push_back(std::make_unique<C2Worklet>());
+            std::list<std::unique_ptr<C2Work>> items;
+            items.push_back(std::move(eosWork));
+            mComp->queue_nb(&items);
+            return C2_OK;
+        }
+        case DRAIN_COMPONENT_NO_EOS:
+        case DRAIN_CHAIN:
+        default:
+            return C2_BAD_VALUE;
+        }
+    }
+
+    c2_status_t start() override {
+        std::vector<FilterWrapper::Component> filters;
+        if (std::shared_ptr<FilterWrapper> filterWrapper = mFilterWrapper.lock()) {
+            // Let's check if we have filters that we can skip
+            for (FilterWrapper::Component &filter : mFilters) {
+                if (!filterWrapper->isFilteringEnabled(filter.intf)) {
+                    LOG(VERBOSE) << "filtering disabled for " << filter.traits.name;
+                    continue;
+                }
+                LOG(VERBOSE) << "filtering enabled for " << filter.traits.name;
+                filters.push_back(filter);
+            }
+            if (filters.size() < mFilters.size()) {
+                LOG(VERBOSE) << (mFilters.size() - filters.size()) << " filter(s) skipped";
+                setListenerInternal(filters, mListener, C2_MAY_BLOCK);
+                std::vector filtersCopy(filters);
+                mIntf->takeFilters(std::move(filtersCopy));
+            }
+        }
+
+        c2_status_t err = mComp->start();
+        if (err != C2_OK) {
+            return err;
+        }
+        for (FilterWrapper::Component &filter : filters) {
+            c2_status_t err = filter.comp->start();
+            if (err != C2_OK) {
+                // Previous components are already started successfully;
+                // we ended up in an incoherent state.
+                return C2_CORRUPTED;
+            }
+        }
+        mRunningFilters = std::move(filters);
+        return C2_OK;
+    }
+
+    c2_status_t stop() override {
+        c2_status_t err = mComp->stop();
+        if (err != C2_OK) {
+            return err;
+        }
+        for (FilterWrapper::Component filter : mRunningFilters) {
+            c2_status_t err = filter.comp->stop();
+            if (err != C2_OK) {
+                // Previous components are already stopped successfully;
+                // we ended up in an incoherent state.
+                return C2_CORRUPTED;
+            }
+        }
+        mRunningFilters.clear();
+        return C2_OK;
+    }
+
+    c2_status_t reset() override {
+        c2_status_t result = mComp->reset();
+        if (result != C2_OK) {
+            result = C2_CORRUPTED;
+        }
+        for (FilterWrapper::Component filter : mFilters) {
+            c2_status_t err = filter.comp->reset();
+            if (err != C2_OK) {
+                // Previous components are already reset successfully;
+                // we ended up in an incoherent state.
+                result = C2_CORRUPTED;
+                // continue for the rest of the chain
+            }
+        }
+        mRunningFilters.clear();
+        return result;
+    }
+
+    c2_status_t release() override {
+        c2_status_t result = mComp->release();
+        if (result != C2_OK) {
+            result = C2_CORRUPTED;
+        }
+        for (FilterWrapper::Component filter : mFilters) {
+            c2_status_t err = filter.comp->release();
+            if (err != C2_OK) {
+                // Previous components are already released successfully;
+                // we ended up in an incoherent state.
+                result = C2_CORRUPTED;
+                // continue for the rest of the chain
+            }
+        }
+        mRunningFilters.clear();
+        return result;
+    }
+
+private:
+    class PassingListener : public Listener {
+    public:
+        PassingListener(
+                std::shared_ptr<C2Component> wrappedComponent,
+                const std::shared_ptr<Listener> &wrappedComponentListener,
+                std::shared_ptr<C2Component> nextComponent)
+            : mWrappedComponent(wrappedComponent),
+              mWrappedComponentListener(wrappedComponentListener),
+              mNextComponent(nextComponent) {
+        }
+
+        void onWorkDone_nb(
+                std::weak_ptr<C2Component>,
+                std::list<std::unique_ptr<C2Work>> workItems) override {
+            std::shared_ptr<C2Component> nextComponent = mNextComponent.lock();
+            std::list<std::unique_ptr<C2Work>> failedWorkItems;
+            if (!nextComponent) {
+                for (std::unique_ptr<C2Work> &work : workItems) {
+                    // Next component unexpectedly released while the work is
+                    // in-flight. Report C2_CORRUPTED to the client.
+                    work->result = C2_CORRUPTED;
+                    failedWorkItems.push_back(std::move(work));
+                }
+                workItems.clear();
+            } else {
+                for (auto it = workItems.begin(); it != workItems.end(); ) {
+                    const std::unique_ptr<C2Work> &work = *it;
+                    if (work->result != C2_OK
+                            || work->worklets.size() != 1) {
+                        failedWorkItems.push_back(std::move(*it));
+                        it = workItems.erase(it);
+                        continue;
+                    }
+                    C2FrameData &output = work->worklets.front()->output;
+                    c2_cntr64_t customOrdinal = work->input.ordinal.customOrdinal;
+                    work->input = std::move(output);
+                    work->input.ordinal.customOrdinal = customOrdinal;
+                    output.flags = C2FrameData::flags_t(0);
+                    output.buffers.clear();
+                    output.configUpdate.clear();
+                    output.infoBuffers.clear();
+                    ++it;
+                }
+            }
+            if (!failedWorkItems.empty()) {
+                for (const std::unique_ptr<C2Work> &work : failedWorkItems) {
+                    LOG(VERBOSE) << "work #" << work->input.ordinal.frameIndex.peek()
+                            << " failed: err=" << work->result
+                            << " worklets.size()=" << work->worklets.size();
+                }
+                if (std::shared_ptr<Listener> wrappedComponentListener =
+                        mWrappedComponentListener.lock()) {
+                    wrappedComponentListener->onWorkDone_nb(
+                            mWrappedComponent, std::move(failedWorkItems));
+                }
+            }
+            if (!workItems.empty()) {
+                nextComponent->queue_nb(&workItems);
+            }
+        }
+
+        void onTripped_nb(
+                std::weak_ptr<C2Component>,
+                std::vector<std::shared_ptr<C2SettingResult>>) override {
+            // Trip not supported
+        }
+
+        void onError_nb(std::weak_ptr<C2Component>, uint32_t errorCode) {
+            if (std::shared_ptr<Listener> wrappedComponentListener =
+                    mWrappedComponentListener.lock()) {
+                wrappedComponentListener->onError_nb(mWrappedComponent, errorCode);
+            }
+        }
+
+    private:
+        std::weak_ptr<C2Component> mWrappedComponent;
+        std::weak_ptr<Listener> mWrappedComponentListener;
+        std::weak_ptr<C2Component> mNextComponent;
+    };
+
+    class LastListener : public Listener {
+    public:
+        LastListener(
+                std::shared_ptr<C2Component> wrappedComponent,
+                const std::shared_ptr<Listener> &wrappedComponentListener)
+            : mWrappedComponent(wrappedComponent),
+              mWrappedComponentListener(wrappedComponentListener) {
+        }
+
+        void onWorkDone_nb(
+                std::weak_ptr<C2Component>,
+                std::list<std::unique_ptr<C2Work>> workItems) override {
+            if (mWrappedComponent.expired()) {
+                return;
+            }
+            if (std::shared_ptr<Listener> wrappedComponentListener =
+                    mWrappedComponentListener.lock()) {
+                wrappedComponentListener->onWorkDone_nb(
+                        mWrappedComponent, std::move(workItems));
+            }
+        }
+
+        void onTripped_nb(
+                std::weak_ptr<C2Component>,
+                std::vector<std::shared_ptr<C2SettingResult>>) override {
+            // Trip not supported
+        }
+
+        void onError_nb(std::weak_ptr<C2Component>, uint32_t errorCode) {
+            if (mWrappedComponent.expired()) {
+                return;
+            }
+            if (std::shared_ptr<Listener> wrappedComponentListener =
+                    mWrappedComponentListener.lock()) {
+                wrappedComponentListener->onError_nb(mWrappedComponent, errorCode);
+            }
+        }
+
+    private:
+        std::weak_ptr<C2Component> mWrappedComponent;
+        std::weak_ptr<Listener> mWrappedComponentListener;
+    };
+
+    std::shared_ptr<C2Component> mComp;
+    std::shared_ptr<WrappedDecoderInterface> mIntf;
+    std::vector<FilterWrapper::Component> mFilters;
+    std::vector<FilterWrapper::Component> mRunningFilters;
+    std::weak_ptr<FilterWrapper> mFilterWrapper;
+    std::shared_ptr<Listener> mListener;
+#if defined(LOG_NDEBUG) && !LOG_NDEBUG
+    base::ScopedLogSeverity mScopedLogSeverity{base::VERBOSE};
+#endif
+
+    c2_status_t setListenerInternal(
+            const std::vector<FilterWrapper::Component> &filters,
+            const std::shared_ptr<Listener> &listener,
+            c2_blocking_t mayBlock) {
+        if (filters.empty()) {
+            return mComp->setListener_vb(listener, mayBlock);
+        }
+        std::shared_ptr passingListener = std::make_shared<PassingListener>(
+                shared_from_this(),
+                listener,
+                filters.front().comp);
+        mComp->setListener_vb(passingListener, mayBlock);
+        for (size_t i = 0; i < filters.size() - 1; ++i) {
+            filters[i].comp->setListener_vb(
+                    std::make_shared<PassingListener>(
+                            shared_from_this(),
+                            listener,
+                            filters[i + 1].comp),
+                    mayBlock);
+        }
+        filters.back().comp->setListener_vb(
+                std::make_shared<LastListener>(shared_from_this(), listener), mayBlock);
+        return C2_OK;
+    }
+};
+
+}  // anonymous namespace
+
+FilterWrapper::FilterWrapper(std::unique_ptr<Plugin> &&plugin)
+    : mInit(NO_INIT),
+      mPlugin(std::move(plugin)) {
+    if (mPlugin->status() != OK) {
+        LOG(ERROR) << "plugin not OK: " << mPlugin->status();
+        mPlugin.reset();
+        return;
+    }
+    mStore = mPlugin->getStore();
+    if (!mStore) {
+        LOG(ERROR) << "no store";
+        mPlugin.reset();
+        return;
+    }
+    std::vector<std::shared_ptr<const C2Component::Traits>> traits =
+        mStore->listComponents();
+    std::sort(
+            traits.begin(),
+            traits.end(),
+            [](std::shared_ptr<const C2Component::Traits> &a,
+                    std::shared_ptr<const C2Component::Traits> &b) {
+                return a->rank < b->rank;
+            });
+    for (size_t i = 0; i < traits.size(); ++i) {
+        const std::shared_ptr<const C2Component::Traits> &trait = traits[i];
+        if (trait->domain == C2Component::DOMAIN_OTHER
+                || trait->domain == C2Component::DOMAIN_AUDIO
+                || trait->kind != C2Component::KIND_OTHER) {
+            LOG(DEBUG) << trait->name << " is ignored because of domain/kind: "
+                << trait->domain << "/" << trait->kind;
+            continue;
+        }
+        Descriptor desc;
+        if (!mPlugin->describe(trait->name, &desc)) {
+            LOG(DEBUG) << trait->name << " is ignored because describe() failed";
+            continue;
+        }
+        mComponents.push_back({nullptr, nullptr, *trait, desc});
+    }
+    if (mComponents.empty()) {
+        LOG(DEBUG) << "FilterWrapper: no filter component found";
+        mPlugin.reset();
+        return;
+    }
+    mInit = OK;
+}
+
+FilterWrapper::~FilterWrapper() {
+}
+
+std::vector<FilterWrapper::Component> FilterWrapper::createFilters() {
+    std::vector<FilterWrapper::Component> filters;
+    for (const FilterWrapper::Component &filter : mComponents) {
+        std::shared_ptr<C2Component> comp;
+        std::shared_ptr<C2ComponentInterface> intf;
+        if (C2_OK != mStore->createComponent(filter.traits.name, &comp)) {
+            return {};
+        }
+        if (C2_OK != mStore->createInterface(filter.traits.name, &intf)) {
+            return {};
+        }
+        filters.push_back({comp, intf, filter.traits, filter.desc});
+    }
+    return filters;
+}
+
+C2Component::Traits FilterWrapper::getTraits(
+        const std::shared_ptr<C2ComponentInterface> &intf) {
+    {
+        std::unique_lock lock(mCacheMutex);
+        if (mCachedTraits.count(intf->getName())) {
+            return mCachedTraits.at(intf->getName());
+        }
+    }
+    C2ComponentDomainSetting domain;
+    C2ComponentKindSetting kind;
+    c2_status_t err = intf->query_vb({&domain, &kind}, {}, C2_MAY_BLOCK, nullptr);
+    C2Component::Traits traits = {
+        "query failed",  // name
+        C2Component::DOMAIN_OTHER,
+        C2Component::KIND_OTHER,
+        0,   // rank, unused
+        "",  // media type, unused
+        "",  // owner, unused
+        {},  // aliases, unused
+    };
+    if (err == C2_OK) {
+        traits = {
+            intf->getName(),
+            domain.value,
+            kind.value,
+            0,   // rank, unused
+            "",  // media type, unused
+            "",  // owner, unused
+            {},  // aliases, unused
+        };
+        std::unique_lock lock(mCacheMutex);
+        mCachedTraits[traits.name] = traits;
+    }
+    return traits;
+}
+
+std::shared_ptr<C2ComponentInterface> FilterWrapper::maybeWrapInterface(
+        const std::shared_ptr<C2ComponentInterface> intf) {
+    if (mInit != OK) {
+        LOG(VERBOSE) << "maybeWrapInterface: Wrapper not initialized: "
+                << intf->getName() << " is not wrapped.";
+        return intf;
+    }
+    C2Component::Traits traits = getTraits(intf);
+    if (traits.name != intf->getName()) {
+        LOG(INFO) << "maybeWrapInterface: Querying traits from " << intf->getName()
+                << " failed; not wrapping the interface";
+        return intf;
+    }
+    if ((traits.domain != C2Component::DOMAIN_VIDEO && traits.domain != C2Component::DOMAIN_IMAGE)
+            || traits.kind != C2Component::KIND_DECODER) {
+        LOG(VERBOSE) << "maybeWrapInterface: " << traits.name
+                << " is not video/image decoder; not wrapping the interface";
+        return intf;
+    }
+    return std::make_shared<WrappedDecoderInterface>(intf, createFilters());
+}
+
+std::shared_ptr<C2Component> FilterWrapper::maybeWrapComponent(
+        const std::shared_ptr<C2Component> comp) {
+    if (mInit != OK) {
+        LOG(VERBOSE) << "maybeWrapComponent: Wrapper not initialized: "
+                << comp->intf()->getName() << " is not wrapped.";
+        return comp;
+    }
+    C2Component::Traits traits = getTraits(comp->intf());
+    if (traits.name != comp->intf()->getName()) {
+        LOG(INFO) << "maybeWrapComponent: Querying traits from " << comp->intf()->getName()
+                << " failed; not wrapping the component";
+        return comp;
+    }
+    if ((traits.domain != C2Component::DOMAIN_VIDEO && traits.domain != C2Component::DOMAIN_IMAGE)
+            || traits.kind != C2Component::KIND_DECODER) {
+        LOG(VERBOSE) << "maybeWrapComponent: " << traits.name
+                << " is not video/image decoder; not wrapping the component";
+        return comp;
+    }
+    std::vector<Component> filters = createFilters();
+    std::shared_ptr wrapped = std::make_shared<WrappedDecoder>(
+            comp, std::move(filters), weak_from_this());
+    {
+        std::unique_lock lock(mWrappedComponentsMutex);
+        std::vector<std::weak_ptr<const C2Component>> &components =
+            mWrappedComponents.emplace_back();
+        components.push_back(wrapped);
+        components.push_back(comp);
+        for (const Component &filter : filters) {
+            components.push_back(filter.comp);
+        }
+    }
+    return wrapped;
+}
+
+bool FilterWrapper::isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf) {
+    if (mInit != OK) {
+        LOG(WARNING) << "isFilteringEnabled: Wrapper not initialized: ";
+        return false;
+    }
+    return mPlugin->isFilteringEnabled(intf);
+}
+
+c2_status_t FilterWrapper::createBlockPool(
+        C2PlatformAllocatorStore::id_t allocatorId,
+        std::shared_ptr<const C2Component> component,
+        std::shared_ptr<C2BlockPool> *pool) {
+    std::unique_lock lock(mWrappedComponentsMutex);
+    for (auto it = mWrappedComponents.begin(); it != mWrappedComponents.end(); ) {
+        std::shared_ptr<const C2Component> comp = it->front().lock();
+        if (!comp) {
+            it = mWrappedComponents.erase(it);
+            continue;
+        }
+        if (component == comp) {
+            std::vector<std::shared_ptr<const C2Component>> components(it->size());
+            std::transform(
+                    it->begin(), it->end(), components.begin(),
+                    [](const std::weak_ptr<const C2Component> &el) {
+                        return el.lock();
+                    });
+            if (C2_OK == CreateCodec2BlockPool(allocatorId, components, pool)) {
+                return C2_OK;
+            }
+        }
+        ++it;
+    }
+    return CreateCodec2BlockPool(allocatorId, component, pool);
+}
+
+}  // namespace android
diff --git a/media/codec2/hidl/plugin/FilterWrapperStub.cpp b/media/codec2/hidl/plugin/FilterWrapperStub.cpp
new file mode 100644
index 0000000..1b94a1a
--- /dev/null
+++ b/media/codec2/hidl/plugin/FilterWrapperStub.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-FilterWrapperStub"
+
+#include <FilterWrapper.h>
+
+namespace android {
+
+FilterWrapper::FilterWrapper(std::unique_ptr<Plugin> &&) {
+}
+
+FilterWrapper::~FilterWrapper() {
+}
+
+std::shared_ptr<C2ComponentInterface> FilterWrapper::maybeWrapInterface(
+        const std::shared_ptr<C2ComponentInterface> intf) {
+    return intf;
+}
+
+std::shared_ptr<C2Component> FilterWrapper::maybeWrapComponent(
+        const std::shared_ptr<C2Component> comp) {
+    return comp;
+}
+
+bool FilterWrapper::isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &) {
+    return false;
+}
+
+c2_status_t FilterWrapper::createBlockPool(
+        C2PlatformAllocatorStore::id_t,
+        std::shared_ptr<const C2Component>,
+        std::shared_ptr<C2BlockPool> *) {
+    return C2_OMITTED;
+}
+
+}  // namespace android
diff --git a/media/codec2/hidl/plugin/include/codec2/hidl/plugin/FilterPlugin.h b/media/codec2/hidl/plugin/include/codec2/hidl/plugin/FilterPlugin.h
new file mode 100644
index 0000000..6f1f907
--- /dev/null
+++ b/media/codec2/hidl/plugin/include/codec2/hidl/plugin/FilterPlugin.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2018, 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_HIDL_PLUGIN_FILTER_PLUGIN_H
+
+#define CODEC2_HIDL_PLUGIN_FILTER_PLUGIN_H
+
+#include <memory>
+
+#include <C2Component.h>
+
+namespace android {
+
+class FilterPlugin_V1 {
+public:
+    static constexpr int32_t VERSION = 1;
+
+    virtual ~FilterPlugin_V1() = default;
+
+    /**
+     * Returns a C2ComponentStore object with which clients can create
+     * filter components / interfaces.
+     */
+    virtual std::shared_ptr<C2ComponentStore> getComponentStore() = 0;
+    struct Descriptor {
+        // Parameters that client sets for filter control.
+        std::initializer_list<C2Param::Type> controlParams;
+        // Parameters that the component changes after filtering.
+        std::initializer_list<C2Param::Type> affectedParams;
+    };
+
+    /**
+     * Describe a filter component.
+     *
+     * @param name[in]  filter's name
+     * @param desc[out] pointer to filter descriptor to be populated
+     * @return  true if |name| is in the store and |desc| is populated;
+     *          false if |name| is not recognized
+     */
+    virtual bool describe(C2String name, Descriptor *desc) = 0;
+
+    /**
+     * Returns true if a component will apply filtering after all given the
+     * current configuration; false if it will be no-op.
+     */
+    virtual bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf) = 0;
+};
+
+}  // namespace android
+
+extern "C" {
+
+typedef int32_t (*GetFilterPluginVersionFunc)();
+int32_t GetFilterPluginVersion();
+
+typedef void* (*CreateFilterPluginFunc)();
+void *CreateFilterPlugin();
+
+typedef void (*DestroyFilterPluginFunc)(void *);
+void DestroyFilterPlugin(void *plugin);
+
+}  // extern "C"
+
+#endif  // CODEC2_HIDL_PLUGIN_FILTER_PLUGIN_H
diff --git a/media/codec2/hidl/plugin/internal/DefaultFilterPlugin.h b/media/codec2/hidl/plugin/internal/DefaultFilterPlugin.h
new file mode 100644
index 0000000..f856324
--- /dev/null
+++ b/media/codec2/hidl/plugin/internal/DefaultFilterPlugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020, 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_HIDL_PLUGIN_DEFAULT_FILTER_PLUGIN_H
+
+#define CODEC2_HIDL_PLUGIN_DEFAULT_FILTER_PLUGIN_H
+
+#include <codec2/hidl/plugin/FilterPlugin.h>
+
+#include <FilterWrapper.h>
+
+namespace android {
+
+class DefaultFilterPlugin : public FilterWrapper::Plugin {
+public:
+    explicit DefaultFilterPlugin(const char *pluginPath);
+
+    ~DefaultFilterPlugin();
+
+    status_t status() const override { return mInit; }
+
+    std::shared_ptr<C2ComponentStore> getStore() override { return mStore; }
+    bool describe(C2String name, FilterWrapper::Descriptor *desc) override;
+    bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf) override;
+
+private:
+    status_t mInit;
+    void *mHandle;
+    DestroyFilterPluginFunc mDestroyPlugin;
+    FilterPlugin_V1 *mPlugin;
+    std::shared_ptr<C2ComponentStore> mStore;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_HIDL_PLUGIN_DEFAULT_FILTER_PLUGIN_H
diff --git a/media/codec2/hidl/plugin/internal/FilterWrapper.h b/media/codec2/hidl/plugin/internal/FilterWrapper.h
new file mode 100644
index 0000000..5ced435
--- /dev/null
+++ b/media/codec2/hidl/plugin/internal/FilterWrapper.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020, 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_HIDL_PLUGIN_FILTER_WRAPPER_H
+
+#define CODEC2_HIDL_PLUGIN_FILTER_WRAPPER_H
+
+#include <map>
+#include <memory>
+#include <mutex>
+
+#include <C2Component.h>
+#include <C2PlatformSupport.h>
+
+#include <codec2/hidl/plugin/FilterPlugin.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+// TODO: documentation
+class FilterWrapper : public std::enable_shared_from_this<FilterWrapper> {
+public:
+    using Descriptor = FilterPlugin_V1::Descriptor;
+
+    class Plugin {
+    public:
+        Plugin() = default;
+        virtual ~Plugin() = default;
+        virtual status_t status() const = 0;
+        virtual std::shared_ptr<C2ComponentStore> getStore() = 0;
+        virtual bool describe(C2String name, Descriptor *desc) = 0;
+        virtual bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf) = 0;
+        C2_DO_NOT_COPY(Plugin);
+    };
+
+    struct Component {
+        const std::shared_ptr<C2Component> comp;
+        const std::shared_ptr<C2ComponentInterface> intf;
+        const C2Component::Traits traits;
+        const Descriptor desc;
+    };
+
+private:
+    explicit FilterWrapper(std::unique_ptr<Plugin> &&plugin);
+public:
+    static std::shared_ptr<FilterWrapper> Create(std::unique_ptr<Plugin> &&plugin) {
+        return std::shared_ptr<FilterWrapper>(new FilterWrapper(std::move(plugin)));
+    }
+    ~FilterWrapper();
+
+    /**
+     * Returns wrapped interface, or |intf| if wrapping is not possible / needed.
+     */
+    std::shared_ptr<C2ComponentInterface> maybeWrapInterface(
+            const std::shared_ptr<C2ComponentInterface> intf);
+
+    /**
+     * Returns wrapped component, or |comp| if wrapping is not possible / needed.
+     */
+    std::shared_ptr<C2Component> maybeWrapComponent(
+            const std::shared_ptr<C2Component> comp);
+
+    /**
+     * Returns ture iff the filtering will apply to the buffer in current configuration.
+     */
+    bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf);
+
+    c2_status_t createBlockPool(
+            C2PlatformAllocatorStore::id_t allocatorId,
+            std::shared_ptr<const C2Component> component,
+            std::shared_ptr<C2BlockPool> *pool);
+
+private:
+    status_t mInit;
+    std::unique_ptr<Plugin> mPlugin;
+    std::shared_ptr<C2ComponentStore> mStore;
+    std::list<FilterWrapper::Component> mComponents;
+
+    std::mutex mCacheMutex;
+    std::map<std::string, C2Component::Traits> mCachedTraits;
+
+    std::mutex mWrappedComponentsMutex;
+    std::list<std::vector<std::weak_ptr<const C2Component>>> mWrappedComponents;
+
+    std::vector<FilterWrapper::Component> createFilters();
+    C2Component::Traits getTraits(const std::shared_ptr<C2ComponentInterface> &intf);
+
+    C2_DO_NOT_COPY(FilterWrapper);
+};
+
+}  // namespace android
+
+#endif  // CODEC2_HIDL_PLUGIN_FILTER_WRAPPER_H
