diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
new file mode 100644
index 0000000..831fb35
--- /dev/null
+++ b/media/codec2/sfplugin/Android.bp
@@ -0,0 +1,61 @@
+cc_library_shared {
+    name: "libstagefright_ccodec",
+
+    srcs: [
+        "C2OMXNode.cpp",
+        "CCodec.cpp",
+        "CCodecBufferChannel.cpp",
+        "CCodecConfig.cpp",
+        "Codec2Buffer.cpp",
+        "Codec2InfoBuilder.cpp",
+        "ReflectedParamUpdater.cpp",
+        "SkipCutBuffer.cpp",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    header_libs: [
+        "libstagefright_codec2_internal",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas.native@1.0",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.media.omx@1.0",
+        "hardware.google.media.c2@1.0",
+        "libbase",
+        "libbinder",
+        "libcodec2_hidl_client",
+        "libcutils",
+        "libgui",
+        "libhidlallocatorutils",
+        "libhidlbase",
+        "liblog",
+        "libmedia",
+        "libmedia_omx",
+        "libstagefright_bufferqueue_helper",
+        "libstagefright_ccodec_utils",
+        "libstagefright_codec2",
+        "libstagefright_codec2_vndk",
+        "libstagefright_codecbase",
+        "libstagefright_foundation",
+        "libstagefright_omx_utils",
+        "libstagefright_xmlparser",
+        "libui",
+        "libutils",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        diag: {
+            cfi: true,
+        },
+    },
+}
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
new file mode 100644
index 0000000..749fd7a
--- /dev/null
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2OMXNode"
+#include <log/log.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Component.h>
+#include <C2PlatformSupport.h>
+
+#include <OMX_Component.h>
+#include <OMX_Index.h>
+#include <OMX_IndexExt.h>
+
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/MediaErrors.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+
+#include "C2OMXNode.h"
+
+namespace android {
+
+namespace {
+
+class Buffer2D : public C2Buffer {
+public:
+    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
+};
+
+}  // namespace
+
+C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
+    : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0),
+      mAdjustTimestampGapUs(0), mFirstInputFrame(true) {
+    // TODO: read from intf()
+    if (!strncmp(comp->getName().c_str(), "c2.android.", 11)) {
+        mUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+    } else {
+        mUsage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
+    }
+}
+
+status_t C2OMXNode::freeNode() {
+    mComp.reset();
+    return OK;
+}
+
+status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
+    if (cmd == OMX_CommandStateSet && param == OMX_StateLoaded) {
+        // Reset first input frame so if C2OMXNode is recycled, the timestamp does not become
+        // negative. This is a workaround for HW codecs that do not handle timestamp rollover.
+        mFirstInputFrame = true;
+    }
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) {
+    status_t err = ERROR_UNSUPPORTED;
+    switch ((uint32_t)index) {
+        case OMX_IndexParamConsumerUsageBits: {
+            OMX_U32 *usage = (OMX_U32 *)params;
+            *usage = mUsage;
+            err = OK;
+            break;
+        }
+        case OMX_IndexParamPortDefinition: {
+            if (size < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+                return BAD_VALUE;
+            }
+            OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+            // TODO: read these from intf()
+            pDef->nBufferCountActual = 16;
+            pDef->eDomain = OMX_PortDomainVideo;
+            pDef->format.video.nFrameWidth = mWidth;
+            pDef->format.video.nFrameHeight = mHeight;
+            err = OK;
+            break;
+        }
+        default:
+            break;
+    }
+    return err;
+}
+
+status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
+    // handle max/fixed frame duration control
+    if (index == (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl
+            && params != NULL
+            && size == sizeof(OMX_PARAM_U32TYPE)) {
+        // The incoming number is an int32_t contained in OMX_U32.
+        mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
+        return OK;
+    }
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getConfig(OMX_INDEXTYPE index, void *config, size_t size) {
+    (void)index;
+    (void)config;
+    (void)size;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setConfig(OMX_INDEXTYPE index, const void *config, size_t size) {
+    (void)index;
+    (void)config;
+    (void)size;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
+    (void)portIndex;
+    (void)mode;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::prepareForAdaptivePlayback(
+        OMX_U32 portIndex, OMX_BOOL enable,
+        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+    (void)portIndex;
+    (void)enable;
+    (void)maxFrameWidth;
+    (void)maxFrameHeight;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::configureVideoTunnelMode(
+        OMX_U32 portIndex, OMX_BOOL tunneled,
+        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
+    (void)portIndex;
+    (void)tunneled;
+    (void)audioHwSync;
+    *sidebandHandle = nullptr;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage) {
+    (void)portIndex;
+    *usage = 0;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
+    c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
+            C2PlatformAllocatorStore::GRALLOC,
+            &mAllocator);
+    if (err != OK) {
+        return UNKNOWN_ERROR;
+    }
+    mBufferSource = bufferSource;
+    return OK;
+}
+
+status_t C2OMXNode::allocateSecureBuffer(
+        OMX_U32 portIndex, size_t size, buffer_id *buffer,
+        void **bufferData, sp<NativeHandle> *nativeHandle) {
+    (void)portIndex;
+    (void)size;
+    (void)nativeHandle;
+    *buffer = 0;
+    *bufferData = nullptr;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::useBuffer(
+        OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer) {
+    (void)portIndex;
+    (void)omxBuf;
+    *buffer = 0;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::freeBuffer(OMX_U32 portIndex, buffer_id buffer) {
+    (void)portIndex;
+    (void)buffer;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::fillBuffer(
+        buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
+    (void)buffer;
+    (void)omxBuf;
+    (void)fenceFd;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::emptyBuffer(
+        buffer_id buffer, const OMXBuffer &omxBuf,
+        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+    // TODO: better fence handling
+    if (fenceFd >= 0) {
+        sp<Fence> fence = new Fence(fenceFd);
+        fence->waitForever(LOG_TAG);
+    }
+    std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
+    if (!comp) {
+        return NO_INIT;
+    }
+
+    uint32_t c2Flags = (flags & OMX_BUFFERFLAG_EOS)
+            ? C2FrameData::FLAG_END_OF_STREAM : 0;
+    std::shared_ptr<C2GraphicBlock> block;
+
+    C2Handle *handle = nullptr;
+    if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer
+            && omxBuf.mGraphicBuffer != nullptr) {
+        std::shared_ptr<C2GraphicAllocation> alloc;
+        handle = WrapNativeCodec2GrallocHandle(
+                native_handle_clone(omxBuf.mGraphicBuffer->handle),
+                omxBuf.mGraphicBuffer->width,
+                omxBuf.mGraphicBuffer->height,
+                omxBuf.mGraphicBuffer->format,
+                omxBuf.mGraphicBuffer->usage,
+                omxBuf.mGraphicBuffer->stride);
+        c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
+        if (err != OK) {
+            return UNKNOWN_ERROR;
+        }
+        block = _C2BlockFactory::CreateGraphicBlock(alloc);
+    } else if (!(flags & OMX_BUFFERFLAG_EOS)) {
+        return BAD_VALUE;
+    }
+
+    std::unique_ptr<C2Work> work(new C2Work);
+    work->input.flags = (C2FrameData::flags_t)c2Flags;
+    work->input.ordinal.timestamp = timestamp;
+
+    // WORKAROUND: adjust timestamp based on gapUs
+    {
+        work->input.ordinal.customOrdinal = timestamp; // save input timestamp
+        if (mFirstInputFrame) {
+            // grab timestamps on first frame
+            mPrevInputTimestamp = timestamp;
+            mPrevCodecTimestamp = timestamp;
+            mFirstInputFrame = false;
+        } else if (mAdjustTimestampGapUs > 0) {
+            work->input.ordinal.timestamp =
+                mPrevCodecTimestamp
+                        + c2_min((timestamp - mPrevInputTimestamp).peek(), mAdjustTimestampGapUs);
+        } else if (mAdjustTimestampGapUs < 0) {
+            work->input.ordinal.timestamp = mPrevCodecTimestamp - mAdjustTimestampGapUs;
+        }
+        mPrevInputTimestamp = work->input.ordinal.customOrdinal;
+        mPrevCodecTimestamp = work->input.ordinal.timestamp;
+        ALOGV("adjusting %lld to %lld (gap=%lld)",
+              work->input.ordinal.customOrdinal.peekll(),
+              work->input.ordinal.timestamp.peekll(),
+              (long long)mAdjustTimestampGapUs);
+    }
+
+    work->input.ordinal.frameIndex = mFrameIndex++;
+    work->input.buffers.clear();
+    if (block) {
+        std::shared_ptr<C2Buffer> c2Buffer(
+                // TODO: fence
+                new Buffer2D(block->share(
+                        C2Rect(block->width(), block->height()), ::C2Fence())),
+                [buffer, source = getSource()](C2Buffer *ptr) {
+                    delete ptr;
+                    // TODO: fence
+                    (void)source->onInputBufferEmptied(buffer, -1);
+                });
+        work->input.buffers.push_back(c2Buffer);
+    }
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+
+    c2_status_t err = comp->queue(&items);
+    if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2OMXNode::getExtensionIndex(
+        const char *parameterName, OMX_INDEXTYPE *index) {
+    (void)parameterName;
+    *index = OMX_IndexMax;
+    return ERROR_UNSUPPORTED;
+}
+
+status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
+    if (msg.type != omx_message::EVENT) {
+        return ERROR_UNSUPPORTED;
+    }
+    if (msg.u.event_data.event != OMX_EventDataSpaceChanged) {
+        return ERROR_UNSUPPORTED;
+    }
+    android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
+    uint32_t pixelFormat = msg.u.event_data.data3;
+
+    // TODO: set dataspace on component to see if it impacts color aspects
+    ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
+    return OK;
+}
+
+sp<IOMXBufferSource> C2OMXNode::getSource() {
+    return mBufferSource;
+}
+
+void C2OMXNode::setFrameSize(uint32_t width, uint32_t height) {
+    mWidth = width;
+    mHeight = height;
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/C2OMXNode.h b/media/codec2/sfplugin/C2OMXNode.h
new file mode 100644
index 0000000..b5a815e
--- /dev/null
+++ b/media/codec2/sfplugin/C2OMXNode.h
@@ -0,0 +1,103 @@
+/*
+ * 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 C2_OMX_NODE_H_
+#define C2_OMX_NODE_H_
+
+#include <atomic>
+
+#include <android/IOMXBufferSource.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <codec2/hidl/client.h>
+
+namespace android {
+
+/**
+ * IOmxNode implementation around codec 2.0 component, only to be used in
+ * IGraphicBufferSource::configure. Only subset of IOmxNode API is implemented
+ * and others are left as stub. As a result, one cannot expect this IOmxNode
+ * to work in any other usage than IGraphicBufferSource.
+ */
+struct C2OMXNode : public BnOMXNode {
+    explicit C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp);
+    ~C2OMXNode() override = default;
+
+    // IOMXNode
+    status_t freeNode() override;
+    status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) override;
+    status_t getParameter(
+            OMX_INDEXTYPE index, void *params, size_t size) override;
+    status_t setParameter(
+            OMX_INDEXTYPE index, const void *params, size_t size) override;
+    status_t getConfig(
+            OMX_INDEXTYPE index, void *params, size_t size) override;
+    status_t setConfig(
+            OMX_INDEXTYPE index, const void *params, size_t size) override;
+    status_t setPortMode(OMX_U32 port_index, IOMX::PortMode mode) override;
+    status_t prepareForAdaptivePlayback(
+            OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) override;
+    status_t configureVideoTunnelMode(
+            OMX_U32 portIndex, OMX_BOOL tunneled,
+            OMX_U32 audioHwSync, native_handle_t **sidebandHandle) override;
+    status_t getGraphicBufferUsage(
+            OMX_U32 port_index, OMX_U32* usage) override;
+    status_t setInputSurface(
+            const sp<IOMXBufferSource> &bufferSource) override;
+    status_t allocateSecureBuffer(
+            OMX_U32 port_index, size_t size, buffer_id *buffer,
+            void **buffer_data, sp<NativeHandle> *native_handle) override;
+    status_t useBuffer(
+            OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) override;
+    status_t freeBuffer(
+            OMX_U32 port_index, buffer_id buffer) override;
+    status_t fillBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) override;
+    status_t emptyBuffer(
+            buffer_id buffer, const OMXBuffer &omxBuf,
+            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) override;
+    status_t getExtensionIndex(
+            const char *parameter_name,
+            OMX_INDEXTYPE *index) override;
+    status_t dispatchMessage(const omx_message &msg) override;
+
+    sp<IOMXBufferSource> getSource();
+    void setFrameSize(uint32_t width, uint32_t height);
+
+private:
+    std::weak_ptr<Codec2Client::Component> mComp;
+    sp<IOMXBufferSource> mBufferSource;
+    std::shared_ptr<C2Allocator> mAllocator;
+    std::atomic_uint64_t mFrameIndex;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint64_t mUsage;
+
+    // WORKAROUND: timestamp adjustment
+
+    // if >0: this is the max timestamp gap, if <0: this is -1 times the fixed timestamp gap
+    // if 0: no timestamp adjustment is made
+    // note that C2OMXNode can be recycled between encoding sessions.
+    int32_t mAdjustTimestampGapUs;
+    bool mFirstInputFrame; // true for first input
+    c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame
+    c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
+};
+
+}  // namespace android
+
+#endif  // C2_OMX_NODE_H_
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
new file mode 100644
index 0000000..f00c62e
--- /dev/null
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -0,0 +1,1746 @@
+/*
+ * Copyright (C) 2017 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 "CCodec"
+#include <utils/Log.h>
+
+#include <sstream>
+#include <thread>
+
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+#include <C2PlatformSupport.h>
+
+#include <android/IGraphicBufferSource.h>
+#include <android/IOMXBufferSource.h>
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android-base/stringprintf.h>
+#include <cutils/properties.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/Surface.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/PersistentSurface.h>
+#include <media/stagefright/codec2/1.0/InputSurface.h>
+
+#include "C2OMXNode.h"
+#include "CCodec.h"
+#include "CCodecBufferChannel.h"
+#include "InputSurfaceWrapper.h"
+
+extern "C" android::PersistentSurface *CreateInputSurface();
+
+namespace android {
+
+using namespace std::chrono_literals;
+using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+using android::base::StringPrintf;
+using BGraphicBufferSource = ::android::IGraphicBufferSource;
+using ::hardware::google::media::c2::V1_0::IInputSurface;
+
+namespace {
+
+class CCodecWatchdog : public AHandler {
+private:
+    enum {
+        kWhatWatch,
+    };
+    constexpr static int64_t kWatchIntervalUs = 3300000;  // 3.3 secs
+
+public:
+    static sp<CCodecWatchdog> getInstance() {
+        static sp<CCodecWatchdog> instance(new CCodecWatchdog);
+        static std::once_flag flag;
+        // Call Init() only once.
+        std::call_once(flag, Init, instance);
+        return instance;
+    }
+
+    ~CCodecWatchdog() = default;
+
+    void watch(sp<CCodec> codec) {
+        bool shouldPost = false;
+        {
+            Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
+            // If a watch message is in flight, piggy-back this instance as well.
+            // Otherwise, post a new watch message.
+            shouldPost = codecs->empty();
+            codecs->emplace(codec);
+        }
+        if (shouldPost) {
+            ALOGV("posting watch message");
+            (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs);
+        }
+    }
+
+protected:
+    void onMessageReceived(const sp<AMessage> &msg) {
+        switch (msg->what()) {
+            case kWhatWatch: {
+                Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
+                ALOGV("watch for %zu codecs", codecs->size());
+                for (auto it = codecs->begin(); it != codecs->end(); ++it) {
+                    sp<CCodec> codec = it->promote();
+                    if (codec == nullptr) {
+                        continue;
+                    }
+                    codec->initiateReleaseIfStuck();
+                }
+                codecs->clear();
+                break;
+            }
+
+            default: {
+                TRESPASS("CCodecWatchdog: unrecognized message");
+            }
+        }
+    }
+
+private:
+    CCodecWatchdog() : mLooper(new ALooper) {}
+
+    static void Init(const sp<CCodecWatchdog> &thiz) {
+        ALOGV("Init");
+        thiz->mLooper->setName("CCodecWatchdog");
+        thiz->mLooper->registerHandler(thiz);
+        thiz->mLooper->start();
+    }
+
+    sp<ALooper> mLooper;
+
+    Mutexed<std::set<wp<CCodec>>> mCodecsToWatch;
+};
+
+class C2InputSurfaceWrapper : public InputSurfaceWrapper {
+public:
+    explicit C2InputSurfaceWrapper(
+            const std::shared_ptr<Codec2Client::InputSurface> &surface) :
+        mSurface(surface) {
+    }
+
+    ~C2InputSurfaceWrapper() override = default;
+
+    status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
+        if (mConnection != nullptr) {
+            return ALREADY_EXISTS;
+        }
+        return toStatusT(mSurface->connectToComponent(comp, &mConnection),
+                         C2_OPERATION_InputSurface_connectToComponent);
+    }
+
+    void disconnect() override {
+        if (mConnection != nullptr) {
+            mConnection->disconnect();
+            mConnection = nullptr;
+        }
+    }
+
+    status_t start() override {
+        // InputSurface does not distinguish started state
+        return OK;
+    }
+
+    status_t signalEndOfInputStream() override {
+        C2InputSurfaceEosTuning eos(true);
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        c2_status_t err = mSurface->getConfigurable()->config({&eos}, C2_MAY_BLOCK, &failures);
+        if (err != C2_OK) {
+            return UNKNOWN_ERROR;
+        }
+        return OK;
+    }
+
+    status_t configure(Config &config __unused) {
+        // TODO
+        return OK;
+    }
+
+private:
+    std::shared_ptr<Codec2Client::InputSurface> mSurface;
+    std::shared_ptr<Codec2Client::InputSurfaceConnection> mConnection;
+};
+
+class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
+public:
+//    explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {}
+    GraphicBufferSourceWrapper(
+            const sp<BGraphicBufferSource> &source,
+            uint32_t width,
+            uint32_t height)
+        : mSource(source), mWidth(width), mHeight(height) {
+        mDataSpace = HAL_DATASPACE_BT709;
+    }
+    ~GraphicBufferSourceWrapper() override = default;
+
+    status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
+        mNode = new C2OMXNode(comp);
+        mNode->setFrameSize(mWidth, mHeight);
+
+        // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
+        // communicate that directly to the component.
+        mSource->configure(mNode, mDataSpace);
+        return OK;
+    }
+
+    void disconnect() override {
+        if (mNode == nullptr) {
+            return;
+        }
+        sp<IOMXBufferSource> source = mNode->getSource();
+        if (source == nullptr) {
+            ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
+            return;
+        }
+        source->onOmxIdle();
+        source->onOmxLoaded();
+        mNode.clear();
+    }
+
+    status_t GetStatus(const binder::Status &status) {
+        status_t err = OK;
+        if (!status.isOk()) {
+            err = status.serviceSpecificErrorCode();
+            if (err == OK) {
+                err = status.transactionError();
+                if (err == OK) {
+                    // binder status failed, but there is no servie or transaction error
+                    err = UNKNOWN_ERROR;
+                }
+            }
+        }
+        return err;
+    }
+
+    status_t start() override {
+        sp<IOMXBufferSource> source = mNode->getSource();
+        if (source == nullptr) {
+            return NO_INIT;
+        }
+        constexpr size_t kNumSlots = 16;
+        for (size_t i = 0; i < kNumSlots; ++i) {
+            source->onInputBufferAdded(i);
+        }
+
+        source->onOmxExecuting();
+        return OK;
+    }
+
+    status_t signalEndOfInputStream() override {
+        return GetStatus(mSource->signalEndOfInputStream());
+    }
+
+    status_t configure(Config &config) {
+        std::stringstream status;
+        status_t err = OK;
+
+        // handle each configuration granually, in case we need to handle part of the configuration
+        // elsewhere
+
+        // TRICKY: we do not unset frame delay repeating
+        if (config.mMinFps > 0 && config.mMinFps != mConfig.mMinFps) {
+            int64_t us = 1e6 / config.mMinFps + 0.5;
+            status_t res = GetStatus(mSource->setRepeatPreviousFrameDelayUs(us));
+            status << " minFps=" << config.mMinFps << " => repeatDelayUs=" << us;
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mMinFps = config.mMinFps;
+        }
+
+        // pts gap
+        if (config.mMinAdjustedFps > 0 || config.mFixedAdjustedFps > 0) {
+            if (mNode != nullptr) {
+                OMX_PARAM_U32TYPE ptrGapParam = {};
+                ptrGapParam.nSize = sizeof(OMX_PARAM_U32TYPE);
+                ptrGapParam.nU32 = (config.mMinAdjustedFps > 0)
+                        ? c2_min(INT32_MAX + 0., 1e6 / config.mMinAdjustedFps + 0.5)
+                        : c2_max(0. - INT32_MAX, -1e6 / config.mFixedAdjustedFps - 0.5);
+                (void)mNode->setParameter(
+                        (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
+                        &ptrGapParam, sizeof(ptrGapParam));
+            }
+        }
+
+        // max fps
+        // TRICKY: we do not unset max fps to 0 unless using fixed fps
+        if ((config.mMaxFps > 0 || (config.mFixedAdjustedFps > 0 && config.mMaxFps == 0))
+                && config.mMaxFps != mConfig.mMaxFps) {
+            status_t res = GetStatus(mSource->setMaxFps(config.mMaxFps));
+            status << " maxFps=" << config.mMaxFps;
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mMaxFps = config.mMaxFps;
+        }
+
+        if (config.mTimeOffsetUs != mConfig.mTimeOffsetUs) {
+            status_t res = GetStatus(mSource->setTimeOffsetUs(config.mTimeOffsetUs));
+            status << " timeOffset " << config.mTimeOffsetUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mTimeOffsetUs = config.mTimeOffsetUs;
+        }
+
+        if (config.mCaptureFps != mConfig.mCaptureFps || config.mCodedFps != mConfig.mCodedFps) {
+            status_t res =
+                GetStatus(mSource->setTimeLapseConfig(config.mCodedFps, config.mCaptureFps));
+            status << " timeLapse " << config.mCaptureFps << "fps as " << config.mCodedFps << "fps";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mCaptureFps = config.mCaptureFps;
+            mConfig.mCodedFps = config.mCodedFps;
+        }
+
+        if (config.mStartAtUs != mConfig.mStartAtUs
+                || (config.mStopped != mConfig.mStopped && !config.mStopped)) {
+            status_t res = GetStatus(mSource->setStartTimeUs(config.mStartAtUs));
+            status << " start at " << config.mStartAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mStartAtUs = config.mStartAtUs;
+            mConfig.mStopped = config.mStopped;
+        }
+
+        // suspend-resume
+        if (config.mSuspended != mConfig.mSuspended) {
+            status_t res = GetStatus(mSource->setSuspend(config.mSuspended, config.mSuspendAtUs));
+            status << " " << (config.mSuspended ? "suspend" : "resume")
+                    << " at " << config.mSuspendAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            }
+            mConfig.mSuspended = config.mSuspended;
+            mConfig.mSuspendAtUs = config.mSuspendAtUs;
+        }
+
+        if (config.mStopped != mConfig.mStopped && config.mStopped) {
+            status_t res = GetStatus(mSource->setStopTimeUs(config.mStopAtUs));
+            status << " stop at " << config.mStopAtUs << "us";
+            if (res != OK) {
+                status << " (=> " << asString(res) << ")";
+                err = res;
+            } else {
+                status << " delayUs";
+                res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs));
+                if (res != OK) {
+                    status << " (=> " << asString(res) << ")";
+                } else {
+                    status << "=" << config.mInputDelayUs << "us";
+                }
+                mConfig.mInputDelayUs = config.mInputDelayUs;
+            }
+            mConfig.mStopAtUs = config.mStopAtUs;
+            mConfig.mStopped = config.mStopped;
+        }
+
+        // color aspects (android._color-aspects)
+
+        // consumer usage
+        ALOGD("ISConfig%s", status.str().c_str());
+        return err;
+    }
+
+private:
+    sp<BGraphicBufferSource> mSource;
+    sp<C2OMXNode> mNode;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    Config mConfig;
+};
+
+class Codec2ClientInterfaceWrapper : public C2ComponentStore {
+    std::shared_ptr<Codec2Client> mClient;
+
+public:
+    Codec2ClientInterfaceWrapper(std::shared_ptr<Codec2Client> client)
+        : mClient(client) { }
+
+    virtual ~Codec2ClientInterfaceWrapper() = default;
+
+    virtual c2_status_t config_sm(
+            const std::vector<C2Param *> &params,
+            std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
+        return mClient->config(params, C2_MAY_BLOCK, failures);
+    };
+
+    virtual c2_status_t copyBuffer(
+            std::shared_ptr<C2GraphicBuffer>,
+            std::shared_ptr<C2GraphicBuffer>) {
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t createComponent(
+            C2String, std::shared_ptr<C2Component> *const component) {
+        component->reset();
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t createInterface(
+            C2String, std::shared_ptr<C2ComponentInterface> *const interface) {
+        interface->reset();
+        return C2_OMITTED;
+    }
+
+    virtual c2_status_t query_sm(
+            const std::vector<C2Param *> &stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
+        return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
+    }
+
+    virtual c2_status_t querySupportedParams_nb(
+            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+        return mClient->querySupportedParams(params);
+    }
+
+    virtual c2_status_t querySupportedValues_sm(
+            std::vector<C2FieldSupportedValuesQuery> &fields) const {
+        return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
+    }
+
+    virtual C2String getName() const {
+        return mClient->getName();
+    }
+
+    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
+        return mClient->getParamReflector();
+    }
+
+    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() {
+        return std::vector<std::shared_ptr<const C2Component::Traits>>();
+    }
+};
+
+}  // namespace
+
+// CCodec::ClientListener
+
+struct CCodec::ClientListener : public Codec2Client::Listener {
+
+    explicit ClientListener(const wp<CCodec> &codec) : mCodec(codec) {}
+
+    virtual void onWorkDone(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            std::list<std::unique_ptr<C2Work>>& workItems,
+            size_t numDiscardedInputBuffers) override {
+        (void)component;
+        sp<CCodec> codec(mCodec.promote());
+        if (!codec) {
+            return;
+        }
+        codec->onWorkDone(workItems, numDiscardedInputBuffers);
+    }
+
+    virtual void onTripped(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            const std::vector<std::shared_ptr<C2SettingResult>>& settingResult
+            ) override {
+        // TODO
+        (void)component;
+        (void)settingResult;
+    }
+
+    virtual void onError(
+            const std::weak_ptr<Codec2Client::Component>& component,
+            uint32_t errorCode) override {
+        // TODO
+        (void)component;
+        (void)errorCode;
+    }
+
+    virtual void onDeath(
+            const std::weak_ptr<Codec2Client::Component>& component) override {
+        { // Log the death of the component.
+            std::shared_ptr<Codec2Client::Component> comp = component.lock();
+            if (!comp) {
+                ALOGE("Codec2 component died.");
+            } else {
+                ALOGE("Codec2 component \"%s\" died.", comp->getName().c_str());
+            }
+        }
+
+        // Report to MediaCodec.
+        sp<CCodec> codec(mCodec.promote());
+        if (!codec || !codec->mCallback) {
+            return;
+        }
+        codec->mCallback->onError(DEAD_OBJECT, ACTION_CODE_FATAL);
+    }
+
+    virtual void onFramesRendered(
+            const std::vector<RenderedFrame>& renderedFrames) override {
+        // TODO
+        (void)renderedFrames;
+    }
+
+    virtual void onInputBufferDone(
+            const std::shared_ptr<C2Buffer>& buffer) override {
+        sp<CCodec> codec(mCodec.promote());
+        if (codec) {
+            codec->onInputBufferDone(buffer);
+        }
+    }
+
+private:
+    wp<CCodec> mCodec;
+};
+
+// CCodecCallbackImpl
+
+class CCodecCallbackImpl : public CCodecCallback {
+public:
+    explicit CCodecCallbackImpl(CCodec *codec) : mCodec(codec) {}
+    ~CCodecCallbackImpl() override = default;
+
+    void onError(status_t err, enum ActionCode actionCode) override {
+        mCodec->mCallback->onError(err, actionCode);
+    }
+
+    void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) override {
+        mCodec->mCallback->onOutputFramesRendered(
+                {RenderedFrameInfo(mediaTimeUs, renderTimeNs)});
+    }
+
+    void onWorkQueued(bool eos) override {
+        mCodec->onWorkQueued(eos);
+    }
+
+    void onOutputBuffersChanged() override {
+        mCodec->mCallback->onOutputBuffersChanged();
+    }
+
+private:
+    CCodec *mCodec;
+};
+
+// CCodec
+
+CCodec::CCodec()
+    : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))),
+      mQueuedWorkCount(0) {
+}
+
+CCodec::~CCodec() {
+}
+
+std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
+    return mChannel;
+}
+
+status_t CCodec::tryAndReportOnError(std::function<status_t()> job) {
+    status_t err = job();
+    if (err != C2_OK) {
+        mCallback->onError(err, ACTION_CODE_FATAL);
+    }
+    return err;
+}
+
+void CCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
+    auto setAllocating = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != RELEASED) {
+            return INVALID_OPERATION;
+        }
+        state->set(ALLOCATING);
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocating) != OK) {
+        return;
+    }
+
+    sp<RefBase> codecInfo;
+    CHECK(msg->findObject("codecInfo", &codecInfo));
+    // For Codec 2.0 components, componentName == codecInfo->getCodecName().
+
+    sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this));
+    allocMsg->setObject("codecInfo", codecInfo);
+    allocMsg->post();
+}
+
+void CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) {
+    if (codecInfo == nullptr) {
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return;
+    }
+    ALOGD("allocate(%s)", codecInfo->getCodecName());
+    mClientListener.reset(new ClientListener(this));
+
+    AString componentName = codecInfo->getCodecName();
+    std::shared_ptr<Codec2Client> client;
+
+    // set up preferred component store to access vendor store parameters
+    client = Codec2Client::CreateFromService("default", false);
+    if (client) {
+        ALOGI("setting up '%s' as default (vendor) store", client->getInstanceName().c_str());
+        SetPreferredCodec2ComponentStore(
+                std::make_shared<Codec2ClientInterfaceWrapper>(client));
+    }
+
+    std::shared_ptr<Codec2Client::Component> comp =
+            Codec2Client::CreateComponentByName(
+            componentName.c_str(),
+            mClientListener,
+            &client);
+    if (!comp) {
+        ALOGE("Failed Create component: %s", componentName.c_str());
+        Mutexed<State>::Locked state(mState);
+        state->set(RELEASED);
+        state.unlock();
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        state.lock();
+        return;
+    }
+    ALOGI("Created component [%s]", componentName.c_str());
+    mChannel->setComponent(comp);
+    auto setAllocated = [this, comp, client] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATING) {
+            state->set(RELEASED);
+            return UNKNOWN_ERROR;
+        }
+        state->set(ALLOCATED);
+        state->comp = comp;
+        mClient = client;
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocated) != OK) {
+        return;
+    }
+
+    // initialize config here in case setParameters is called prior to configure
+    Mutexed<Config>::Locked config(mConfig);
+    status_t err = config->initialize(mClient, comp);
+    if (err != OK) {
+        ALOGW("Failed to initialize configuration support");
+        // TODO: report error once we complete implementation.
+    }
+    config->queryConfiguration(comp);
+
+    mCallback->onComponentAllocated(componentName.c_str());
+}
+
+void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
+    auto checkAllocated = [this] {
+        Mutexed<State>::Locked state(mState);
+        return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
+    }
+
+    sp<AMessage> msg(new AMessage(kWhatConfigure, this));
+    msg->setMessage("format", format);
+    msg->post();
+}
+
+void CCodec::configure(const sp<AMessage> &msg) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkAllocated = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            state->set(RELEASED);
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
+    }
+
+    auto doConfig = [msg, comp, this]() -> status_t {
+        AString mime;
+        if (!msg->findString("mime", &mime)) {
+            return BAD_VALUE;
+        }
+
+        int32_t encoder;
+        if (!msg->findInt32("encoder", &encoder)) {
+            encoder = false;
+        }
+
+        // TODO: read from intf()
+        if ((!encoder) != (comp->getName().find("encoder") == std::string::npos)) {
+            return UNKNOWN_ERROR;
+        }
+
+        int32_t storeMeta;
+        if (encoder
+                && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
+                && storeMeta != kMetadataBufferTypeInvalid) {
+            if (storeMeta != kMetadataBufferTypeANWBuffer) {
+                ALOGD("Only ANW buffers are supported for legacy metadata mode");
+                return BAD_VALUE;
+            }
+            mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW);
+        }
+
+        sp<RefBase> obj;
+        sp<Surface> surface;
+        if (msg->findObject("native-window", &obj)) {
+            surface = static_cast<Surface *>(obj.get());
+            setSurface(surface);
+        }
+
+        Mutexed<Config>::Locked config(mConfig);
+        config->mUsingSurface = surface != nullptr;
+
+        /*
+         * Handle input surface configuration
+         */
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
+                && (config->mDomain & Config::IS_ENCODER)) {
+            config->mISConfig.reset(new InputSurfaceWrapper::Config{});
+            {
+                config->mISConfig->mMinFps = 0;
+                int64_t value;
+                if (msg->findInt64("repeat-previous-frame-after", &value) && value > 0) {
+                    config->mISConfig->mMinFps = 1e6 / value;
+                }
+                (void)msg->findFloat("max-fps-to-encoder", &config->mISConfig->mMaxFps);
+                config->mISConfig->mMinAdjustedFps = 0;
+                config->mISConfig->mFixedAdjustedFps = 0;
+                if (msg->findInt64("max-pts-gap-to-encoder", &value)) {
+                    if (value < 0 && value >= INT32_MIN) {
+                        config->mISConfig->mFixedAdjustedFps = -1e6 / value;
+                    } else if (value > 0 && value <= INT32_MAX) {
+                        config->mISConfig->mMinAdjustedFps = 1e6 / value;
+                    }
+                }
+            }
+
+            {
+                double value;
+                if (msg->findDouble("time-lapse-fps", &value)) {
+                    config->mISConfig->mCaptureFps = value;
+                    (void)msg->findAsFloat(KEY_FRAME_RATE, &config->mISConfig->mCodedFps);
+                }
+            }
+
+            {
+                config->mISConfig->mSuspended = false;
+                config->mISConfig->mSuspendAtUs = -1;
+                int32_t value;
+                if (msg->findInt32("create-input-buffers-suspended", &value) && value) {
+                    config->mISConfig->mSuspended = true;
+                }
+            }
+        }
+
+        /*
+         * Handle desired color format.
+         */
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
+            int32_t format = -1;
+            if (!msg->findInt32(KEY_COLOR_FORMAT, &format)) {
+                /*
+                 * Also handle default color format (encoders require color format, so this is only
+                 * needed for decoders.
+                 */
+                if (!(config->mDomain & Config::IS_ENCODER)) {
+                    format = (surface == nullptr) ? COLOR_FormatYUV420Planar : COLOR_FormatSurface;
+                }
+            }
+
+            if (format >= 0) {
+                msg->setInt32("android._color-format", format);
+            }
+        }
+
+        std::vector<std::unique_ptr<C2Param>> configUpdate;
+        status_t err = config->getConfigUpdateFromSdkParams(
+                comp, msg, Config::IS_CONFIG, C2_DONT_BLOCK, &configUpdate);
+        if (err != OK) {
+            ALOGW("failed to convert configuration to c2 params");
+        }
+        err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK);
+        if (err != OK) {
+            ALOGW("failed to configure c2 params");
+            return err;
+        }
+
+        std::vector<std::unique_ptr<C2Param>> params;
+        C2StreamUsageTuning::input usage(0u, 0u);
+        C2StreamMaxBufferSizeInfo::input maxInputSize(0u, 0u);
+
+        std::initializer_list<C2Param::Index> indices {
+        };
+        c2_status_t c2err = comp->query(
+                { &usage, &maxInputSize },
+                indices,
+                C2_DONT_BLOCK,
+                &params);
+        if (c2err != C2_OK && c2err != C2_BAD_INDEX) {
+            ALOGE("Failed to query component interface: %d", c2err);
+            return UNKNOWN_ERROR;
+        }
+        if (params.size() != indices.size()) {
+            ALOGE("Component returns wrong number of params: expected %zu actual %zu",
+                    indices.size(), params.size());
+            return UNKNOWN_ERROR;
+        }
+        if (usage && (usage.value & C2MemoryUsage::CPU_READ)) {
+            config->mInputFormat->setInt32("using-sw-read-often", true);
+        }
+
+        // NOTE: we don't blindly use client specified input size if specified as clients
+        // at times specify too small size. Instead, mimic the behavior from OMX, where the
+        // client specified size is only used to ask for bigger buffers than component suggested
+        // size.
+        int32_t clientInputSize = 0;
+        bool clientSpecifiedInputSize =
+            msg->findInt32(KEY_MAX_INPUT_SIZE, &clientInputSize) && clientInputSize > 0;
+        // TEMP: enforce minimum buffer size of 1MB for video decoders
+        // and 16K / 4K for audio encoders/decoders
+        if (maxInputSize.value == 0) {
+            if (config->mDomain & Config::IS_AUDIO) {
+                maxInputSize.value = encoder ? 16384 : 4096;
+            } else if (!encoder) {
+                maxInputSize.value = 1048576u;
+            }
+        }
+
+        // verify that CSD fits into this size (if defined)
+        if ((config->mDomain & Config::IS_DECODER) && maxInputSize.value > 0) {
+            sp<ABuffer> csd;
+            for (size_t ix = 0; msg->findBuffer(StringPrintf("csd-%zu", ix).c_str(), &csd); ++ix) {
+                if (csd && csd->size() > maxInputSize.value) {
+                    maxInputSize.value = csd->size();
+                }
+            }
+        }
+
+        // TODO: do this based on component requiring linear allocator for input
+        if ((config->mDomain & Config::IS_DECODER) || (config->mDomain & Config::IS_AUDIO)) {
+            if (clientSpecifiedInputSize) {
+                // Warn that we're overriding client's max input size if necessary.
+                if ((uint32_t)clientInputSize < maxInputSize.value) {
+                    ALOGD("client requested max input size %d, which is smaller than "
+                          "what component recommended (%u); overriding with component "
+                          "recommendation.", clientInputSize, maxInputSize.value);
+                    ALOGW("This behavior is subject to change. It is recommended that "
+                          "app developers double check whether the requested "
+                          "max input size is in reasonable range.");
+                } else {
+                    maxInputSize.value = clientInputSize;
+                }
+            }
+            // Pass max input size on input format to the buffer channel (if supplied by the
+            // component or by a default)
+            if (maxInputSize.value) {
+                config->mInputFormat->setInt32(
+                        KEY_MAX_INPUT_SIZE,
+                        (int32_t)(c2_min(maxInputSize.value, uint32_t(INT32_MAX))));
+            }
+        }
+
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
+            // propagate HDR static info to output format for both encoders and decoders
+            // if component supports this info, we will update from component, but only the raw port,
+            // so don't propagate if component already filled it in.
+            sp<ABuffer> hdrInfo;
+            if (msg->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)
+                    && !config->mOutputFormat->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)) {
+                config->mOutputFormat->setBuffer(KEY_HDR_STATIC_INFO, hdrInfo);
+            }
+
+            // Set desired color format from configuration parameter
+            int32_t format;
+            if (msg->findInt32("android._color-format", &format)) {
+                if (config->mDomain & Config::IS_ENCODER) {
+                    config->mInputFormat->setInt32(KEY_COLOR_FORMAT, format);
+                } else {
+                    config->mOutputFormat->setInt32(KEY_COLOR_FORMAT, format);
+                }
+            }
+        }
+
+        // propagate encoder delay and padding to output format
+        if ((config->mDomain & Config::IS_DECODER) && (config->mDomain & Config::IS_AUDIO)) {
+            int delay = 0;
+            if (msg->findInt32("encoder-delay", &delay)) {
+                config->mOutputFormat->setInt32("encoder-delay", delay);
+            }
+            int padding = 0;
+            if (msg->findInt32("encoder-padding", &padding)) {
+                config->mOutputFormat->setInt32("encoder-padding", padding);
+            }
+        }
+
+        // set channel-mask
+        if (config->mDomain & Config::IS_AUDIO) {
+            int32_t mask;
+            if (msg->findInt32(KEY_CHANNEL_MASK, &mask)) {
+                if (config->mDomain & Config::IS_ENCODER) {
+                    config->mInputFormat->setInt32(KEY_CHANNEL_MASK, mask);
+                } else {
+                    config->mOutputFormat->setInt32(KEY_CHANNEL_MASK, mask);
+                }
+            }
+        }
+
+        ALOGD("setup formats input: %s and output: %s",
+                config->mInputFormat->debugString().c_str(),
+                config->mOutputFormat->debugString().c_str());
+        return OK;
+    };
+    if (tryAndReportOnError(doConfig) != OK) {
+        return;
+    }
+
+    Mutexed<Config>::Locked config(mConfig);
+
+    mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat);
+}
+
+void CCodec::initiateCreateInputSurface() {
+    status_t err = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            return UNKNOWN_ERROR;
+        }
+        // TODO: read it from intf() properly.
+        if (state->comp->getName().find("encoder") == std::string::npos) {
+            return INVALID_OPERATION;
+        }
+        return OK;
+    }();
+    if (err != OK) {
+        mCallback->onInputSurfaceCreationFailed(err);
+        return;
+    }
+
+    (new AMessage(kWhatCreateInputSurface, this))->post();
+}
+
+void CCodec::createInputSurface() {
+    status_t err;
+    sp<IGraphicBufferProducer> bufferProducer;
+
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+    }
+
+    std::shared_ptr<PersistentSurface> persistentSurface(CreateInputSurface());
+
+    if (persistentSurface->getHidlTarget()) {
+        sp<IInputSurface> inputSurface = IInputSurface::castFrom(
+                persistentSurface->getHidlTarget());
+        if (!inputSurface) {
+            ALOGE("Corrupted input surface");
+            mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR);
+            return;
+        }
+        err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
+                std::make_shared<Codec2Client::InputSurface>(inputSurface)));
+        bufferProducer = new H2BGraphicBufferProducer(inputSurface);
+    } else {
+        int32_t width = 0;
+        (void)outputFormat->findInt32("width", &width);
+        int32_t height = 0;
+        (void)outputFormat->findInt32("height", &height);
+        err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
+                persistentSurface->getBufferSource(), width, height));
+        bufferProducer = persistentSurface->getBufferProducer();
+    }
+
+    if (err != OK) {
+        ALOGE("Failed to set up input surface: %d", err);
+        mCallback->onInputSurfaceCreationFailed(err);
+        return;
+    }
+
+    mCallback->onInputSurfaceCreated(
+            inputFormat,
+            outputFormat,
+            new BufferProducerWrapper(bufferProducer));
+}
+
+status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
+    Mutexed<Config>::Locked config(mConfig);
+    config->mUsingSurface = true;
+
+    // we are now using surface - apply default color aspects to input format - as well as
+    // get dataspace
+    bool inputFormatChanged = config->updateFormats(config->IS_INPUT);
+    ALOGD("input format %s to %s",
+            inputFormatChanged ? "changed" : "unchanged",
+            config->mInputFormat->debugString().c_str());
+
+    // configure dataspace
+    static_assert(sizeof(int32_t) == sizeof(android_dataspace), "dataspace size mismatch");
+    android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+    (void)config->mInputFormat->findInt32("android._dataspace", (int32_t*)&dataSpace);
+    surface->setDataSpace(dataSpace);
+
+    status_t err = mChannel->setInputSurface(surface);
+    if (err != OK) {
+        // undo input format update
+        config->mUsingSurface = false;
+        (void)config->updateFormats(config->IS_INPUT);
+        return err;
+    }
+    config->mInputSurface = surface;
+
+    if (config->mISConfig) {
+        surface->configure(*config->mISConfig);
+    } else {
+        ALOGD("ISConfig: no configuration");
+    }
+
+    return surface->start();
+}
+
+void CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) {
+    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
+    msg->setObject("surface", surface);
+    msg->post();
+}
+
+void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+    }
+    auto hidlTarget = surface->getHidlTarget();
+    if (hidlTarget) {
+        sp<IInputSurface> inputSurface =
+                IInputSurface::castFrom(hidlTarget);
+        if (!inputSurface) {
+            ALOGE("Failed to set input surface: Corrupted surface.");
+            mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
+            return;
+        }
+        status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
+                std::make_shared<Codec2Client::InputSurface>(inputSurface)));
+        if (err != OK) {
+            ALOGE("Failed to set up input surface: %d", err);
+            mCallback->onInputSurfaceDeclined(err);
+            return;
+        }
+    } else {
+        int32_t width = 0;
+        (void)outputFormat->findInt32("width", &width);
+        int32_t height = 0;
+        (void)outputFormat->findInt32("height", &height);
+        status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
+                surface->getBufferSource(), width, height));
+        if (err != OK) {
+            ALOGE("Failed to set up input surface: %d", err);
+            mCallback->onInputSurfaceDeclined(err);
+            return;
+        }
+    }
+    mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
+}
+
+void CCodec::initiateStart() {
+    auto setStarting = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(STARTING);
+        return OK;
+    };
+    if (tryAndReportOnError(setStarting) != OK) {
+        return;
+    }
+
+    (new AMessage(kWhatStart, this))->post();
+}
+
+void CCodec::start() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkStarting = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != STARTING) {
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkStarting) != OK) {
+        return;
+    }
+
+    c2_status_t err = comp->start();
+    if (err != C2_OK) {
+        mCallback->onError(toStatusT(err, C2_OPERATION_Component_start),
+                           ACTION_CODE_FATAL);
+        return;
+    }
+    sp<AMessage> inputFormat;
+    sp<AMessage> outputFormat;
+    {
+        Mutexed<Config>::Locked config(mConfig);
+        inputFormat = config->mInputFormat;
+        outputFormat = config->mOutputFormat;
+    }
+    status_t err2 = mChannel->start(inputFormat, outputFormat);
+    if (err2 != OK) {
+        mCallback->onError(err2, ACTION_CODE_FATAL);
+        return;
+    }
+
+    auto setRunning = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != STARTING) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(RUNNING);
+        return OK;
+    };
+    if (tryAndReportOnError(setRunning) != OK) {
+        return;
+    }
+    mCallback->onStartCompleted();
+
+    (void)mChannel->requestInitialInputBuffers();
+}
+
+void CCodec::initiateShutdown(bool keepComponentAllocated) {
+    if (keepComponentAllocated) {
+        initiateStop();
+    } else {
+        initiateRelease();
+    }
+}
+
+void CCodec::initiateStop() {
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == ALLOCATED
+                || state->get()  == RELEASED
+                || state->get() == STOPPING
+                || state->get() == RELEASING) {
+            // We're already stopped, released, or doing it right now.
+            state.unlock();
+            mCallback->onStopCompleted();
+            state.lock();
+            return;
+        }
+        state->set(STOPPING);
+    }
+
+    mChannel->stop();
+    (new AMessage(kWhatStop, this))->post();
+}
+
+void CCodec::stop() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASING) {
+            state.unlock();
+            // We're already stopped or release is in progress.
+            mCallback->onStopCompleted();
+            state.lock();
+            return;
+        } else if (state->get() != STOPPING) {
+            state.unlock();
+            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            state.lock();
+            return;
+        }
+        comp = state->comp;
+    }
+    status_t err = comp->stop();
+    if (err != C2_OK) {
+        // TODO: convert err into status_t
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+    }
+
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == STOPPING) {
+            state->set(ALLOCATED);
+        }
+    }
+    mCallback->onStopCompleted();
+}
+
+void CCodec::initiateRelease(bool sendCallback /* = true */) {
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED || state->get() == RELEASING) {
+            // We're already released or doing it right now.
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        if (state->get() == ALLOCATING) {
+            state->set(RELEASING);
+            // With the altered state allocate() would fail and clean up.
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        state->set(RELEASING);
+    }
+
+    mChannel->stop();
+    // thiz holds strong ref to this while the thread is running.
+    sp<CCodec> thiz(this);
+    std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach();
+}
+
+void CCodec::release(bool sendCallback) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            if (sendCallback) {
+                state.unlock();
+                mCallback->onReleaseCompleted();
+                state.lock();
+            }
+            return;
+        }
+        comp = state->comp;
+    }
+    comp->release();
+
+    {
+        Mutexed<State>::Locked state(mState);
+        state->set(RELEASED);
+        state->comp.reset();
+    }
+    if (sendCallback) {
+        mCallback->onReleaseCompleted();
+    }
+}
+
+status_t CCodec::setSurface(const sp<Surface> &surface) {
+    return mChannel->setSurface(surface);
+}
+
+void CCodec::signalFlush() {
+    status_t err = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == FLUSHED) {
+            return ALREADY_EXISTS;
+        }
+        if (state->get() != RUNNING) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(FLUSHING);
+        return OK;
+    }();
+    switch (err) {
+        case ALREADY_EXISTS:
+            mCallback->onFlushCompleted();
+            return;
+        case OK:
+            break;
+        default:
+            mCallback->onError(err, ACTION_CODE_FATAL);
+            return;
+    }
+
+    mChannel->stop();
+    (new AMessage(kWhatFlush, this))->post();
+}
+
+void CCodec::flush() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkFlushing = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != FLUSHING) {
+            return UNKNOWN_ERROR;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkFlushing) != OK) {
+        return;
+    }
+
+    std::list<std::unique_ptr<C2Work>> flushedWork;
+    c2_status_t err = comp->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    {
+        Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+        flushedWork.splice(flushedWork.end(), *queue);
+    }
+    if (err != C2_OK) {
+        // TODO: convert err into status_t
+        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+    }
+
+    mChannel->flush(flushedWork);
+    subQueuedWorkCount(flushedWork.size());
+
+    {
+        Mutexed<State>::Locked state(mState);
+        state->set(FLUSHED);
+    }
+    mCallback->onFlushCompleted();
+}
+
+void CCodec::signalResume() {
+    auto setResuming = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != FLUSHED) {
+            return UNKNOWN_ERROR;
+        }
+        state->set(RESUMING);
+        return OK;
+    };
+    if (tryAndReportOnError(setResuming) != OK) {
+        return;
+    }
+
+    (void)mChannel->start(nullptr, nullptr);
+
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != RESUMING) {
+            state.unlock();
+            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            state.lock();
+            return;
+        }
+        state->set(RUNNING);
+    }
+
+    (void)mChannel->requestInitialInputBuffers();
+}
+
+void CCodec::signalSetParameters(const sp<AMessage> &params) {
+    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
+    msg->setMessage("params", params);
+    msg->post();
+}
+
+void CCodec::setParameters(const sp<AMessage> &params) {
+    std::shared_ptr<Codec2Client::Component> comp;
+    auto checkState = [this, &comp] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            return INVALID_OPERATION;
+        }
+        comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkState) != OK) {
+        return;
+    }
+
+    Mutexed<Config>::Locked config(mConfig);
+
+    /**
+     * Handle input surface parameters
+     */
+    if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
+            && (config->mDomain & Config::IS_ENCODER) && config->mInputSurface && config->mISConfig) {
+        (void)params->findInt64("time-offset-us", &config->mISConfig->mTimeOffsetUs);
+
+        if (params->findInt64("skip-frames-before", &config->mISConfig->mStartAtUs)) {
+            config->mISConfig->mStopped = false;
+        } else if (params->findInt64("stop-time-us", &config->mISConfig->mStopAtUs)) {
+            config->mISConfig->mStopped = true;
+        }
+
+        int32_t value;
+        if (params->findInt32("drop-input-frames", &value)) {
+            config->mISConfig->mSuspended = value;
+            config->mISConfig->mSuspendAtUs = -1;
+            (void)params->findInt64("drop-start-time-us", &config->mISConfig->mSuspendAtUs);
+        }
+
+        (void)config->mInputSurface->configure(*config->mISConfig);
+        if (config->mISConfig->mStopped) {
+            config->mInputFormat->setInt64(
+                    "android._stop-time-offset-us", config->mISConfig->mInputDelayUs);
+        }
+    }
+
+    std::vector<std::unique_ptr<C2Param>> configUpdate;
+    (void)config->getConfigUpdateFromSdkParams(
+            comp, params, Config::IS_PARAM, C2_MAY_BLOCK, &configUpdate);
+    // Prefer to pass parameters to the buffer channel, so they can be synchronized with the frames.
+    // Parameter synchronization is not defined when using input surface. For now, route
+    // these directly to the component.
+    if (config->mInputSurface == nullptr
+            && (property_get_bool("debug.stagefright.ccodec_delayed_params", false)
+                    || comp->getName().find("c2.android.") == 0)) {
+        mChannel->setParameters(configUpdate);
+    } else {
+        (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK);
+    }
+}
+
+void CCodec::signalEndOfInputStream() {
+    mCallback->onSignaledInputEOS(mChannel->signalEndOfInputStream());
+}
+
+void CCodec::signalRequestIDRFrame() {
+    std::shared_ptr<Codec2Client::Component> comp;
+    {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() == RELEASED) {
+            ALOGD("no IDR request sent since component is released");
+            return;
+        }
+        comp = state->comp;
+    }
+    ALOGV("request IDR");
+    Mutexed<Config>::Locked config(mConfig);
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.push_back(
+            std::make_unique<C2StreamRequestSyncFrameTuning::output>(0u, true));
+    config->setParameters(comp, params, C2_MAY_BLOCK);
+}
+
+void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems,
+                        size_t numDiscardedInputBuffers) {
+    if (!workItems.empty()) {
+        {
+            Mutexed<std::list<size_t>>::Locked numDiscardedInputBuffersQueue(
+                    mNumDiscardedInputBuffersQueue);
+            numDiscardedInputBuffersQueue->insert(
+                    numDiscardedInputBuffersQueue->end(),
+                    workItems.size() - 1, 0);
+            numDiscardedInputBuffersQueue->emplace_back(
+                    numDiscardedInputBuffers);
+        }
+        {
+            Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+            queue->splice(queue->end(), workItems);
+        }
+    }
+    (new AMessage(kWhatWorkDone, this))->post();
+}
+
+void CCodec::onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer) {
+    mChannel->onInputBufferDone(buffer);
+}
+
+void CCodec::onMessageReceived(const sp<AMessage> &msg) {
+    TimePoint now = std::chrono::steady_clock::now();
+    CCodecWatchdog::getInstance()->watch(this);
+    switch (msg->what()) {
+        case kWhatAllocate: {
+            // C2ComponentStore::createComponent() should return within 100ms.
+            setDeadline(now, 150ms, "allocate");
+            sp<RefBase> obj;
+            CHECK(msg->findObject("codecInfo", &obj));
+            allocate((MediaCodecInfo *)obj.get());
+            break;
+        }
+        case kWhatConfigure: {
+            // C2Component::commit_sm() should return within 5ms.
+            setDeadline(now, 250ms, "configure");
+            sp<AMessage> format;
+            CHECK(msg->findMessage("format", &format));
+            configure(format);
+            break;
+        }
+        case kWhatStart: {
+            // C2Component::start() should return within 500ms.
+            setDeadline(now, 550ms, "start");
+            mQueuedWorkCount = 0;
+            start();
+            break;
+        }
+        case kWhatStop: {
+            // C2Component::stop() should return within 500ms.
+            setDeadline(now, 550ms, "stop");
+            stop();
+
+            mQueuedWorkCount = 0;
+            Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
+            deadline->set(TimePoint::max(), "none");
+            break;
+        }
+        case kWhatFlush: {
+            // C2Component::flush_sm() should return within 5ms.
+            setDeadline(now, 50ms, "flush");
+            flush();
+            break;
+        }
+        case kWhatCreateInputSurface: {
+            // Surface operations may be briefly blocking.
+            setDeadline(now, 100ms, "createInputSurface");
+            createInputSurface();
+            break;
+        }
+        case kWhatSetInputSurface: {
+            // Surface operations may be briefly blocking.
+            setDeadline(now, 100ms, "setInputSurface");
+            sp<RefBase> obj;
+            CHECK(msg->findObject("surface", &obj));
+            sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get()));
+            setInputSurface(surface);
+            break;
+        }
+        case kWhatSetParameters: {
+            setDeadline(now, 50ms, "setParameters");
+            sp<AMessage> params;
+            CHECK(msg->findMessage("params", &params));
+            setParameters(params);
+            break;
+        }
+        case kWhatWorkDone: {
+            std::unique_ptr<C2Work> work;
+            size_t numDiscardedInputBuffers;
+            bool shouldPost = false;
+            {
+                Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
+                if (queue->empty()) {
+                    break;
+                }
+                work.swap(queue->front());
+                queue->pop_front();
+                shouldPost = !queue->empty();
+            }
+            {
+                Mutexed<std::list<size_t>>::Locked numDiscardedInputBuffersQueue(
+                        mNumDiscardedInputBuffersQueue);
+                if (numDiscardedInputBuffersQueue->empty()) {
+                    numDiscardedInputBuffers = 0;
+                } else {
+                    numDiscardedInputBuffers = numDiscardedInputBuffersQueue->front();
+                    numDiscardedInputBuffersQueue->pop_front();
+                }
+            }
+            if (shouldPost) {
+                (new AMessage(kWhatWorkDone, this))->post();
+            }
+
+            if (work->worklets.empty()
+                    || !(work->worklets.front()->output.flags & C2FrameData::FLAG_INCOMPLETE)) {
+                subQueuedWorkCount(1);
+            }
+            // handle configuration changes in work done
+            Mutexed<Config>::Locked config(mConfig);
+            bool changed = false;
+            Config::Watcher<C2StreamInitDataInfo::output> initData =
+                config->watch<C2StreamInitDataInfo::output>();
+            if (!work->worklets.empty()
+                    && (work->worklets.front()->output.flags
+                            & C2FrameData::FLAG_DISCARD_FRAME) == 0) {
+
+                // copy buffer info to config
+                std::vector<std::unique_ptr<C2Param>> updates =
+                    std::move(work->worklets.front()->output.configUpdate);
+                unsigned stream = 0;
+                for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
+                    for (const std::shared_ptr<const C2Info> &info : buf->info()) {
+                        // move all info into output-stream #0 domain
+                        updates.emplace_back(C2Param::CopyAsStream(*info, true /* output */, stream));
+                    }
+                    for (const C2ConstGraphicBlock &block : buf->data().graphicBlocks()) {
+                        // ALOGV("got output buffer with crop %u,%u+%u,%u and size %u,%u",
+                        //      block.crop().left, block.crop().top,
+                        //      block.crop().width, block.crop().height,
+                        //      block.width(), block.height());
+                        updates.emplace_back(new C2StreamCropRectInfo::output(stream, block.crop()));
+                        updates.emplace_back(new C2StreamPictureSizeInfo::output(
+                                stream, block.width(), block.height()));
+                        break; // for now only do the first block
+                    }
+                    ++stream;
+                }
+
+                changed = config->updateConfiguration(updates, config->mOutputDomain);
+
+                // copy standard infos to graphic buffers if not already present (otherwise, we
+                // may overwrite the actual intermediate value with a final value)
+                stream = 0;
+                const static std::vector<C2Param::Index> stdGfxInfos = {
+                    C2StreamRotationInfo::output::PARAM_TYPE,
+                    C2StreamColorAspectsInfo::output::PARAM_TYPE,
+                    C2StreamDataSpaceInfo::output::PARAM_TYPE,
+                    C2StreamHdrStaticInfo::output::PARAM_TYPE,
+                    C2StreamPixelAspectRatioInfo::output::PARAM_TYPE,
+                    C2StreamSurfaceScalingInfo::output::PARAM_TYPE
+                };
+                for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
+                    if (buf->data().graphicBlocks().size()) {
+                        for (C2Param::Index ix : stdGfxInfos) {
+                            if (!buf->hasInfo(ix)) {
+                                const C2Param *param =
+                                    config->getConfigParameterValue(ix.withStream(stream));
+                                if (param) {
+                                    std::shared_ptr<C2Param> info(C2Param::Copy(*param));
+                                    buf->setInfo(std::static_pointer_cast<C2Info>(info));
+                                }
+                            }
+                        }
+                    }
+                    ++stream;
+                }
+            }
+            mChannel->onWorkDone(
+                    std::move(work), changed ? config->mOutputFormat : nullptr,
+                    initData.hasChanged() ? initData.update().get() : nullptr,
+                    numDiscardedInputBuffers);
+            break;
+        }
+        case kWhatWatch: {
+            // watch message already posted; no-op.
+            break;
+        }
+        default: {
+            ALOGE("unrecognized message");
+            break;
+        }
+    }
+    setDeadline(TimePoint::max(), 0ms, "none");
+}
+
+void CCodec::setDeadline(
+        const TimePoint &now,
+        const std::chrono::milliseconds &timeout,
+        const char *name) {
+    int32_t mult = std::max(1, property_get_int32("debug.stagefright.ccodec_timeout_mult", 1));
+    Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
+    deadline->set(now + (timeout * mult), name);
+}
+
+void CCodec::initiateReleaseIfStuck() {
+    std::string name;
+    bool pendingDeadline = false;
+    for (Mutexed<NamedTimePoint> *deadlinePtr : { &mDeadline, &mQueueDeadline, &mEosDeadline }) {
+        Mutexed<NamedTimePoint>::Locked deadline(*deadlinePtr);
+        if (deadline->get() < std::chrono::steady_clock::now()) {
+            name = deadline->getName();
+            break;
+        }
+        if (deadline->get() != TimePoint::max()) {
+            pendingDeadline = true;
+        }
+    }
+    if (name.empty()) {
+        // We're not stuck.
+        if (pendingDeadline) {
+            // If we are not stuck yet but still has deadline coming up,
+            // post watch message to check back later.
+            (new AMessage(kWhatWatch, this))->post();
+        }
+        return;
+    }
+
+    ALOGW("previous call to %s exceeded timeout", name.c_str());
+    initiateRelease(false);
+    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+}
+
+void CCodec::onWorkQueued(bool eos) {
+    ALOGV("queued work count +1 from %d", mQueuedWorkCount.load());
+    int32_t count = ++mQueuedWorkCount;
+    if (eos) {
+        CCodecWatchdog::getInstance()->watch(this);
+        Mutexed<NamedTimePoint>::Locked deadline(mEosDeadline);
+        deadline->set(std::chrono::steady_clock::now() + 3s, "eos");
+    }
+    // TODO: query and use input/pipeline/output delay combined
+    if (count >= 8) {
+        CCodecWatchdog::getInstance()->watch(this);
+        Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
+        deadline->set(std::chrono::steady_clock::now() + 3s, "queue");
+    }
+}
+
+void CCodec::subQueuedWorkCount(uint32_t count) {
+    ALOGV("queued work count -%u from %d", count, mQueuedWorkCount.load());
+    int32_t currentCount = (mQueuedWorkCount -= count);
+    if (currentCount == 0) {
+        Mutexed<NamedTimePoint>::Locked deadline(mEosDeadline);
+        deadline->set(TimePoint::max(), "none");
+    }
+    Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
+    deadline->set(TimePoint::max(), "none");
+}
+
+}  // namespace android
+
+extern "C" android::CodecBase *CreateCodec() {
+    return new android::CCodec;
+}
+
+extern "C" android::PersistentSurface *CreateInputSurface() {
+    // Attempt to create a Codec2's input surface.
+    std::shared_ptr<android::Codec2Client::InputSurface> inputSurface =
+            android::Codec2Client::CreateInputSurface();
+    if (inputSurface) {
+        return new android::PersistentSurface(
+                inputSurface->getGraphicBufferProducer(),
+                static_cast<android::sp<android::hidl::base::V1_0::IBase>>(
+                inputSurface->getHalInterface()));
+    }
+
+    // Fall back to OMX.
+    using namespace android::hardware::media::omx::V1_0;
+    using namespace android::hardware::media::omx::V1_0::utils;
+    using namespace android::hardware::graphics::bufferqueue::V1_0::utils;
+    typedef android::hardware::media::omx::V1_0::Status OmxStatus;
+    android::sp<IOmx> omx = IOmx::getService();
+    typedef android::hardware::graphics::bufferqueue::V1_0::
+            IGraphicBufferProducer HGraphicBufferProducer;
+    typedef android::hardware::media::omx::V1_0::
+            IGraphicBufferSource HGraphicBufferSource;
+    OmxStatus s;
+    android::sp<HGraphicBufferProducer> gbp;
+    android::sp<HGraphicBufferSource> gbs;
+    android::Return<void> transStatus = omx->createInputSurface(
+            [&s, &gbp, &gbs](
+                    OmxStatus status,
+                    const android::sp<HGraphicBufferProducer>& producer,
+                    const android::sp<HGraphicBufferSource>& source) {
+                s = status;
+                gbp = producer;
+                gbs = source;
+            });
+    if (transStatus.isOk() && s == OmxStatus::OK) {
+        return new android::PersistentSurface(
+                new H2BGraphicBufferProducer(gbp),
+                sp<::android::IGraphicBufferSource>(
+                    new LWGraphicBufferSource(gbs)));
+    }
+
+    return nullptr;
+}
+
diff --git a/media/codec2/sfplugin/CCodec.h b/media/codec2/sfplugin/CCodec.h
new file mode 100644
index 0000000..78b009e
--- /dev/null
+++ b/media/codec2/sfplugin/CCodec.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 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 C_CODEC_H_
+#define C_CODEC_H_
+
+#include <chrono>
+#include <list>
+#include <memory>
+#include <set>
+
+#include <C2Component.h>
+#include <codec2/hidl/client.h>
+
+#include <android/native_window.h>
+#include <media/hardware/MetadataBufferType.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/stagefright/CodecBase.h>
+#include <media/stagefright/FrameRenderTracker.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
+#include <hardware/gralloc.h>
+#include <nativebase/nativebase.h>
+
+#include "CCodecConfig.h"
+
+namespace android {
+
+class CCodecBufferChannel;
+class InputSurfaceWrapper;
+struct MediaCodecInfo;
+
+class CCodec : public CodecBase {
+public:
+    CCodec();
+
+    virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
+    virtual void initiateAllocateComponent(const sp<AMessage> &msg) override;
+    virtual void initiateConfigureComponent(const sp<AMessage> &msg) override;
+    virtual void initiateCreateInputSurface() override;
+    virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override;
+    virtual void initiateStart() override;
+    virtual void initiateShutdown(bool keepComponentAllocated = false) override;
+
+    virtual status_t setSurface(const sp<Surface> &surface) override;
+
+    virtual void signalFlush() override;
+    virtual void signalResume() override;
+
+    virtual void signalSetParameters(const sp<AMessage> &params) override;
+    virtual void signalEndOfInputStream() override;
+    virtual void signalRequestIDRFrame() override;
+
+    void initiateReleaseIfStuck();
+    void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems,
+                    size_t numDiscardedInputBuffers);
+    void onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer);
+
+protected:
+    virtual ~CCodec();
+
+    virtual void onMessageReceived(const sp<AMessage> &msg) override;
+
+private:
+    typedef std::chrono::time_point<std::chrono::steady_clock> TimePoint;
+
+    status_t tryAndReportOnError(std::function<status_t()> job);
+
+    void initiateStop();
+    void initiateRelease(bool sendCallback = true);
+
+    void allocate(const sp<MediaCodecInfo> &codecInfo);
+    void configure(const sp<AMessage> &msg);
+    void start();
+    void stop();
+    void flush();
+    void release(bool sendCallback);
+
+    void createInputSurface();
+    void setInputSurface(const sp<PersistentSurface> &surface);
+    status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
+    void setParameters(const sp<AMessage> &params);
+
+    void setDeadline(
+            const TimePoint &now,
+            const std::chrono::milliseconds &timeout,
+            const char *name);
+
+    void onWorkQueued(bool eos);
+    void subQueuedWorkCount(uint32_t count);
+
+    enum {
+        kWhatAllocate,
+        kWhatConfigure,
+        kWhatStart,
+        kWhatFlush,
+        kWhatStop,
+        kWhatRelease,
+        kWhatCreateInputSurface,
+        kWhatSetInputSurface,
+        kWhatSetParameters,
+
+        kWhatWorkDone,
+        kWhatWatch,
+    };
+
+    enum {
+        RELEASED,
+        ALLOCATED,
+        FLUSHED,
+        RUNNING,
+
+        ALLOCATING,  // RELEASED -> ALLOCATED
+        STARTING,    // ALLOCATED -> RUNNING
+        STOPPING,    // RUNNING -> ALLOCATED
+        FLUSHING,    // RUNNING -> FLUSHED
+        RESUMING,    // FLUSHED -> RUNNING
+        RELEASING,   // {ANY EXCEPT RELEASED} -> RELEASED
+    };
+
+    struct State {
+        inline State() : mState(RELEASED) {}
+        inline int get() const { return mState; }
+        inline void set(int newState) { mState = newState; }
+
+        std::shared_ptr<Codec2Client::Component> comp;
+    private:
+        int mState;
+    };
+
+    struct NamedTimePoint {
+        NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
+
+        inline void set(
+                const TimePoint &timePoint,
+                const char *name) {
+            mTimePoint = timePoint;
+            mName = name;
+        }
+
+        inline TimePoint get() const { return mTimePoint; }
+        inline const char *getName() const { return mName; }
+    private:
+        TimePoint mTimePoint;
+        const char *mName;
+    };
+
+    Mutexed<State> mState;
+    std::shared_ptr<CCodecBufferChannel> mChannel;
+
+    std::shared_ptr<Codec2Client> mClient;
+    std::shared_ptr<Codec2Client::Listener> mClientListener;
+    struct ClientListener;
+
+    Mutexed<NamedTimePoint> mDeadline;
+    std::atomic_int32_t mQueuedWorkCount;
+    Mutexed<NamedTimePoint> mQueueDeadline;
+    Mutexed<NamedTimePoint> mEosDeadline;
+    typedef CCodecConfig Config;
+    Mutexed<Config> mConfig;
+    Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
+    Mutexed<std::list<size_t>> mNumDiscardedInputBuffersQueue;
+
+    friend class CCodecCallbackImpl;
+
+    DISALLOW_EVIL_CONSTRUCTORS(CCodec);
+};
+
+}  // namespace android
+
+#endif  // C_CODEC_H_
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
new file mode 100644
index 0000000..01b9c1e
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -0,0 +1,2791 @@
+/*
+ * Copyright 2017, 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 "CCodecBufferChannel"
+#include <utils/Log.h>
+
+#include <numeric>
+
+#include <C2AllocatorGralloc.h>
+#include <C2PlatformSupport.h>
+#include <C2BlockInternal.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <android-base/stringprintf.h>
+#include <binder/MemoryDealer.h>
+#include <gui/Surface.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/MediaCodecBuffer.h>
+#include <system/window.h>
+
+#include "CCodecBufferChannel.h"
+#include "Codec2Buffer.h"
+#include "SkipCutBuffer.h"
+
+namespace android {
+
+using android::base::StringPrintf;
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
+
+using CasStatus = hardware::cas::V1_0::Status;
+
+/**
+ * Base class for representation of buffers at one port.
+ */
+class CCodecBufferChannel::Buffers {
+public:
+    Buffers(const char *componentName, const char *name = "Buffers")
+        : mComponentName(componentName),
+          mChannelName(std::string(componentName) + ":" + name),
+          mName(mChannelName.c_str()) {
+    }
+    virtual ~Buffers() = default;
+
+    /**
+     * Set format for MediaCodec-facing buffers.
+     */
+    void setFormat(const sp<AMessage> &format) {
+        CHECK(format != nullptr);
+        mFormat = format;
+    }
+
+    /**
+     * Return a copy of current format.
+     */
+    sp<AMessage> dupFormat() {
+        return mFormat != nullptr ? mFormat->dup() : nullptr;
+    }
+
+    /**
+     * Returns true if the buffers are operating under array mode.
+     */
+    virtual bool isArrayMode() const { return false; }
+
+    /**
+     * Fills the vector with MediaCodecBuffer's if in array mode; otherwise,
+     * no-op.
+     */
+    virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {}
+
+protected:
+    std::string mComponentName; ///< name of component for debugging
+    std::string mChannelName; ///< name of channel for debugging
+    const char *mName; ///< C-string version of channel name
+    // Format to be used for creating MediaCodec-facing buffers.
+    sp<AMessage> mFormat;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(Buffers);
+};
+
+class CCodecBufferChannel::InputBuffers : public CCodecBufferChannel::Buffers {
+public:
+    InputBuffers(const char *componentName, const char *name = "Input[]")
+        : Buffers(componentName, name) { }
+    virtual ~InputBuffers() = default;
+
+    /**
+     * Set a block pool to obtain input memory blocks.
+     */
+    void setPool(const std::shared_ptr<C2BlockPool> &pool) { mPool = pool; }
+
+    /**
+     * Get a new MediaCodecBuffer for input and its corresponding index.
+     * Returns false if no new buffer can be obtained at the moment.
+     */
+    virtual bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) = 0;
+
+    /**
+     * Release the buffer obtained from requestNewBuffer() and get the
+     * associated C2Buffer object back. Returns true if the buffer was on file
+     * and released successfully.
+     */
+    virtual bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0;
+
+    /**
+     * Release the buffer that is no longer used by the codec process. Return
+     * true if and only if the buffer was on file and released successfully.
+     */
+    virtual bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) = 0;
+
+    /**
+     * Flush internal state. After this call, no index or buffer previously
+     * returned from requestNewBuffer() is valid.
+     */
+    virtual void flush() = 0;
+
+    /**
+     * Return array-backed version of input buffers. The returned object
+     * shall retain the internal state so that it will honor index and
+     * buffer from previous calls of requestNewBuffer().
+     */
+    virtual std::unique_ptr<InputBuffers> toArrayMode(size_t size) = 0;
+
+protected:
+    // Pool to obtain blocks for input buffers.
+    std::shared_ptr<C2BlockPool> mPool;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(InputBuffers);
+};
+
+class CCodecBufferChannel::OutputBuffers : public CCodecBufferChannel::Buffers {
+public:
+    OutputBuffers(const char *componentName, const char *name = "Output")
+        : Buffers(componentName, name) { }
+    virtual ~OutputBuffers() = default;
+
+    /**
+     * Register output C2Buffer from the component and obtain corresponding
+     * index and MediaCodecBuffer object. Returns false if registration
+     * fails.
+     */
+    virtual status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) = 0;
+
+    /**
+     * Register codec specific data as a buffer to be consistent with
+     * MediaCodec behavior.
+     */
+    virtual status_t registerCsd(
+            const C2StreamCsdInfo::output * /* csd */,
+            size_t * /* index */,
+            sp<MediaCodecBuffer> * /* clientBuffer */) = 0;
+
+    /**
+     * Release the buffer obtained from registerBuffer() and get the
+     * associated C2Buffer object back. Returns true if the buffer was on file
+     * and released successfully.
+     */
+    virtual bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0;
+
+    /**
+     * Flush internal state. After this call, no index or buffer previously
+     * returned from registerBuffer() is valid.
+     */
+    virtual void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) = 0;
+
+    /**
+     * Return array-backed version of output buffers. The returned object
+     * shall retain the internal state so that it will honor index and
+     * buffer from previous calls of registerBuffer().
+     */
+    virtual std::unique_ptr<OutputBuffers> toArrayMode(size_t size) = 0;
+
+    /**
+     * Initialize SkipCutBuffer object.
+     */
+    void initSkipCutBuffer(
+            int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount) {
+        CHECK(mSkipCutBuffer == nullptr);
+        mDelay = delay;
+        mPadding = padding;
+        mSampleRate = sampleRate;
+        setSkipCutBuffer(delay, padding, channelCount);
+    }
+
+    /**
+     * Update the SkipCutBuffer object. No-op if it's never initialized.
+     */
+    void updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) {
+        if (mSkipCutBuffer == nullptr) {
+            return;
+        }
+        int32_t delay = mDelay;
+        int32_t padding = mPadding;
+        if (sampleRate != mSampleRate) {
+            delay = ((int64_t)delay * sampleRate) / mSampleRate;
+            padding = ((int64_t)padding * sampleRate) / mSampleRate;
+        }
+        setSkipCutBuffer(delay, padding, channelCount);
+    }
+
+    /**
+     * Submit buffer to SkipCutBuffer object, if initialized.
+     */
+    void submit(const sp<MediaCodecBuffer> &buffer) {
+        if (mSkipCutBuffer != nullptr) {
+            mSkipCutBuffer->submit(buffer);
+        }
+    }
+
+    /**
+     * Transfer SkipCutBuffer object to the other Buffers object.
+     */
+    void transferSkipCutBuffer(const sp<SkipCutBuffer> &scb) {
+        mSkipCutBuffer = scb;
+    }
+
+protected:
+    sp<SkipCutBuffer> mSkipCutBuffer;
+
+private:
+    int32_t mDelay;
+    int32_t mPadding;
+    int32_t mSampleRate;
+
+    void setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount) {
+        if (mSkipCutBuffer != nullptr) {
+            size_t prevSize = mSkipCutBuffer->size();
+            if (prevSize != 0u) {
+                ALOGD("[%s] Replacing SkipCutBuffer holding %zu bytes", mName, prevSize);
+            }
+        }
+        mSkipCutBuffer = new SkipCutBuffer(skip, cut, channelCount);
+    }
+
+    DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
+};
+
+namespace {
+
+// TODO: get this info from component
+const static size_t kMinInputBufferArraySize = 4;
+const static size_t kMaxPipelineCapacity = 18;
+const static size_t kChannelOutputDelay = 0;
+const static size_t kMinOutputBufferArraySize = kMaxPipelineCapacity +
+                                                kChannelOutputDelay;
+const static size_t kLinearBufferSize = 1048576;
+// This can fit 4K RGBA frame, and most likely client won't need more than this.
+const static size_t kMaxLinearBufferSize = 3840 * 2160 * 4;
+
+/**
+ * Simple local buffer pool backed by std::vector.
+ */
+class LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> {
+public:
+    /**
+     * Create a new LocalBufferPool object.
+     *
+     * \param poolCapacity  max total size of buffers managed by this pool.
+     *
+     * \return  a newly created pool object.
+     */
+    static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity) {
+        return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity));
+    }
+
+    /**
+     * Return an ABuffer object whose size is at least |capacity|.
+     *
+     * \param   capacity  requested capacity
+     * \return  nullptr if the pool capacity is reached
+     *          an ABuffer object otherwise.
+     */
+    sp<ABuffer> newBuffer(size_t capacity) {
+        Mutex::Autolock lock(mMutex);
+        auto it = std::find_if(
+                mPool.begin(), mPool.end(),
+                [capacity](const std::vector<uint8_t> &vec) {
+                    return vec.capacity() >= capacity;
+                });
+        if (it != mPool.end()) {
+            sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
+            mPool.erase(it);
+            return buffer;
+        }
+        if (mUsedSize + capacity > mPoolCapacity) {
+            while (!mPool.empty()) {
+                mUsedSize -= mPool.back().capacity();
+                mPool.pop_back();
+            }
+            if (mUsedSize + capacity > mPoolCapacity) {
+                ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
+                        mUsedSize, capacity, mPoolCapacity);
+                return nullptr;
+            }
+        }
+        std::vector<uint8_t> vec(capacity);
+        mUsedSize += vec.capacity();
+        return new VectorBuffer(std::move(vec), shared_from_this());
+    }
+
+private:
+    /**
+     * ABuffer backed by std::vector.
+     */
+    class VectorBuffer : public ::android::ABuffer {
+    public:
+        /**
+         * Construct a VectorBuffer by taking the ownership of supplied vector.
+         *
+         * \param vec   backing vector of the buffer. this object takes
+         *              ownership at construction.
+         * \param pool  a LocalBufferPool object to return the vector at
+         *              destruction.
+         */
+        VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
+            : ABuffer(vec.data(), vec.capacity()),
+              mVec(std::move(vec)),
+              mPool(pool) {
+        }
+
+        ~VectorBuffer() override {
+            std::shared_ptr<LocalBufferPool> pool = mPool.lock();
+            if (pool) {
+                // If pool is alive, return the vector back to the pool so that
+                // it can be recycled.
+                pool->returnVector(std::move(mVec));
+            }
+        }
+
+    private:
+        std::vector<uint8_t> mVec;
+        std::weak_ptr<LocalBufferPool> mPool;
+    };
+
+    Mutex mMutex;
+    size_t mPoolCapacity;
+    size_t mUsedSize;
+    std::list<std::vector<uint8_t>> mPool;
+
+    /**
+     * Private constructor to prevent constructing non-managed LocalBufferPool.
+     */
+    explicit LocalBufferPool(size_t poolCapacity)
+        : mPoolCapacity(poolCapacity), mUsedSize(0) {
+    }
+
+    /**
+     * Take back the ownership of vec from the destructed VectorBuffer and put
+     * it in front of the pool.
+     */
+    void returnVector(std::vector<uint8_t> &&vec) {
+        Mutex::Autolock lock(mMutex);
+        mPool.push_front(std::move(vec));
+    }
+
+    DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool);
+};
+
+sp<GraphicBlockBuffer> AllocateGraphicBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const sp<AMessage> &format,
+        uint32_t pixelFormat,
+        const C2MemoryUsage &usage,
+        const std::shared_ptr<LocalBufferPool> &localBufferPool) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
+        ALOGD("format lacks width or height");
+        return nullptr;
+    }
+
+    std::shared_ptr<C2GraphicBlock> block;
+    c2_status_t err = pool->fetchGraphicBlock(
+            width, height, pixelFormat, usage, &block);
+    if (err != C2_OK) {
+        ALOGD("fetch graphic block failed: %d", err);
+        return nullptr;
+    }
+
+    return GraphicBlockBuffer::Allocate(
+            format,
+            block,
+            [localBufferPool](size_t capacity) {
+                return localBufferPool->newBuffer(capacity);
+            });
+}
+
+class BuffersArrayImpl;
+
+/**
+ * Flexible buffer slots implementation.
+ */
+class FlexBuffersImpl {
+public:
+    FlexBuffersImpl(const char *name)
+        : mImplName(std::string(name) + ".Impl"),
+          mName(mImplName.c_str()) { }
+
+    /**
+     * Assign an empty slot for a buffer and return the index. If there's no
+     * empty slot, just add one at the end and return it.
+     *
+     * \param buffer[in]  a new buffer to assign a slot.
+     * \return            index of the assigned slot.
+     */
+    size_t assignSlot(const sp<Codec2Buffer> &buffer) {
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (mBuffers[i].clientBuffer == nullptr
+                    && mBuffers[i].compBuffer.expired()) {
+                mBuffers[i].clientBuffer = buffer;
+                return i;
+            }
+        }
+        mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() });
+        return mBuffers.size() - 1;
+    }
+
+    /**
+     * Release the slot from the client, and get the C2Buffer object back from
+     * the previously assigned buffer. Note that the slot is not completely free
+     * until the returned C2Buffer object is freed.
+     *
+     * \param   buffer[in]        the buffer previously assigned a slot.
+     * \param   c2buffer[in,out]  pointer to C2Buffer to be populated. Ignored
+     *                            if null.
+     * \return  true  if the buffer is successfully released from a slot
+     *          false otherwise
+     */
+    bool releaseSlot(const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) {
+        sp<Codec2Buffer> clientBuffer;
+        size_t index = mBuffers.size();
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (mBuffers[i].clientBuffer == buffer) {
+                clientBuffer = mBuffers[i].clientBuffer;
+                mBuffers[i].clientBuffer.clear();
+                index = i;
+                break;
+            }
+        }
+        if (clientBuffer == nullptr) {
+            ALOGV("[%s] %s: No matching buffer found", mName, __func__);
+            return false;
+        }
+        std::shared_ptr<C2Buffer> result = clientBuffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+        if (c2buffer) {
+            *c2buffer = result;
+        }
+        return true;
+    }
+
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            std::shared_ptr<C2Buffer> compBuffer =
+                    mBuffers[i].compBuffer.lock();
+            if (!compBuffer || compBuffer != c2buffer) {
+                continue;
+            }
+            mBuffers[i].clientBuffer = nullptr;
+            mBuffers[i].compBuffer.reset();
+            return true;
+        }
+        ALOGV("[%s] codec released an unknown buffer", mName);
+        return false;
+    }
+
+    void flush() {
+        ALOGV("[%s] buffers are flushed %zu", mName, mBuffers.size());
+        mBuffers.clear();
+    }
+
+private:
+    friend class BuffersArrayImpl;
+
+    std::string mImplName; ///< name for debugging
+    const char *mName; ///< C-string version of name
+
+    struct Entry {
+        sp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+    };
+    std::vector<Entry> mBuffers;
+};
+
+/**
+ * Static buffer slots implementation based on a fixed-size array.
+ */
+class BuffersArrayImpl {
+public:
+    BuffersArrayImpl()
+        : mImplName("BuffersArrayImpl"),
+          mName(mImplName.c_str()) { }
+
+    /**
+     * Initialize buffer array from the original |impl|. The buffers known by
+     * the client is preserved, and the empty slots are populated so that the
+     * array size is at least |minSize|.
+     *
+     * \param impl[in]      FlexBuffersImpl object used so far.
+     * \param minSize[in]   minimum size of the buffer array.
+     * \param allocate[in]  function to allocate a client buffer for an empty slot.
+     */
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate) {
+        mImplName = impl.mImplName + "[N]";
+        mName = mImplName.c_str();
+        for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
+            sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer;
+            bool ownedByClient = (clientBuffer != nullptr);
+            if (!ownedByClient) {
+                clientBuffer = allocate();
+            }
+            mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
+        }
+        ALOGV("[%s] converted %zu buffers to array mode of %zu", mName, mBuffers.size(), minSize);
+        for (size_t i = impl.mBuffers.size(); i < minSize; ++i) {
+            mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false });
+        }
+    }
+
+    /**
+     * Grab a buffer from the underlying array which matches the criteria.
+     *
+     * \param index[out]    index of the slot.
+     * \param buffer[out]   the matching buffer.
+     * \param match[in]     a function to test whether the buffer matches the
+     *                      criteria or not.
+     * \return OK           if successful,
+     *         WOULD_BLOCK  if slots are being used,
+     *         NO_MEMORY    if no slot matches the criteria, even though it's
+     *                      available
+     */
+    status_t grabBuffer(
+            size_t *index,
+            sp<Codec2Buffer> *buffer,
+            std::function<bool(const sp<Codec2Buffer> &)> match =
+                [](const sp<Codec2Buffer> &) { return true; }) {
+        // allBuffersDontMatch remains true if all buffers are available but
+        // match() returns false for every buffer.
+        bool allBuffersDontMatch = true;
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()) {
+                if (match(mBuffers[i].clientBuffer)) {
+                    mBuffers[i].ownedByClient = true;
+                    *buffer = mBuffers[i].clientBuffer;
+                    (*buffer)->meta()->clear();
+                    (*buffer)->setRange(0, (*buffer)->capacity());
+                    *index = i;
+                    return OK;
+                }
+            } else {
+                allBuffersDontMatch = false;
+            }
+        }
+        return allBuffersDontMatch ? NO_MEMORY : WOULD_BLOCK;
+    }
+
+    /**
+     * Return the buffer from the client, and get the C2Buffer object back from
+     * the buffer. Note that the slot is not completely free until the returned
+     * C2Buffer object is freed.
+     *
+     * \param   buffer[in]        the buffer previously grabbed.
+     * \param   c2buffer[in,out]  pointer to C2Buffer to be populated. Ignored
+     *                            if null.
+     * \return  true  if the buffer is successfully returned
+     *          false otherwise
+     */
+    bool returnBuffer(const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) {
+        sp<Codec2Buffer> clientBuffer;
+        size_t index = mBuffers.size();
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (mBuffers[i].clientBuffer == buffer) {
+                if (!mBuffers[i].ownedByClient) {
+                    ALOGD("[%s] Client returned a buffer it does not own according to our record: %zu", mName, i);
+                }
+                clientBuffer = mBuffers[i].clientBuffer;
+                mBuffers[i].ownedByClient = false;
+                index = i;
+                break;
+            }
+        }
+        if (clientBuffer == nullptr) {
+            ALOGV("[%s] %s: No matching buffer found", mName, __func__);
+            return false;
+        }
+        ALOGV("[%s] %s: matching buffer found (index=%zu)", mName, __func__, index);
+        std::shared_ptr<C2Buffer> result = clientBuffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+        if (c2buffer) {
+            *c2buffer = result;
+        }
+        return true;
+    }
+
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            std::shared_ptr<C2Buffer> compBuffer =
+                    mBuffers[i].compBuffer.lock();
+            if (!compBuffer) {
+                continue;
+            }
+            if (c2buffer == compBuffer) {
+                if (mBuffers[i].ownedByClient) {
+                    // This should not happen.
+                    ALOGD("[%s] codec released a buffer owned by client "
+                          "(index %zu)", mName, i);
+                    mBuffers[i].ownedByClient = false;
+                }
+                mBuffers[i].compBuffer.reset();
+                return true;
+            }
+        }
+        ALOGV("[%s] codec released an unknown buffer (array mode)", mName);
+        return false;
+    }
+
+    /**
+     * Populate |array| with the underlying buffer array.
+     *
+     * \param array[out]  an array to be filled with the underlying buffer array.
+     */
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const {
+        array->clear();
+        for (const Entry &entry : mBuffers) {
+            array->push(entry.clientBuffer);
+        }
+    }
+
+    /**
+     * The client abandoned all known buffers, so reclaim the ownership.
+     */
+    void flush() {
+        for (Entry &entry : mBuffers) {
+            entry.ownedByClient = false;
+        }
+    }
+
+    void realloc(std::function<sp<Codec2Buffer>()> alloc) {
+        size_t size = mBuffers.size();
+        mBuffers.clear();
+        for (size_t i = 0; i < size; ++i) {
+            mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
+        }
+    }
+
+private:
+    std::string mImplName; ///< name for debugging
+    const char *mName; ///< C-string version of name
+
+    struct Entry {
+        const sp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+        bool ownedByClient;
+    };
+    std::vector<Entry> mBuffers;
+};
+
+class InputBuffersArray : public CCodecBufferChannel::InputBuffers {
+public:
+    InputBuffersArray(const char *componentName, const char *name = "Input[N]")
+        : InputBuffers(componentName, name) { }
+    ~InputBuffersArray() override = default;
+
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate) {
+        mImpl.initialize(impl, minSize, allocate);
+    }
+
+    bool isArrayMode() const final { return true; }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
+            size_t) final {
+        return nullptr;
+    }
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
+        mImpl.getArray(array);
+    }
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
+        sp<Codec2Buffer> c2Buffer;
+        status_t err = mImpl.grabBuffer(index, &c2Buffer);
+        if (err == OK) {
+            c2Buffer->setFormat(mFormat);
+            *buffer = c2Buffer;
+            return true;
+        }
+        return false;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.returnBuffer(buffer, c2buffer);
+    }
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override {
+        return mImpl.expireComponentBuffer(c2buffer);
+    }
+
+    void flush() override {
+        mImpl.flush();
+    }
+
+private:
+    BuffersArrayImpl mImpl;
+};
+
+class LinearInputBuffers : public CCodecBufferChannel::InputBuffers {
+public:
+    LinearInputBuffers(const char *componentName, const char *name = "1D-Input")
+        : InputBuffers(componentName, name),
+          mImpl(mName) { }
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
+        int32_t capacity = kLinearBufferSize;
+        (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+        if ((size_t)capacity > kMaxLinearBufferSize) {
+            ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+            capacity = kMaxLinearBufferSize;
+        }
+        // TODO: proper max input size
+        // TODO: read usage from intf
+        sp<Codec2Buffer> newBuffer = alloc((size_t)capacity);
+        if (newBuffer == nullptr) {
+            return false;
+        }
+        *index = mImpl.assignSlot(newBuffer);
+        *buffer = newBuffer;
+        return true;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.releaseSlot(buffer, c2buffer);
+    }
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override {
+        return mImpl.expireComponentBuffer(c2buffer);
+    }
+
+    void flush() override {
+        // This is no-op by default unless we're in array mode where we need to keep
+        // track of the flushed work.
+        mImpl.flush();
+    }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
+            size_t size) final {
+        int32_t capacity = kLinearBufferSize;
+        (void)mFormat->findInt32(C2_NAME_STREAM_MAX_BUFFER_SIZE_SETTING, &capacity);
+
+        std::unique_ptr<InputBuffersArray> array(
+                new InputBuffersArray(mComponentName.c_str(), "1D-Input[N]"));
+        array->setPool(mPool);
+        array->setFormat(mFormat);
+        array->initialize(
+                mImpl,
+                size,
+                [this, capacity] () -> sp<Codec2Buffer> { return alloc(capacity); });
+        return std::move(array);
+    }
+
+    virtual sp<Codec2Buffer> alloc(size_t size) const {
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        std::shared_ptr<C2LinearBlock> block;
+
+        c2_status_t err = mPool->fetchLinearBlock(size, usage, &block);
+        if (err != C2_OK) {
+            return nullptr;
+        }
+
+        return LinearBlockBuffer::Allocate(mFormat, block);
+    }
+
+private:
+    FlexBuffersImpl mImpl;
+};
+
+class EncryptedLinearInputBuffers : public LinearInputBuffers {
+public:
+    EncryptedLinearInputBuffers(
+            bool secure,
+            const sp<MemoryDealer> &dealer,
+            const sp<ICrypto> &crypto,
+            int32_t heapSeqNum,
+            size_t capacity,
+            const char *componentName, const char *name = "EncryptedInput")
+        : LinearInputBuffers(componentName, name),
+          mUsage({0, 0}),
+          mDealer(dealer),
+          mCrypto(crypto),
+          mHeapSeqNum(heapSeqNum) {
+        if (secure) {
+            mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
+        } else {
+            mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        }
+        for (size_t i = 0; i < kMinInputBufferArraySize; ++i) {
+            sp<IMemory> memory = mDealer->allocate(capacity);
+            if (memory == nullptr) {
+                ALOGD("[%s] Failed to allocate memory from dealer: only %zu slots allocated", mName, i);
+                break;
+            }
+            mMemoryVector.push_back({std::weak_ptr<C2LinearBlock>(), memory});
+        }
+    }
+
+    ~EncryptedLinearInputBuffers() override {
+    }
+
+    sp<Codec2Buffer> alloc(size_t size) const override {
+        sp<IMemory> memory;
+        for (const Entry &entry : mMemoryVector) {
+            if (entry.block.expired()) {
+                memory = entry.memory;
+                break;
+            }
+        }
+        if (memory == nullptr) {
+            return nullptr;
+        }
+
+        std::shared_ptr<C2LinearBlock> block;
+        c2_status_t err = mPool->fetchLinearBlock(size, mUsage, &block);
+        if (err != C2_OK) {
+            return nullptr;
+        }
+
+        return new EncryptedLinearBlockBuffer(mFormat, block, memory, mHeapSeqNum);
+    }
+
+private:
+    C2MemoryUsage mUsage;
+    sp<MemoryDealer> mDealer;
+    sp<ICrypto> mCrypto;
+    int32_t mHeapSeqNum;
+    struct Entry {
+        std::weak_ptr<C2LinearBlock> block;
+        sp<IMemory> memory;
+    };
+    std::vector<Entry> mMemoryVector;
+};
+
+class GraphicMetadataInputBuffers : public CCodecBufferChannel::InputBuffers {
+public:
+    GraphicMetadataInputBuffers(const char *componentName, const char *name = "2D-MetaInput")
+        : InputBuffers(componentName, name),
+          mImpl(mName),
+          mStore(GetCodec2PlatformAllocatorStore()) { }
+    ~GraphicMetadataInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
+        std::shared_ptr<C2Allocator> alloc;
+        c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
+        if (err != C2_OK) {
+            return false;
+        }
+        sp<GraphicMetadataBuffer> newBuffer = new GraphicMetadataBuffer(mFormat, alloc);
+        if (newBuffer == nullptr) {
+            return false;
+        }
+        *index = mImpl.assignSlot(newBuffer);
+        *buffer = newBuffer;
+        return true;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.releaseSlot(buffer, c2buffer);
+    }
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override {
+        return mImpl.expireComponentBuffer(c2buffer);
+    }
+
+    void flush() override {
+        // This is no-op by default unless we're in array mode where we need to keep
+        // track of the flushed work.
+    }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
+            size_t size) final {
+        std::shared_ptr<C2Allocator> alloc;
+        c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
+        if (err != C2_OK) {
+            return nullptr;
+        }
+        std::unique_ptr<InputBuffersArray> array(
+                new InputBuffersArray(mComponentName.c_str(), "2D-MetaInput[N]"));
+        array->setPool(mPool);
+        array->setFormat(mFormat);
+        array->initialize(
+                mImpl,
+                size,
+                [format = mFormat, alloc]() -> sp<Codec2Buffer> {
+                    return new GraphicMetadataBuffer(format, alloc);
+                });
+        return std::move(array);
+    }
+
+private:
+    FlexBuffersImpl mImpl;
+    std::shared_ptr<C2AllocatorStore> mStore;
+};
+
+class GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
+public:
+    GraphicInputBuffers(const char *componentName, const char *name = "2D-BB-Input")
+        : InputBuffers(componentName, name),
+          mImpl(mName),
+          mLocalBufferPool(LocalBufferPool::Create(
+                  kMaxLinearBufferSize * kMinInputBufferArraySize)) { }
+    ~GraphicInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
+        // TODO: proper max input size
+        // TODO: read usage from intf
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer(
+                mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
+        if (newBuffer == nullptr) {
+            return false;
+        }
+        *index = mImpl.assignSlot(newBuffer);
+        *buffer = newBuffer;
+        return true;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.releaseSlot(buffer, c2buffer);
+    }
+
+    bool expireComponentBuffer(
+            const std::shared_ptr<C2Buffer> &c2buffer) override {
+        return mImpl.expireComponentBuffer(c2buffer);
+    }
+    void flush() override {
+        // This is no-op by default unless we're in array mode where we need to keep
+        // track of the flushed work.
+    }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
+            size_t size) final {
+        std::unique_ptr<InputBuffersArray> array(
+                new InputBuffersArray(mComponentName.c_str(), "2D-BB-Input[N]"));
+        array->setPool(mPool);
+        array->setFormat(mFormat);
+        array->initialize(
+                mImpl,
+                size,
+                [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> {
+                    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                    return AllocateGraphicBuffer(
+                            pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp);
+                });
+        return std::move(array);
+    }
+
+private:
+    FlexBuffersImpl mImpl;
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
+class DummyInputBuffers : public CCodecBufferChannel::InputBuffers {
+public:
+    DummyInputBuffers(const char *componentName, const char *name = "2D-Input")
+        : InputBuffers(componentName, name) { }
+
+    bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
+        return false;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &, std::shared_ptr<C2Buffer> *) override {
+        return false;
+    }
+
+    bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &) override {
+        return false;
+    }
+    void flush() override {
+    }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
+            size_t) final {
+        return nullptr;
+    }
+
+    bool isArrayMode() const final { return true; }
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
+        array->clear();
+    }
+};
+
+class OutputBuffersArray : public CCodecBufferChannel::OutputBuffers {
+public:
+    OutputBuffersArray(const char *componentName, const char *name = "Output[N]")
+        : OutputBuffers(componentName, name) { }
+    ~OutputBuffersArray() override = default;
+
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate) {
+        mImpl.initialize(impl, minSize, allocate);
+    }
+
+    bool isArrayMode() const final { return true; }
+
+    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode(
+            size_t) final {
+        return nullptr;
+    }
+
+    status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final {
+        sp<Codec2Buffer> c2Buffer;
+        status_t err = mImpl.grabBuffer(
+                index,
+                &c2Buffer,
+                [buffer](const sp<Codec2Buffer> &clientBuffer) {
+                    return clientBuffer->canCopy(buffer);
+                });
+        if (err == WOULD_BLOCK) {
+            ALOGV("[%s] buffers temporarily not available", mName);
+            return err;
+        } else if (err != OK) {
+            ALOGD("[%s] grabBuffer failed: %d", mName, err);
+            return err;
+        }
+        c2Buffer->setFormat(mFormat);
+        if (!c2Buffer->copy(buffer)) {
+            ALOGD("[%s] copy buffer failed", mName);
+            return WOULD_BLOCK;
+        }
+        submit(c2Buffer);
+        *clientBuffer = c2Buffer;
+        ALOGV("[%s] grabbed buffer %zu", mName, *index);
+        return OK;
+    }
+
+    status_t registerCsd(
+            const C2StreamCsdInfo::output *csd,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final {
+        sp<Codec2Buffer> c2Buffer;
+        status_t err = mImpl.grabBuffer(
+                index,
+                &c2Buffer,
+                [csd](const sp<Codec2Buffer> &clientBuffer) {
+                    return clientBuffer->base() != nullptr
+                            && clientBuffer->capacity() >= csd->flexCount();
+                });
+        if (err != OK) {
+            return err;
+        }
+        memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
+        c2Buffer->setRange(0, csd->flexCount());
+        c2Buffer->setFormat(mFormat);
+        *clientBuffer = c2Buffer;
+        return OK;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.returnBuffer(buffer, c2buffer);
+    }
+
+    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
+        (void)flushedWork;
+        mImpl.flush();
+        if (mSkipCutBuffer != nullptr) {
+            mSkipCutBuffer->clear();
+        }
+    }
+
+    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
+        mImpl.getArray(array);
+    }
+
+    void realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
+        std::function<sp<Codec2Buffer>()> alloc;
+        switch (c2buffer->data().type()) {
+            case C2BufferData::LINEAR: {
+                uint32_t size = kLinearBufferSize;
+                const C2ConstLinearBlock &block = c2buffer->data().linearBlocks().front();
+                if (block.size() < kMaxLinearBufferSize / 2) {
+                    size = block.size() * 2;
+                } else {
+                    size = kMaxLinearBufferSize;
+                }
+                alloc = [format = mFormat, size] {
+                    return new LocalLinearBuffer(format, new ABuffer(size));
+                };
+                break;
+            }
+
+            // TODO: add support
+            case C2BufferData::GRAPHIC:         FALLTHROUGH_INTENDED;
+
+            case C2BufferData::INVALID:         FALLTHROUGH_INTENDED;
+            case C2BufferData::LINEAR_CHUNKS:   FALLTHROUGH_INTENDED;
+            case C2BufferData::GRAPHIC_CHUNKS:  FALLTHROUGH_INTENDED;
+            default:
+                ALOGD("Unsupported type: %d", (int)c2buffer->data().type());
+                return;
+        }
+        mImpl.realloc(alloc);
+    }
+
+private:
+    BuffersArrayImpl mImpl;
+};
+
+class FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers {
+public:
+    FlexOutputBuffers(const char *componentName, const char *name = "Output[]")
+        : OutputBuffers(componentName, name),
+          mImpl(mName) { }
+
+    status_t registerBuffer(
+            const std::shared_ptr<C2Buffer> &buffer,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) override {
+        sp<Codec2Buffer> newBuffer = wrap(buffer);
+        newBuffer->setFormat(mFormat);
+        *index = mImpl.assignSlot(newBuffer);
+        *clientBuffer = newBuffer;
+        ALOGV("[%s] registered buffer %zu", mName, *index);
+        return OK;
+    }
+
+    status_t registerCsd(
+            const C2StreamCsdInfo::output *csd,
+            size_t *index,
+            sp<MediaCodecBuffer> *clientBuffer) final {
+        sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(
+                mFormat, ABuffer::CreateAsCopy(csd->m.value, csd->flexCount()));
+        *index = mImpl.assignSlot(newBuffer);
+        *clientBuffer = newBuffer;
+        return OK;
+    }
+
+    bool releaseBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
+        return mImpl.releaseSlot(buffer, c2buffer);
+    }
+
+    void flush(
+            const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
+        (void) flushedWork;
+        // This is no-op by default unless we're in array mode where we need to keep
+        // track of the flushed work.
+    }
+
+    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode(
+            size_t size) override {
+        std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray(mComponentName.c_str()));
+        array->setFormat(mFormat);
+        array->transferSkipCutBuffer(mSkipCutBuffer);
+        array->initialize(
+                mImpl,
+                size,
+                [this]() { return allocateArrayBuffer(); });
+        return std::move(array);
+    }
+
+    /**
+     * Return an appropriate Codec2Buffer object for the type of buffers.
+     *
+     * \param buffer  C2Buffer object to wrap.
+     *
+     * \return  appropriate Codec2Buffer object to wrap |buffer|.
+     */
+    virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
+
+    /**
+     * Return an appropriate Codec2Buffer object for the type of buffers, to be
+     * used as an empty array buffer.
+     *
+     * \return  appropriate Codec2Buffer object which can copy() from C2Buffers.
+     */
+    virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
+
+private:
+    FlexBuffersImpl mImpl;
+};
+
+class LinearOutputBuffers : public FlexOutputBuffers {
+public:
+    LinearOutputBuffers(const char *componentName, const char *name = "1D-Output")
+        : FlexOutputBuffers(componentName, name) { }
+
+    void flush(
+            const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
+        if (mSkipCutBuffer != nullptr) {
+            mSkipCutBuffer->clear();
+        }
+        FlexOutputBuffers::flush(flushedWork);
+    }
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
+        if (buffer == nullptr) {
+            ALOGV("[%s] using a dummy buffer", mName);
+            return new LocalLinearBuffer(mFormat, new ABuffer(0));
+        }
+        if (buffer->data().type() != C2BufferData::LINEAR) {
+            ALOGV("[%s] non-linear buffer %d", mName, buffer->data().type());
+            // We expect linear output buffers from the component.
+            return nullptr;
+        }
+        if (buffer->data().linearBlocks().size() != 1u) {
+            ALOGV("[%s] no linear buffers", mName);
+            // We expect one and only one linear block from the component.
+            return nullptr;
+        }
+        sp<Codec2Buffer> clientBuffer = ConstLinearBlockBuffer::Allocate(mFormat, buffer);
+        submit(clientBuffer);
+        return clientBuffer;
+    }
+
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        // TODO: proper max output size
+        return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
+    }
+};
+
+class GraphicOutputBuffers : public FlexOutputBuffers {
+public:
+    GraphicOutputBuffers(const char *componentName, const char *name = "2D-Output")
+        : FlexOutputBuffers(componentName, name) { }
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
+        return new DummyContainerBuffer(mFormat, buffer);
+    }
+
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        return new DummyContainerBuffer(mFormat);
+    }
+};
+
+class RawGraphicOutputBuffers : public FlexOutputBuffers {
+public:
+    RawGraphicOutputBuffers(const char *componentName, const char *name = "2D-BB-Output")
+        : FlexOutputBuffers(componentName, name),
+          mLocalBufferPool(LocalBufferPool::Create(
+                  kMaxLinearBufferSize * kMinOutputBufferArraySize)) { }
+    ~RawGraphicOutputBuffers() override = default;
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
+        if (buffer == nullptr) {
+            sp<Codec2Buffer> c2buffer = ConstGraphicBlockBuffer::AllocateEmpty(
+                    mFormat,
+                    [lbp = mLocalBufferPool](size_t capacity) {
+                        return lbp->newBuffer(capacity);
+                    });
+            c2buffer->setRange(0, 0);
+            return c2buffer;
+        } else {
+            return ConstGraphicBlockBuffer::Allocate(
+                    mFormat,
+                    buffer,
+                    [lbp = mLocalBufferPool](size_t capacity) {
+                        return lbp->newBuffer(capacity);
+                    });
+        }
+    }
+
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        return ConstGraphicBlockBuffer::AllocateEmpty(
+                mFormat,
+                [lbp = mLocalBufferPool](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+    }
+
+private:
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
+}  // namespace
+
+CCodecBufferChannel::QueueGuard::QueueGuard(
+        CCodecBufferChannel::QueueSync &sync) : mSync(sync) {
+    Mutex::Autolock l(mSync.mGuardLock);
+    // At this point it's guaranteed that mSync is not under state transition,
+    // as we are holding its mutex.
+
+    Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
+    if (count->value == -1) {
+        mRunning = false;
+    } else {
+        ++count->value;
+        mRunning = true;
+    }
+}
+
+CCodecBufferChannel::QueueGuard::~QueueGuard() {
+    if (mRunning) {
+        // We are not holding mGuardLock at this point so that QueueSync::stop() can
+        // keep holding the lock until mCount reaches zero.
+        Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
+        --count->value;
+        count->cond.broadcast();
+    }
+}
+
+void CCodecBufferChannel::QueueSync::start() {
+    Mutex::Autolock l(mGuardLock);
+    // If stopped, it goes to running state; otherwise no-op.
+    Mutexed<Counter>::Locked count(mCount);
+    if (count->value == -1) {
+        count->value = 0;
+    }
+}
+
+void CCodecBufferChannel::QueueSync::stop() {
+    Mutex::Autolock l(mGuardLock);
+    Mutexed<Counter>::Locked count(mCount);
+    if (count->value == -1) {
+        // no-op
+        return;
+    }
+    // Holding mGuardLock here blocks creation of additional QueueGuard objects, so
+    // mCount can only decrement. In other words, threads that acquired the lock
+    // are allowed to finish execution but additional threads trying to acquire
+    // the lock at this point will block, and then get QueueGuard at STOPPED
+    // state.
+    while (count->value != 0) {
+        count.waitForCondition(count->cond);
+    }
+    count->value = -1;
+}
+
+// CCodecBufferChannel::PipelineCapacity
+
+CCodecBufferChannel::PipelineCapacity::PipelineCapacity()
+      : input(0), component(0),
+        mName("<UNKNOWN COMPONENT>") {
+}
+
+void CCodecBufferChannel::PipelineCapacity::initialize(
+        int newInput,
+        int newComponent,
+        const char* newName,
+        const char* callerTag) {
+    input.store(newInput, std::memory_order_relaxed);
+    component.store(newComponent, std::memory_order_relaxed);
+    mName = newName;
+    ALOGV("[%s] %s -- PipelineCapacity::initialize(): "
+          "pipeline availability initialized ==> "
+          "input = %d, component = %d",
+            mName, callerTag ? callerTag : "*",
+            newInput, newComponent);
+}
+
+bool CCodecBufferChannel::PipelineCapacity::allocate(const char* callerTag) {
+    int prevInput = input.fetch_sub(1, std::memory_order_relaxed);
+    int prevComponent = component.fetch_sub(1, std::memory_order_relaxed);
+    if (prevInput > 0 && prevComponent > 0) {
+        ALOGV("[%s] %s -- PipelineCapacity::allocate() returns true: "
+              "pipeline availability -1 all ==> "
+              "input = %d, component = %d",
+                mName, callerTag ? callerTag : "*",
+                prevInput - 1,
+                prevComponent - 1);
+        return true;
+    }
+    input.fetch_add(1, std::memory_order_relaxed);
+    component.fetch_add(1, std::memory_order_relaxed);
+    ALOGV("[%s] %s -- PipelineCapacity::allocate() returns false: "
+          "pipeline availability unchanged ==> "
+          "input = %d, component = %d",
+            mName, callerTag ? callerTag : "*",
+            prevInput,
+            prevComponent);
+    return false;
+}
+
+void CCodecBufferChannel::PipelineCapacity::free(const char* callerTag) {
+    int prevInput = input.fetch_add(1, std::memory_order_relaxed);
+    int prevComponent = component.fetch_add(1, std::memory_order_relaxed);
+    ALOGV("[%s] %s -- PipelineCapacity::free(): "
+          "pipeline availability +1 all ==> "
+          "input = %d, component = %d",
+            mName, callerTag ? callerTag : "*",
+            prevInput + 1,
+            prevComponent + 1);
+}
+
+int CCodecBufferChannel::PipelineCapacity::freeInputSlots(
+        size_t numDiscardedInputBuffers,
+        const char* callerTag) {
+    int prevInput = input.fetch_add(numDiscardedInputBuffers,
+                                    std::memory_order_relaxed);
+    ALOGV("[%s] %s -- PipelineCapacity::freeInputSlots(%zu): "
+          "pipeline availability +%zu input ==> "
+          "input = %d, component = %d",
+            mName, callerTag ? callerTag : "*",
+            numDiscardedInputBuffers,
+            numDiscardedInputBuffers,
+            prevInput + static_cast<int>(numDiscardedInputBuffers),
+            component.load(std::memory_order_relaxed));
+    return prevInput + static_cast<int>(numDiscardedInputBuffers);
+}
+
+int CCodecBufferChannel::PipelineCapacity::freeComponentSlot(
+        const char* callerTag) {
+    int prevComponent = component.fetch_add(1, std::memory_order_relaxed);
+    ALOGV("[%s] %s -- PipelineCapacity::freeComponentSlot(): "
+          "pipeline availability +1 component ==> "
+          "input = %d, component = %d",
+            mName, callerTag ? callerTag : "*",
+            input.load(std::memory_order_relaxed),
+            prevComponent + 1);
+    return prevComponent + 1;
+}
+
+// CCodecBufferChannel::ReorderStash
+
+CCodecBufferChannel::ReorderStash::ReorderStash() {
+    clear();
+}
+
+void CCodecBufferChannel::ReorderStash::clear() {
+    mPending.clear();
+    mStash.clear();
+    mDepth = 0;
+    mKey = C2Config::ORDINAL;
+}
+
+void CCodecBufferChannel::ReorderStash::setDepth(uint32_t depth) {
+    mPending.splice(mPending.end(), mStash);
+    mDepth = depth;
+}
+void CCodecBufferChannel::ReorderStash::setKey(C2Config::ordinal_key_t key) {
+    mPending.splice(mPending.end(), mStash);
+    mKey = key;
+}
+
+bool CCodecBufferChannel::ReorderStash::pop(Entry *entry) {
+    if (mPending.empty()) {
+        return false;
+    }
+    entry->buffer     = mPending.front().buffer;
+    entry->timestamp  = mPending.front().timestamp;
+    entry->flags      = mPending.front().flags;
+    entry->ordinal    = mPending.front().ordinal;
+    mPending.pop_front();
+    return true;
+}
+
+void CCodecBufferChannel::ReorderStash::emplace(
+        const std::shared_ptr<C2Buffer> &buffer,
+        int64_t timestamp,
+        int32_t flags,
+        const C2WorkOrdinalStruct &ordinal) {
+    for (auto it = mStash.begin(); it != mStash.end(); ++it) {
+        if (less(ordinal, it->ordinal)) {
+            mStash.emplace(it, buffer, timestamp, flags, ordinal);
+            return;
+        }
+    }
+    mStash.emplace_back(buffer, timestamp, flags, ordinal);
+    while (!mStash.empty() && mStash.size() > mDepth) {
+        mPending.push_back(mStash.front());
+        mStash.pop_front();
+    }
+}
+
+void CCodecBufferChannel::ReorderStash::defer(
+        const CCodecBufferChannel::ReorderStash::Entry &entry) {
+    mPending.push_front(entry);
+}
+
+bool CCodecBufferChannel::ReorderStash::hasPending() const {
+    return !mPending.empty();
+}
+
+bool CCodecBufferChannel::ReorderStash::less(
+        const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2) {
+    switch (mKey) {
+        case C2Config::ORDINAL:   return o1.frameIndex < o2.frameIndex;
+        case C2Config::TIMESTAMP: return o1.timestamp < o2.timestamp;
+        case C2Config::CUSTOM:    return o1.customOrdinal < o2.customOrdinal;
+        default:
+            ALOGD("Unrecognized key; default to timestamp");
+            return o1.frameIndex < o2.frameIndex;
+    }
+}
+
+// CCodecBufferChannel
+
+CCodecBufferChannel::CCodecBufferChannel(
+        const std::shared_ptr<CCodecCallback> &callback)
+    : mHeapSeqNum(-1),
+      mCCodecCallback(callback),
+      mFrameIndex(0u),
+      mFirstValidFrameIndex(0u),
+      mMetaMode(MODE_NONE),
+      mAvailablePipelineCapacity(),
+      mInputMetEos(false) {
+    Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+    buffers->reset(new DummyInputBuffers(""));
+}
+
+CCodecBufferChannel::~CCodecBufferChannel() {
+    if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
+        mCrypto->unsetHeap(mHeapSeqNum);
+    }
+}
+
+void CCodecBufferChannel::setComponent(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    mComponent = component;
+    mComponentName = component->getName() + StringPrintf("#%d", int(uintptr_t(component.get()) % 997));
+    mName = mComponentName.c_str();
+}
+
+status_t CCodecBufferChannel::setInputSurface(
+        const std::shared_ptr<InputSurfaceWrapper> &surface) {
+    ALOGV("[%s] setInputSurface", mName);
+    mInputSurface = surface;
+    return mInputSurface->connect(mComponent);
+}
+
+status_t CCodecBufferChannel::signalEndOfInputStream() {
+    if (mInputSurface == nullptr) {
+        return INVALID_OPERATION;
+    }
+    return mInputSurface->signalEndOfInputStream();
+}
+
+status_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) {
+    int64_t timeUs;
+    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+    if (mInputMetEos) {
+        ALOGD("[%s] buffers after EOS ignored (%lld us)", mName, (long long)timeUs);
+        return OK;
+    }
+
+    int32_t flags = 0;
+    int32_t tmp = 0;
+    bool eos = false;
+    if (buffer->meta()->findInt32("eos", &tmp) && tmp) {
+        eos = true;
+        mInputMetEos = true;
+        ALOGV("[%s] input EOS", mName);
+    }
+    if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
+        flags |= C2FrameData::FLAG_CODEC_CONFIG;
+    }
+    ALOGV("[%s] queueInputBuffer: buffer->size() = %zu", mName, buffer->size());
+    std::unique_ptr<C2Work> work(new C2Work);
+    work->input.ordinal.timestamp = timeUs;
+    work->input.ordinal.frameIndex = mFrameIndex++;
+    // WORKAROUND: until codecs support handling work after EOS and max output sizing, use timestamp
+    // manipulation to achieve image encoding via video codec, and to constrain encoded output.
+    // Keep client timestamp in customOrdinal
+    work->input.ordinal.customOrdinal = timeUs;
+    work->input.buffers.clear();
+
+    if (buffer->size() > 0u) {
+        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+        std::shared_ptr<C2Buffer> c2buffer;
+        if (!(*buffers)->releaseBuffer(buffer, &c2buffer)) {
+            return -ENOENT;
+        }
+        work->input.buffers.push_back(c2buffer);
+    } else {
+        mAvailablePipelineCapacity.freeInputSlots(1, "queueInputBufferInternal");
+        if (eos) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        }
+    }
+    work->input.flags = (C2FrameData::flags_t)flags;
+    // TODO: fill info's
+
+    work->input.configUpdate = std::move(mParamsToBeSet);
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    c2_status_t err = mComponent->queue(&items);
+
+    if (err == C2_OK && eos && buffer->size() > 0u) {
+        mCCodecCallback->onWorkQueued(false);
+        work.reset(new C2Work);
+        work->input.ordinal.timestamp = timeUs;
+        work->input.ordinal.frameIndex = mFrameIndex++;
+        // WORKAROUND: keep client timestamp in customOrdinal
+        work->input.ordinal.customOrdinal = timeUs;
+        work->input.buffers.clear();
+        work->input.flags = C2FrameData::FLAG_END_OF_STREAM;
+
+        items.clear();
+        items.push_back(std::move(work));
+        err = mComponent->queue(&items);
+    }
+    if (err == C2_OK) {
+        mCCodecCallback->onWorkQueued(eos);
+    }
+
+    feedInputBufferIfAvailableInternal();
+    return err;
+}
+
+status_t CCodecBufferChannel::setParameters(std::vector<std::unique_ptr<C2Param>> &params) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] setParameters is only supported in the running state.", mName);
+        return -ENOSYS;
+    }
+    mParamsToBeSet.insert(mParamsToBeSet.end(),
+                          std::make_move_iterator(params.begin()),
+                          std::make_move_iterator(params.end()));
+    params.clear();
+    return OK;
+}
+
+status_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] No more buffers should be queued at current state.", mName);
+        return -ENOSYS;
+    }
+    return queueInputBufferInternal(buffer);
+}
+
+status_t CCodecBufferChannel::queueSecureInputBuffer(
+        const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
+        const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
+        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+        AString *errorDetailMsg) {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGD("[%s] No more buffers should be queued at current state.", mName);
+        return -ENOSYS;
+    }
+
+    if (!hasCryptoOrDescrambler()) {
+        return -ENOSYS;
+    }
+    sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
+
+    ssize_t result = -1;
+    ssize_t codecDataOffset = 0;
+    if (mCrypto != nullptr) {
+        ICrypto::DestinationBuffer destination;
+        if (secure) {
+            destination.mType = ICrypto::kDestinationTypeNativeHandle;
+            destination.mHandle = encryptedBuffer->handle();
+        } else {
+            destination.mType = ICrypto::kDestinationTypeSharedMemory;
+            destination.mSharedMemory = mDecryptDestination;
+        }
+        ICrypto::SourceBuffer source;
+        encryptedBuffer->fillSourceBuffer(&source);
+        result = mCrypto->decrypt(
+                key, iv, mode, pattern, source, buffer->offset(),
+                subSamples, numSubSamples, destination, errorDetailMsg);
+        if (result < 0) {
+            return result;
+        }
+        if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+            encryptedBuffer->copyDecryptedContent(mDecryptDestination, result);
+        }
+    } else {
+        // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
+        // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
+        hidl_vec<SubSample> hidlSubSamples;
+        hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
+
+        hardware::cas::native::V1_0::SharedBuffer srcBuffer;
+        encryptedBuffer->fillSourceBuffer(&srcBuffer);
+
+        DestinationBuffer dstBuffer;
+        if (secure) {
+            dstBuffer.type = BufferType::NATIVE_HANDLE;
+            dstBuffer.secureMemory = hidl_handle(encryptedBuffer->handle());
+        } else {
+            dstBuffer.type = BufferType::SHARED_MEMORY;
+            dstBuffer.nonsecureMemory = srcBuffer;
+        }
+
+        CasStatus status = CasStatus::OK;
+        hidl_string detailedError;
+        ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
+
+        if (key != nullptr) {
+            sctrl = (ScramblingControl)key[0];
+            // Adjust for the PES offset
+            codecDataOffset = key[2] | (key[3] << 8);
+        }
+
+        auto returnVoid = mDescrambler->descramble(
+                sctrl,
+                hidlSubSamples,
+                srcBuffer,
+                0,
+                dstBuffer,
+                0,
+                [&status, &result, &detailedError] (
+                        CasStatus _status, uint32_t _bytesWritten,
+                        const hidl_string& _detailedError) {
+                    status = _status;
+                    result = (ssize_t)_bytesWritten;
+                    detailedError = _detailedError;
+                });
+
+        if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) {
+            ALOGI("[%s] descramble failed, trans=%s, status=%d, result=%zd",
+                    mName, returnVoid.description().c_str(), status, result);
+            return UNKNOWN_ERROR;
+        }
+
+        if (result < codecDataOffset) {
+            ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
+            return BAD_VALUE;
+        }
+
+        ALOGV("[%s] descramble succeeded, %zd bytes", mName, result);
+
+        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+            encryptedBuffer->copyDecryptedContentFromMemory(result);
+        }
+    }
+
+    buffer->setRange(codecDataOffset, result - codecDataOffset);
+    return queueInputBufferInternal(buffer);
+}
+
+void CCodecBufferChannel::feedInputBufferIfAvailable() {
+    QueueGuard guard(mSync);
+    if (!guard.isRunning()) {
+        ALOGV("[%s] We're not running --- no input buffer reported", mName);
+        return;
+    }
+    feedInputBufferIfAvailableInternal();
+}
+
+void CCodecBufferChannel::feedInputBufferIfAvailableInternal() {
+    while (!mInputMetEos &&
+           !mReorderStash.lock()->hasPending() &&
+           mAvailablePipelineCapacity.allocate("feedInputBufferIfAvailable")) {
+        sp<MediaCodecBuffer> inBuffer;
+        size_t index;
+        {
+            Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+            if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) {
+                ALOGV("[%s] no new buffer available", mName);
+                mAvailablePipelineCapacity.free("feedInputBufferIfAvailable");
+                break;
+            }
+        }
+        ALOGV("[%s] new input index = %zu [%p]", mName, index, inBuffer.get());
+        mCallback->onInputBufferAvailable(index, inBuffer);
+    }
+}
+
+status_t CCodecBufferChannel::renderOutputBuffer(
+        const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
+    std::shared_ptr<C2Buffer> c2Buffer;
+    {
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        if (*buffers) {
+            (*buffers)->releaseBuffer(buffer, &c2Buffer);
+        }
+    }
+    if (!c2Buffer) {
+        return INVALID_OPERATION;
+    }
+    sendOutputBuffers();
+
+#if 0
+    const std::vector<std::shared_ptr<const C2Info>> infoParams = c2Buffer->info();
+    ALOGV("[%s] queuing gfx buffer with %zu infos", mName, infoParams.size());
+    for (const std::shared_ptr<const C2Info> &info : infoParams) {
+        AString res;
+        for (size_t ix = 0; ix + 3 < info->size(); ix += 4) {
+            if (ix) res.append(", ");
+            res.append(*((int32_t*)info.get() + (ix / 4)));
+        }
+        ALOGV("  [%s]", res.c_str());
+    }
+#endif
+    std::shared_ptr<const C2StreamRotationInfo::output> rotation =
+        std::static_pointer_cast<const C2StreamRotationInfo::output>(
+                c2Buffer->getInfo(C2StreamRotationInfo::output::PARAM_TYPE));
+    bool flip = rotation && (rotation->flip & 1);
+    uint32_t quarters = ((rotation ? rotation->value : 0) / 90) & 3;
+    uint32_t transform = 0;
+    switch (quarters) {
+        case 0: // no rotation
+            transform = flip ? HAL_TRANSFORM_FLIP_H : 0;
+            break;
+        case 1: // 90 degrees counter-clockwise
+            transform = flip ? (HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90)
+                    : HAL_TRANSFORM_ROT_270;
+            break;
+        case 2: // 180 degrees
+            transform = flip ? HAL_TRANSFORM_FLIP_V : HAL_TRANSFORM_ROT_180;
+            break;
+        case 3: // 90 degrees clockwise
+            transform = flip ? (HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90)
+                    : HAL_TRANSFORM_ROT_90;
+            break;
+    }
+
+    std::shared_ptr<const C2StreamSurfaceScalingInfo::output> surfaceScaling =
+        std::static_pointer_cast<const C2StreamSurfaceScalingInfo::output>(
+                c2Buffer->getInfo(C2StreamSurfaceScalingInfo::output::PARAM_TYPE));
+    uint32_t videoScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+    if (surfaceScaling) {
+        videoScalingMode = surfaceScaling->value;
+    }
+
+    // Use dataspace from format as it has the default aspects already applied
+    android_dataspace_t dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
+    (void)buffer->format()->findInt32("android._dataspace", (int32_t *)&dataSpace);
+
+    // HDR static info
+    std::shared_ptr<const C2StreamHdrStaticInfo::output> hdrStaticInfo =
+        std::static_pointer_cast<const C2StreamHdrStaticInfo::output>(
+                c2Buffer->getInfo(C2StreamHdrStaticInfo::output::PARAM_TYPE));
+
+    {
+        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+        if (output->surface == nullptr) {
+            ALOGI("[%s] cannot render buffer without surface", mName);
+            return OK;
+        }
+    }
+
+    std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
+    if (blocks.size() != 1u) {
+        ALOGD("[%s] expected 1 graphic block, but got %zu", mName, blocks.size());
+        return UNKNOWN_ERROR;
+    }
+    const C2ConstGraphicBlock &block = blocks.front();
+
+    // TODO: revisit this after C2Fence implementation.
+    android::IGraphicBufferProducer::QueueBufferInput qbi(
+            timestampNs,
+            false, // droppable
+            dataSpace,
+            Rect(blocks.front().crop().left,
+                 blocks.front().crop().top,
+                 blocks.front().crop().right(),
+                 blocks.front().crop().bottom()),
+            videoScalingMode,
+            transform,
+            Fence::NO_FENCE, 0);
+    if (hdrStaticInfo) {
+        struct android_smpte2086_metadata smpte2086_meta = {
+            .displayPrimaryRed = {
+                hdrStaticInfo->mastering.red.x, hdrStaticInfo->mastering.red.y
+            },
+            .displayPrimaryGreen = {
+                hdrStaticInfo->mastering.green.x, hdrStaticInfo->mastering.green.y
+            },
+            .displayPrimaryBlue = {
+                hdrStaticInfo->mastering.blue.x, hdrStaticInfo->mastering.blue.y
+            },
+            .whitePoint = {
+                hdrStaticInfo->mastering.white.x, hdrStaticInfo->mastering.white.y
+            },
+            .maxLuminance = hdrStaticInfo->mastering.maxLuminance,
+            .minLuminance = hdrStaticInfo->mastering.minLuminance,
+        };
+
+        struct android_cta861_3_metadata cta861_meta = {
+            .maxContentLightLevel = hdrStaticInfo->maxCll,
+            .maxFrameAverageLightLevel = hdrStaticInfo->maxFall,
+        };
+
+        HdrMetadata hdr;
+        hdr.validTypes = HdrMetadata::SMPTE2086 | HdrMetadata::CTA861_3;
+        hdr.smpte2086 = smpte2086_meta;
+        hdr.cta8613 = cta861_meta;
+        qbi.setHdrMetadata(hdr);
+    }
+    android::IGraphicBufferProducer::QueueBufferOutput qbo;
+    status_t result = mComponent->queueToOutputSurface(block, qbi, &qbo);
+    if (result != OK) {
+        ALOGI("[%s] queueBuffer failed: %d", mName, result);
+        return result;
+    }
+    ALOGV("[%s] queue buffer successful", mName);
+
+    int64_t mediaTimeUs = 0;
+    (void)buffer->meta()->findInt64("timeUs", &mediaTimeUs);
+    mCCodecCallback->onOutputFramesRendered(mediaTimeUs, timestampNs);
+
+    return OK;
+}
+
+status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
+    ALOGV("[%s] discardBuffer: %p", mName, buffer.get());
+    bool released = false;
+    {
+        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+        if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr)) {
+            buffers.unlock();
+            released = true;
+            mAvailablePipelineCapacity.freeInputSlots(1, "discardBuffer");
+        }
+    }
+    {
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr)) {
+            buffers.unlock();
+            released = true;
+        }
+    }
+    if (released) {
+        feedInputBufferIfAvailable();
+        sendOutputBuffers();
+    } else {
+        ALOGD("[%s] MediaCodec discarded an unknown buffer", mName);
+    }
+    return OK;
+}
+
+void CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+    array->clear();
+    Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+
+    if (!(*buffers)->isArrayMode()) {
+        *buffers = (*buffers)->toArrayMode(kMinInputBufferArraySize);
+    }
+
+    (*buffers)->getArray(array);
+}
+
+void CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+    array->clear();
+    Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+
+    if (!(*buffers)->isArrayMode()) {
+        *buffers = (*buffers)->toArrayMode(kMinOutputBufferArraySize);
+    }
+
+    (*buffers)->getArray(array);
+}
+
+status_t CCodecBufferChannel::start(
+        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
+    C2StreamBufferTypeSetting::input iStreamFormat(0u);
+    C2StreamBufferTypeSetting::output oStreamFormat(0u);
+    C2PortReorderBufferDepthTuning::output reorderDepth;
+    C2PortReorderKeySetting::output reorderKey;
+    c2_status_t err = mComponent->query(
+            {
+                &iStreamFormat,
+                &oStreamFormat,
+                &reorderDepth,
+                &reorderKey,
+            },
+            {},
+            C2_DONT_BLOCK,
+            nullptr);
+    if (err == C2_BAD_INDEX) {
+        if (!iStreamFormat || !oStreamFormat) {
+            return UNKNOWN_ERROR;
+        }
+    } else if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+
+    {
+        Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+        reorder->clear();
+        if (reorderDepth) {
+            reorder->setDepth(reorderDepth.value);
+        }
+        if (reorderKey) {
+            reorder->setKey(reorderKey.value);
+        }
+    }
+    // TODO: get this from input format
+    bool secure = mComponent->getName().find(".secure") != std::string::npos;
+
+    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+    int poolMask = property_get_int32(
+            "debug.stagefright.c2-poolmask",
+            1 << C2PlatformAllocatorStore::ION |
+            1 << C2PlatformAllocatorStore::BUFFERQUEUE);
+
+    if (inputFormat != nullptr) {
+        bool graphic = (iStreamFormat.value == C2FormatVideo);
+        std::shared_ptr<C2BlockPool> pool;
+        {
+            Mutexed<BlockPools>::Locked pools(mBlockPools);
+
+            // set default allocator ID.
+            pools->inputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
+                                                : C2PlatformAllocatorStore::ION;
+
+            // query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained
+            // from component, create the input block pool with given ID. Otherwise, use default IDs.
+            std::vector<std::unique_ptr<C2Param>> params;
+            err = mComponent->query({ },
+                                    { C2PortAllocatorsTuning::input::PARAM_TYPE },
+                                    C2_DONT_BLOCK,
+                                    &params);
+            if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                ALOGD("[%s] Query input allocators returned %zu params => %s (%u)",
+                        mName, params.size(), asString(err), err);
+            } else if (err == C2_OK && params.size() == 1) {
+                C2PortAllocatorsTuning::input *inputAllocators =
+                    C2PortAllocatorsTuning::input::From(params[0].get());
+                if (inputAllocators && inputAllocators->flexCount() > 0) {
+                    std::shared_ptr<C2Allocator> allocator;
+                    // verify allocator IDs and resolve default allocator
+                    allocatorStore->fetchAllocator(inputAllocators->m.values[0], &allocator);
+                    if (allocator) {
+                        pools->inputAllocatorId = allocator->getId();
+                    } else {
+                        ALOGD("[%s] component requested invalid input allocator ID %u",
+                                mName, inputAllocators->m.values[0]);
+                    }
+                }
+            }
+
+            // TODO: use C2Component wrapper to associate this pool with ourselves
+            if ((poolMask >> pools->inputAllocatorId) & 1) {
+                err = CreateCodec2BlockPool(pools->inputAllocatorId, nullptr, &pool);
+                ALOGD("[%s] Created input block pool with allocatorID %u => poolID %llu - %s (%d)",
+                        mName, pools->inputAllocatorId,
+                        (unsigned long long)(pool ? pool->getLocalId() : 111000111),
+                        asString(err), err);
+            } else {
+                err = C2_NOT_FOUND;
+            }
+            if (err != C2_OK) {
+                C2BlockPool::local_id_t inputPoolId =
+                    graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
+                err = GetCodec2BlockPool(inputPoolId, nullptr, &pool);
+                ALOGD("[%s] Using basic input block pool with poolID %llu => got %llu - %s (%d)",
+                        mName, (unsigned long long)inputPoolId,
+                        (unsigned long long)(pool ? pool->getLocalId() : 111000111),
+                        asString(err), err);
+                if (err != C2_OK) {
+                    return NO_MEMORY;
+                }
+            }
+            pools->inputPool = pool;
+        }
+
+        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+        if (graphic) {
+            if (mInputSurface) {
+                buffers->reset(new DummyInputBuffers(mName));
+            } else if (mMetaMode == MODE_ANW) {
+                buffers->reset(new GraphicMetadataInputBuffers(mName));
+            } else {
+                buffers->reset(new GraphicInputBuffers(mName));
+            }
+        } else {
+            if (hasCryptoOrDescrambler()) {
+                int32_t capacity = kLinearBufferSize;
+                (void)inputFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
+                if ((size_t)capacity > kMaxLinearBufferSize) {
+                    ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
+                    capacity = kMaxLinearBufferSize;
+                }
+                if (mDealer == nullptr) {
+                    mDealer = new MemoryDealer(
+                            align(capacity, MemoryDealer::getAllocationAlignment())
+                                * (kMinInputBufferArraySize + 1),
+                            "EncryptedLinearInputBuffers");
+                    mDecryptDestination = mDealer->allocate((size_t)capacity);
+                }
+                if (mCrypto != nullptr && mHeapSeqNum < 0) {
+                    mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
+                } else {
+                    mHeapSeqNum = -1;
+                }
+                buffers->reset(new EncryptedLinearInputBuffers(
+                        secure, mDealer, mCrypto, mHeapSeqNum, (size_t)capacity, mName));
+            } else {
+                buffers->reset(new LinearInputBuffers(mName));
+            }
+        }
+        (*buffers)->setFormat(inputFormat);
+
+        if (err == C2_OK) {
+            (*buffers)->setPool(pool);
+        } else {
+            // TODO: error
+        }
+    }
+
+    if (outputFormat != nullptr) {
+        sp<IGraphicBufferProducer> outputSurface;
+        uint32_t outputGeneration;
+        {
+            Mutexed<OutputSurface>::Locked output(mOutputSurface);
+            outputSurface = output->surface ?
+                    output->surface->getIGraphicBufferProducer() : nullptr;
+            outputGeneration = output->generation;
+        }
+
+        bool graphic = (oStreamFormat.value == C2FormatVideo);
+        C2BlockPool::local_id_t outputPoolId_;
+
+        {
+            Mutexed<BlockPools>::Locked pools(mBlockPools);
+
+            // set default allocator ID.
+            pools->outputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
+                                                 : C2PlatformAllocatorStore::ION;
+
+            // query C2PortAllocatorsTuning::output from component, or use default allocator if
+            // unsuccessful.
+            std::vector<std::unique_ptr<C2Param>> params;
+            err = mComponent->query({ },
+                                    { C2PortAllocatorsTuning::output::PARAM_TYPE },
+                                    C2_DONT_BLOCK,
+                                    &params);
+            if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                ALOGD("[%s] Query output allocators returned %zu params => %s (%u)",
+                        mName, params.size(), asString(err), err);
+            } else if (err == C2_OK && params.size() == 1) {
+                C2PortAllocatorsTuning::output *outputAllocators =
+                    C2PortAllocatorsTuning::output::From(params[0].get());
+                if (outputAllocators && outputAllocators->flexCount() > 0) {
+                    std::shared_ptr<C2Allocator> allocator;
+                    // verify allocator IDs and resolve default allocator
+                    allocatorStore->fetchAllocator(outputAllocators->m.values[0], &allocator);
+                    if (allocator) {
+                        pools->outputAllocatorId = allocator->getId();
+                    } else {
+                        ALOGD("[%s] component requested invalid output allocator ID %u",
+                                mName, outputAllocators->m.values[0]);
+                    }
+                }
+            }
+
+            // use bufferqueue if outputting to a surface.
+            // query C2PortSurfaceAllocatorTuning::output from component, or use default allocator
+            // if unsuccessful.
+            if (outputSurface) {
+                params.clear();
+                err = mComponent->query({ },
+                                        { C2PortSurfaceAllocatorTuning::output::PARAM_TYPE },
+                                        C2_DONT_BLOCK,
+                                        &params);
+                if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
+                    ALOGD("[%s] Query output surface allocator returned %zu params => %s (%u)",
+                            mName, params.size(), asString(err), err);
+                } else if (err == C2_OK && params.size() == 1) {
+                    C2PortSurfaceAllocatorTuning::output *surfaceAllocator =
+                        C2PortSurfaceAllocatorTuning::output::From(params[0].get());
+                    if (surfaceAllocator) {
+                        std::shared_ptr<C2Allocator> allocator;
+                        // verify allocator IDs and resolve default allocator
+                        allocatorStore->fetchAllocator(surfaceAllocator->value, &allocator);
+                        if (allocator) {
+                            pools->outputAllocatorId = allocator->getId();
+                        } else {
+                            ALOGD("[%s] component requested invalid surface output allocator ID %u",
+                                    mName, surfaceAllocator->value);
+                            err = C2_BAD_VALUE;
+                        }
+                    }
+                }
+                if (pools->outputAllocatorId == C2PlatformAllocatorStore::GRALLOC
+                        && err != C2_OK
+                        && ((poolMask >> C2PlatformAllocatorStore::BUFFERQUEUE) & 1)) {
+                    pools->outputAllocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
+                }
+            }
+
+            if ((poolMask >> pools->outputAllocatorId) & 1) {
+                err = mComponent->createBlockPool(
+                        pools->outputAllocatorId, &pools->outputPoolId, &pools->outputPoolIntf);
+                ALOGI("[%s] Created output block pool with allocatorID %u => poolID %llu - %s",
+                        mName, pools->outputAllocatorId,
+                        (unsigned long long)pools->outputPoolId,
+                        asString(err));
+            } else {
+                err = C2_NOT_FOUND;
+            }
+            if (err != C2_OK) {
+                // use basic pool instead
+                pools->outputPoolId =
+                    graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
+            }
+
+            // Configure output block pool ID as parameter C2PortBlockPoolsTuning::output to
+            // component.
+            std::unique_ptr<C2PortBlockPoolsTuning::output> poolIdsTuning =
+                    C2PortBlockPoolsTuning::output::AllocUnique({ pools->outputPoolId });
+
+            std::vector<std::unique_ptr<C2SettingResult>> failures;
+            err = mComponent->config({ poolIdsTuning.get() }, C2_MAY_BLOCK, &failures);
+            ALOGD("[%s] Configured output block pool ids %llu => %s",
+                    mName, (unsigned long long)poolIdsTuning->m.values[0], asString(err));
+            outputPoolId_ = pools->outputPoolId;
+        }
+
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+
+        if (graphic) {
+            if (outputSurface) {
+                buffers->reset(new GraphicOutputBuffers(mName));
+            } else {
+                buffers->reset(new RawGraphicOutputBuffers(mName));
+            }
+        } else {
+            buffers->reset(new LinearOutputBuffers(mName));
+        }
+        (*buffers)->setFormat(outputFormat->dup());
+
+
+        // Try to set output surface to created block pool if given.
+        if (outputSurface) {
+            mComponent->setOutputSurface(
+                    outputPoolId_,
+                    outputSurface,
+                    outputGeneration);
+        }
+
+        if (oStreamFormat.value == C2BufferData::LINEAR
+                && mComponentName.find("c2.qti.") == std::string::npos) {
+            // WORKAROUND: if we're using early CSD workaround we convert to
+            //             array mode, to appease apps assuming the output
+            //             buffers to be of the same size.
+            (*buffers) = (*buffers)->toArrayMode(kMinOutputBufferArraySize);
+
+            int32_t channelCount;
+            int32_t sampleRate;
+            if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
+                    && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+                int32_t delay = 0;
+                int32_t padding = 0;;
+                if (!outputFormat->findInt32("encoder-delay", &delay)) {
+                    delay = 0;
+                }
+                if (!outputFormat->findInt32("encoder-padding", &padding)) {
+                    padding = 0;
+                }
+                if (delay || padding) {
+                    // We need write access to the buffers, and we're already in
+                    // array mode.
+                    (*buffers)->initSkipCutBuffer(delay, padding, sampleRate, channelCount);
+                }
+            }
+        }
+    }
+
+    // Set up pipeline control. This has to be done after mInputBuffers and
+    // mOutputBuffers are initialized to make sure that lingering callbacks
+    // about buffers from the previous generation do not interfere with the
+    // newly initialized pipeline capacity.
+
+    // Query delays
+    C2PortRequestedDelayTuning::input inputDelay;
+    C2PortRequestedDelayTuning::output outputDelay;
+    C2RequestedPipelineDelayTuning pipelineDelay;
+#if 0
+    err = mComponent->query(
+            { &inputDelay, &pipelineDelay, &outputDelay },
+            {},
+            C2_DONT_BLOCK,
+            nullptr);
+    mAvailablePipelineCapacity.initialize(
+            inputDelay,
+            inputDelay + pipelineDelay,
+            inputDelay + pipelineDelay + outputDelay,
+            mName);
+#else
+    mAvailablePipelineCapacity.initialize(
+            kMinInputBufferArraySize,
+            kMaxPipelineCapacity,
+            mName);
+#endif
+
+    mInputMetEos = false;
+    mSync.start();
+    return OK;
+}
+
+status_t CCodecBufferChannel::requestInitialInputBuffers() {
+    if (mInputSurface) {
+        return OK;
+    }
+
+    C2StreamFormatConfig::output oStreamFormat(0u);
+    c2_status_t err = mComponent->query({ &oStreamFormat }, {}, C2_DONT_BLOCK, nullptr);
+    if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+    std::vector<sp<MediaCodecBuffer>> toBeQueued;
+    // TODO: use proper buffer depth instead of this random value
+    for (size_t i = 0; i < kMinInputBufferArraySize; ++i) {
+        size_t index;
+        sp<MediaCodecBuffer> buffer;
+        {
+            Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+            if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
+                if (i == 0) {
+                    ALOGW("[%s] start: cannot allocate memory at all", mName);
+                    return NO_MEMORY;
+                } else {
+                    ALOGV("[%s] start: cannot allocate memory, only %zu buffers allocated",
+                            mName, i);
+                }
+                break;
+            }
+        }
+        if (buffer) {
+            Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
+            ALOGV("[%s] input buffer %zu available", mName, index);
+            bool post = true;
+            if (!configs->empty()) {
+                sp<ABuffer> config = configs->front();
+                if (buffer->capacity() >= config->size()) {
+                    memcpy(buffer->base(), config->data(), config->size());
+                    buffer->setRange(0, config->size());
+                    buffer->meta()->clear();
+                    buffer->meta()->setInt64("timeUs", 0);
+                    buffer->meta()->setInt32("csd", 1);
+                    post = false;
+                } else {
+                    ALOGD("[%s] buffer capacity too small for the config (%zu < %zu)",
+                            mName, buffer->capacity(), config->size());
+                }
+            } else if (oStreamFormat.value == C2BufferData::LINEAR && i == 0
+                    && mComponentName.find("c2.qti.") == std::string::npos) {
+                // WORKAROUND: Some apps expect CSD available without queueing
+                //             any input. Queue an empty buffer to get the CSD.
+                buffer->setRange(0, 0);
+                buffer->meta()->clear();
+                buffer->meta()->setInt64("timeUs", 0);
+                post = false;
+            }
+            if (mAvailablePipelineCapacity.allocate("requestInitialInputBuffers")) {
+                if (post) {
+                    mCallback->onInputBufferAvailable(index, buffer);
+                } else {
+                    toBeQueued.emplace_back(buffer);
+                }
+            } else {
+                ALOGD("[%s] pipeline is full while requesting %zu-th input buffer",
+                        mName, i);
+            }
+        }
+    }
+    for (const sp<MediaCodecBuffer> &buffer : toBeQueued) {
+        if (queueInputBufferInternal(buffer) != OK) {
+            mAvailablePipelineCapacity.freeComponentSlot("requestInitialInputBuffers");
+        }
+    }
+    return OK;
+}
+
+void CCodecBufferChannel::stop() {
+    mSync.stop();
+    mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
+    if (mInputSurface != nullptr) {
+        mInputSurface->disconnect();
+        mInputSurface.reset();
+    }
+}
+
+void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
+    ALOGV("[%s] flush", mName);
+    {
+        Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
+        for (const std::unique_ptr<C2Work> &work : flushedWork) {
+            if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
+                continue;
+            }
+            if (work->input.buffers.empty()
+                    || work->input.buffers.front()->data().linearBlocks().empty()) {
+                ALOGD("[%s] no linear codec config data found", mName);
+                continue;
+            }
+            C2ReadView view =
+                    work->input.buffers.front()->data().linearBlocks().front().map().get();
+            if (view.error() != C2_OK) {
+                ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error());
+                continue;
+            }
+            configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity()));
+            ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity());
+        }
+    }
+    {
+        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+        (*buffers)->flush();
+    }
+    {
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        (*buffers)->flush(flushedWork);
+    }
+}
+
+void CCodecBufferChannel::onWorkDone(
+        std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+        const C2StreamInitDataInfo::output *initData,
+        size_t numDiscardedInputBuffers) {
+    if (handleWork(std::move(work), outputFormat, initData)) {
+        mAvailablePipelineCapacity.freeInputSlots(numDiscardedInputBuffers,
+                                                  "onWorkDone");
+        feedInputBufferIfAvailable();
+    }
+}
+
+void CCodecBufferChannel::onInputBufferDone(
+        const std::shared_ptr<C2Buffer>& buffer) {
+    bool newInputSlotAvailable;
+    {
+        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+        newInputSlotAvailable = (*buffers)->expireComponentBuffer(buffer);
+        if (newInputSlotAvailable) {
+            mAvailablePipelineCapacity.freeInputSlots(1, "onInputBufferDone");
+        }
+    }
+    if (newInputSlotAvailable) {
+        feedInputBufferIfAvailable();
+    }
+}
+
+bool CCodecBufferChannel::handleWork(
+        std::unique_ptr<C2Work> work,
+        const sp<AMessage> &outputFormat,
+        const C2StreamInitDataInfo::output *initData) {
+    if ((work->input.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
+        // Discard frames from previous generation.
+        ALOGD("[%s] Discard frames from previous generation.", mName);
+        return false;
+    }
+
+    if (work->worklets.size() != 1u
+            || !work->worklets.front()
+            || !(work->worklets.front()->output.flags & C2FrameData::FLAG_INCOMPLETE)) {
+        mAvailablePipelineCapacity.freeComponentSlot("handleWork");
+    }
+
+    if (work->result == C2_NOT_FOUND) {
+        ALOGD("[%s] flushed work; ignored.", mName);
+        return true;
+    }
+
+    if (work->result != C2_OK) {
+        ALOGD("[%s] work failed to complete: %d", mName, work->result);
+        mCCodecCallback->onError(work->result, ACTION_CODE_FATAL);
+        return false;
+    }
+
+    // NOTE: MediaCodec usage supposedly have only one worklet
+    if (work->worklets.size() != 1u) {
+        ALOGI("[%s] onWorkDone: incorrect number of worklets: %zu",
+                mName, work->worklets.size());
+        mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return false;
+    }
+
+    const std::unique_ptr<C2Worklet> &worklet = work->worklets.front();
+
+    std::shared_ptr<C2Buffer> buffer;
+    // NOTE: MediaCodec usage supposedly have only one output stream.
+    if (worklet->output.buffers.size() > 1u) {
+        ALOGI("[%s] onWorkDone: incorrect number of output buffers: %zu",
+                mName, worklet->output.buffers.size());
+        mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        return false;
+    } else if (worklet->output.buffers.size() == 1u) {
+        buffer = worklet->output.buffers[0];
+        if (!buffer) {
+            ALOGD("[%s] onWorkDone: nullptr found in buffers; ignored.", mName);
+        }
+    }
+
+    while (!worklet->output.configUpdate.empty()) {
+        std::unique_ptr<C2Param> param;
+        worklet->output.configUpdate.back().swap(param);
+        worklet->output.configUpdate.pop_back();
+        switch (param->coreIndex().coreIndex()) {
+            case C2PortReorderBufferDepthTuning::CORE_INDEX: {
+                C2PortReorderBufferDepthTuning::output reorderDepth;
+                if (reorderDepth.updateFrom(*param)) {
+                    mReorderStash.lock()->setDepth(reorderDepth.value);
+                    ALOGV("[%s] onWorkDone: updated reorder depth to %u",
+                          mName, reorderDepth.value);
+                } else {
+                    ALOGD("[%s] onWorkDone: failed to read reorder depth", mName);
+                }
+                break;
+            }
+            case C2PortReorderKeySetting::CORE_INDEX: {
+                C2PortReorderKeySetting::output reorderKey;
+                if (reorderKey.updateFrom(*param)) {
+                    mReorderStash.lock()->setKey(reorderKey.value);
+                    ALOGV("[%s] onWorkDone: updated reorder key to %u",
+                          mName, reorderKey.value);
+                } else {
+                    ALOGD("[%s] onWorkDone: failed to read reorder key", mName);
+                }
+                break;
+            }
+            default:
+                ALOGV("[%s] onWorkDone: unrecognized config update (%08X)",
+                      mName, param->index());
+                break;
+        }
+    }
+
+    if (outputFormat != nullptr) {
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        ALOGD("[%s] onWorkDone: output format changed to %s",
+                mName, outputFormat->debugString().c_str());
+        (*buffers)->setFormat(outputFormat);
+
+        AString mediaType;
+        if (outputFormat->findString(KEY_MIME, &mediaType)
+                && mediaType == MIMETYPE_AUDIO_RAW) {
+            int32_t channelCount;
+            int32_t sampleRate;
+            if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
+                    && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+                (*buffers)->updateSkipCutBuffer(sampleRate, channelCount);
+            }
+        }
+    }
+
+    int32_t flags = 0;
+    if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= MediaCodec::BUFFER_FLAG_EOS;
+        ALOGV("[%s] onWorkDone: output EOS", mName);
+    }
+
+    sp<MediaCodecBuffer> outBuffer;
+    size_t index;
+
+    // WORKAROUND: adjust output timestamp based on client input timestamp and codec
+    // input timestamp. Codec output timestamp (in the timestamp field) shall correspond to
+    // the codec input timestamp, but client output timestamp should (reported in timeUs)
+    // shall correspond to the client input timesamp (in customOrdinal). By using the
+    // delta between the two, this allows for some timestamp deviation - e.g. if one input
+    // produces multiple output.
+    c2_cntr64_t timestamp =
+        worklet->output.ordinal.timestamp + work->input.ordinal.customOrdinal
+                - work->input.ordinal.timestamp;
+    ALOGV("[%s] onWorkDone: input %lld, codec %lld => output %lld => %lld",
+          mName,
+          work->input.ordinal.customOrdinal.peekll(),
+          work->input.ordinal.timestamp.peekll(),
+          worklet->output.ordinal.timestamp.peekll(),
+          timestamp.peekll());
+
+    if (initData != nullptr) {
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        if ((*buffers)->registerCsd(initData, &index, &outBuffer) == OK) {
+            outBuffer->meta()->setInt64("timeUs", timestamp.peek());
+            outBuffer->meta()->setInt32("flags", MediaCodec::BUFFER_FLAG_CODECCONFIG);
+            ALOGV("[%s] onWorkDone: csd index = %zu [%p]", mName, index, outBuffer.get());
+
+            buffers.unlock();
+            mCallback->onOutputBufferAvailable(index, outBuffer);
+            buffers.lock();
+        } else {
+            ALOGD("[%s] onWorkDone: unable to register csd", mName);
+            buffers.unlock();
+            mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+            buffers.lock();
+            return false;
+        }
+    }
+
+    if (!buffer && !flags) {
+        ALOGV("[%s] onWorkDone: Not reporting output buffer (%lld)",
+              mName, work->input.ordinal.frameIndex.peekull());
+        return true;
+    }
+
+    if (buffer) {
+        for (const std::shared_ptr<const C2Info> &info : buffer->info()) {
+            // TODO: properly translate these to metadata
+            switch (info->coreIndex().coreIndex()) {
+                case C2StreamPictureTypeMaskInfo::CORE_INDEX:
+                    if (((C2StreamPictureTypeMaskInfo *)info.get())->value & C2PictureTypeKeyFrame) {
+                        flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME;
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    {
+        Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+        reorder->emplace(buffer, timestamp.peek(), flags, worklet->output.ordinal);
+        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+            // Flush reorder stash
+            reorder->setDepth(0);
+        }
+    }
+    sendOutputBuffers();
+    return true;
+}
+
+void CCodecBufferChannel::sendOutputBuffers() {
+    ReorderStash::Entry entry;
+    sp<MediaCodecBuffer> outBuffer;
+    size_t index;
+
+    while (true) {
+        {
+            Mutexed<ReorderStash>::Locked reorder(mReorderStash);
+            if (!reorder->hasPending()) {
+                break;
+            }
+            if (!reorder->pop(&entry)) {
+                break;
+            }
+        }
+        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+        status_t err = (*buffers)->registerBuffer(entry.buffer, &index, &outBuffer);
+        if (err != OK) {
+            if (err != WOULD_BLOCK) {
+                OutputBuffersArray *array = (OutputBuffersArray *)buffers->get();
+                array->realloc(entry.buffer);
+                mCCodecCallback->onOutputBuffersChanged();
+            }
+            buffers.unlock();
+            ALOGV("[%s] sendOutputBuffers: unable to register output buffer", mName);
+            mReorderStash.lock()->defer(entry);
+            return;
+        }
+        buffers.unlock();
+
+        outBuffer->meta()->setInt64("timeUs", entry.timestamp);
+        outBuffer->meta()->setInt32("flags", entry.flags);
+        ALOGV("[%s] sendOutputBuffers: out buffer index = %zu [%p] => %p + %zu",
+                mName, index, outBuffer.get(), outBuffer->data(), outBuffer->size());
+        mCallback->onOutputBufferAvailable(index, outBuffer);
+    }
+}
+
+status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
+    static std::atomic_uint32_t surfaceGeneration{0};
+    uint32_t generation = (getpid() << 10) |
+            ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1)
+                & ((1 << 10) - 1));
+
+    sp<IGraphicBufferProducer> producer;
+    if (newSurface) {
+        newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+        newSurface->setMaxDequeuedBufferCount(kMinOutputBufferArraySize);
+        producer = newSurface->getIGraphicBufferProducer();
+        producer->setGenerationNumber(generation);
+    } else {
+        ALOGE("[%s] setting output surface to null", mName);
+        return INVALID_OPERATION;
+    }
+
+    std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
+    C2BlockPool::local_id_t outputPoolId;
+    {
+        Mutexed<BlockPools>::Locked pools(mBlockPools);
+        outputPoolId = pools->outputPoolId;
+        outputPoolIntf = pools->outputPoolIntf;
+    }
+
+    if (outputPoolIntf) {
+        if (mComponent->setOutputSurface(
+                outputPoolId,
+                producer,
+                generation) != C2_OK) {
+            ALOGI("[%s] setSurface: component setOutputSurface failed", mName);
+            return INVALID_OPERATION;
+        }
+    }
+
+    {
+        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+        output->surface = newSurface;
+        output->generation = generation;
+    }
+
+    return OK;
+}
+
+void CCodecBufferChannel::setMetaMode(MetaMode mode) {
+    mMetaMode = mode;
+}
+
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
+    // C2_OK is always translated to OK.
+    if (c2s == C2_OK) {
+        return OK;
+    }
+
+    // Operation-dependent translation
+    // TODO: Add as necessary
+    switch (c2op) {
+    case C2_OPERATION_Component_start:
+        switch (c2s) {
+        case C2_NO_MEMORY:
+            return NO_MEMORY;
+        default:
+            return UNKNOWN_ERROR;
+        }
+    default:
+        break;
+    }
+
+    // Backup operation-agnostic translation
+    switch (c2s) {
+    case C2_BAD_INDEX:
+        return BAD_INDEX;
+    case C2_BAD_VALUE:
+        return BAD_VALUE;
+    case C2_BLOCKING:
+        return WOULD_BLOCK;
+    case C2_DUPLICATE:
+        return ALREADY_EXISTS;
+    case C2_NO_INIT:
+        return NO_INIT;
+    case C2_NO_MEMORY:
+        return NO_MEMORY;
+    case C2_NOT_FOUND:
+        return NAME_NOT_FOUND;
+    case C2_TIMED_OUT:
+        return TIMED_OUT;
+    case C2_BAD_STATE:
+    case C2_CANCELED:
+    case C2_CANNOT_DO:
+    case C2_CORRUPTED:
+    case C2_OMITTED:
+    case C2_REFUSED:
+        return UNKNOWN_ERROR;
+    default:
+        return -static_cast<status_t>(c2s);
+    }
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
new file mode 100644
index 0000000..431baaa
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -0,0 +1,417 @@
+/*
+ * Copyright 2017, 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 CCODEC_BUFFER_CHANNEL_H_
+
+#define CCODEC_BUFFER_CHANNEL_H_
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <Codec2Mapper.h>
+
+#include <codec2/hidl/client.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <media/stagefright/codec2/1.0/InputSurface.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/stagefright/CodecBase.h>
+#include <media/ICrypto.h>
+
+#include "InputSurfaceWrapper.h"
+
+namespace android {
+
+class CCodecCallback {
+public:
+    virtual ~CCodecCallback() = default;
+    virtual void onError(status_t err, enum ActionCode actionCode) = 0;
+    virtual void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) = 0;
+    virtual void onWorkQueued(bool eos) = 0;
+    virtual void onOutputBuffersChanged() = 0;
+};
+
+/**
+ * BufferChannelBase implementation for CCodec.
+ */
+class CCodecBufferChannel
+    : public BufferChannelBase, public std::enable_shared_from_this<CCodecBufferChannel> {
+public:
+    explicit CCodecBufferChannel(const std::shared_ptr<CCodecCallback> &callback);
+    virtual ~CCodecBufferChannel();
+
+    // BufferChannelBase interface
+    virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
+    virtual status_t queueSecureInputBuffer(
+            const sp<MediaCodecBuffer> &buffer,
+            bool secure,
+            const uint8_t *key,
+            const uint8_t *iv,
+            CryptoPlugin::Mode mode,
+            CryptoPlugin::Pattern pattern,
+            const CryptoPlugin::SubSample *subSamples,
+            size_t numSubSamples,
+            AString *errorDetailMsg) override;
+    virtual status_t renderOutputBuffer(
+            const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
+    virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override;
+    virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
+    virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
+
+    // Methods below are interface for CCodec to use.
+
+    /**
+     * Set the component object for buffer processing.
+     */
+    void setComponent(const std::shared_ptr<Codec2Client::Component> &component);
+
+    /**
+     * Set output graphic surface for rendering.
+     */
+    status_t setSurface(const sp<Surface> &surface);
+
+    /**
+     * Set GraphicBufferSource object from which the component extracts input
+     * buffers.
+     */
+    status_t setInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
+
+    /**
+     * Signal EOS to input surface.
+     */
+    status_t signalEndOfInputStream();
+
+    /**
+     * Set parameters.
+     */
+    status_t setParameters(std::vector<std::unique_ptr<C2Param>> &params);
+
+    /**
+     * Start queueing buffers to the component. This object should never queue
+     * buffers before this call has completed.
+     */
+    status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
+
+    /**
+     * Request initial input buffers to be filled by client.
+     */
+    status_t requestInitialInputBuffers();
+
+    /**
+     * Stop queueing buffers to the component. This object should never queue
+     * buffers after this call, until start() is called.
+     */
+    void stop();
+
+    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork);
+
+    /**
+     * Notify input client about work done.
+     *
+     * @param workItems   finished work item.
+     * @param outputFormat new output format if it has changed, otherwise nullptr
+     * @param initData    new init data (CSD) if it has changed, otherwise nullptr
+     * @param numDiscardedInputBuffers the number of input buffers that are
+     *                    returned for the first time (not previously returned by
+     *                    onInputBufferDone()).
+     */
+    void onWorkDone(
+            std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+            const C2StreamInitDataInfo::output *initData,
+            size_t numDiscardedInputBuffers);
+
+    /**
+     * Make an input buffer available for the client as it is no longer needed
+     * by the codec.
+     *
+     * @param buffer The buffer that becomes unused.
+     */
+    void onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer);
+
+    enum MetaMode {
+        MODE_NONE,
+        MODE_ANW,
+    };
+
+    void setMetaMode(MetaMode mode);
+
+    // Internal classes
+    class Buffers;
+    class InputBuffers;
+    class OutputBuffers;
+
+private:
+    class QueueGuard;
+
+    /**
+     * Special mutex-like object with the following properties:
+     *
+     * - At STOPPED state (initial, or after stop())
+     *   - QueueGuard object gets created at STOPPED state, and the client is
+     *     supposed to return immediately.
+     * - At RUNNING state (after start())
+     *   - Each QueueGuard object
+     */
+    class QueueSync {
+    public:
+        /**
+         * At construction the sync object is in STOPPED state.
+         */
+        inline QueueSync() {}
+        ~QueueSync() = default;
+
+        /**
+         * Transition to RUNNING state when stopped. No-op if already in RUNNING
+         * state.
+         */
+        void start();
+
+        /**
+         * At RUNNING state, wait until all QueueGuard object created during
+         * RUNNING state are destroyed, and then transition to STOPPED state.
+         * No-op if already in STOPPED state.
+         */
+        void stop();
+
+    private:
+        Mutex mGuardLock;
+
+        struct Counter {
+            inline Counter() : value(-1) {}
+            int32_t value;
+            Condition cond;
+        };
+        Mutexed<Counter> mCount;
+
+        friend class CCodecBufferChannel::QueueGuard;
+    };
+
+    class QueueGuard {
+    public:
+        QueueGuard(QueueSync &sync);
+        ~QueueGuard();
+        inline bool isRunning() { return mRunning; }
+
+    private:
+        QueueSync &mSync;
+        bool mRunning;
+    };
+
+    void feedInputBufferIfAvailable();
+    void feedInputBufferIfAvailableInternal();
+    status_t queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer);
+    bool handleWork(
+            std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
+            const C2StreamInitDataInfo::output *initData);
+    void sendOutputBuffers();
+
+    QueueSync mSync;
+    sp<MemoryDealer> mDealer;
+    sp<IMemory> mDecryptDestination;
+    int32_t mHeapSeqNum;
+
+    std::shared_ptr<Codec2Client::Component> mComponent;
+    std::string mComponentName; ///< component name for debugging
+    const char *mName; ///< C-string version of component name
+    std::shared_ptr<CCodecCallback> mCCodecCallback;
+    std::shared_ptr<C2BlockPool> mInputAllocator;
+    QueueSync mQueueSync;
+    std::vector<std::unique_ptr<C2Param>> mParamsToBeSet;
+
+    Mutexed<std::unique_ptr<InputBuffers>> mInputBuffers;
+    Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
+    Mutexed<std::unique_ptr<OutputBuffers>> mOutputBuffers;
+
+    std::atomic_uint64_t mFrameIndex;
+    std::atomic_uint64_t mFirstValidFrameIndex;
+
+    sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
+
+    struct OutputSurface {
+        sp<Surface> surface;
+        uint32_t generation;
+    };
+    Mutexed<OutputSurface> mOutputSurface;
+
+    struct BlockPools {
+        C2Allocator::id_t inputAllocatorId;
+        std::shared_ptr<C2BlockPool> inputPool;
+        C2Allocator::id_t outputAllocatorId;
+        C2BlockPool::local_id_t outputPoolId;
+        std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
+    };
+    Mutexed<BlockPools> mBlockPools;
+
+    std::shared_ptr<InputSurfaceWrapper> mInputSurface;
+
+    MetaMode mMetaMode;
+
+    // PipelineCapacity is used in the input buffer gating logic.
+    //
+    // There are three criteria that need to be met before
+    // onInputBufferAvailable() is called:
+    // 1. The number of input buffers that have been received by
+    //    CCodecBufferChannel but not returned via onWorkDone() or
+    //    onInputBufferDone() does not exceed a certain limit. (Let us call this
+    //    number the "input" capacity.)
+    // 2. The number of work items that have been received by
+    //    CCodecBufferChannel whose outputs have not been returned from the
+    //    component (by calling onWorkDone()) does not exceed a certain limit.
+    //    (Let us call this the "component" capacity.)
+    //
+    // These three criteria guarantee that a new input buffer that arrives from
+    // the invocation of onInputBufferAvailable() will not
+    // 1. overload CCodecBufferChannel's input buffers;
+    // 2. overload the component; or
+    //
+    struct PipelineCapacity {
+        // The number of available input capacity.
+        std::atomic_int input;
+        // The number of available component capacity.
+        std::atomic_int component;
+
+        PipelineCapacity();
+        // Set the values of #input and #component.
+        void initialize(int newInput, int newComponent,
+                        const char* newName = "<UNKNOWN COMPONENT>",
+                        const char* callerTag = nullptr);
+
+        // Return true and decrease #input and #component by one if
+        // they are all greater than zero; return false otherwise.
+        //
+        // callerTag is used for logging only.
+        //
+        // allocate() is called by CCodecBufferChannel to check whether it can
+        // receive another input buffer. If the return value is true,
+        // onInputBufferAvailable() and onOutputBufferAvailable() can be called
+        // afterwards.
+        bool allocate(const char* callerTag = nullptr);
+
+        // Increase #input and #component by one.
+        //
+        // callerTag is used for logging only.
+        //
+        // free() is called by CCodecBufferChannel after allocate() returns true
+        // but onInputBufferAvailable() cannot be called for any reasons. It
+        // essentially undoes an allocate() call.
+        void free(const char* callerTag = nullptr);
+
+        // Increase #input by @p numDiscardedInputBuffers.
+        //
+        // callerTag is used for logging only.
+        //
+        // freeInputSlots() is called by CCodecBufferChannel when onWorkDone()
+        // or onInputBufferDone() is called. @p numDiscardedInputBuffers is
+        // provided in onWorkDone(), and is 1 in onInputBufferDone().
+        int freeInputSlots(size_t numDiscardedInputBuffers,
+                           const char* callerTag = nullptr);
+
+        // Increase #component by one and return the updated value.
+        //
+        // callerTag is used for logging only.
+        //
+        // freeComponentSlot() is called by CCodecBufferChannel when
+        // onWorkDone() is called.
+        int freeComponentSlot(const char* callerTag = nullptr);
+
+    private:
+        // Component name. Used for logging.
+        const char* mName;
+    };
+    PipelineCapacity mAvailablePipelineCapacity;
+
+    class ReorderStash {
+    public:
+        struct Entry {
+            inline Entry() : buffer(nullptr), timestamp(0), flags(0), ordinal({0, 0, 0}) {}
+            inline Entry(
+                    const std::shared_ptr<C2Buffer> &b,
+                    int64_t t,
+                    int32_t f,
+                    const C2WorkOrdinalStruct &o)
+                : buffer(b), timestamp(t), flags(f), ordinal(o) {}
+            std::shared_ptr<C2Buffer> buffer;
+            int64_t timestamp;
+            int32_t flags;
+            C2WorkOrdinalStruct ordinal;
+        };
+
+        ReorderStash();
+
+        void clear();
+        void setDepth(uint32_t depth);
+        void setKey(C2Config::ordinal_key_t key);
+        bool pop(Entry *entry);
+        void emplace(
+                const std::shared_ptr<C2Buffer> &buffer,
+                int64_t timestamp,
+                int32_t flags,
+                const C2WorkOrdinalStruct &ordinal);
+        void defer(const Entry &entry);
+        bool hasPending() const;
+
+    private:
+        std::list<Entry> mPending;
+        std::list<Entry> mStash;
+        uint32_t mDepth;
+        C2Config::ordinal_key_t mKey;
+
+        bool less(const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2);
+    };
+    Mutexed<ReorderStash> mReorderStash;
+
+    std::atomic_bool mInputMetEos;
+
+    inline bool hasCryptoOrDescrambler() {
+        return mCrypto != nullptr || mDescrambler != nullptr;
+    }
+};
+
+// Conversion of a c2_status_t value to a status_t value may depend on the
+// operation that returns the c2_status_t value.
+enum c2_operation_t {
+    C2_OPERATION_NONE,
+    C2_OPERATION_Component_connectToOmxInputSurface,
+    C2_OPERATION_Component_createBlockPool,
+    C2_OPERATION_Component_destroyBlockPool,
+    C2_OPERATION_Component_disconnectFromInputSurface,
+    C2_OPERATION_Component_drain,
+    C2_OPERATION_Component_flush,
+    C2_OPERATION_Component_queue,
+    C2_OPERATION_Component_release,
+    C2_OPERATION_Component_reset,
+    C2_OPERATION_Component_setOutputSurface,
+    C2_OPERATION_Component_start,
+    C2_OPERATION_Component_stop,
+    C2_OPERATION_ComponentStore_copyBuffer,
+    C2_OPERATION_ComponentStore_createComponent,
+    C2_OPERATION_ComponentStore_createInputSurface,
+    C2_OPERATION_ComponentStore_createInterface,
+    C2_OPERATION_Configurable_config,
+    C2_OPERATION_Configurable_query,
+    C2_OPERATION_Configurable_querySupportedParams,
+    C2_OPERATION_Configurable_querySupportedValues,
+    C2_OPERATION_InputSurface_connectToComponent,
+    C2_OPERATION_InputSurfaceConnection_disconnect,
+};
+
+status_t toStatusT(c2_status_t c2s, c2_operation_t c2op = C2_OPERATION_NONE);
+
+}  // namespace android
+
+#endif  // CCODEC_BUFFER_CHANNEL_H_
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
new file mode 100644
index 0000000..8dbfd0e
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -0,0 +1,1588 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CCodecConfig"
+#include <cutils/properties.h>
+#include <log/log.h>
+
+#include <C2Component.h>
+#include <C2Debug.h>
+#include <C2Param.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include "CCodecConfig.h"
+#include "Codec2Mapper.h"
+
+#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+// names of properties that can be used to override the default DRC settings
+#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
+#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
+#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL  "aac_drc_enc_target_level"
+#define PROP_DRC_OVERRIDE_EFFECT     "ro.aac_drc_effect_type"
+
+namespace android {
+
+// CCodecConfig
+
+namespace {
+
+/**
+ * mapping between SDK and Codec 2.0 configurations.
+ */
+struct ConfigMapper {
+    /**
+     * Value mapper (C2Value => C2Value)
+     */
+    typedef std::function<C2Value(C2Value)> Mapper;
+
+    /// shorthand
+    typedef CCodecConfig::Domain Domain;
+
+    ConfigMapper(std::string mediaKey, C2String c2struct, C2String c2field)
+        : mDomain(Domain::ALL), mMediaKey(mediaKey), mStruct(c2struct), mField(c2field) { }
+
+    /// Limits this parameter to the given domain
+    ConfigMapper &limitTo(uint32_t domain) {
+        C2_CHECK(domain & Domain::GUARD_BIT);
+        mDomain = Domain(mDomain & domain);
+        return *this;
+    }
+
+    /// Adds SDK => Codec 2.0 mapper (should not be in the SDK format)
+    ConfigMapper &withMapper(Mapper mapper) {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = mapper;
+        return *this;
+    }
+
+    /// Adds SDK <=> Codec 2.0 value mappers
+    ConfigMapper &withMappers(Mapper mapper, Mapper reverse) {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = mapper;
+        mReverse = reverse;
+        return *this;
+    }
+
+    /// Adds SDK <=> Codec 2.0 value mappers based on C2Mapper
+    template<typename C2Type, typename SdkType=int32_t>
+    ConfigMapper &withC2Mappers() {
+        C2_CHECK(!mMapper);
+        C2_CHECK(!mReverse);
+        mMapper = [](C2Value v) -> C2Value {
+            SdkType sdkValue;
+            C2Type c2Value;
+            if (v.get(&sdkValue) && C2Mapper::map(sdkValue, &c2Value)) {
+                return c2Value;
+            }
+            return C2Value();
+        };
+        mReverse = [](C2Value v) -> C2Value {
+            SdkType sdkValue;
+            C2Type c2Value;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<C2Type>::type;
+            if (v.get((C2ValueType*)&c2Value) && C2Mapper::map(c2Value, &sdkValue)) {
+                return sdkValue;
+            }
+            return C2Value();
+        };
+        return *this;
+    }
+
+    /// Maps from SDK values in an AMessage to a suitable C2Value.
+    C2Value mapFromMessage(const AMessage::ItemData &item) const {
+        C2Value value;
+        int32_t int32Value;
+        int64_t int64Value;
+        float floatValue;
+        double doubleValue;
+        if (item.find(&int32Value)) {
+            value = int32Value;
+        } else if (item.find(&int64Value)) {
+            value = int64Value;
+        } else if (item.find(&floatValue)) {
+            value = floatValue;
+        } else if (item.find(&doubleValue)) {
+            value = (float)doubleValue;
+        }
+        if (value.type() != C2Value::NO_INIT && mMapper) {
+            value = mMapper(value);
+        }
+        return value;
+    }
+
+    /// Maps from a C2Value to an SDK value in an AMessage.
+    AMessage::ItemData mapToMessage(C2Value value) const {
+        AMessage::ItemData item;
+        int32_t int32Value;
+        uint32_t uint32Value;
+        int64_t int64Value;
+        uint64_t uint64Value;
+        float floatValue;
+        if (value.type() != C2Value::NO_INIT && mReverse) {
+            value = mReverse(value);
+        }
+        if (value.get(&int32Value)) {
+            item.set(int32Value);
+        } else if (value.get(&uint32Value) && uint32Value <= uint32_t(INT32_MAX)) {
+            // SDK does not support unsigned values
+            item.set((int32_t)uint32Value);
+        } else if (value.get(&int64Value)) {
+            item.set(int64Value);
+        } else if (value.get(&uint64Value) && uint64Value <= uint64_t(INT64_MAX)) {
+            // SDK does not support unsigned values
+            item.set((int64_t)uint64Value);
+        } else if (value.get(&floatValue)) {
+            item.set(floatValue);
+        }
+        return item;
+    }
+
+    Domain domain() const { return mDomain; }
+    std::string mediaKey() const { return mMediaKey; }
+    std::string path() const { return mField.size() ? mStruct + '.' + mField : mStruct; }
+    Mapper mapper() const { return mMapper; }
+    Mapper reverse() const { return mReverse; }
+
+private:
+    Domain mDomain;         ///< parameter domain (mask) containing port, kind and config domains
+    std::string mMediaKey;  ///< SDK key
+    C2String mStruct;       ///< Codec 2.0 struct name
+    C2String mField;        ///< Codec 2.0 field name
+    Mapper mMapper;         ///< optional SDK => Codec 2.0 value mapper
+    Mapper mReverse;        ///< optional Codec 2.0 => SDK value mapper
+};
+
+template <typename PORT, typename STREAM>
+AString QueryMediaTypeImpl(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    AString mediaType;
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err = component->query(
+            {}, { PORT::PARAM_TYPE, STREAM::PARAM_TYPE }, C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK && queried.size() == 0) {
+        ALOGD("Query media type failed => %s", asString(c2err));
+    } else {
+        PORT *portMediaType =
+            PORT::From(queried[0].get());
+        if (portMediaType) {
+            mediaType = AString(
+                    portMediaType->m.value,
+                    strnlen(portMediaType->m.value, portMediaType->flexCount()));
+        } else {
+            STREAM *streamMediaType = STREAM::From(queried[0].get());
+            if (streamMediaType) {
+                mediaType = AString(
+                        streamMediaType->m.value,
+                        strnlen(streamMediaType->m.value, streamMediaType->flexCount()));
+            }
+        }
+        ALOGD("read media type: %s", mediaType.c_str());
+    }
+    return mediaType;
+}
+
+AString QueryMediaType(
+        bool input, const std::shared_ptr<Codec2Client::Component> &component) {
+    typedef C2PortMediaTypeSetting P;
+    typedef C2StreamMediaTypeSetting S;
+    if (input) {
+        return QueryMediaTypeImpl<P::input, S::input>(component);
+    } else {
+        return QueryMediaTypeImpl<P::output, S::output>(component);
+    }
+}
+
+}  // namespace
+
+/**
+ * Set of standard parameters used by CCodec that are exposed to MediaCodec.
+ */
+struct StandardParams {
+    typedef CCodecConfig::Domain Domain;
+
+    // standard (MediaCodec) params are keyed by media format key
+    typedef std::string SdkKey;
+
+    /// used to return reference to no config mappers in getConfigMappersForSdkKey
+    static const std::vector<ConfigMapper> NO_MAPPERS;
+
+    /// Returns Codec 2.0 equivalent parameters for an SDK format key.
+    const std::vector<ConfigMapper> &getConfigMappersForSdkKey(std::string key) const {
+        auto it = mConfigMappers.find(key);
+        if (it == mConfigMappers.end()) {
+            ALOGD("no c2 equivalents for %s", key.c_str());
+            return NO_MAPPERS;
+        }
+        ALOGV("found %zu eqs for %s", it->second.size(), key.c_str());
+        return it->second;
+    }
+
+    /**
+     * Adds a SDK <=> Codec 2.0 parameter mapping. Multiple Codec 2.0 parameters may map to a
+     * single SDK key, in which case they shall be ordered from least authoritative to most
+     * authoritative. When constructing SDK formats, the last mapped Codec 2.0 parameter that
+     * is supported by the component will determine the exposed value. (TODO: perhaps restrict this
+     * by domain.)
+     */
+    void add(const ConfigMapper &cm) {
+        auto it = mConfigMappers.find(cm.mediaKey());
+        ALOGV("%c%c%c%c %c%c%c %04x %9s %s => %s",
+              ((cm.domain() & Domain::IS_INPUT) ? 'I' : ' '),
+              ((cm.domain() & Domain::IS_OUTPUT) ? 'O' : ' '),
+              ((cm.domain() & Domain::IS_CODED) ? 'C' : ' '),
+              ((cm.domain() & Domain::IS_RAW) ? 'R' : ' '),
+              ((cm.domain() & Domain::IS_CONFIG) ? 'c' : ' '),
+              ((cm.domain() & Domain::IS_PARAM) ? 'p' : ' '),
+              ((cm.domain() & Domain::IS_READ) ? 'r' : ' '),
+              cm.domain(),
+              it == mConfigMappers.end() ? "adding" : "extending",
+              cm.mediaKey().c_str(), cm.path().c_str());
+        if (it == mConfigMappers.end()) {
+            std::vector<ConfigMapper> eqs = { cm };
+            mConfigMappers.emplace(cm.mediaKey(), eqs);
+        } else {
+            it->second.push_back(cm);
+        }
+    }
+
+    /**
+     * Returns all paths for a specific domain.
+     *
+     * \param any maximum domain mask. Returned parameters must match at least one of the domains
+     *            in the mask.
+     * \param all minimum domain mask. Returned parameters must match all of the domains in the
+     *            mask. This is restricted to the bits of the maximum mask.
+     */
+    std::vector<std::string> getPathsForDomain(
+            Domain any, Domain all = Domain::ALL) const {
+        std::vector<std::string> res;
+        for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
+            for (const ConfigMapper &cm : el.second) {
+                ALOGV("filtering %s %x %x %x %x", cm.path().c_str(), cm.domain(), any,
+                        (cm.domain() & any), (cm.domain() & any & all));
+                if ((cm.domain() & any) && ((cm.domain() & any & all) == (any & all))) {
+                    res.push_back(cm.path());
+                }
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Returns SDK <=> Codec 2.0 mappings.
+     *
+     * TODO: replace these with better methods as this exposes the inner structure.
+     */
+    const std::map<SdkKey, std::vector<ConfigMapper>> getKeys() const {
+        return mConfigMappers;
+    }
+
+private:
+    std::map<SdkKey, std::vector<ConfigMapper>> mConfigMappers;
+};
+
+const std::vector<ConfigMapper> StandardParams::NO_MAPPERS;
+
+
+CCodecConfig::CCodecConfig()
+    : mInputFormat(new AMessage),
+      mOutputFormat(new AMessage),
+      mUsingSurface(false) { }
+
+void CCodecConfig::initializeStandardParams() {
+    typedef Domain D;
+    mStandardParams = std::make_shared<StandardParams>();
+    std::function<void(const ConfigMapper &)> add =
+        [params = mStandardParams](const ConfigMapper &cm) {
+            params->add(cm);
+    };
+    std::function<void(const ConfigMapper &)> deprecated = add;
+
+    // allow int32 or float SDK values and represent them as float
+    ConfigMapper::Mapper makeFloat = [](C2Value v) -> C2Value {
+        // convert from i32 to float
+        int32_t i32Value;
+        float fpValue;
+        if (v.get(&i32Value)) {
+            return (float)i32Value;
+        } else if (v.get(&fpValue)) {
+            return fpValue;
+        }
+        return C2Value();
+    };
+
+    ConfigMapper::Mapper negate = [](C2Value v) -> C2Value {
+        int32_t value;
+        if (v.get(&value)) {
+            return -value;
+        }
+        return C2Value();
+    };
+
+    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_INPUT_MEDIA_TYPE,    "value")
+        .limitTo(D::INPUT & D::READ));
+    add(ConfigMapper(KEY_MIME,     C2_PARAMKEY_OUTPUT_MEDIA_TYPE,   "value")
+        .limitTo(D::OUTPUT & D::READ));
+
+    add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::OUTPUT));
+    // we also need to put the bitrate in the max bitrate field
+    add(ConfigMapper(KEY_MAX_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::READ & D::OUTPUT));
+    add(ConfigMapper(PARAMETER_KEY_VIDEO_BITRATE, C2_PARAMKEY_BITRATE, "value")
+        .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
+    add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
+        .limitTo(D::ENCODER & D::CODED)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            C2Config::bitrate_mode_t mode;
+            if (v.get(&value) && C2Mapper::map(value, &mode)) {
+                return mode;
+            }
+            return C2Value();
+        }));
+    // remove when codecs switch to PARAMKEY and new modes
+    deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
+               .limitTo(D::ENCODER));
+    add(ConfigMapper(KEY_FRAME_RATE, C2_PARAMKEY_FRAME_RATE, "value")
+        .limitTo(D::VIDEO)
+        .withMappers(makeFloat, [](C2Value v) -> C2Value {
+            // read back always as int
+            float value;
+            if (v.get(&value)) {
+                return (int32_t)value;
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_MAX_INPUT_SIZE, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE, "value")
+        .limitTo(D::INPUT));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper(KEY_MAX_INPUT_SIZE, "coded.max-frame-size", "value")
+               .limitTo(D::INPUT));
+
+    // Rotation
+    // Note: SDK rotation is clock-wise, while C2 rotation is counter-clock-wise
+    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
+        .limitTo(D::VIDEO & D::CODED)
+        .withMappers(negate, negate));
+    add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
+        .limitTo(D::VIDEO & D::RAW)
+        .withMappers(negate, negate));
+
+    // android 'video-scaling'
+    add(ConfigMapper("android._video-scaling", C2_PARAMKEY_SURFACE_SCALING_MODE, "value")
+        .limitTo(D::VIDEO & D::DECODER & D::RAW));
+
+    // Color Aspects
+    //
+    // configure default for decoders
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM))
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_DEFAULT_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::CODED & (D::CONFIG | D::PARAM)));
+
+    // read back final for decoder output (also, configure final aspects as well. This should be
+    // overwritten based on coded/default values if component supports color aspects, but is used
+    // as final values if component does not support aspects at all)
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::DECODER  & D::RAW));
+
+    // configure source aspects for encoders and read them back on the coded(!) port.
+    // This is to ensure muxing the desired aspects into the container.
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::CODED));
+
+    // read back coded aspects for encoders (on the raw port), but also configure
+    // desired aspects here.
+    add(ConfigMapper(KEY_COLOR_RANGE,       C2_PARAMKEY_VUI_COLOR_ASPECTS,   "range")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
+        .withC2Mappers<C2Color::range_t>());
+    add(ConfigMapper(KEY_COLOR_TRANSFER,    C2_PARAMKEY_VUI_COLOR_ASPECTS,   "transfer")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW)
+        .withC2Mappers<C2Color::transfer_t>());
+    add(ConfigMapper("color-primaries",     C2_PARAMKEY_VUI_COLOR_ASPECTS,   "primaries")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));
+    add(ConfigMapper("color-matrix",        C2_PARAMKEY_VUI_COLOR_ASPECTS,   "matrix")
+        .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER  & D::RAW));
+
+    // Dataspace
+    add(ConfigMapper("android._dataspace", C2_PARAMKEY_DATA_SPACE, "value")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    // HDR
+    add(ConfigMapper("smpte2086.red.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.red.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.green.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.green.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.blue.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.blue.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.white.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.x")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.white.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.y")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.max-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.max-luminance")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("smpte2086.min-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.min-luminance")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("cta861.max-cll", C2_PARAMKEY_HDR_STATIC_INFO, "max-cll")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper("cta861.max-fall", C2_PARAMKEY_HDR_STATIC_INFO, "max-fall")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
+                     C2_PARAMKEY_SECURE_MODE, "value"));
+
+    add(ConfigMapper("prepend-sps-pps-to-idr-frames",
+                     C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
+        .limitTo(D::ENCODER & D::VIDEO)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value) && value) {
+                return C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC);
+            } else {
+                return C2Value(C2Config::PREPEND_HEADER_TO_NONE);
+            }
+        }));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper("prepend-sps-pps-to-idr-frames",
+                            "coding.add-csd-to-sync-frames", "value")
+               .limitTo(D::ENCODER & D::VIDEO));
+    // convert to timestamp base
+    add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
+        .withMapper([](C2Value v) -> C2Value {
+            // convert from i32 to float
+            int32_t i32Value;
+            float fpValue;
+            if (v.get(&i32Value)) {
+                return int64_t(1000000) * i32Value;
+            } else if (v.get(&fpValue)) {
+                return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
+            }
+            return C2Value();
+        }));
+    // remove when codecs switch to proper coding.gop (add support for calculating gop)
+    deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
+               .limitTo(D::ENCODER & D::VIDEO));
+    add(ConfigMapper(KEY_INTRA_REFRESH_PERIOD, C2_PARAMKEY_INTRA_REFRESH, "period")
+        .limitTo(D::VIDEO & D::ENCODER)
+        .withMappers(makeFloat, [](C2Value v) -> C2Value {
+            // read back always as int
+            float value;
+            if (v.get(&value)) {
+                return (int32_t)value;
+            }
+            return C2Value();
+        }));
+    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
+    deprecated(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
+                     "coding.request-sync", "value")
+        .limitTo(D::PARAM & D::ENCODER)
+        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
+    add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
+                     C2_PARAMKEY_REQUEST_SYNC_FRAME, "value")
+        .limitTo(D::PARAM & D::ENCODER)
+        .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
+
+    add(ConfigMapper(KEY_OPERATING_RATE,   C2_PARAMKEY_OPERATING_RATE,     "value")
+        .limitTo(D::PARAM | D::CONFIG) // write-only
+        .withMapper(makeFloat));
+    // C2 priorities are inverted
+    add(ConfigMapper(KEY_PRIORITY,         C2_PARAMKEY_PRIORITY,           "value")
+        .withMappers(negate, negate));
+    // remove when codecs switch to PARAMKEY
+    deprecated(ConfigMapper(KEY_OPERATING_RATE,   "ctrl.operating-rate",     "value")
+               .withMapper(makeFloat));
+    deprecated(ConfigMapper(KEY_PRIORITY,         "ctrl.priority",           "value"));
+
+    add(ConfigMapper(KEY_WIDTH,         C2_PARAMKEY_PICTURE_SIZE,       "width")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper(KEY_HEIGHT,        C2_PARAMKEY_PICTURE_SIZE,       "height")
+        .limitTo(D::VIDEO | D::IMAGE));
+
+    add(ConfigMapper("crop-left",       C2_PARAMKEY_CROP_RECT,       "left")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-top",        C2_PARAMKEY_CROP_RECT,       "top")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-width",      C2_PARAMKEY_CROP_RECT,       "width")
+        .limitTo(D::VIDEO | D::IMAGE));
+    add(ConfigMapper("crop-height",     C2_PARAMKEY_CROP_RECT,       "height")
+        .limitTo(D::VIDEO | D::IMAGE));
+
+    add(ConfigMapper(KEY_MAX_WIDTH,     C2_PARAMKEY_MAX_PICTURE_SIZE,    "width")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+    add(ConfigMapper(KEY_MAX_HEIGHT,    C2_PARAMKEY_MAX_PICTURE_SIZE,    "height")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+
+    add(ConfigMapper("csd-0",           C2_PARAMKEY_INIT_DATA,       "value")
+        .limitTo(D::OUTPUT & D::READ));
+
+    add(ConfigMapper(C2_PARAMKEY_TEMPORAL_LAYERING, C2_PARAMKEY_TEMPORAL_LAYERING, "")
+        .limitTo(D::ENCODER & D::VIDEO & D::OUTPUT));
+
+    // Pixel Format (use local key for actual pixel format as we don't distinguish between
+    // SDK layouts for flexible format and we need the actual SDK color format in the media format)
+    add(ConfigMapper("android._color-format",  C2_PARAMKEY_PIXEL_FORMAT, "value")
+        .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value)) {
+                switch (value) {
+                    case COLOR_FormatSurface:
+                        return (uint32_t)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+                    case COLOR_FormatYUV420Flexible:
+                        return (uint32_t)HAL_PIXEL_FORMAT_YCBCR_420_888;
+                    case COLOR_FormatYUV420Planar:
+                    case COLOR_FormatYUV420SemiPlanar:
+                    case COLOR_FormatYUV420PackedPlanar:
+                    case COLOR_FormatYUV420PackedSemiPlanar:
+                        return (uint32_t)HAL_PIXEL_FORMAT_YV12;
+                    default:
+                        // TODO: support some sort of passthrough
+                        break;
+                }
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            uint32_t value;
+            if (v.get(&value)) {
+                switch (value) {
+                    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+                        return COLOR_FormatSurface;
+                    case HAL_PIXEL_FORMAT_YV12:
+                    case HAL_PIXEL_FORMAT_YCBCR_420_888:
+                        return COLOR_FormatYUV420Flexible;
+                    default:
+                        // TODO: support some sort of passthrough
+                        break;
+                }
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CHANNEL_COUNT,       "value")
+        .limitTo(D::AUDIO)); // read back to both formats
+    add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CODED_CHANNEL_COUNT, "value")
+        .limitTo(D::AUDIO & D::CODED));
+
+    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_SAMPLE_RATE,        "value")
+        .limitTo(D::AUDIO)); // read back to both port formats
+    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_CODED_SAMPLE_RATE,  "value")
+        .limitTo(D::AUDIO & D::CODED));
+
+    add(ConfigMapper(KEY_PCM_ENCODING,  C2_PARAMKEY_PCM_ENCODING,       "value")
+        .limitTo(D::AUDIO));
+
+    add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
+        .limitTo(D::AUDIO & D::CODED)
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value) && value) {
+                return C2Config::AAC_PACKAGING_ADTS;
+            }
+            return C2Value();
+        }, [](C2Value v) -> C2Value {
+            uint32_t value;
+            if (v.get(&value) && value == C2Config::AAC_PACKAGING_ADTS) {
+                return (int32_t)1;
+            }
+            return C2Value();
+        }));
+
+    std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
+        C2Mapper::GetProfileLevelMapper(mCodingMediaType);
+
+    add(ConfigMapper(KEY_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
+        .limitTo(D::CODED)
+        .withMappers([mapper](C2Value v) -> C2Value {
+            C2Config::profile_t c2 = PROFILE_UNUSED;
+            int32_t sdk;
+            if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
+                return c2;
+            }
+            return PROFILE_UNUSED;
+        }, [mapper](C2Value v) -> C2Value {
+            C2Config::profile_t c2;
+            int32_t sdk;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
+            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapProfile(c2, &sdk)) {
+                return sdk;
+            }
+            return C2Value();
+        }));
+
+    add(ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
+        .limitTo(D::CODED)
+        .withMappers([mapper](C2Value v) -> C2Value {
+            C2Config::level_t c2 = LEVEL_UNUSED;
+            int32_t sdk;
+            if (mapper && v.get(&sdk) && mapper->mapLevel(sdk, &c2)) {
+                return c2;
+            }
+            return LEVEL_UNUSED;
+        }, [mapper](C2Value v) -> C2Value {
+            C2Config::level_t c2;
+            int32_t sdk;
+            using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
+            if (mapper && v.get((C2ValueType*)&c2) && mapper->mapLevel(c2, &sdk)) {
+                return sdk;
+            }
+            return C2Value();
+        }));
+
+    // convert to dBFS and add default
+    add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
+            }
+            return float(-0.25 * c2_min(value, 127));
+        }));
+
+    // convert to 0-1 (%) and add default
+    add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_CUT, DRC_DEFAULT_MOBILE_DRC_CUT);
+            }
+            return float(c2_min(value, 127) / 127.);
+        }));
+
+    // convert to 0-1 (%) and add default
+    add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_BOOST, DRC_DEFAULT_MOBILE_DRC_BOOST);
+            }
+            return float(c2_min(value, 127) / 127.);
+        }));
+
+    // convert to compression type and add default
+    add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
+            }
+            return value == 1 ? C2Config::DRC_COMPRESSION_HEAVY : C2Config::DRC_COMPRESSION_LIGHT;
+        }));
+
+    // convert to dBFS and add default
+    add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_ENC_LEVEL, DRC_DEFAULT_MOBILE_ENC_LEVEL);
+            }
+            return float(-0.25 * c2_min(value, 127));
+        }));
+
+    // convert to effect type (these map to SDK values) and add default
+    add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
+        .limitTo(D::AUDIO & D::DECODER)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < -1 || value > 8) {
+                value = property_get_int32(PROP_DRC_OVERRIDE_EFFECT, DRC_DEFAULT_MOBILE_DRC_EFFECT);
+                // ensure value is within range
+                if (value < -1 || value > 8) {
+                    value = DRC_DEFAULT_MOBILE_DRC_EFFECT;
+                }
+            }
+            return value;
+        }));
+
+    add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
+        .limitTo(D::AUDIO));
+
+    add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
+        .limitTo(D::AUDIO & D::ENCODER & D::CONFIG)
+        .withMapper([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0) {
+                return C2Config::AAC_SBR_AUTO;
+            }
+            switch (value) {
+                case 0: return C2Config::AAC_SBR_OFF;
+                case 1: return C2Config::AAC_SBR_SINGLE_RATE;
+                case 2: return C2Config::AAC_SBR_DUAL_RATE;
+                default: return C2Config::AAC_SBR_AUTO + 1; // invalid value
+            }
+        }));
+
+    add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
+    add(ConfigMapper(KEY_FLAC_COMPRESSION_LEVEL, C2_PARAMKEY_COMPLEXITY, "value")
+        .limitTo(D::AUDIO & D::ENCODER));
+    add(ConfigMapper("complexity", C2_PARAMKEY_COMPLEXITY, "value")
+        .limitTo(D::ENCODER));
+
+    add(ConfigMapper(KEY_GRID_COLUMNS, C2_PARAMKEY_TILE_LAYOUT, "columns")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_GRID_ROWS, C2_PARAMKEY_TILE_LAYOUT, "rows")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_TILE_WIDTH, C2_PARAMKEY_TILE_LAYOUT, "tile.width")
+        .limitTo(D::IMAGE));
+    add(ConfigMapper(KEY_TILE_HEIGHT, C2_PARAMKEY_TILE_LAYOUT, "tile.height")
+        .limitTo(D::IMAGE));
+
+    add(ConfigMapper(KEY_LATENCY, C2_PARAMKEY_PIPELINE_DELAY_REQUEST, "value")
+        .limitTo(D::VIDEO & D::ENCODER));
+
+    add(ConfigMapper(C2_PARAMKEY_INPUT_TIME_STRETCH, C2_PARAMKEY_INPUT_TIME_STRETCH, "value"));
+
+    /* still to do
+    constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
+
+       not yet used by MediaCodec, but defined as MediaFormat
+    KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
+    KEY_OUTPUT_REORDER_DEPTH
+    */
+}
+
+status_t CCodecConfig::initialize(
+        const std::shared_ptr<Codec2Client> &client,
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
+    C2ComponentKindSetting kind(C2Component::KIND_OTHER);
+
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2err = component->query({ &domain, &kind }, {}, C2_DONT_BLOCK, &queried);
+    if (c2err != C2_OK) {
+        ALOGD("Query domain & kind failed => %s", asString(c2err));
+        // TEMP: determine kind from component name
+        if (kind.value == C2Component::KIND_OTHER) {
+            if (component->getName().find("encoder") != std::string::npos) {
+                kind.value = C2Component::KIND_ENCODER;
+            } else if (component->getName().find("decoder") != std::string::npos) {
+                kind.value = C2Component::KIND_DECODER;
+            }
+        }
+
+        // TEMP: determine domain from media type (port (preferred) or stream #0)
+        if (domain.value == C2Component::DOMAIN_OTHER) {
+            AString mediaType = QueryMediaType(true /* input */, component);
+            if (mediaType.startsWith("audio/")) {
+                domain.value = C2Component::DOMAIN_AUDIO;
+            } else if (mediaType.startsWith("video/")) {
+                domain.value = C2Component::DOMAIN_VIDEO;
+            } else if (mediaType.startsWith("image/")) {
+                domain.value = C2Component::DOMAIN_IMAGE;
+            }
+        }
+    }
+
+    mDomain = (domain.value == C2Component::DOMAIN_VIDEO ? Domain::IS_VIDEO :
+               domain.value == C2Component::DOMAIN_IMAGE ? Domain::IS_IMAGE :
+               domain.value == C2Component::DOMAIN_AUDIO ? Domain::IS_AUDIO : Domain::OTHER_DOMAIN)
+            | (kind.value == C2Component::KIND_DECODER ? Domain::IS_DECODER :
+               kind.value == C2Component::KIND_ENCODER ? Domain::IS_ENCODER : Domain::OTHER_KIND);
+
+    mInputDomain = Domain(((mDomain & IS_DECODER) ? IS_CODED : IS_RAW) | IS_INPUT);
+    mOutputDomain = Domain(((mDomain & IS_ENCODER) ? IS_CODED : IS_RAW) | IS_OUTPUT);
+
+    ALOGV("domain is %#x (%u %u)", mDomain, domain.value, kind.value);
+
+    std::vector<C2Param::Index> paramIndices;
+    switch (kind.value) {
+    case C2Component::KIND_DECODER:
+        mCodingMediaType = QueryMediaType(true /* input */, component).c_str();
+        break;
+    case C2Component::KIND_ENCODER:
+        mCodingMediaType = QueryMediaType(false /* input */, component).c_str();
+        break;
+    default:
+        mCodingMediaType = "";
+    }
+
+    c2err = component->querySupportedParams(&mParamDescs);
+    if (c2err != C2_OK) {
+        ALOGD("Query supported params failed after returning %zu values => %s",
+                mParamDescs.size(), asString(c2err));
+        return UNKNOWN_ERROR;
+    }
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
+        mSupportedIndices.emplace(desc->index());
+    }
+
+    mReflector = client->getParamReflector();
+    if (mReflector == nullptr) {
+        ALOGE("Failed to get param reflector");
+        return UNKNOWN_ERROR;
+    }
+
+    // enumerate all fields
+    mParamUpdater = std::make_shared<ReflectedParamUpdater>();
+    mParamUpdater->clear();
+    mParamUpdater->supportWholeParam(
+            C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
+    mParamUpdater->addParamDesc(mReflector, mParamDescs);
+
+    // TEMP: add some standard fields even if not reflected
+    if (kind.value == C2Component::KIND_ENCODER) {
+        mParamUpdater->addStandardParam<C2StreamInitDataInfo::output>(C2_PARAMKEY_INIT_DATA);
+    }
+    if (domain.value == C2Component::DOMAIN_IMAGE || domain.value == C2Component::DOMAIN_VIDEO) {
+        if (kind.value != C2Component::KIND_ENCODER) {
+            addLocalParam<C2StreamPictureSizeInfo::output>(C2_PARAMKEY_PICTURE_SIZE);
+            addLocalParam<C2StreamCropRectInfo::output>(C2_PARAMKEY_CROP_RECT);
+            addLocalParam(
+                    new C2StreamPixelAspectRatioInfo::output(0u, 1u, 1u),
+                    C2_PARAMKEY_PIXEL_ASPECT_RATIO);
+            addLocalParam(new C2StreamRotationInfo::output(0u, 0), C2_PARAMKEY_ROTATION);
+            addLocalParam(new C2StreamColorAspectsInfo::output(0u), C2_PARAMKEY_COLOR_ASPECTS);
+            addLocalParam<C2StreamDataSpaceInfo::output>(C2_PARAMKEY_DATA_SPACE);
+            addLocalParam<C2StreamHdrStaticInfo::output>(C2_PARAMKEY_HDR_STATIC_INFO);
+            addLocalParam(new C2StreamSurfaceScalingInfo::output(0u, VIDEO_SCALING_MODE_SCALE_TO_FIT),
+                          C2_PARAMKEY_SURFACE_SCALING_MODE);
+        } else {
+            addLocalParam(new C2StreamColorAspectsInfo::input(0u), C2_PARAMKEY_COLOR_ASPECTS);
+        }
+    }
+
+    initializeStandardParams();
+
+    // subscribe to all supported standard (exposed) params
+    // TODO: limit this to params that are actually in the domain
+    std::vector<std::string> formatKeys = mStandardParams->getPathsForDomain(Domain(1 << 30));
+    std::vector<C2Param::Index> indices;
+    mParamUpdater->getParamIndicesForKeys(formatKeys, &indices);
+    mSubscribedIndices.insert(indices.begin(), indices.end());
+
+    // also subscribe to some non-SDK standard parameters
+    // for number of input/output buffers
+    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::input::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::output::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2ActualPipelineDelayTuning::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortActualDelayTuning::input::PARAM_TYPE);
+    mSubscribedIndices.emplace(C2PortActualDelayTuning::output::PARAM_TYPE);
+    // for output buffer array allocation
+    mSubscribedIndices.emplace(C2StreamMaxBufferSizeInfo::output::PARAM_TYPE);
+    // init data (CSD)
+    mSubscribedIndices.emplace(C2StreamInitDataInfo::output::PARAM_TYPE);
+
+    return OK;
+}
+
+status_t CCodecConfig::subscribeToConfigUpdate(
+        const std::shared_ptr<Codec2Client::Component> &component,
+        const std::vector<C2Param::Index> &indices,
+        c2_blocking_t blocking) {
+    mSubscribedIndices.insert(indices.begin(), indices.end());
+    // TODO: enable this when components no longer crash on this config
+    if (mSubscribedIndices.size() != mSubscribedIndicesSize && false) {
+        std::vector<uint32_t> indices;
+        for (C2Param::Index ix : mSubscribedIndices) {
+            indices.push_back(ix);
+        }
+        std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
+            C2SubscribedParamIndicesTuning::AllocUnique(indices);
+        std::vector<std::unique_ptr<C2SettingResult>> results;
+        c2_status_t c2Err = component->config({ subscribeTuning.get() }, blocking, &results);
+        if (c2Err != C2_OK && c2Err != C2_BAD_INDEX) {
+            ALOGD("Failed to subscribe to parameters => %s", asString(c2Err));
+            // TODO: error
+        }
+        ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
+        mSubscribedIndicesSize = mSubscribedIndices.size();
+    }
+    return OK;
+}
+
+status_t CCodecConfig::queryConfiguration(
+        const std::shared_ptr<Codec2Client::Component> &component) {
+    // query all subscribed parameters
+    std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
+    std::vector<std::unique_ptr<C2Param>> queried;
+    c2_status_t c2Err = component->query({}, indices, C2_MAY_BLOCK, &queried);
+    if (c2Err != OK) {
+        ALOGI("query failed after returning %zu values (%s)", queried.size(), asString(c2Err));
+        // TODO: error
+    }
+
+    updateConfiguration(queried, ALL);
+    return OK;
+}
+
+bool CCodecConfig::updateConfiguration(
+        std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain) {
+    ALOGV("updating configuration with %zu params", configUpdate.size());
+    bool changed = false;
+    for (std::unique_ptr<C2Param> &p : configUpdate) {
+        if (p && *p) {
+            auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
+            if (insertion.second || *insertion.first->second != *p) {
+                if (mSupportedIndices.count(p->index()) || mLocalParams.count(p->index())) {
+                    // only track changes in supported (reflected or local) indices
+                    changed = true;
+                } else {
+                    ALOGV("an unlisted config was %s: %#x",
+                            insertion.second ? "added" : "updated", p->index());
+                }
+            }
+            insertion.first->second = std::move(p);
+        }
+    }
+
+    ALOGV("updated configuration has %zu params (%s)", mCurrentConfig.size(),
+            changed ? "CHANGED" : "no change");
+    if (changed) {
+        return updateFormats(domain);
+    }
+    return false;
+}
+
+bool CCodecConfig::updateFormats(Domain domain) {
+    // get addresses of params in the current config
+    std::vector<C2Param*> paramPointers;
+    for (const auto &it : mCurrentConfig) {
+        paramPointers.push_back(it.second.get());
+    }
+
+    ReflectedParamUpdater::Dict reflected = mParamUpdater->getParams(paramPointers);
+    ALOGD("c2 config is %s", reflected.debugString().c_str());
+
+    bool changed = false;
+    if (domain & mInputDomain) {
+        sp<AMessage> oldFormat = mInputFormat;
+        mInputFormat = mInputFormat->dup(); // trigger format changed
+        mInputFormat->extend(getSdkFormatForDomain(reflected, mInputDomain));
+        if (mInputFormat->countEntries() != oldFormat->countEntries()
+                || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
+            changed = true;
+        } else {
+            mInputFormat = oldFormat; // no change
+        }
+    }
+    if (domain & mOutputDomain) {
+        sp<AMessage> oldFormat = mOutputFormat;
+        mOutputFormat = mOutputFormat->dup(); // trigger output format changed
+        mOutputFormat->extend(getSdkFormatForDomain(reflected, mOutputDomain));
+        if (mOutputFormat->countEntries() != oldFormat->countEntries()
+                || mOutputFormat->changesFrom(oldFormat)->countEntries() > 0) {
+            changed = true;
+        } else {
+            mOutputFormat = oldFormat; // no change
+        }
+    }
+    ALOGV_IF(changed, "format(s) changed");
+    return changed;
+}
+
+sp<AMessage> CCodecConfig::getSdkFormatForDomain(
+        const ReflectedParamUpdater::Dict &reflected, Domain portDomain) const {
+    sp<AMessage> msg = new AMessage;
+    for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
+        for (const ConfigMapper &cm : el.second) {
+            if ((cm.domain() & portDomain) == 0 // input-output-coded-raw
+                || (cm.domain() & mDomain) != mDomain // component domain + kind (these must match)
+                || (cm.domain() & IS_READ) == 0) {
+                continue;
+            }
+            auto it = reflected.find(cm.path());
+            if (it == reflected.end()) {
+                continue;
+            }
+            C2Value c2Value;
+            sp<ABuffer> bufValue;
+            AString strValue;
+            AMessage::ItemData item;
+            if (it->second.find(&c2Value)) {
+                item = cm.mapToMessage(c2Value);
+            } else if (it->second.find(&bufValue)) {
+                item.set(bufValue);
+            } else if (it->second.find(&strValue)) {
+                item.set(strValue);
+            } else {
+                ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
+                continue;
+            }
+            msg->setItem(el.first.c_str(), item);
+        }
+    }
+
+    { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
+        int32_t left, top, width, height;
+        if (msg->findInt32("crop-left", &left) && msg->findInt32("crop-width", &width)
+                && msg->findInt32("crop-top", &top) && msg->findInt32("crop-height", &height)
+                && left >= 0 && width >=0 && width <= INT32_MAX - left
+                && top >= 0 && height >=0 && height <= INT32_MAX - top) {
+            msg->removeEntryAt(msg->findEntryByName("crop-left"));
+            msg->removeEntryAt(msg->findEntryByName("crop-top"));
+            msg->removeEntryAt(msg->findEntryByName("crop-width"));
+            msg->removeEntryAt(msg->findEntryByName("crop-height"));
+            msg->setRect("crop", left, top, left + width - 1, top + height - 1);
+        } else if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
+            msg->setRect("crop", 0, 0, width - 1, height - 1);
+        }
+    }
+
+    { // convert temporal layering to schema
+        sp<ABuffer> tmp;
+        if (msg->findBuffer(C2_PARAMKEY_TEMPORAL_LAYERING, &tmp) && tmp != nullptr) {
+            C2StreamTemporalLayeringTuning *layering =
+                C2StreamTemporalLayeringTuning::From(C2Param::From(tmp->data(), tmp->size()));
+            if (layering && layering->m.layerCount > 0
+                    && layering->m.bLayerCount < layering->m.layerCount) {
+                // check if this is webrtc compatible
+                AString mime;
+                if (msg->findString(KEY_MIME, &mime) &&
+                        mime.equalsIgnoreCase(MIMETYPE_VIDEO_VP8) &&
+                        layering->m.bLayerCount == 0 &&
+                        (layering->m.layerCount == 1
+                                || (layering->m.layerCount == 2
+                                        && layering->flexCount() >= 1
+                                        && layering->m.bitrateRatios[0] == .6f)
+                                || (layering->m.layerCount == 3
+                                        && layering->flexCount() >= 2
+                                        && layering->m.bitrateRatios[0] == .4f
+                                        && layering->m.bitrateRatios[1] == .6f)
+                                || (layering->m.layerCount == 4
+                                        && layering->flexCount() >= 3
+                                        && layering->m.bitrateRatios[0] == .25f
+                                        && layering->m.bitrateRatios[1] == .4f
+                                        && layering->m.bitrateRatios[2] == .6f))) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "webrtc.vp8.%u-layer", layering->m.layerCount));
+                } else if (layering->m.bLayerCount) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "android.generic.%u+%u",
+                            layering->m.layerCount - layering->m.bLayerCount,
+                            layering->m.bLayerCount));
+                } else if (layering->m.bLayerCount) {
+                    msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
+                            "android.generic.%u", layering->m.layerCount));
+                }
+            }
+            msg->removeEntryAt(msg->findEntryByName(C2_PARAMKEY_TEMPORAL_LAYERING));
+        }
+    }
+
+    { // convert color info
+        C2Color::primaries_t primaries;
+        C2Color::matrix_t matrix;
+        if (msg->findInt32("color-primaries", (int32_t*)&primaries)
+                && msg->findInt32("color-matrix", (int32_t*)&matrix)) {
+            int32_t standard;
+
+            if (C2Mapper::map(primaries, matrix, &standard)) {
+                msg->setInt32(KEY_COLOR_STANDARD, standard);
+            }
+
+            msg->removeEntryAt(msg->findEntryByName("color-primaries"));
+            msg->removeEntryAt(msg->findEntryByName("color-matrix"));
+        }
+
+
+        // calculate dataspace for raw graphic buffers if not specified by component, or if
+        // using surface with unspecified aspects (as those must be defaulted which may change
+        // the dataspace)
+        if ((portDomain & IS_RAW) && (mDomain & (IS_IMAGE | IS_VIDEO))) {
+            android_dataspace dataspace;
+            ColorAspects aspects = {
+                ColorAspects::RangeUnspecified, ColorAspects::PrimariesUnspecified,
+                ColorAspects::TransferUnspecified, ColorAspects::MatrixUnspecified
+            };
+            ColorUtils::getColorAspectsFromFormat(msg, aspects);
+            ColorAspects origAspects = aspects;
+            if (mUsingSurface) {
+                // get image size (default to HD)
+                int32_t width = 1280;
+                int32_t height = 720;
+                int32_t left, top, right, bottom;
+                if (msg->findRect("crop", &left, &top, &right, &bottom)) {
+                    width = right - left + 1;
+                    height = bottom - top + 1;
+                } else {
+                    (void)msg->findInt32(KEY_WIDTH, &width);
+                    (void)msg->findInt32(KEY_HEIGHT, &height);
+                }
+                ColorUtils::setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
+                ColorUtils::setColorAspectsIntoFormat(aspects, msg);
+            }
+
+            if (!msg->findInt32("android._dataspace", (int32_t*)&dataspace)
+                    || aspects.mRange != origAspects.mRange
+                    || aspects.mPrimaries != origAspects.mPrimaries
+                    || aspects.mTransfer != origAspects.mTransfer
+                    || aspects.mMatrixCoeffs != origAspects.mMatrixCoeffs) {
+                dataspace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
+                msg->setInt32("android._dataspace", dataspace);
+            }
+        }
+
+        // HDR static info
+
+        C2HdrStaticMetadataStruct hdr;
+        if (msg->findFloat("smpte2086.red.x", &hdr.mastering.red.x)
+                && msg->findFloat("smpte2086.red.y", &hdr.mastering.red.y)
+                && msg->findFloat("smpte2086.green.x", &hdr.mastering.green.x)
+                && msg->findFloat("smpte2086.green.y", &hdr.mastering.green.y)
+                && msg->findFloat("smpte2086.blue.x", &hdr.mastering.blue.x)
+                && msg->findFloat("smpte2086.blue.y", &hdr.mastering.blue.y)
+                && msg->findFloat("smpte2086.white.x", &hdr.mastering.white.x)
+                && msg->findFloat("smpte2086.white.y", &hdr.mastering.white.y)
+                && msg->findFloat("smpte2086.max-luminance", &hdr.mastering.maxLuminance)
+                && msg->findFloat("smpte2086.min-luminance", &hdr.mastering.minLuminance)
+                && msg->findFloat("cta861.max-cll", &hdr.maxCll)
+                && msg->findFloat("cta861.max-fall", &hdr.maxFall)) {
+            if (hdr.mastering.red.x >= 0                && hdr.mastering.red.x <= 1
+                    && hdr.mastering.red.y >= 0         && hdr.mastering.red.y <= 1
+                    && hdr.mastering.green.x >= 0       && hdr.mastering.green.x <= 1
+                    && hdr.mastering.green.y >= 0       && hdr.mastering.green.y <= 1
+                    && hdr.mastering.blue.x >= 0        && hdr.mastering.blue.x <= 1
+                    && hdr.mastering.blue.y >= 0        && hdr.mastering.blue.y <= 1
+                    && hdr.mastering.white.x >= 0       && hdr.mastering.white.x <= 1
+                    && hdr.mastering.white.y >= 0       && hdr.mastering.white.y <= 1
+                    && hdr.mastering.maxLuminance >= 0  && hdr.mastering.maxLuminance <= 65535
+                    && hdr.mastering.minLuminance >= 0  && hdr.mastering.minLuminance <= 6.5535
+                    && hdr.maxCll >= 0                  && hdr.maxCll <= 65535
+                    && hdr.maxFall >= 0                 && hdr.maxFall <= 65535) {
+                HDRStaticInfo meta;
+                meta.mID = meta.kType1;
+                meta.sType1.mR.x = hdr.mastering.red.x / 0.00002 + 0.5;
+                meta.sType1.mR.y = hdr.mastering.red.y / 0.00002 + 0.5;
+                meta.sType1.mG.x = hdr.mastering.green.x / 0.00002 + 0.5;
+                meta.sType1.mG.y = hdr.mastering.green.y / 0.00002 + 0.5;
+                meta.sType1.mB.x = hdr.mastering.blue.x / 0.00002 + 0.5;
+                meta.sType1.mB.y = hdr.mastering.blue.y / 0.00002 + 0.5;
+                meta.sType1.mW.x = hdr.mastering.white.x / 0.00002 + 0.5;
+                meta.sType1.mW.y = hdr.mastering.white.y / 0.00002 + 0.5;
+                meta.sType1.mMaxDisplayLuminance = hdr.mastering.maxLuminance + 0.5;
+                meta.sType1.mMinDisplayLuminance = hdr.mastering.minLuminance / 0.0001 + 0.5;
+                meta.sType1.mMaxContentLightLevel = hdr.maxCll + 0.5;
+                meta.sType1.mMaxFrameAverageLightLevel = hdr.maxFall + 0.5;
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.red.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.red.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.green.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.green.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.white.x"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.white.y"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.max-luminance"));
+                msg->removeEntryAt(msg->findEntryByName("smpte2086.min-luminance"));
+                msg->removeEntryAt(msg->findEntryByName("cta861.max-cll"));
+                msg->removeEntryAt(msg->findEntryByName("cta861.max-fall"));
+                msg->setBuffer(KEY_HDR_STATIC_INFO, ABuffer::CreateAsCopy(&meta, sizeof(meta)));
+            } else {
+                ALOGD("found invalid HDR static metadata %s", msg->debugString(8).c_str());
+            }
+        }
+    }
+
+    ALOGV("converted to SDK values as %s", msg->debugString().c_str());
+    return msg;
+}
+
+/// converts an AMessage value to a ParamUpdater value
+static void convert(const AMessage::ItemData &from, ReflectedParamUpdater::Value *to) {
+    int32_t int32Value;
+    int64_t int64Value;
+    sp<ABuffer> bufValue;
+    AString strValue;
+    float floatValue;
+    double doubleValue;
+
+    if (from.find(&int32Value)) {
+        to->set(int32Value);
+    } else if (from.find(&int64Value)) {
+        to->set(int64Value);
+    } else if (from.find(&bufValue)) {
+        to->set(bufValue);
+    } else if (from.find(&strValue)) {
+        to->set(strValue);
+    } else if (from.find(&floatValue)) {
+        to->set(C2Value(floatValue));
+    } else if (from.find(&doubleValue)) {
+        // convert double to float
+        to->set(C2Value((float)doubleValue));
+    }
+    // ignore all other AMessage types
+}
+
+/// relaxes Codec 2.0 specific value types to SDK types (mainly removes signedness and counterness
+/// from 32/64-bit values.)
+static void relaxValues(ReflectedParamUpdater::Value &item) {
+    C2Value c2Value;
+    int32_t int32Value;
+    int64_t int64Value;
+    (void)item.find(&c2Value);
+    if (c2Value.get(&int32Value) || c2Value.get((uint32_t*)&int32Value)
+            || c2Value.get((c2_cntr32_t*)&int32Value)) {
+        item.set(int32Value);
+    } else if (c2Value.get(&int64Value)
+            || c2Value.get((uint64_t*)&int64Value)
+            || c2Value.get((c2_cntr64_t*)&int64Value)) {
+        item.set(int64Value);
+    }
+}
+
+ReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
+        const sp<AMessage> &params_, Domain configDomain) const {
+    // create a modifiable copy of params
+    sp<AMessage> params = params_->dup();
+    ALOGV("filtering with config domain %x", configDomain);
+
+    // convert some macro parameters to Codec 2.0 specific expressions
+
+    { // make i-frame-interval frame based
+        float iFrameInterval;
+        if (params->findAsFloat(KEY_I_FRAME_INTERVAL, &iFrameInterval)) {
+            float frameRate;
+            if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
+                params->setInt32("i-frame-period",
+                        (frameRate <= 0 || iFrameInterval < 0)
+                                 ? -1 /* no sync frames */
+                                 : (int32_t)c2_min(iFrameInterval * frameRate + 0.5,
+                                                   (float)INT32_MAX));
+            }
+        }
+    }
+
+    if (mDomain == (IS_VIDEO | IS_ENCODER)) {
+        // convert capture-rate into input-time-stretch
+        float frameRate, captureRate;
+        if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
+            if (!params->findAsFloat("time-lapse-fps", &captureRate)
+                    && !params->findAsFloat(KEY_CAPTURE_RATE, &captureRate)) {
+                captureRate = frameRate;
+            }
+            if (captureRate > 0 && frameRate > 0) {
+                params->setFloat(C2_PARAMKEY_INPUT_TIME_STRETCH, captureRate / frameRate);
+            }
+        }
+    }
+
+    {   // reflect temporal layering into a binary blob
+        AString schema;
+        if (params->findString(KEY_TEMPORAL_LAYERING, &schema)) {
+            unsigned int numLayers = 0;
+            unsigned int numBLayers = 0;
+            int tags;
+            char dummy;
+            std::unique_ptr<C2StreamTemporalLayeringTuning::output> layering;
+            if (sscanf(schema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+                && numLayers > 0) {
+                switch (numLayers) {
+                    case 1:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                {}, 0u, 1u, 0u);
+                        break;
+                    case 2:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .6f }, 0u, 2u, 0u);
+                        break;
+                    case 3:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .4f, .6f }, 0u, 3u, 0u);
+                        break;
+                    default:
+                        layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                                { .25f, .4f, .6f }, 0u, 4u, 0u);
+                        break;
+                }
+            } else if ((tags = sscanf(schema.c_str(), "android.generic.%u%c%u%c",
+                        &numLayers, &dummy, &numBLayers, &dummy))
+                && (tags == 1 || (tags == 3 && dummy == '+'))
+                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
+                layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+                        {}, 0u, numLayers + numBLayers, numBLayers);
+            } else {
+                ALOGD("Ignoring unsupported ts-schema [%s]", schema.c_str());
+            }
+            if (layering) {
+                params->setBuffer(C2_PARAMKEY_TEMPORAL_LAYERING,
+                                  ABuffer::CreateAsCopy(layering.get(), layering->size()));
+            }
+        }
+    }
+
+    { // convert from MediaFormat rect to Codec 2.0 rect
+        int32_t offset;
+        int32_t end;
+        AMessage::ItemData item;
+        if (params->findInt32("crop-left", &offset) && params->findInt32("crop-right", &end)
+                && offset >= 0 && end >= offset - 1) {
+            size_t ix = params->findEntryByName("crop-right");
+            params->setEntryNameAt(ix, "crop-width");
+            item.set(end - offset + 1);
+            params->setEntryAt(ix, item);
+        }
+        if (params->findInt32("crop-top", &offset) && params->findInt32("crop-bottom", &end)
+                && offset >= 0 && end >= offset - 1) {
+            size_t ix = params->findEntryByName("crop-bottom");
+            params->setEntryNameAt(ix, "crop-height");
+            item.set(end - offset + 1);
+            params->setEntryAt(ix, item);
+        }
+    }
+
+    { // convert color info
+        int32_t standard;
+        if (params->findInt32(KEY_COLOR_STANDARD, &standard)) {
+            C2Color::primaries_t primaries;
+            C2Color::matrix_t matrix;
+
+            if (C2Mapper::map(standard, &primaries, &matrix)) {
+                params->setInt32("color-primaries", primaries);
+                params->setInt32("color-matrix", matrix);
+            }
+        }
+
+        sp<ABuffer> hdrMeta;
+        if (params->findBuffer(KEY_HDR_STATIC_INFO, &hdrMeta)
+                && hdrMeta->size() == sizeof(HDRStaticInfo)) {
+            HDRStaticInfo *meta = (HDRStaticInfo*)hdrMeta->data();
+            if (meta->mID == meta->kType1) {
+                params->setFloat("smpte2086.red.x", meta->sType1.mR.x * 0.00002);
+                params->setFloat("smpte2086.red.y", meta->sType1.mR.y * 0.00002);
+                params->setFloat("smpte2086.green.x", meta->sType1.mG.x * 0.00002);
+                params->setFloat("smpte2086.green.y", meta->sType1.mG.y * 0.00002);
+                params->setFloat("smpte2086.blue.x", meta->sType1.mB.x * 0.00002);
+                params->setFloat("smpte2086.blue.y", meta->sType1.mB.y * 0.00002);
+                params->setFloat("smpte2086.white.x", meta->sType1.mW.x * 0.00002);
+                params->setFloat("smpte2086.white.y", meta->sType1.mW.y * 0.00002);
+                params->setFloat("smpte2086.max-luminance", meta->sType1.mMaxDisplayLuminance);
+                params->setFloat("smpte2086.min-luminance", meta->sType1.mMinDisplayLuminance * 0.0001);
+                params->setFloat("cta861.max-cll", meta->sType1.mMaxContentLightLevel);
+                params->setFloat("cta861.max-fall", meta->sType1.mMaxFrameAverageLightLevel);
+            }
+        }
+    }
+
+    // this is to verify that we set proper signedness for standard parameters
+    bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
+    // this is to allow vendors to use the wrong signedness for standard parameters
+    bool beVeryLax = property_get_bool("debug.stagefright.ccodec_lax_type", false);
+
+    ReflectedParamUpdater::Dict filtered;
+    for (size_t ix = 0; ix < params->countEntries(); ++ix) {
+        AMessage::Type type;
+        AString name = params->getEntryNameAt(ix, &type);
+        AMessage::ItemData msgItem = params->getEntryAt(ix);
+        ReflectedParamUpdater::Value item;
+        convert(msgItem, &item); // convert item to param updater item
+
+        if (name.startsWith("vendor.")) {
+            // vendor params pass through as is
+            filtered.emplace(name.c_str(), item);
+            continue;
+        }
+        // standard parameters may get modified, filtered or duplicated
+        for (const ConfigMapper &cm : mStandardParams->getConfigMappersForSdkKey(name.c_str())) {
+            // note: we ignore port domain for configuration
+            if ((cm.domain() & configDomain)
+                    // component domain + kind (these must match)
+                    && (cm.domain() & mDomain) == mDomain) {
+                // map arithmetic values, pass through string or buffer
+                switch (type) {
+                    case AMessage::kTypeBuffer:
+                    case AMessage::kTypeString:
+                        break;
+                    case AMessage::kTypeInt32:
+                    case AMessage::kTypeInt64:
+                    case AMessage::kTypeFloat:
+                    case AMessage::kTypeDouble:
+                        // for now only map settings with mappers as we are not creating
+                        // signed <=> unsigned mappers
+                        // TODO: be precise about signed unsigned
+                        if (beVeryStrict || cm.mapper()) {
+                            item.set(cm.mapFromMessage(params->getEntryAt(ix)));
+                            // also allow to relax type strictness
+                            if (beVeryLax) {
+                                relaxValues(item);
+                            }
+                        }
+                        break;
+                    default:
+                        continue;
+                }
+                filtered.emplace(cm.path(), item);
+            }
+        }
+    }
+    ALOGV("filtered %s to %s", params->debugString(4).c_str(),
+            filtered.debugString(4).c_str());
+    return filtered;
+}
+
+status_t CCodecConfig::getConfigUpdateFromSdkParams(
+        std::shared_ptr<Codec2Client::Component> component,
+        const sp<AMessage> &sdkParams, Domain configDomain,
+        c2_blocking_t blocking,
+        std::vector<std::unique_ptr<C2Param>> *configUpdate) const {
+    ReflectedParamUpdater::Dict params = getReflectedFormat(sdkParams, configDomain);
+
+    std::vector<C2Param::Index> indices;
+    mParamUpdater->getParamIndicesFromMessage(params, &indices);
+    if (indices.empty()) {
+        ALOGD("no recognized params in: %s", params.debugString().c_str());
+        return OK;
+    }
+
+    configUpdate->clear();
+    std::vector<C2Param::Index> supportedIndices;
+    for (C2Param::Index ix : indices) {
+        if (mSupportedIndices.count(ix)) {
+            supportedIndices.push_back(ix);
+        } else if (mLocalParams.count(ix)) {
+            // query local parameter here
+            auto it = mCurrentConfig.find(ix);
+            if (it != mCurrentConfig.end()) {
+                configUpdate->emplace_back(C2Param::Copy(*it->second));
+            }
+        }
+    }
+
+    c2_status_t err = component->query({ }, supportedIndices, blocking, configUpdate);
+    if (err != C2_OK) {
+        ALOGD("query failed after returning %zu params => %s", configUpdate->size(), asString(err));
+    }
+
+    if (configUpdate->size()) {
+        mParamUpdater->updateParamsFromMessage(params, configUpdate);
+    }
+    return OK;
+}
+
+status_t CCodecConfig::setParameters(
+        std::shared_ptr<Codec2Client::Component> component,
+        std::vector<std::unique_ptr<C2Param>> &configUpdate,
+        c2_blocking_t blocking) {
+    status_t result = OK;
+    if (configUpdate.empty()) {
+        return OK;
+    }
+
+    std::vector<C2Param::Index> indices;
+    std::vector<C2Param *> paramVector;
+    for (const std::unique_ptr<C2Param> &param : configUpdate) {
+        if (mSupportedIndices.count(param->index())) {
+            // component parameter
+            paramVector.push_back(param.get());
+            indices.push_back(param->index());
+        } else if (mLocalParams.count(param->index())) {
+            // handle local parameter here
+            LocalParamValidator validator = mLocalParams.find(param->index())->second;
+            c2_status_t err = C2_OK;
+            std::unique_ptr<C2Param> copy = C2Param::Copy(*param);
+            if (validator) {
+                err = validator(copy);
+            }
+            if (err == C2_OK) {
+                ALOGV("updated local parameter value for %s",
+                        mParamUpdater->getParamName(param->index()).c_str());
+
+                mCurrentConfig[param->index()] = std::move(copy);
+            } else {
+                ALOGD("failed to set parameter value for %s => %s",
+                        mParamUpdater->getParamName(param->index()).c_str(), asString(err));
+                result = BAD_VALUE;
+            }
+        }
+    }
+    // update subscribed param indices
+    subscribeToConfigUpdate(component, indices, blocking);
+
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    c2_status_t err = component->config(paramVector, blocking, &failures);
+    if (err != C2_OK) {
+        ALOGD("config failed => %s", asString(err));
+        // This is non-fatal.
+    }
+    for (const std::unique_ptr<C2SettingResult> &failure : failures) {
+        switch (failure->failure) {
+            case C2SettingResult::BAD_VALUE:
+                ALOGD("Bad parameter value");
+                result = BAD_VALUE;
+                break;
+            default:
+                ALOGV("failure = %d", int(failure->failure));
+                break;
+        }
+    }
+
+    // Re-query parameter values in case config could not update them and update the current
+    // configuration.
+    configUpdate.clear();
+    err = component->query({}, indices, blocking, &configUpdate);
+    if (err != C2_OK) {
+        ALOGD("query failed after returning %zu params => %s", configUpdate.size(), asString(err));
+    }
+    (void)updateConfiguration(configUpdate, ALL);
+
+    // TODO: error value
+    return result;
+}
+
+const C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const {
+    auto it = mCurrentConfig.find(index);
+    if (it == mCurrentConfig.end()) {
+        return nullptr;
+    } else {
+        return it->second.get();
+    }
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/CCodecConfig.h b/media/codec2/sfplugin/CCodecConfig.h
new file mode 100644
index 0000000..3bafe3f
--- /dev/null
+++ b/media/codec2/sfplugin/CCodecConfig.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 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 C_CODEC_CONFIG_H_
+#define C_CODEC_CONFIG_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include <C2Component.h>
+#include <codec2/hidl/client.h>
+
+#include <utils/RefBase.h>
+
+#include "InputSurfaceWrapper.h"
+#include "ReflectedParamUpdater.h"
+
+namespace android {
+
+struct AMessage;
+struct StandardParams;
+
+/**
+ * Struct managing the codec configuration for CCodec.
+ */
+struct CCodecConfig {
+
+    /**
+     * Domain consists of a bitmask divided into fields, and specifiers work by excluding other
+     * values in those domains.
+     *
+     * Component domains are composed by or-ing the individual IS_ constants, e.g.
+     * IS_DECODER | IS_AUDIO.
+     *
+     * Config specifiers are composed by or-ing the individual mask constants, and
+     * and-ing these groups: e.g. (DECODER | ENCODER) & AUDIO.
+     *
+     * The naming of these constants was to limit the length of mask names as these are used more
+     * commonly as masks.
+     */
+    enum Domain : uint32_t {
+        // component domain (domain & kind)
+        GUARD_BIT   = (1 << 1),   ///< this is to prevent against accidental && or || usage
+        IS_AUDIO    = (1 << 2),   ///< for audio codecs
+        IS_VIDEO    = (1 << 3),   ///< for video codecs
+        IS_IMAGE    = (1 << 4),   ///< for image codecs
+        OTHER_DOMAIN = (1 << 5),  ///< for other domains
+
+        IS_ENCODER  = (1 << 6),   ///< for encoders
+        IS_DECODER  = (1 << 7),   ///< for decoders
+        OTHER_KIND  = (1 << 8),   ///< for other domains
+
+        // config domain
+        IS_PARAM    = (1 << 9),   ///< for setParameter
+        IS_CONFIG   = (1 << 10),  ///< for configure
+        IS_READ     = (1 << 11),  ///< for getFormat
+
+        // port domain
+        IS_INPUT    = (1 << 12),  ///< for input port (getFormat)
+        IS_OUTPUT   = (1 << 13),  ///< for output port (getFormat)
+        IS_RAW      = (1 << 14),  ///< for raw port (input-encoder, output-decoder)
+        IS_CODED    = (1 << 15),  ///< for coded port (input-decoder, output-encoder)
+
+        ALL     = ~0U,
+        NONE    = 0,
+
+        AUDIO   = ~(IS_IMAGE | IS_VIDEO | OTHER_DOMAIN),
+        VIDEO   = ~(IS_AUDIO | IS_IMAGE | OTHER_DOMAIN),
+        IMAGE   = ~(IS_AUDIO | IS_VIDEO | OTHER_DOMAIN),
+
+        DECODER = ~(IS_ENCODER | OTHER_KIND),
+        ENCODER = ~(IS_DECODER | OTHER_KIND),
+
+        PARAM   = ~(IS_CONFIG | IS_READ),
+        CONFIG  = ~(IS_PARAM  | IS_READ),
+        READ    = ~(IS_CONFIG | IS_PARAM),
+
+        INPUT   = ~(IS_OUTPUT | IS_RAW    | IS_CODED),
+        OUTPUT  = ~(IS_INPUT  | IS_RAW    | IS_CODED),
+        RAW     = ~(IS_INPUT  | IS_OUTPUT | IS_CODED),
+        CODED   = ~(IS_INPUT  | IS_RAW    | IS_OUTPUT),
+    };
+
+    // things required to manage formats
+    std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
+    std::shared_ptr<C2ParamReflector> mReflector;
+
+    std::shared_ptr<ReflectedParamUpdater> mParamUpdater;
+
+    Domain mDomain; // component domain
+    Domain mInputDomain; // input port domain
+    Domain mOutputDomain; // output port domain
+    std::string mCodingMediaType;  // media type of the coded stream
+
+    // standard MediaCodec to Codec 2.0 params mapping
+    std::shared_ptr<StandardParams> mStandardParams;
+
+    std::set<C2Param::Index> mSupportedIndices; ///< indices supported by the component
+    std::set<C2Param::Index> mSubscribedIndices; ///< indices to subscribe to
+    size_t mSubscribedIndicesSize; ///< count of currently subscribed indices
+
+    sp<AMessage> mInputFormat;
+    sp<AMessage> mOutputFormat;
+
+    bool mUsingSurface; ///< using input or output surface
+
+    std::shared_ptr<InputSurfaceWrapper> mInputSurface;
+    std::unique_ptr<InputSurfaceWrapper::Config> mISConfig;
+
+    /// the current configuration. Updated after configure() and based on configUpdate in
+    /// onWorkDone
+    std::map<C2Param::Index, std::unique_ptr<C2Param>> mCurrentConfig;
+
+    typedef std::function<c2_status_t(std::unique_ptr<C2Param>&)> LocalParamValidator;
+
+    /// Parameter indices tracked in current config that are not supported by the component.
+    /// these are provided so that optional parameters can remain in the current configuration.
+    /// as such, these parameters have no dependencies. TODO: use C2InterfaceHelper for this.
+    /// For now support a validation function.
+    std::map<C2Param::Index, LocalParamValidator> mLocalParams;
+
+    CCodecConfig();
+
+    /// initializes the members required to manage the format: descriptors, reflector,
+    /// reflected param helper, domain, standard params, and subscribes to standard
+    /// indices.
+    status_t initialize(
+            const std::shared_ptr<Codec2Client> &client,
+            const std::shared_ptr<Codec2Client::Component> &component);
+
+
+    /**
+     * Adds a locally maintained parameter. This is used for output configuration that can be
+     * appended to the output buffers in case it is not supported by the component.
+     */
+    template<typename T>
+    bool addLocalParam(
+            const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        C2Param::Index index = T::PARAM_TYPE;
+        if (mSupportedIndices.count(index) || mLocalParams.count(index)) {
+            if (mSupportedIndices.count(index)) {
+                mSubscribedIndices.emplace(index);
+            }
+            ALOGD("ignoring local param %s (%#x) as it is already %s",
+                    name.c_str(), (uint32_t)index, mSupportedIndices.count(index) ? "supported" : "local");
+            return false; // already supported by the component or already added
+        }
+
+        // wrap typed validator into untyped validator
+        LocalParamValidator validator;
+        if (validator_) {
+            validator = [validator_](std::unique_ptr<C2Param>& p){
+                c2_status_t res = C2_BAD_VALUE;
+                std::unique_ptr<T> typed(static_cast<T*>(p.release()));
+                // if parameter is correctly typed
+                if (T::From(typed.get())) {
+                    res = validator_(typed);
+                    p.reset(typed.release());
+                }
+                return res;
+            };
+        }
+
+        mLocalParams.emplace(index, validator);
+        mParamUpdater->addStandardParam<T>(name, attrib);
+        return true;
+    }
+
+    /**
+     * Adds a locally maintained parameter with a default value.
+     */
+    template<typename T>
+    bool addLocalParam(
+            std::unique_ptr<T> default_,
+            const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        if (addLocalParam<T>(name, attrib, validator_)) {
+            if (validator_) {
+                c2_status_t err = validator_(default_);
+                if (err != C2_OK) {
+                    ALOGD("default value for %s is invalid => %s", name.c_str(), asString(err));
+                    return false;
+                }
+            }
+            mCurrentConfig[T::PARAM_TYPE] = std::move(default_);
+            return true;
+        }
+        return false;
+    }
+
+    template<typename T>
+    bool addLocalParam(
+            T *default_, const std::string &name,
+            C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
+            std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
+                std::function<c2_status_t(std::unique_ptr<T>&)>()) {
+        return addLocalParam(std::unique_ptr<T>(default_), name, attrib, validator_);
+    }
+
+    /// Applies configuration updates, and updates format in the specific domain.
+    /// Returns true if formats were updated
+    /// \param domain input/output bitmask
+    bool updateConfiguration(
+            std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain);
+
+    /// Updates formats in the specific domain. Returns true if any of the formats have changed.
+    /// \param domain input/output bitmask
+    bool updateFormats(Domain domain);
+
+    /**
+     * Applies SDK configurations in a specific configuration domain.
+     * Updates relevant input/output formats and subscribes to parameters specified in the
+     * configuration.
+     * \param domain config/setParam bitmask
+     * \param blocking blocking mode to use with the component
+     */
+    status_t getConfigUpdateFromSdkParams(
+            std::shared_ptr<Codec2Client::Component> component,
+            const sp<AMessage> &sdkParams, Domain domain,
+            c2_blocking_t blocking,
+            std::vector<std::unique_ptr<C2Param>> *configUpdate) const;
+
+    /**
+     * Applies a configuration update to the component.
+     * Updates relevant input/output formats and subscribes to parameters specified in the
+     * configuration.
+     * \param blocking blocking mode to use with the component
+     */
+    status_t setParameters(
+            std::shared_ptr<Codec2Client::Component> component,
+            std::vector<std::unique_ptr<C2Param>> &configUpdate,
+            c2_blocking_t blocking);
+
+    /// Queries subscribed indices (which contains all SDK-exposed values) and updates
+    /// input/output formats.
+    status_t queryConfiguration(
+            const std::shared_ptr<Codec2Client::Component> &component);
+
+    /// Queries a configuration parameter value. Returns nullptr if the parameter is not
+    /// part of the current configuration
+    const C2Param *getConfigParameterValue(C2Param::Index index) const;
+
+    /**
+     * Object that can be used to access configuration parameters and if they change.
+     */
+    template<typename T>
+    struct Watcher {
+        ~Watcher() = default;
+
+        /// returns true if the value of this configuration has changed
+        bool hasChanged() const {
+            const C2Param *value = mParent->getConfigParameterValue(mIndex);
+            if (value && mValue) {
+                return *value != *mValue;
+            } else {
+                return value != mValue.get();
+            }
+        }
+
+        /// updates the current value and returns it
+        std::shared_ptr<const T> update() {
+            const C2Param *value = mParent->getConfigParameterValue(mIndex);
+            if (value) {
+                mValue = std::shared_ptr<const T>(T::From(C2Param::Copy(*value).release()));
+            }
+            return mValue;
+        }
+
+    private:
+        Watcher(C2Param::Index index, const CCodecConfig *parent)
+            : mParent(parent), mIndex(index) {
+            update();
+        }
+
+        friend struct CCodecConfig;
+
+        const CCodecConfig *mParent;
+        std::shared_ptr<const T> mValue;
+        C2Param::Index mIndex;
+    };
+
+    /**
+     * Returns a watcher object for a parameter.
+     */
+    template<typename T>
+    Watcher<T> watch(C2Param::Index index = T::PARAM_TYPE) const {
+        if (index.type() != T::PARAM_TYPE) {
+            __builtin_trap();
+        }
+        return Watcher<T>(index, this);
+    }
+
+private:
+
+    /// initializes the standard MediaCodec to Codec 2.0 params mapping
+    void initializeStandardParams();
+
+    /// Adds indices to the subscribed indices, and updated subscription to component
+    /// \param blocking blocking mode to use with the component
+    status_t subscribeToConfigUpdate(
+            const std::shared_ptr<Codec2Client::Component> &component,
+            const std::vector<C2Param::Index> &indices,
+            c2_blocking_t blocking = C2_DONT_BLOCK);
+
+    /// Gets SDK format from codec 2.0 reflected configuration
+    /// \param domain input/output bitmask
+    sp<AMessage> getSdkFormatForDomain(
+            const ReflectedParamUpdater::Dict &reflected, Domain domain) const;
+
+    /**
+     * Converts a set of configuration parameters in an AMessage to a list of path-based Codec
+     * 2.0 configuration parameters.
+     *
+     * \param domain config/setParam bitmask
+     */
+    ReflectedParamUpdater::Dict getReflectedFormat(
+            const sp<AMessage> &config, Domain domain) const;
+};
+
+DEFINE_ENUM_OPERATORS(CCodecConfig::Domain)
+
+}  // namespace android
+
+#endif  // C_CODEC_H_
+
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
new file mode 100644
index 0000000..bf6062e
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -0,0 +1,810 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2Buffer"
+#include <utils/Log.h>
+
+#include <hidlmemory/FrameworkUtils.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <nativebase/nativebase.h>
+
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Debug.h>
+
+#include "Codec2Buffer.h"
+
+namespace android {
+
+// Codec2Buffer
+
+bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
+        return false;
+    }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
+    if (buffer->data().type() != C2BufferData::LINEAR) {
+        return false;
+    }
+    if (buffer->data().linearBlocks().size() == 0u) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    } else if (buffer->data().linearBlocks().size() > 1u) {
+        // We don't know how to copy more than one blocks.
+        return false;
+    }
+    if (buffer->data().linearBlocks()[0].size() > capacity()) {
+        // It won't fit.
+        return false;
+    }
+    return true;
+}
+
+bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
+    // We assume that all canCopyLinear() checks passed.
+    if (!buffer || buffer->data().linearBlocks().size() == 0u
+            || buffer->data().linearBlocks()[0].size() == 0u) {
+        setRange(0, 0);
+        return true;
+    }
+    C2ReadView view = buffer->data().linearBlocks()[0].map().get();
+    if (view.error() != C2_OK) {
+        ALOGD("Error while mapping: %d", view.error());
+        return false;
+    }
+    if (view.capacity() > capacity()) {
+        ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)",
+                view.capacity(), capacity());
+        return false;
+    }
+    memcpy(base(), view.data(), view.capacity());
+    setRange(0, view.capacity());
+    return true;
+}
+
+void Codec2Buffer::setImageData(const sp<ABuffer> &imageData) {
+    meta()->setBuffer("image-data", imageData);
+    format()->setBuffer("image-data", imageData);
+    MediaImage2 *img = (MediaImage2*)imageData->data();
+    if (img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
+        int32_t stride = img->mPlane[0].mRowInc;
+        format()->setInt32(KEY_STRIDE, stride);
+        if (img->mNumPlanes > 1 && stride > 0) {
+            int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride;
+            format()->setInt32(KEY_SLICE_HEIGHT, vstride);
+        }
+    }
+}
+
+// LocalLinearBuffer
+
+bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    return canCopyLinear(buffer);
+}
+
+bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    return copyLinear(buffer);
+}
+
+// DummyContainerBuffer
+
+DummyContainerBuffer::DummyContainerBuffer(
+        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer)
+    : Codec2Buffer(format, new ABuffer(nullptr, 1)),
+      mBufferRef(buffer) {
+    setRange(0, buffer ? 1 : 0);
+}
+
+std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
+    return std::move(mBufferRef);
+}
+
+bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
+    return !mBufferRef;
+}
+
+bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    mBufferRef = buffer;
+    setRange(0, mBufferRef ? 1 : 0);
+    return true;
+}
+
+// LinearBlockBuffer
+
+// static
+sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
+        const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
+    C2WriteView writeView(block->map().get());
+    if (writeView.error() != C2_OK) {
+        return nullptr;
+    }
+    return new LinearBlockBuffer(format, std::move(writeView), block);
+}
+
+std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() {
+    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
+}
+
+bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    return canCopyLinear(buffer);
+}
+
+bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    return copyLinear(buffer);
+}
+
+LinearBlockBuffer::LinearBlockBuffer(
+        const sp<AMessage> &format,
+        C2WriteView&& writeView,
+        const std::shared_ptr<C2LinearBlock> &block)
+    : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
+      mWriteView(writeView),
+      mBlock(block) {
+}
+
+// ConstLinearBlockBuffer
+
+// static
+sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate(
+        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) {
+    if (!buffer
+            || buffer->data().type() != C2BufferData::LINEAR
+            || buffer->data().linearBlocks().size() != 1u) {
+        return nullptr;
+    }
+    C2ReadView readView(buffer->data().linearBlocks()[0].map().get());
+    if (readView.error() != C2_OK) {
+        return nullptr;
+    }
+    return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
+}
+
+ConstLinearBlockBuffer::ConstLinearBlockBuffer(
+        const sp<AMessage> &format,
+        C2ReadView&& readView,
+        const std::shared_ptr<C2Buffer> &buffer)
+    : Codec2Buffer(format, new ABuffer(
+            // NOTE: ABuffer only takes non-const pointer but this data is
+            //       supposed to be read-only.
+            const_cast<uint8_t *>(readView.data()), readView.capacity())),
+      mReadView(readView),
+      mBufferRef(buffer) {
+}
+
+std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
+    return std::move(mBufferRef);
+}
+
+// GraphicView2MediaImageConverter
+
+namespace {
+
+class GraphicView2MediaImageConverter {
+public:
+    /**
+     * Creates a C2GraphicView <=> MediaImage converter
+     *
+     * \param view C2GraphicView object
+     * \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
+     *        an attempt is made to simply represent the graphic view as a flexible SDK format
+     *        without a memcpy)
+     */
+    GraphicView2MediaImageConverter(
+            const C2GraphicView &view, int32_t colorFormat)
+        : mInitCheck(NO_INIT),
+          mView(view),
+          mWidth(view.width()),
+          mHeight(view.height()),
+          mColorFormat(colorFormat),
+          mAllocatedDepth(0),
+          mBackBufferSize(0),
+          mMediaImage(new ABuffer(sizeof(MediaImage2))) {
+        if (view.error() != C2_OK) {
+            ALOGD("Converter: view.error() = %d", view.error());
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        MediaImage2 *mediaImage = (MediaImage2 *)mMediaImage->base();
+        const C2PlanarLayout &layout = view.layout();
+        if (layout.numPlanes == 0) {
+            ALOGD("Converter: 0 planes");
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        mAllocatedDepth = layout.planes[0].allocatedDepth;
+        uint32_t bitDepth = layout.planes[0].bitDepth;
+
+        // align width and height to support subsampling cleanly
+        uint32_t mStride = align(mWidth, 2) * divUp(layout.planes[0].allocatedDepth, 8u);
+        uint32_t mVStride = align(mHeight, 2);
+
+        switch (layout.type) {
+            case C2PlanarLayout::TYPE_YUV:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
+                if (layout.numPlanes != 3) {
+                    ALOGD("Converter: %d planes for YUV layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                if (layout.planes[0].channel != C2PlaneInfo::CHANNEL_Y
+                        || layout.planes[1].channel != C2PlaneInfo::CHANNEL_CB
+                        || layout.planes[2].channel != C2PlaneInfo::CHANNEL_CR
+                        || layout.planes[0].colSampling != 1
+                        || layout.planes[0].rowSampling != 1
+                        || layout.planes[1].colSampling != 2
+                        || layout.planes[1].rowSampling != 2
+                        || layout.planes[2].colSampling != 2
+                        || layout.planes[2].rowSampling != 2) {
+                    ALOGD("Converter: not YUV420 for YUV layout");
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                switch (mColorFormat) {
+                    case COLOR_FormatYUV420Flexible:
+                    {  // try to map directly. check if the planes are near one another
+                        const uint8_t *minPtr = mView.data()[0];
+                        const uint8_t *maxPtr = mView.data()[0];
+                        int32_t planeSize = 0;
+                        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                            const C2PlaneInfo &plane = layout.planes[i];
+                            ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+                            ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+                            if (minPtr > mView.data()[i] + minOffset) {
+                                minPtr = mView.data()[i] + minOffset;
+                            }
+                            if (maxPtr < mView.data()[i] + maxOffset) {
+                                maxPtr = mView.data()[i] + maxOffset;
+                            }
+                            planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
+                                    / plane.rowSampling / plane.colSampling * divUp(mAllocatedDepth, 8u);
+                        }
+
+                        if ((maxPtr - minPtr + 1) <= planeSize) {
+                            // FIXME: this is risky as reading/writing data out of bound results in
+                            //        an undefined behavior, but gralloc does assume a contiguous
+                            //        mapping
+                            for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                                const C2PlaneInfo &plane = layout.planes[i];
+                                mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+                                mediaImage->mPlane[i].mColInc = plane.colInc;
+                                mediaImage->mPlane[i].mRowInc = plane.rowInc;
+                                mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+                                mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+                            }
+                            mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
+                            break;
+                        }
+                    }
+                    [[fallthrough]];
+
+                    case COLOR_FormatYUV420Planar:
+                    case COLOR_FormatYUV420PackedPlanar:
+                        mediaImage->mPlane[mediaImage->Y].mOffset = 0;
+                        mediaImage->mPlane[mediaImage->Y].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->Y].mRowInc = mStride;
+                        mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
+                        mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
+
+                        mediaImage->mPlane[mediaImage->U].mOffset = mStride * mVStride;
+                        mediaImage->mPlane[mediaImage->U].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->U].mRowInc = mStride / 2;
+                        mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
+
+                        mediaImage->mPlane[mediaImage->V].mOffset = mStride * mVStride * 5 / 4;
+                        mediaImage->mPlane[mediaImage->V].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->V].mRowInc = mStride / 2;
+                        mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
+                        break;
+
+                    case COLOR_FormatYUV420SemiPlanar:
+                    case COLOR_FormatYUV420PackedSemiPlanar:
+                        mediaImage->mPlane[mediaImage->Y].mOffset = 0;
+                        mediaImage->mPlane[mediaImage->Y].mColInc = 1;
+                        mediaImage->mPlane[mediaImage->Y].mRowInc = mStride;
+                        mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
+                        mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
+
+                        mediaImage->mPlane[mediaImage->U].mOffset = mStride * mVStride;
+                        mediaImage->mPlane[mediaImage->U].mColInc = 2;
+                        mediaImage->mPlane[mediaImage->U].mRowInc = mStride;
+                        mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
+
+                        mediaImage->mPlane[mediaImage->V].mOffset = mStride * mVStride + 1;
+                        mediaImage->mPlane[mediaImage->V].mColInc = 2;
+                        mediaImage->mPlane[mediaImage->V].mRowInc = mStride;
+                        mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
+                        mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
+                        break;
+
+                    default:
+                        ALOGD("Converter: incompactible color format (%d) for YUV layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                break;
+            case C2PlanarLayout::TYPE_YUVA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA;
+                // We don't have an SDK YUVA format
+                ALOGD("Converter: incompactible color format (%d) for YUVA layout", mColorFormat);
+                mInitCheck = BAD_VALUE;
+                return;
+            case C2PlanarLayout::TYPE_RGB:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB;
+                switch (mColorFormat) {
+                    // TODO media image
+                    case COLOR_FormatRGBFlexible:
+                    case COLOR_Format24bitBGR888:
+                    case COLOR_Format24bitRGB888:
+                        break;
+                    default:
+                        ALOGD("Converter: incompactible color format (%d) for RGB layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 3) {
+                    ALOGD("Converter: %d planes for RGB layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
+            case C2PlanarLayout::TYPE_RGBA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA;
+                switch (mColorFormat) {
+                    // TODO media image
+                    case COLOR_FormatRGBAFlexible:
+                    case COLOR_Format32bitABGR8888:
+                    case COLOR_Format32bitARGB8888:
+                    case COLOR_Format32bitBGRA8888:
+                        break;
+                    default:
+                        ALOGD("Incompactible color format (%d) for RGBA layout", mColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 4) {
+                    ALOGD("Converter: %d planes for RGBA layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
+            default:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
+                ALOGD("Unknown layout");
+                mInitCheck = BAD_VALUE;
+                return;
+        }
+        mediaImage->mNumPlanes = layout.numPlanes;
+        mediaImage->mWidth = mWidth;
+        mediaImage->mHeight = mHeight;
+        mediaImage->mBitDepth = bitDepth;
+        mediaImage->mBitDepthAllocated = mAllocatedDepth;
+
+        uint32_t bufferSize = 0;
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            if (plane.allocatedDepth < plane.bitDepth
+                    || plane.rightShift != plane.allocatedDepth - plane.bitDepth) {
+                ALOGD("rightShift value of %u unsupported", plane.rightShift);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.allocatedDepth > 8 && plane.endianness != C2PlaneInfo::NATIVE) {
+                ALOGD("endianness value of %u unsupported", plane.endianness);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.allocatedDepth != mAllocatedDepth || plane.bitDepth != bitDepth) {
+                ALOGV("different allocatedDepth/bitDepth per plane unsupported");
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            bufferSize += mStride * mVStride
+                    / plane.rowSampling / plane.colSampling;
+        }
+
+        mBackBufferSize = bufferSize;
+        mInitCheck = OK;
+    }
+
+    status_t initCheck() const { return mInitCheck; }
+
+    uint32_t backBufferSize() const { return mBackBufferSize; }
+
+    /**
+     * Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
+     * in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
+     * data into a backing buffer explicitly.
+     *
+     * \return media buffer. This is null if wrapping failed.
+     */
+    sp<ABuffer> wrap() const {
+        if (mBackBuffer == nullptr) {
+            return mWrapped;
+        }
+        return nullptr;
+    }
+
+    bool setBackBuffer(const sp<ABuffer> &backBuffer) {
+        if (backBuffer->capacity() < mBackBufferSize) {
+            return false;
+        }
+        backBuffer->setRange(0, mBackBufferSize);
+        mBackBuffer = backBuffer;
+        return true;
+    }
+
+    /**
+     * Copy C2GraphicView to MediaImage2.
+     */
+    status_t copyToMediaImage() {
+        if (mInitCheck != OK) {
+            return mInitCheck;
+        }
+        return ImageCopy(mBackBuffer->base(), getMediaImage(), mView);
+    }
+
+    const sp<ABuffer> &imageData() const { return mMediaImage; }
+
+private:
+    status_t mInitCheck;
+
+    const C2GraphicView mView;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    int32_t mColorFormat;  ///< SDK color format for MediaImage
+    sp<ABuffer> mWrapped;  ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
+    uint32_t mAllocatedDepth;
+    uint32_t mBackBufferSize;
+    sp<ABuffer> mMediaImage;
+    std::function<sp<ABuffer>(size_t)> mAlloc;
+
+    sp<ABuffer> mBackBuffer;    ///< backing buffer if we have to copy C2Buffer <=> ABuffer
+
+    MediaImage2 *getMediaImage() {
+        return (MediaImage2 *)mMediaImage->base();
+    }
+};
+
+}  // namespace
+
+// GraphicBlockBuffer
+
+// static
+sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    C2GraphicView view(block->map().get());
+    if (view.error() != C2_OK) {
+        ALOGD("C2GraphicBlock::map failed: %d", view.error());
+        return nullptr;
+    }
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    (void)format->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(view, colorFormat);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> buffer = converter.wrap();
+    if (buffer == nullptr) {
+        buffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(buffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+    }
+    return new GraphicBlockBuffer(
+            format,
+            buffer,
+            std::move(view),
+            block,
+            converter.imageData(),
+            wrapped);
+}
+
+GraphicBlockBuffer::GraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &buffer,
+        C2GraphicView &&view,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, buffer),
+      mView(view),
+      mBlock(block),
+      mImageData(imageData),
+      mWrapped(wrapped) {
+    setImageData(imageData);
+}
+
+std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
+    uint32_t width = mView.width();
+    uint32_t height = mView.height();
+    if (!mWrapped) {
+        (void)ImageCopy(mView, base(), imageData());
+    }
+    return C2Buffer::CreateGraphicBuffer(
+            mBlock->share(C2Rect(width, height), C2Fence()));
+}
+
+// GraphicMetadataBuffer
+GraphicMetadataBuffer::GraphicMetadataBuffer(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2Allocator> &alloc)
+    : Codec2Buffer(format, new ABuffer(sizeof(VideoNativeMetadata))),
+      mAlloc(alloc) {
+    ((VideoNativeMetadata *)base())->pBuffer = nullptr;
+}
+
+std::shared_ptr<C2Buffer> GraphicMetadataBuffer::asC2Buffer() {
+#ifndef __LP64__
+    VideoNativeMetadata *meta = (VideoNativeMetadata *)base();
+    ANativeWindowBuffer *buffer = (ANativeWindowBuffer *)meta->pBuffer;
+    if (buffer == nullptr) {
+        ALOGD("VideoNativeMetadata contains null buffer");
+        return nullptr;
+    }
+
+    ALOGV("VideoNativeMetadata: %dx%d", buffer->width, buffer->height);
+    C2Handle *handle = WrapNativeCodec2GrallocHandle(
+            native_handle_clone(buffer->handle),
+            buffer->width,
+            buffer->height,
+            buffer->format,
+            buffer->usage,
+            buffer->stride);
+    std::shared_ptr<C2GraphicAllocation> alloc;
+    c2_status_t err = mAlloc->priorGraphicAllocation(handle, &alloc);
+    if (err != C2_OK) {
+        ALOGD("Failed to wrap VideoNativeMetadata into C2GraphicAllocation");
+        return nullptr;
+    }
+    std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
+
+    meta->pBuffer = 0;
+    // TODO: fence
+    return C2Buffer::CreateGraphicBuffer(
+            block->share(C2Rect(buffer->width, buffer->height), C2Fence()));
+#else
+    ALOGE("GraphicMetadataBuffer does not work on 64-bit arch");
+    return nullptr;
+#endif
+}
+
+// ConstGraphicBlockBuffer
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2Buffer> &buffer,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    if (!buffer
+            || buffer->data().type() != C2BufferData::GRAPHIC
+            || buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("C2Buffer precond fail");
+        return nullptr;
+    }
+    std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
+            buffer->data().graphicBlocks()[0].map().get()));
+    std::unique_ptr<const C2GraphicView> holder;
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    (void)format->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(*view, colorFormat);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> aBuffer = converter.wrap();
+    if (aBuffer == nullptr) {
+        aBuffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(aBuffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+        converter.copyToMediaImage();
+        // We don't need the view.
+        holder = std::move(view);
+    }
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            std::move(view),
+            buffer,
+            converter.imageData(),
+            wrapped);
+}
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
+        const sp<AMessage> &format,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width)
+            || !format->findInt32("height", &height)) {
+        ALOGD("format had no width / height");
+        return nullptr;
+    }
+    sp<ABuffer> aBuffer(alloc(width * height * 4));
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            nullptr,
+            nullptr,
+            nullptr,
+            false);
+}
+
+ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &aBuffer,
+        std::unique_ptr<const C2GraphicView> &&view,
+        const std::shared_ptr<C2Buffer> &buffer,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, aBuffer),
+      mView(std::move(view)),
+      mBufferRef(buffer),
+      mWrapped(wrapped) {
+    if (imageData != nullptr) {
+        setImageData(imageData);
+    }
+}
+
+std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
+    mView.reset();
+    return std::move(mBufferRef);
+}
+
+bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (mWrapped || mBufferRef) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
+                mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
+        return false;
+    }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
+    if (buffer->data().type() != C2BufferData::GRAPHIC) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
+        return false;
+    }
+    if (buffer->data().graphicBlocks().size() == 0) {
+        return true;
+    } else if (buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
+        return false;
+    }
+
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    // FIXME: format() is not const, but we cannot change it, so do a const cast here
+    const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    if (converter.backBufferSize() > capacity()) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
+                converter.backBufferSize(), capacity());
+        return false;
+    }
+    return true;
+}
+
+bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    if (!buffer || buffer->data().graphicBlocks().size() == 0) {
+        setRange(0, 0);
+        return true;
+    }
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
+    format()->findInt32("color-format", &colorFormat);
+
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
+    if (!converter.setBackBuffer(aBuffer)) {
+        ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
+        return false;
+    }
+    converter.copyToMediaImage();
+    setImageData(converter.imageData());
+    mBufferRef = buffer;
+    return true;
+}
+
+// EncryptedLinearBlockBuffer
+
+EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2LinearBlock> &block,
+        const sp<IMemory> &memory,
+        int32_t heapSeqNum)
+    : Codec2Buffer(format, new ABuffer(memory->pointer(), memory->size())),
+      mBlock(block),
+      mMemory(memory),
+      mHeapSeqNum(heapSeqNum) {
+}
+
+std::shared_ptr<C2Buffer> EncryptedLinearBlockBuffer::asC2Buffer() {
+    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
+}
+
+void EncryptedLinearBlockBuffer::fillSourceBuffer(
+        ICrypto::SourceBuffer *source) {
+    source->mSharedMemory = mMemory;
+    source->mHeapSeqNum = mHeapSeqNum;
+}
+
+void EncryptedLinearBlockBuffer::fillSourceBuffer(
+        hardware::cas::native::V1_0::SharedBuffer *source) {
+    ssize_t offset;
+    size_t size;
+
+    mHidlMemory = hardware::fromHeap(mMemory->getMemory(&offset, &size));
+    source->heapBase = *mHidlMemory;
+    source->offset = offset;
+    source->size = size;
+}
+
+bool EncryptedLinearBlockBuffer::copyDecryptedContent(
+        const sp<IMemory> &decrypted, size_t length) {
+    C2WriteView view = mBlock->map().get();
+    if (view.error() != C2_OK) {
+        return false;
+    }
+    if (view.size() < length) {
+        return false;
+    }
+    memcpy(view.data(), decrypted->pointer(), length);
+    return true;
+}
+
+bool EncryptedLinearBlockBuffer::copyDecryptedContentFromMemory(size_t length) {
+    return copyDecryptedContent(mMemory, length);
+}
+
+native_handle_t *EncryptedLinearBlockBuffer::handle() const {
+    return const_cast<native_handle_t *>(mBlock->handle());
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
new file mode 100644
index 0000000..481975f
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2017, 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_BUFFER_H_
+
+#define CODEC2_BUFFER_H_
+
+#include <C2Buffer.h>
+
+#include <android/hardware/cas/native/1.0/types.h>
+#include <binder/IMemory.h>
+#include <media/hardware/VideoAPI.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/ICrypto.h>
+
+namespace android {
+
+/**
+ * Copies a graphic view into a media image.
+ *
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ * \param view graphic view
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
+
+/**
+ * Copies a media image into a graphic view.
+ *
+ * \param view graphic view
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
+
+class Codec2Buffer : public MediaCodecBuffer {
+public:
+    using MediaCodecBuffer::MediaCodecBuffer;
+    ~Codec2Buffer() override = default;
+
+    /**
+     * \return  C2Buffer object represents this buffer.
+     */
+    virtual std::shared_ptr<C2Buffer> asC2Buffer() = 0;
+
+    /**
+     * Test if we can copy the content of |buffer| into this object.
+     *
+     * \param   buffer  C2Buffer object to copy.
+     * \return  true    if the content of buffer can be copied over to this buffer
+     *          false   otherwise.
+     */
+    virtual bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+        (void)buffer;
+        return false;
+    }
+
+    /**
+     * Copy the content of |buffer| into this object. This method assumes that
+     * canCopy() check already passed.
+     *
+     * \param   buffer  C2Buffer object to copy.
+     * \return  true    if successful
+     *          false   otherwise.
+     */
+    virtual bool copy(const std::shared_ptr<C2Buffer> &buffer) {
+        (void)buffer;
+        return false;
+    }
+
+protected:
+    /**
+     * canCopy() implementation for linear buffers.
+     */
+    bool canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const;
+
+    /**
+     * copy() implementation for linear buffers.
+     */
+    bool copyLinear(const std::shared_ptr<C2Buffer> &buffer);
+
+    /**
+     * sets MediaImage data for flexible graphic buffers
+     */
+    void setImageData(const sp<ABuffer> &imageData);
+};
+
+/**
+ * MediaCodecBuffer implementation on top of local linear buffer. This cannot
+ * cross process boundary so asC2Buffer() returns only nullptr.
+ */
+class LocalLinearBuffer : public Codec2Buffer {
+public:
+    using Codec2Buffer::Codec2Buffer;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override { return nullptr; }
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+};
+
+/**
+ * MediaCodecBuffer implementation to be used only as a dummy wrapper around a
+ * C2Buffer object.
+ */
+class DummyContainerBuffer : public Codec2Buffer {
+public:
+    DummyContainerBuffer(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2Buffer> &buffer = nullptr);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+private:
+    std::shared_ptr<C2Buffer> mBufferRef;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2LinearBlock.
+ */
+class LinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2LinearBlock object to wrap around.
+     * \return          LinearBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<LinearBlockBuffer> Allocate(
+            const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
+
+    virtual ~LinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+private:
+    LinearBlockBuffer(
+            const sp<AMessage> &format,
+            C2WriteView &&writeView,
+            const std::shared_ptr<C2LinearBlock> &block);
+    LinearBlockBuffer() = delete;
+
+    C2WriteView mWriteView;
+    std::shared_ptr<C2LinearBlock> mBlock;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
+ */
+class ConstLinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  linear C2Buffer object to wrap around.
+     * \return          ConstLinearBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<ConstLinearBlockBuffer> Allocate(
+            const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);
+
+    virtual ~ConstLinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+private:
+    ConstLinearBlockBuffer(
+            const sp<AMessage> &format,
+            C2ReadView &&readView,
+            const std::shared_ptr<C2Buffer> &buffer);
+    ConstLinearBlockBuffer() = delete;
+
+    C2ReadView mReadView;
+    std::shared_ptr<C2Buffer> mBufferRef;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2GraphicBlock.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class GraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
+     * If |block| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content over at asC2Buffer().
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2GraphicBlock object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          GraphicBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<GraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+    virtual ~GraphicBlockBuffer() = default;
+
+private:
+    GraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &buffer,
+            C2GraphicView &&view,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    GraphicBlockBuffer() = delete;
+
+    inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }
+
+    C2GraphicView mView;
+    std::shared_ptr<C2GraphicBlock> mBlock;
+    sp<ABuffer> mImageData;
+    const bool mWrapped;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around VideoNativeMetadata.
+ */
+class GraphicMetadataBuffer : public Codec2Buffer {
+public:
+    /**
+     * Construct a new GraphicMetadataBuffer with local linear buffer for
+     * VideoNativeMetadata.
+     *
+     * \param   format      mandatory buffer format for MediaCodecBuffer
+     */
+    GraphicMetadataBuffer(
+            const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+    virtual ~GraphicMetadataBuffer() = default;
+
+private:
+    GraphicMetadataBuffer() = delete;
+
+    std::shared_ptr<C2Allocator> mAlloc;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class ConstGraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
+     * If |buffer| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  graphic C2Buffer object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<ConstGraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2Buffer> &buffer,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    /**
+     * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with no wrapping buffer.
+     */
+    static sp<ConstGraphicBlockBuffer> AllocateEmpty(
+            const sp<AMessage> &format,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+    virtual ~ConstGraphicBlockBuffer() = default;
+
+private:
+    ConstGraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &aBuffer,
+            std::unique_ptr<const C2GraphicView> &&view,
+            const std::shared_ptr<C2Buffer> &buffer,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    ConstGraphicBlockBuffer() = delete;
+
+    sp<ABuffer> mImageData;
+    std::unique_ptr<const C2GraphicView> mView;
+    std::shared_ptr<C2Buffer> mBufferRef;
+    const bool mWrapped;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around C2LinearBlock for component
+ * and IMemory for client. Underlying C2LinearBlock won't be mapped for secure
+ * usecases..
+ */
+class EncryptedLinearBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Construct a new EncryptedLinearBufferBlock wrapping around C2LinearBlock
+     * object and writable IMemory region.
+     *
+     * \param   format      mandatory buffer format for MediaCodecBuffer
+     * \param   block       C2LinearBlock object to wrap around.
+     * \param   memory      IMemory object to store encrypted content.
+     * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
+     */
+    EncryptedLinearBlockBuffer(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2LinearBlock> &block,
+            const sp<IMemory> &memory,
+            int32_t heapSeqNum = -1);
+    EncryptedLinearBlockBuffer() = delete;
+
+    virtual ~EncryptedLinearBlockBuffer() = default;
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+    /**
+     * Fill the source buffer structure with appropriate value based on
+     * internal IMemory object.
+     *
+     * \param source  source buffer structure to fill.
+     */
+    void fillSourceBuffer(ICrypto::SourceBuffer *source);
+    void fillSourceBuffer(
+            hardware::cas::native::V1_0::SharedBuffer *source);
+
+    /**
+     * Copy the content of |decrypted| into C2LinearBlock inside. This shall
+     * only be called in non-secure usecases.
+     *
+     * \param   decrypted   decrypted content to copy from.
+     * \param   length      length of the content
+     * \return  true        if successful
+     *          false       otherwise.
+     */
+    bool copyDecryptedContent(const sp<IMemory> &decrypted, size_t length);
+
+    /**
+     * Copy the content of internal IMemory object into C2LinearBlock inside.
+     * This shall only be called in non-secure usecases.
+     *
+     * \param   length      length of the content
+     * \return  true        if successful
+     *          false       otherwise.
+     */
+    bool copyDecryptedContentFromMemory(size_t length);
+
+    /**
+     * Return native handle of secure buffer understood by ICrypto.
+     *
+     * \return secure buffer handle
+     */
+    native_handle_t *handle() const;
+
+private:
+
+    std::shared_ptr<C2LinearBlock> mBlock;
+    sp<IMemory> mMemory;
+    sp<hardware::HidlMemory> mHidlMemory;
+    int32_t mHeapSeqNum;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_BUFFER_H_
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
new file mode 100644
index 0000000..f36027e
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2InfoBuilder"
+#include <log/log.h>
+
+#include <strings.h>
+
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2Mapper.h>
+
+#include <OMX_Audio.h>
+#include <OMX_AudioExt.h>
+#include <OMX_IndexExt.h>
+#include <OMX_Types.h>
+#include <OMX_Video.h>
+#include <OMX_VideoExt.h>
+#include <OMX_AsString.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/types.h>
+
+#include <android-base/properties.h>
+#include <codec2/hidl/client.h>
+#include <cutils/native_handle.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include "Codec2InfoBuilder.h"
+
+namespace android {
+
+using Traits = C2Component::Traits;
+
+namespace /* unnamed */ {
+
+bool hasPrefix(const std::string& s, const char* prefix) {
+    size_t prefixLen = strlen(prefix);
+    return s.compare(0, prefixLen, prefix) == 0;
+}
+
+bool hasSuffix(const std::string& s, const char* suffix) {
+    size_t suffixLen = strlen(suffix);
+    return suffixLen > s.size() ? false :
+            s.compare(s.size() - suffixLen, suffixLen, suffix) == 0;
+}
+
+// Constants from ACodec
+constexpr OMX_U32 kPortIndexInput = 0;
+constexpr OMX_U32 kPortIndexOutput = 1;
+constexpr OMX_U32 kMaxIndicesToCheck = 32;
+
+status_t queryOmxCapabilities(
+        const char* name, const char* mime, bool isEncoder,
+        MediaCodecInfo::CapabilitiesWriter* caps) {
+
+    const char *role = GetComponentRole(isEncoder, mime);
+    if (role == nullptr) {
+        return BAD_VALUE;
+    }
+
+    using namespace ::android::hardware::media::omx::V1_0;
+    using ::android::hardware::Return;
+    using ::android::hardware::Void;
+    using ::android::hardware::hidl_vec;
+    using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
+
+    sp<IOmx> omx = IOmx::getService();
+    if (!omx) {
+        ALOGW("Could not obtain IOmx service.");
+        return NO_INIT;
+    }
+
+    struct Observer : IOmxObserver {
+        virtual Return<void> onMessages(const hidl_vec<Message>&) override {
+            return Void();
+        }
+    };
+
+    sp<Observer> observer = new Observer();
+    Status status;
+    sp<IOmxNode> tOmxNode;
+    Return<void> transStatus = omx->allocateNode(
+            name, observer,
+            [&status, &tOmxNode](Status s, const sp<IOmxNode>& n) {
+                status = s;
+                tOmxNode = n;
+            });
+    if (!transStatus.isOk()) {
+        ALOGW("IOmx::allocateNode -- transaction failed.");
+        return NO_INIT;
+    }
+    if (status != Status::OK) {
+        ALOGW("IOmx::allocateNode -- error returned: %d.",
+                static_cast<int>(status));
+        return NO_INIT;
+    }
+
+    sp<LWOmxNode> omxNode = new LWOmxNode(tOmxNode);
+
+    status_t err = SetComponentRole(omxNode, role);
+    if (err != OK) {
+        omxNode->freeNode();
+        ALOGW("Failed to SetComponentRole: component = %s, role = %s.",
+                name, role);
+        return err;
+    }
+
+    bool isVideo = hasPrefix(mime, "video/") == 0;
+    bool isImage = hasPrefix(mime, "image/") == 0;
+
+    if (isVideo || isImage) {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
+        InitOMXParams(&param);
+        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
+
+        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+            param.nProfileIndex = index;
+            status_t err = omxNode->getParameter(
+                    OMX_IndexParamVideoProfileLevelQuerySupported,
+                    &param, sizeof(param));
+            if (err != OK) {
+                break;
+            }
+            caps->addProfileLevel(param.eProfile, param.eLevel);
+
+            // AVC components may not list the constrained profiles explicitly, but
+            // decoders that support a profile also support its constrained version.
+            // Encoders must explicitly support constrained profiles.
+            if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
+                if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
+                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
+                } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
+                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
+                }
+            }
+
+            if (index == kMaxIndicesToCheck) {
+                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
+                        name, index,
+                        param.eProfile, param.eLevel);
+            }
+        }
+
+        // Color format query
+        // return colors in the order reported by the OMX component
+        // prefix "flexible" standard ones with the flexible equivalent
+        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
+        InitOMXParams(&portFormat);
+        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
+        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+            portFormat.nIndex = index;
+            status_t err = omxNode->getParameter(
+                    OMX_IndexParamVideoPortFormat,
+                    &portFormat, sizeof(portFormat));
+            if (err != OK) {
+                break;
+            }
+
+            OMX_U32 flexibleEquivalent;
+            if (IsFlexibleColorFormat(
+                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
+                    &flexibleEquivalent)) {
+                caps->addColorFormat(flexibleEquivalent);
+            }
+            caps->addColorFormat(portFormat.eColorFormat);
+
+            if (index == kMaxIndicesToCheck) {
+                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
+                        name, index,
+                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
+            }
+        }
+    } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
+        // More audio codecs if they have profiles.
+        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
+        InitOMXParams(&param);
+        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
+        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+            param.nProfileIndex = index;
+            status_t err = omxNode->getParameter(
+                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
+                    &param, sizeof(param));
+            if (err != OK) {
+                break;
+            }
+            // For audio, level is ignored.
+            caps->addProfileLevel(param.eProfile, 0 /* level */);
+
+            if (index == kMaxIndicesToCheck) {
+                ALOGW("[%s] stopping checking profiles after %u: %x",
+                        name, index,
+                        param.eProfile);
+            }
+        }
+
+        // NOTE: Without Android extensions, OMX does not provide a way to query
+        // AAC profile support
+        if (param.nProfileIndex == 0) {
+            ALOGW("component %s doesn't support profile query.", name);
+        }
+    }
+
+    if (isVideo && !isEncoder) {
+        native_handle_t *sidebandHandle = nullptr;
+        if (omxNode->configureVideoTunnelMode(
+                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
+            // tunneled playback includes adaptive playback
+            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
+                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
+        } else if (omxNode->setPortMode(
+                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
+                omxNode->prepareForAdaptivePlayback(
+                kPortIndexOutput, OMX_TRUE,
+                1280 /* width */, 720 /* height */) == OK) {
+            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
+        }
+    }
+
+    if (isVideo && isEncoder) {
+        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
+        InitOMXParams(&params);
+        params.nPortIndex = kPortIndexOutput;
+        // TODO: should we verify if fallback is supported?
+        if (omxNode->getConfig(
+                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
+                &params, sizeof(params)) == OK) {
+            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
+        }
+    }
+
+    omxNode->freeNode();
+    return OK;
+}
+
+void buildOmxInfo(const MediaCodecsXmlParser& parser,
+                  MediaCodecListWriter* writer) {
+    uint32_t omxRank = ::android::base::GetUintProperty(
+            "debug.stagefright.omx_default_rank", uint32_t(0x100));
+    for (const MediaCodecsXmlParser::Codec& codec : parser.getCodecMap()) {
+        const std::string &name = codec.first;
+        if (!hasPrefix(codec.first, "OMX.")) {
+            continue;
+        }
+        const MediaCodecsXmlParser::CodecProperties &properties = codec.second;
+        bool encoder = properties.isEncoder;
+        std::unique_ptr<MediaCodecInfoWriter> info =
+                writer->addMediaCodecInfo();
+        info->setName(name.c_str());
+        info->setOwner("default");
+        info->setEncoder(encoder);
+        info->setRank(omxRank);
+        for (const MediaCodecsXmlParser::Type& type : properties.typeMap) {
+            const std::string &mime = type.first;
+            std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
+                    info->addMime(mime.c_str());
+            const MediaCodecsXmlParser::AttributeMap &attrMap = type.second;
+            for (const MediaCodecsXmlParser::Attribute& attr : attrMap) {
+                const std::string &key = attr.first;
+                const std::string &value = attr.second;
+                if (hasPrefix(key, "feature-") &&
+                        !hasPrefix(key, "feature-bitrate-modes")) {
+                    caps->addDetail(key.c_str(), hasPrefix(value, "1") ? 1 : 0);
+                } else {
+                    caps->addDetail(key.c_str(), value.c_str());
+                }
+            }
+            status_t err = queryOmxCapabilities(
+                    name.c_str(),
+                    mime.c_str(),
+                    encoder,
+                    caps.get());
+            if (err != OK) {
+                ALOGE("Failed to query capabilities for %s (mime: %s). Error: %d",
+                        name.c_str(),
+                        mime.c_str(),
+                        static_cast<int>(err));
+            }
+        }
+    }
+}
+
+} // unnamed namespace
+
+status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
+    // TODO: Remove run-time configurations once all codecs are working
+    // properly. (Assume "full" behavior eventually.)
+    //
+    // debug.stagefright.ccodec supports 5 values.
+    //   0 - Only OMX components are available.
+    //   1 - Audio decoders and encoders with prefix "c2.android." are available
+    //       and ranked first.
+    //       All other components with prefix "c2.android." are available with
+    //       their normal ranks.
+    //       Components with prefix "c2.vda." are available with their normal
+    //       ranks.
+    //       All other components with suffix ".avc.decoder" or ".avc.encoder"
+    //       are available but ranked last.
+    //   2 - Components with prefix "c2.android." are available and ranked
+    //       first.
+    //       Components with prefix "c2.vda." are available with their normal
+    //       ranks.
+    //       All other components with suffix ".avc.decoder" or ".avc.encoder"
+    //       are available but ranked last.
+    //   3 - Components with prefix "c2.android." are available and ranked
+    //       first.
+    //       All other components are available with their normal ranks.
+    //   4 - All components are available with their normal ranks.
+    //
+    // The default value (boot time) is 1.
+    //
+    // Note: Currently, OMX components have default rank 0x100, while all
+    // Codec2.0 software components have default rank 0x200.
+    int option = ::android::base::GetIntProperty("debug.stagefright.ccodec", 1);
+
+    // Obtain Codec2Client
+    std::vector<Traits> traits = Codec2Client::ListComponents();
+
+    MediaCodecsXmlParser parser(
+            MediaCodecsXmlParser::defaultSearchDirs,
+            option == 0 ? "media_codecs.xml" :
+                          "media_codecs_c2.xml",
+            option == 0 ? "media_codecs_performance.xml" :
+                          "media_codecs_performance_c2.xml");
+    if (parser.getParsingStatus() != OK) {
+        ALOGD("XML parser no good");
+        return OK;
+    }
+
+    bool surfaceTest(Codec2Client::CreateInputSurface());
+    if (option == 0 || !surfaceTest) {
+        buildOmxInfo(parser, writer);
+    }
+
+    for (const Traits& trait : traits) {
+        C2Component::rank_t rank = trait.rank;
+
+        std::shared_ptr<Codec2Client::Interface> intf =
+            Codec2Client::CreateInterfaceByName(trait.name.c_str());
+        if (!intf || parser.getCodecMap().count(intf->getName()) == 0) {
+            ALOGD("%s not found in xml", trait.name.c_str());
+            continue;
+        }
+        std::string canonName = intf->getName();
+
+        // TODO: Remove this block once all codecs are enabled by default.
+        switch (option) {
+        case 0:
+            continue;
+        case 1:
+            if (hasPrefix(canonName, "c2.vda.")) {
+                break;
+            }
+            if (hasPrefix(canonName, "c2.android.")) {
+                if (trait.domain == C2Component::DOMAIN_AUDIO) {
+                    rank = 1;
+                    break;
+                }
+                break;
+            }
+            if (hasSuffix(canonName, ".avc.decoder") ||
+                    hasSuffix(canonName, ".avc.encoder")) {
+                rank = std::numeric_limits<decltype(rank)>::max();
+                break;
+            }
+            continue;
+        case 2:
+            if (hasPrefix(canonName, "c2.vda.")) {
+                break;
+            }
+            if (hasPrefix(canonName, "c2.android.")) {
+                rank = 1;
+                break;
+            }
+            if (hasSuffix(canonName, ".avc.decoder") ||
+                    hasSuffix(canonName, ".avc.encoder")) {
+                rank = std::numeric_limits<decltype(rank)>::max();
+                break;
+            }
+            continue;
+        case 3:
+            if (hasPrefix(canonName, "c2.android.")) {
+                rank = 1;
+            }
+            break;
+        }
+
+        std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
+        codecInfo->setName(trait.name.c_str());
+        codecInfo->setOwner("codec2");
+        bool encoder = trait.kind == C2Component::KIND_ENCODER;
+        codecInfo->setEncoder(encoder);
+        codecInfo->setRank(rank);
+        const MediaCodecsXmlParser::CodecProperties &codec =
+            parser.getCodecMap().at(canonName);
+
+        for (auto typeIt = codec.typeMap.begin(); typeIt != codec.typeMap.end(); ++typeIt) {
+            const std::string &mediaType = typeIt->first;
+            const MediaCodecsXmlParser::AttributeMap &attrMap = typeIt->second;
+            std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
+                codecInfo->addMime(mediaType.c_str());
+            for (auto attrIt = attrMap.begin(); attrIt != attrMap.end(); ++attrIt) {
+                std::string key, value;
+                std::tie(key, value) = *attrIt;
+                if (key.find("feature-") == 0 && key.find("feature-bitrate-modes") != 0) {
+                    caps->addDetail(key.c_str(), std::stoi(value));
+                } else {
+                    caps->addDetail(key.c_str(), value.c_str());
+                }
+            }
+
+            bool gotProfileLevels = false;
+            if (intf) {
+                std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
+                    C2Mapper::GetProfileLevelMapper(trait.mediaType);
+                // if we don't know the media type, pass through all values unmapped
+
+                // TODO: we cannot find levels that are local 'maxima' without knowing the coding
+                // e.g. H.263 level 45 and level 30 could be two values for highest level as
+                // they don't include one another. For now we use the last supported value.
+                C2StreamProfileLevelInfo pl(encoder /* output */, 0u);
+                std::vector<C2FieldSupportedValuesQuery> profileQuery = {
+                    C2FieldSupportedValuesQuery::Possible(C2ParamField(&pl, &pl.profile))
+                };
+
+                c2_status_t err = intf->querySupportedValues(profileQuery, C2_DONT_BLOCK);
+                ALOGV("query supported profiles -> %s | %s",
+                        asString(err), asString(profileQuery[0].status));
+                if (err == C2_OK && profileQuery[0].status == C2_OK) {
+                    if (profileQuery[0].values.type == C2FieldSupportedValues::VALUES) {
+                        for (C2Value::Primitive profile : profileQuery[0].values.values) {
+                            pl.profile = (C2Config::profile_t)profile.ref<uint32_t>();
+                            std::vector<std::unique_ptr<C2SettingResult>> failures;
+                            err = intf->config({&pl}, C2_DONT_BLOCK, &failures);
+                            ALOGV("set profile to %u -> %s", pl.profile, asString(err));
+                            std::vector<C2FieldSupportedValuesQuery> levelQuery = {
+                                C2FieldSupportedValuesQuery::Current(C2ParamField(&pl, &pl.level))
+                            };
+                            err = intf->querySupportedValues(levelQuery, C2_DONT_BLOCK);
+                            ALOGV("query supported levels -> %s | %s",
+                                    asString(err), asString(levelQuery[0].status));
+                            if (err == C2_OK && levelQuery[0].status == C2_OK) {
+                                if (levelQuery[0].values.type == C2FieldSupportedValues::VALUES
+                                        && levelQuery[0].values.values.size() > 0) {
+                                    C2Value::Primitive level = levelQuery[0].values.values.back();
+                                    pl.level = (C2Config::level_t)level.ref<uint32_t>();
+                                    ALOGV("supporting level: %u", pl.level);
+                                    int32_t sdkProfile, sdkLevel;
+                                    if (mapper && mapper->mapProfile(pl.profile, &sdkProfile)
+                                            && mapper->mapLevel(pl.level, &sdkLevel)) {
+                                        caps->addProfileLevel(
+                                                (uint32_t)sdkProfile, (uint32_t)sdkLevel);
+                                        gotProfileLevels = true;
+                                    } else if (!mapper) {
+                                        caps->addProfileLevel(pl.profile, pl.level);
+                                        gotProfileLevels = true;
+                                    }
+
+                                    // for H.263 also advertise the second highest level if the
+                                    // codec supports level 45, as level 45 only covers level 10
+                                    // TODO: move this to some form of a setting so it does not
+                                    // have to be here
+                                    if (mediaType == MIMETYPE_VIDEO_H263) {
+                                        C2Config::level_t nextLevel = C2Config::LEVEL_UNUSED;
+                                        for (C2Value::Primitive v : levelQuery[0].values.values) {
+                                            C2Config::level_t level =
+                                                (C2Config::level_t)v.ref<uint32_t>();
+                                            if (level < C2Config::LEVEL_H263_45
+                                                    && level > nextLevel) {
+                                                nextLevel = level;
+                                            }
+                                        }
+                                        if (nextLevel != C2Config::LEVEL_UNUSED
+                                                && nextLevel != pl.level
+                                                && mapper
+                                                && mapper->mapProfile(pl.profile, &sdkProfile)
+                                                && mapper->mapLevel(nextLevel, &sdkLevel)) {
+                                            caps->addProfileLevel(
+                                                    (uint32_t)sdkProfile, (uint32_t)sdkLevel);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!gotProfileLevels) {
+                if (mediaType == MIMETYPE_VIDEO_VP9) {
+                    if (encoder) {
+                        caps->addProfileLevel(VP9Profile0,    VP9Level41);
+                    } else {
+                        caps->addProfileLevel(VP9Profile0,    VP9Level5);
+                        caps->addProfileLevel(VP9Profile2,    VP9Level5);
+                        caps->addProfileLevel(VP9Profile2HDR, VP9Level5);
+                    }
+                } else if (mediaType == MIMETYPE_VIDEO_HEVC && !encoder) {
+                    caps->addProfileLevel(HEVCProfileMain,      HEVCMainTierLevel51);
+                    caps->addProfileLevel(HEVCProfileMainStill, HEVCMainTierLevel51);
+                } else if (mediaType == MIMETYPE_VIDEO_VP8) {
+                    if (encoder) {
+                        caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
+                    } else {
+                        caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
+                    }
+                } else if (mediaType == MIMETYPE_VIDEO_AVC) {
+                    if (encoder) {
+                        caps->addProfileLevel(AVCProfileBaseline,            AVCLevel41);
+//                      caps->addProfileLevel(AVCProfileConstrainedBaseline, AVCLevel41);
+                        caps->addProfileLevel(AVCProfileMain,                AVCLevel41);
+                    } else {
+                        caps->addProfileLevel(AVCProfileBaseline,            AVCLevel52);
+                        caps->addProfileLevel(AVCProfileConstrainedBaseline, AVCLevel52);
+                        caps->addProfileLevel(AVCProfileMain,                AVCLevel52);
+                        caps->addProfileLevel(AVCProfileConstrainedHigh,     AVCLevel52);
+                        caps->addProfileLevel(AVCProfileHigh,                AVCLevel52);
+                    }
+                } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
+                    if (encoder) {
+                        caps->addProfileLevel(MPEG4ProfileSimple,  MPEG4Level2);
+                    } else {
+                        caps->addProfileLevel(MPEG4ProfileSimple,  MPEG4Level3);
+                    }
+                } else if (mediaType == MIMETYPE_VIDEO_H263) {
+                    if (encoder) {
+                        caps->addProfileLevel(H263ProfileBaseline, H263Level45);
+                    } else {
+                        caps->addProfileLevel(H263ProfileBaseline, H263Level30);
+                        caps->addProfileLevel(H263ProfileBaseline, H263Level45);
+                        caps->addProfileLevel(H263ProfileISWV2,    H263Level30);
+                        caps->addProfileLevel(H263ProfileISWV2,    H263Level45);
+                    }
+                } else if (mediaType == MIMETYPE_VIDEO_MPEG2 && !encoder) {
+                    caps->addProfileLevel(MPEG2ProfileSimple, MPEG2LevelHL);
+                    caps->addProfileLevel(MPEG2ProfileMain,   MPEG2LevelHL);
+                }
+            }
+
+            // TODO: get this from intf() as well, but how do we map them to
+            // MediaCodec color formats?
+            if (mediaType.find("video") != std::string::npos) {
+                // vendor video codecs prefer opaque format
+                if (trait.name.find("android") == std::string::npos) {
+                    caps->addColorFormat(COLOR_FormatSurface);
+                }
+                caps->addColorFormat(COLOR_FormatYUV420Flexible);
+                caps->addColorFormat(COLOR_FormatYUV420Planar);
+                caps->addColorFormat(COLOR_FormatYUV420SemiPlanar);
+                caps->addColorFormat(COLOR_FormatYUV420PackedPlanar);
+                caps->addColorFormat(COLOR_FormatYUV420PackedSemiPlanar);
+                // framework video encoders must support surface format, though it is unclear
+                // that they will be able to map it if it is opaque
+                if (encoder && trait.name.find("android") != std::string::npos) {
+                    caps->addColorFormat(COLOR_FormatSurface);
+                }
+            }
+        }
+    }
+    return OK;
+}
+
+}  // namespace android
+
+extern "C" android::MediaCodecListBuilderBase *CreateBuilder() {
+    return new android::Codec2InfoBuilder;
+}
+
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.h b/media/codec2/sfplugin/Codec2InfoBuilder.h
new file mode 100644
index 0000000..30c189e
--- /dev/null
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 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_INFO_BUILDER_H_
+#define CODEC2_INFO_BUILDER_H_
+
+#include <media/stagefright/MediaCodecList.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class Codec2InfoBuilder : public MediaCodecListBuilderBase {
+public:
+    Codec2InfoBuilder() = default;
+    ~Codec2InfoBuilder() override = default;
+    status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_INFO_BUILDER_H_
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
new file mode 100644
index 0000000..d9c4eec
--- /dev/null
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -0,0 +1,107 @@
+/*
+ * 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 INPUT_SURFACE_WRAPPER_H_
+#define INPUT_SURFACE_WRAPPER_H_
+
+#include <codec2/hidl/client.h>
+#include <system/graphics.h>
+
+namespace android {
+
+/**
+ * Wrapper interface around InputSurface.
+ */
+class InputSurfaceWrapper {
+public:
+    InputSurfaceWrapper()
+        : mDataSpace(HAL_DATASPACE_UNKNOWN) {
+    }
+
+    virtual ~InputSurfaceWrapper() = default;
+
+    /**
+     * Connect the surface with |comp|. A surface can
+     * connect to at most one component at a time.
+     *
+     * \return OK               successfully connected to |comp|
+     * \return ALREADY_EXISTS   already connected to another component.
+     */
+    virtual status_t connect(
+            const std::shared_ptr<Codec2Client::Component> &comp) = 0;
+
+    /**
+     * Disconnect the surface from the component if any.
+     */
+    virtual void disconnect() = 0;
+
+    /**
+     * Start pushing buffers to the surface.
+     */
+    virtual status_t start() = 0;
+
+    /**
+     * Ref: GraphicBufferSource::signalEndOfInputStream.
+     */
+    virtual status_t signalEndOfInputStream() = 0;
+
+    /// Input Surface configuration
+    struct Config {
+        // IN PARAMS (GBS)
+        float mMinFps; // minimum fps (repeat frame to achieve this)
+        float mMaxFps; // max fps (via frame drop)
+        float mCaptureFps; // capture fps
+        float mCodedFps;   // coded fps
+        bool mSuspended; // suspended
+        int64_t mTimeOffsetUs; // time offset (input => codec)
+        int64_t mSuspendAtUs; // suspend/resume time
+        int64_t mStartAtUs; // start time
+        bool mStopped; // stopped
+        int64_t mStopAtUs; // stop time
+
+        // OUT PARAMS (GBS)
+        int64_t mInputDelayUs; // delay between encoder input and surface input
+
+        // IN PARAMS (CODEC WRAPPER)
+        float mFixedAdjustedFps; // fixed fps via PTS manipulation
+        float mMinAdjustedFps; // minimum fps via PTS manipulation
+    };
+
+    /**
+     * Configures input surface.
+     *
+     * \param config configuration. This can be updated during this call to provide output
+     *               parameters, but not to provide configured parameters (to avoid continually
+     *               reconfiguring)
+     */
+    virtual status_t configure(Config &config) = 0;
+
+    /**
+     * Configures desired data space.
+     *
+     * \param dataSpace desired data space
+     */
+    inline void setDataSpace(android_dataspace dataSpace) {
+        mDataSpace = dataSpace;
+    }
+
+protected:
+    android_dataspace mDataSpace;
+};
+
+}  // namespace android
+
+#endif  // INPUT_SURFACE_WRAPPER_H_
diff --git a/media/codec2/sfplugin/ReflectedParamUpdater.cpp b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
new file mode 100644
index 0000000..880d4a5
--- /dev/null
+++ b/media/codec2/sfplugin/ReflectedParamUpdater.cpp
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ReflectedParamUpdater"
+#include <utils/Log.h>
+
+#include <iostream>
+#include <set>
+#include <sstream>
+
+#include <C2Debug.h>
+#include <C2ParamInternal.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+#include "ReflectedParamUpdater.h"
+
+namespace android {
+
+std::string ReflectedParamUpdater::Dict::debugString(size_t indent_) const {
+    std::string indent(indent_, ' ');
+    std::stringstream s;
+    s << "Dict {" << std::endl;
+
+    for (const auto &it : *this) {
+        s << indent << "  ";
+
+        C2Value c2Value;
+        int32_t int32Value;
+        uint32_t uint32Value;
+        int64_t int64Value;
+        uint64_t uint64Value;
+        float floatValue;
+        sp<ABuffer> bufValue;
+        AString strValue;
+        if (it.second.find(&c2Value)) {
+            switch (c2Value.type()) {
+                case C2Value::INT32:
+                    (void)c2Value.get(&int32Value);
+                    s << "c2::i32 " << it.first << " = " << int32Value;
+                    break;
+                case C2Value::UINT32:
+                    (void)c2Value.get(&uint32Value);
+                    s << "c2::u32 " << it.first << " = " << uint32Value;
+                    break;
+                case C2Value::CNTR32:
+                    // dump counter value as unsigned
+                    (void)c2Value.get((c2_cntr32_t*)&uint32Value);
+                    s << "c2::c32 " << it.first << " = " << uint32Value;
+                    break;
+                case C2Value::INT64:
+                    (void)c2Value.get(&int64Value);
+                    s << "c2::i64 " << it.first << " = " << int64Value;
+                    break;
+                case C2Value::UINT64:
+                    (void)c2Value.get(&uint64Value);
+                    s << "c2::u64 " << it.first << " = " << uint64Value;
+                    break;
+                case C2Value::CNTR64:
+                    // dump counter value as unsigned
+                    (void)c2Value.get((c2_cntr64_t*)&uint64Value);
+                    s << "c2::c64 " << it.first << " = " << uint64Value;
+                    break;
+                case C2Value::FLOAT:
+                    (void)c2Value.get(&floatValue);
+                    s << "c2::float " << it.first << " = " << floatValue;
+                    break;
+                default:
+                    // dump unsupported values for debugging, these should not be used
+                    s << "c2::unsupported " << it.first;
+            }
+        } else if (it.second.find(&int32Value)) {
+            s << "int32_t " << it.first << " = " << int32Value;
+        } else if (it.second.find(&int64Value)) {
+            s << "int64_t " << it.first << " = " << int64Value;
+        } else if (it.second.find(&strValue)) {
+            s << "string " << it.first << " = \"" << strValue.c_str() << "\"";
+        } else if (it.second.find(&bufValue)) {
+            s << "Buffer " << it.first << " = ";
+            if (bufValue != nullptr && bufValue->data() != nullptr && bufValue->size() <= 64) {
+                s << "{" << std::endl;
+                AString tmp;
+                hexdump(bufValue->data(), bufValue->size(), indent_ + 4, &tmp);
+                s << tmp.c_str() << indent << "  }";
+            } else {
+                s << (void*)bufValue.get();
+            }
+        } else {
+            // dump unsupported values for debugging, this should never happen.
+            s << "unsupported " << it.first;
+        }
+        s << std::endl;
+    }
+    s << indent << "}";
+
+    return s.str();
+}
+
+void ReflectedParamUpdater::addParamDesc(
+        const std::shared_ptr<C2ParamReflector> &reflector,
+        const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs) {
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
+        std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
+                desc->index().coreIndex());
+        if (structDesc == nullptr) {
+            ALOGD("Could not describe %s", desc->name().c_str());
+            continue;
+        }
+        addParamDesc(desc, *structDesc, reflector, true /* markVendor */);
+    }
+
+    // TEMP: also add vendor parameters as non-vendor
+    for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
+        if (!desc->index().isVendor()) {
+            continue;
+        }
+        std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
+                desc->index().coreIndex());
+        if (structDesc) {
+            addParamDesc(desc, *structDesc, reflector, false /* markVendor */);
+        }
+    }
+}
+
+void ReflectedParamUpdater::addParamStructDesc(
+        std::shared_ptr<C2ParamDescriptor> desc,
+        C2String path,
+        size_t offset,
+        const C2StructDescriptor &structDesc,
+        const std::shared_ptr<C2ParamReflector> &reflector) {
+    for (auto it = structDesc.begin(); it != structDesc.end(); ++it) {
+        C2String fieldName = path + "." + it->name();
+        if (it->type() & C2FieldDescriptor::STRUCT_FLAG) {
+            if (reflector == nullptr || it->extent() != 1) {
+                ALOGD("ignored struct field %s", fieldName.c_str());
+                continue;
+            }
+            std::unique_ptr<C2StructDescriptor> structDesc_ = reflector->describe(
+                    C2Param::CoreIndex(it->type()).coreIndex());
+            if (structDesc_ == nullptr) {
+                ALOGD("Could not describe structure of %s", fieldName.c_str());
+                continue;
+            }
+            addParamStructDesc(desc, fieldName, offset + _C2ParamInspector::GetOffset(*it),
+                               *structDesc_, reflector);
+            continue;
+        }
+
+        // verify extent and type
+        switch (it->type()) {
+            case C2FieldDescriptor::INT32:
+            case C2FieldDescriptor::UINT32:
+            case C2FieldDescriptor::CNTR32:
+            case C2FieldDescriptor::INT64:
+            case C2FieldDescriptor::UINT64:
+            case C2FieldDescriptor::CNTR64:
+            case C2FieldDescriptor::FLOAT:
+                if (it->extent() != 1) {
+                    ALOGD("extent() != 1 for single value type: %s", fieldName.c_str());
+                    continue;
+                }
+                break;
+            case C2FieldDescriptor::STRING:
+            case C2FieldDescriptor::BLOB:
+                break;
+
+            default:
+                ALOGD("Unrecognized type: %s", fieldName.c_str());
+                continue;
+        }
+
+        ALOGV("%s registered", fieldName.c_str());
+        // TODO: get the proper size by iterating through the fields.
+        // only insert fields the very first time
+        mMap.emplace(fieldName, FieldDesc {
+            desc,
+            std::make_unique<C2FieldDescriptor>(
+                    it->type(), it->extent(), it->name(),
+                    _C2ParamInspector::GetOffset(*it),
+                    _C2ParamInspector::GetSize(*it)),
+            offset,
+        });
+    }
+}
+
+void ReflectedParamUpdater::addParamDesc(
+        std::shared_ptr<C2ParamDescriptor> desc, const C2StructDescriptor &structDesc,
+        const std::shared_ptr<C2ParamReflector> &reflector, bool markVendor) {
+    C2String paramName = desc->name();
+
+    // prefix vendor parameters
+    if (desc->index().isVendor() && markVendor) {
+        paramName = "vendor." + paramName;
+    }
+    mParamNames.emplace(desc->index(), paramName);
+
+    // also allow setting whole parameters in a binary fashion via ByteBuffer
+    // this is opt-in for now
+    auto it = mWholeParams.find(paramName);
+    if (it != mWholeParams.end() && it->second.coreIndex() == desc->index().coreIndex()) {
+        mMap.emplace(paramName, FieldDesc{ desc, nullptr, 0 /* offset */ });
+        // don't add fields of whole parameters.
+        return;
+    }
+
+    addParamStructDesc(desc, paramName, 0 /* offset */, structDesc, reflector);
+}
+
+void ReflectedParamUpdater::supportWholeParam(std::string name, C2Param::CoreIndex index) {
+    mWholeParams.emplace(name, index);
+}
+
+std::string ReflectedParamUpdater::getParamName(C2Param::Index index) const {
+    auto it = mParamNames.find(index);
+    if (it != mParamNames.end()) {
+        return it->second;
+    }
+
+    std::stringstream ret;
+    ret << "<unknown " << index << ">";
+    return ret.str();
+}
+
+void ReflectedParamUpdater::getParamIndicesFromMessage(
+        const Dict &params,
+        std::vector<C2Param::Index> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+    vec->clear();
+    std::set<C2Param::Index> indices;
+    parseMessageAndDoWork(
+            params,
+            [&indices](const std::string &, const FieldDesc &desc, const void *, size_t) {
+                indices.insert(desc.paramDesc->index());
+            });
+    for (const C2Param::Index &index : indices) {
+        vec->push_back(index);
+    }
+}
+
+void ReflectedParamUpdater::getParamIndicesForKeys(
+        const std::vector<std::string> &keys,
+        std::vector<C2Param::Index> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+    vec->clear();
+    std::set<C2Param::Index> indices;
+
+    std::set<std::string> keyMap(keys.begin(), keys.end());
+
+    ALOGV("in getParamIndicesForKeys with %zu keys and map of %zu entries",
+            keyMap.size(), mMap.size());
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        ALOGV("count of %s is %zu", name.c_str(), keyMap.count(name));
+        if (keyMap.count(name) > 0) {
+            indices.insert(desc.paramDesc->index());
+        }
+    }
+
+    for (const C2Param::Index &index : indices) {
+        vec->push_back(index);
+    }
+}
+
+void ReflectedParamUpdater::updateParamsFromMessage(
+        const Dict &params,
+        std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const {
+    CHECK(vec != nullptr);
+
+    std::map<C2Param::Index, std::unique_ptr<C2Param>*> paramsMap;
+    for (std::unique_ptr<C2Param> &param : *vec) {
+        if (param && *param) {
+            paramsMap[param->index()] = &param;
+        }
+    }
+
+    parseMessageAndDoWork(
+            params,
+            [&paramsMap](const std::string &name, const FieldDesc &desc, const void *ptr, size_t size) {
+                std::unique_ptr<C2Param> *param = nullptr;
+                auto paramIt = paramsMap.find(desc.paramDesc->index());
+                if (paramIt == paramsMap.end()) {
+                    ALOGD("%s found, but param #%d isn't present to update",
+                            name.c_str(), (int32_t)desc.paramDesc->index());
+                    return;
+                }
+                param = paramIt->second;
+
+                struct _C2Param : public C2Param {
+                    using C2Param::C2Param;
+                    _C2Param(uint32_t size, uint32_t index) : C2Param(size, index) { }
+                };
+
+                // we will handle whole param updates as part of a flexible param update using
+                // a zero offset.
+                size_t offset = 0;
+                size_t minOffset = 0;
+
+                // if this descriptor has a field, use the offset and size and ensure that offset
+                // is not part of the header
+                if (desc.fieldDesc) {
+                    minOffset = sizeof(C2Param);
+                    offset = sizeof(C2Param) + desc.offset
+                            + _C2ParamInspector::GetOffset(*desc.fieldDesc);
+                }
+
+                // reallocate or trim flexible param (or whole param) as necessary
+                if (!desc.fieldDesc /* whole param */ || desc.fieldDesc->extent() == 0) {
+                    // reallocate param if more space is needed
+                    if (param->get()->size() < offset + size) {
+                        if (size > INT32_MAX - offset || offset < minOffset) {
+                            // size too long or offset too early - abandon
+                            return;
+                        }
+                        C2Param *newParam = (C2Param *)::operator new(offset + size);
+                        new (newParam) _C2Param(offset + size, param->get()->index());
+                        if (offset > sizeof(C2Param)) {
+                            memcpy(newParam + 1, param->get() + 1, offset - sizeof(C2Param));
+                        }
+                        param->reset(newParam);
+                    } else if (param->get()->size() > offset + size) {
+                        // trim parameter size
+                        _C2ParamInspector::TrimParam(param->get(), offset + size);
+                    }
+                } else if (desc.fieldDesc->type() == C2FieldDescriptor::BLOB) {
+                    // zero fill blobs if updating with smaller blob
+                    if (desc.fieldDesc->extent() > size) {
+                        memset((uint8_t *)(param->get()) + offset + size, 0,
+                               desc.fieldDesc->extent() - size);
+                    }
+                }
+
+                memcpy((uint8_t *)(param->get()) + offset, ptr, size);
+            });
+}
+
+void ReflectedParamUpdater::parseMessageAndDoWork(
+        const Dict &params,
+        std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const {
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        auto param = params.find(name);
+        if (param == params.end()) {
+            continue;
+        }
+
+        // handle whole parameters
+        if (!desc.fieldDesc) {
+            sp<ABuffer> tmp;
+            if (param->second.find(&tmp) && tmp != nullptr) {
+                C2Param *tmpAsParam = C2Param::From(tmp->data(), tmp->size());
+                if (tmpAsParam && tmpAsParam->type().type() == desc.paramDesc->index().type()) {
+                    work(name, desc, tmp->data(), tmp->size());
+                } else {
+                    ALOGD("Param blob does not match param for '%s' (%p, %x vs %x)",
+                            name.c_str(), tmpAsParam, tmpAsParam ? tmpAsParam->type().type() : 0xDEADu,
+                            desc.paramDesc->index().type());
+                }
+            }
+            continue;
+        }
+
+        int32_t int32Value;
+        int64_t int64Value;
+        C2Value c2Value;
+
+        C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
+        size_t fieldExtent = desc.fieldDesc->extent();
+        switch (fieldType) {
+            case C2FieldDescriptor::INT32:
+                if ((param->second.find(&c2Value) && c2Value.get(&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::UINT32:
+                if ((param->second.find(&c2Value) && c2Value.get((uint32_t*)&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::CNTR32:
+                if ((param->second.find(&c2Value) && c2Value.get((c2_cntr32_t*)&int32Value))
+                        || param->second.find(&int32Value)) {
+                    work(name, desc, &int32Value, sizeof(int32Value));
+                }
+                break;
+            case C2FieldDescriptor::INT64:
+                if ((param->second.find(&c2Value) && c2Value.get(&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::UINT64:
+                if ((param->second.find(&c2Value) && c2Value.get((uint64_t*)&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::CNTR64:
+                if ((param->second.find(&c2Value) && c2Value.get((c2_cntr64_t*)&int64Value))
+                        || param->second.find(&int64Value)) {
+                    work(name, desc, &int64Value, sizeof(int64Value));
+                }
+                break;
+            case C2FieldDescriptor::FLOAT: {
+                float tmp;
+                if (param->second.find(&c2Value) && c2Value.get(&tmp)) {
+                    work(name, desc, &tmp, sizeof(tmp));
+                }
+                break;
+            }
+            case C2FieldDescriptor::STRING: {
+                AString tmp;
+                if (!param->second.find(&tmp)) {
+                    break;
+                }
+                if (fieldExtent > 0 && tmp.size() >= fieldExtent) {
+                    AString truncated(tmp, 0, fieldExtent - 1);
+                    ALOGD("String value too long to fit: original \"%s\" truncated to \"%s\"",
+                            tmp.c_str(), truncated.c_str());
+                    tmp = truncated;
+                }
+                work(name, desc, tmp.c_str(), tmp.size() + 1);
+                break;
+            }
+
+            case C2FieldDescriptor::BLOB: {
+                sp<ABuffer> tmp;
+                if (!param->second.find(&tmp) || tmp == nullptr) {
+                    break;
+                }
+
+                if (fieldExtent > 0 && tmp->size() > fieldExtent) {
+                    ALOGD("Blob value too long to fit. Truncating.");
+                    tmp->setRange(tmp->offset(), fieldExtent);
+                }
+                work(name, desc, tmp->data(), tmp->size());
+                break;
+            }
+
+            default:
+                ALOGD("Unsupported data type for %s", name.c_str());
+                break;
+        }
+    }
+}
+
+ReflectedParamUpdater::Dict
+ReflectedParamUpdater::getParams(const std::vector<std::unique_ptr<C2Param>> &params_) const {
+    std::vector<C2Param*> params;
+    params.resize(params_.size());
+    std::transform(params_.begin(), params_.end(), params.begin(),
+                   [](const std::unique_ptr<C2Param>& p) -> C2Param* { return p.get(); });
+    return getParams(params);
+}
+
+ReflectedParamUpdater::Dict
+ReflectedParamUpdater::getParams(const std::vector<C2Param*> &params) const {
+    Dict ret;
+
+    // convert vector to map
+    std::map<C2Param::Index, C2Param *> paramsMap;
+    for (C2Param *param : params) {
+        if (param != nullptr && *param) {
+            paramsMap[param->index()] = param;
+        }
+    }
+
+    for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
+        const std::string &name = kv.first;
+        const FieldDesc &desc = kv.second;
+        if (paramsMap.count(desc.paramDesc->index()) == 0) {
+            continue;
+        }
+        C2Param *param = paramsMap[desc.paramDesc->index()];
+        Value value;
+
+        // handle whole params first
+        if (!desc.fieldDesc) {
+            sp<ABuffer> buf = ABuffer::CreateAsCopy(param, param->size());
+            value.set(buf);
+            ret.emplace(name, value);
+            continue;
+        }
+
+        size_t offset = sizeof(C2Param) + desc.offset
+                + _C2ParamInspector::GetOffset(*desc.fieldDesc);
+        uint8_t *data = (uint8_t *)param + offset;
+        C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
+        switch (fieldType) {
+            case C2FieldDescriptor::STRING: {
+                size_t length = desc.fieldDesc->extent();
+                if (length == 0) {
+                    length = param->size() - offset;
+                }
+
+                if (param->size() < length || param->size() - length < offset) {
+                    ALOGD("param too small for string: length %zu size %zu offset %zu",
+                            length, param->size(), offset);
+                    break;
+                }
+                value.set(AString((char *)data, strnlen((char *)data, length)));
+                break;
+            }
+
+            case C2FieldDescriptor::BLOB: {
+                size_t length = desc.fieldDesc->extent();
+                if (length == 0) {
+                    length = param->size() - offset;
+                }
+
+                if (param->size() < length || param->size() - length < offset) {
+                    ALOGD("param too small for blob: length %zu size %zu offset %zu",
+                            length, param->size(), offset);
+                    break;
+                }
+
+                sp<ABuffer> buf = ABuffer::CreateAsCopy(data, length);
+                value.set(buf);
+                break;
+            }
+
+            default: {
+                size_t valueSize = C2Value::SizeFor((C2Value::type_t)fieldType);
+                if (param->size() < valueSize || param->size() - valueSize < offset) {
+                    ALOGD("param too small for c2value: size %zu offset %zu",
+                            param->size(), offset);
+                    break;
+                }
+
+                C2Value c2Value;
+                switch (fieldType) {
+                    case C2FieldDescriptor::INT32:  c2Value = *((int32_t *)data); break;
+                    case C2FieldDescriptor::UINT32: c2Value = *((uint32_t *)data); break;
+                    case C2FieldDescriptor::CNTR32: c2Value = *((c2_cntr32_t *)data); break;
+                    case C2FieldDescriptor::INT64:  c2Value = *((int64_t *)data); break;
+                    case C2FieldDescriptor::UINT64: c2Value = *((uint64_t *)data); break;
+                    case C2FieldDescriptor::CNTR64: c2Value = *((c2_cntr64_t *)data); break;
+                    case C2FieldDescriptor::FLOAT:  c2Value = *((float *)data); break;
+                    default:
+                        ALOGD("Unsupported data type for %s", name.c_str());
+                        continue;
+                }
+                value.set(c2Value);
+            }
+        }
+        ret.emplace(name, value);
+    }
+    return ret;
+}
+
+void ReflectedParamUpdater::clear() {
+    mMap.clear();
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/ReflectedParamUpdater.h b/media/codec2/sfplugin/ReflectedParamUpdater.h
new file mode 100644
index 0000000..5436ba5
--- /dev/null
+++ b/media/codec2/sfplugin/ReflectedParamUpdater.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 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 REFLECTED_PARAM_BUILDER_H_
+#define REFLECTED_PARAM_BUILDER_H_
+
+#include <map>
+#include <memory>
+
+#include <C2.h>
+#include <C2Param.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AData.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+/**
+ * Utility class to query and update Codec 2.0 configuration values. Use custom dictionary as
+ * AMessage cannot represent all types of Codec 2.0 parameters and C2Value cannot represent
+ * all types of SDK values. We want to be precise when setting standard parameters (use C2Value
+ * for arithmetic values), but also support int32 and int64 for SDK values specifically for
+ * vendor parameters (as SDK API does not allow specifying proper type.) When querying fields,
+ * we can use C2Values as they are defined.
+ *
+ *      Item => Codec 2.0 value mappings:
+ *     CValue::type => type
+ *     int32 => int32, ctr32 or uint32
+ *     int64 => int64, ctr64 or uint64
+ *     AString => string
+ *     ABuffer => blob
+ *     'Rect' => C2RectStruct (not exposed in SDK as a rectangle)
+ */
+class ReflectedParamUpdater {
+public:
+    ReflectedParamUpdater() = default;
+    ~ReflectedParamUpdater() = default;
+
+    /**
+     * Element for values
+     */
+    struct Value : public AData<C2Value, int32_t, int64_t, AString, sp<ABuffer>>::Basic {
+        // allow construction from base types
+        Value() = default;
+        explicit Value(C2Value i)            { set(i); }
+        explicit Value(int32_t i)            { set(i); }
+        explicit Value(int64_t i)            { set(i); }
+        explicit Value(const AString &i)     { set(i); }
+        explicit Value(const sp<ABuffer> &i) { set(i); }
+    };
+
+    struct Dict : public std::map<std::string, Value> {
+        Dict() = default;
+        std::string debugString(size_t indent = 0) const;
+    };
+
+    /**
+     * Enumerates all fields of the parameter descriptors supplied, so that this opbject can later
+     * query and update these.
+     *
+     * For now only first-level fields are supported. Also, array fields are not supported.
+     *
+     * \param reflector   C2ParamReflector object for C2Param reflection.
+     * \param paramDescs  vector of C2ParamDescriptor objects that this object
+     *                    would recognize when building params.
+     */
+    void addParamDesc(
+            const std::shared_ptr<C2ParamReflector> &reflector,
+            const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs);
+
+    /**
+     * Adds fields of a standard parameter (that may not be supported by the parameter reflector
+     * or may not be listed as a supported value by the component). If the parameter name is
+     * used for another parameter, this operation is a no-op. (Technically, this is by fields).
+     *
+     * \param T standard parameter type
+     * \param name parameter name
+     */
+    template<typename T>
+    void addStandardParam(const std::string &name, C2ParamDescriptor::attrib_t attrib =
+                          C2ParamDescriptor::IS_READ_ONLY) {
+        addParamDesc(std::make_shared<C2ParamDescriptor>(
+                C2Param::Index(T::PARAM_TYPE), attrib, name.c_str()),
+                C2StructDescriptor((T*)nullptr), nullptr /* descriptor */);
+    }
+
+    /**
+     * Adds fields of a structure (or a parameater) described by the struct descriptor. If
+     * reflector is provided, fields of sub-structures are also added. Otherwise, only top-level
+     * fundamental typed fields (arithmetic, string and blob) are added.
+     *
+     * \param paramDesc parameter descriptor
+     * \param fieldDesc field descriptor
+     * \param path path/name of the structure (field or parent parameter)
+     * \param offset offset of the structure in the parameter
+     * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
+     */
+    void addParamStructDesc(
+            std::shared_ptr<C2ParamDescriptor> paramDesc, C2String path, size_t offset,
+            const C2StructDescriptor &structDesc,
+            const std::shared_ptr<C2ParamReflector> &reflector);
+
+    /**
+     * Adds fields of a parameter described by the struct descriptor. If reflector is provided,
+     * fields of sub-structures are also added. Otherwise, only top-level fundamental typed fields
+     * (arithmetic, string and blob) are added.
+     *
+     * \param paramDesc parameter descriptor
+     * \param fieldDesc field descriptor
+     * \param reflector  C2ParamReflector object for C2Param reflection (may be null)
+     * \param markVendor TEMP if true, prefix vendor parameter names with "vendor."
+     */
+    void addParamDesc(
+            std::shared_ptr<C2ParamDescriptor> paramDesc, const C2StructDescriptor &structDesc,
+            const std::shared_ptr<C2ParamReflector> &reflector,
+            bool markVendor = true);
+
+    /**
+     * Add support for setting a parameter as a binary blob.
+     *
+     * \param name name of the parameter
+     * \param coreIndex parameter (core) index
+     */
+    void supportWholeParam(std::string name, C2Param::CoreIndex coreIndex);
+
+    /**
+     * Returns the name of the parameter for an index.
+     */
+    std::string getParamName(C2Param::Index index) const;
+
+    /**
+     * Get list of param indices from field names and values in AMessage object.
+     *
+     * TODO: This should be in the order that they are listed by the component.
+     *
+     * \param params[in]  Dict object with field name to value pairs.
+     * \param vec[out]    vector to store the indices from |params|.
+     */
+    void getParamIndicesFromMessage(
+            const Dict &params,
+            std::vector<C2Param::Index> *vec /* nonnull */) const;
+
+    /**
+     * Get list of param indices from field names (only) in AMessage object.
+     *
+     * \param params[in]  Vector object with field names.
+     * \param vec[out]    vector to store the indices from |params|.
+     */
+    void getParamIndicesForKeys(
+            const std::vector<std::string> &keys,
+            std::vector<C2Param::Index> *vec /* nonnull */) const;
+
+    /**
+     * Update C2Param objects from field name and value in AMessage object.
+     *
+     * \param params[in]    Dict object with field name to value pairs.
+     * \param vec[in,out]   vector of the C2Param objects to be updated.
+     */
+    void updateParamsFromMessage(
+            const Dict &params,
+            std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const;
+
+    /**
+     * Get fields from C2Param objects in AMessage object.
+     *
+     * \param params[in]    vector of the C2Param objects to be queried
+     * \return a Dict object containing the known parameters
+     */
+    Dict getParams(
+            const std::vector<C2Param*> &params /* nonnull */) const;
+
+    Dict getParams(
+            const std::vector<std::unique_ptr<C2Param>> &params /* nonnull */) const;
+
+    /**
+     * Clear param descriptors in this object.
+     */
+    void clear();
+
+private:
+    struct FieldDesc {
+        std::shared_ptr<C2ParamDescriptor> paramDesc;
+        std::unique_ptr<C2FieldDescriptor> fieldDesc;
+        size_t offset;
+    };
+    std::map<std::string, FieldDesc> mMap;
+    std::map<C2Param::Index, std::string> mParamNames;
+    std::map<std::string, C2Param::CoreIndex> mWholeParams;
+
+    void parseMessageAndDoWork(
+            const Dict &params,
+            std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const;
+
+    C2_DO_NOT_COPY(ReflectedParamUpdater);
+};
+
+}  // namespace android
+
+#endif  // REFLECTED_PARAM_BUILDER_H_
diff --git a/media/codec2/sfplugin/SkipCutBuffer.cpp b/media/codec2/sfplugin/SkipCutBuffer.cpp
new file mode 100644
index 0000000..5762440
--- /dev/null
+++ b/media/codec2/sfplugin/SkipCutBuffer.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2012 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 "SkipCutBuffer"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/SkipCutBuffer.h>
+
+namespace android {
+
+SkipCutBuffer::SkipCutBuffer(size_t skip, size_t cut, size_t num16BitChannels) {
+
+    mWriteHead = 0;
+    mReadHead = 0;
+    mCapacity = 0;
+    mCutBuffer = nullptr;
+
+    if (num16BitChannels == 0 || num16BitChannels > INT32_MAX / 2) {
+        ALOGW("# channels out of range: %zu, using passthrough instead", num16BitChannels);
+        return;
+    }
+    size_t frameSize = num16BitChannels * 2;
+    if (skip > INT32_MAX / frameSize || cut > INT32_MAX / frameSize
+            || cut * frameSize > INT32_MAX - 4096) {
+        ALOGW("out of range skip/cut: %zu/%zu, using passthrough instead",
+                skip, cut);
+        return;
+    }
+    skip *= frameSize;
+    cut *= frameSize;
+
+    mFrontPadding = mSkip = skip;
+    mBackPadding = cut;
+    mCapacity = cut + 4096;
+    mCutBuffer = new (std::nothrow) char[mCapacity];
+    ALOGV("skipcutbuffer %zu %zu %d", skip, cut, mCapacity);
+}
+
+SkipCutBuffer::~SkipCutBuffer() {
+    delete[] mCutBuffer;
+}
+
+void SkipCutBuffer::submit(MediaBuffer *buffer) {
+    if (mCutBuffer == nullptr) {
+        // passthrough mode
+        return;
+    }
+
+    int32_t offset = buffer->range_offset();
+    int32_t buflen = buffer->range_length();
+
+    // drop the initial data from the buffer if needed
+    if (mFrontPadding > 0) {
+        // still data left to drop
+        int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
+        offset += to_drop;
+        buflen -= to_drop;
+        buffer->set_range(offset, buflen);
+        mFrontPadding -= to_drop;
+    }
+
+
+    // append data to cutbuffer
+    char *src = ((char*) buffer->data()) + offset;
+    write(src, buflen);
+
+
+    // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
+    // at least mBackPadding bytes in the cutbuffer
+    char *dst = (char*) buffer->data();
+    size_t copied = read(dst, buffer->size());
+    buffer->set_range(0, copied);
+}
+
+template <typename T>
+void SkipCutBuffer::submitInternal(const sp<T>& buffer) {
+    if (mCutBuffer == nullptr) {
+        // passthrough mode
+        return;
+    }
+
+    int32_t offset = buffer->offset();
+    int32_t buflen = buffer->size();
+
+    // drop the initial data from the buffer if needed
+    if (mFrontPadding > 0) {
+        // still data left to drop
+        int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
+        offset += to_drop;
+        buflen -= to_drop;
+        buffer->setRange(offset, buflen);
+        mFrontPadding -= to_drop;
+    }
+
+
+    // append data to cutbuffer
+    char *src = (char*) buffer->data();
+    write(src, buflen);
+
+
+    // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
+    // at least mBackPadding bytes in the cutbuffer
+    char *dst = (char*) buffer->base();
+    size_t copied = read(dst, buffer->capacity());
+    buffer->setRange(0, copied);
+}
+
+void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
+    submitInternal(buffer);
+}
+
+void SkipCutBuffer::submit(const sp<MediaCodecBuffer>& buffer) {
+    submitInternal(buffer);
+}
+
+void SkipCutBuffer::clear() {
+    mWriteHead = mReadHead = 0;
+    mFrontPadding = mSkip;
+}
+
+void SkipCutBuffer::write(const char *src, size_t num) {
+    int32_t sizeused = (mWriteHead - mReadHead);
+    if (sizeused < 0) sizeused += mCapacity;
+
+    // Everything must fit. Make sure the buffer is a little larger than needed,
+    // so there is no ambiguity as to whether mWriteHead == mReadHead means buffer
+    // full or empty
+    size_t available = mCapacity - sizeused - 32;
+    if (available < num) {
+        int32_t newcapacity = mCapacity + (num - available);
+        char * newbuffer = new char[newcapacity];
+        memcpy(newbuffer, mCutBuffer, mCapacity);
+        delete [] mCutBuffer;
+        mCapacity = newcapacity;
+        mCutBuffer = newbuffer;
+        ALOGV("reallocated buffer at size %d", newcapacity);
+    }
+
+    size_t copyfirst = (mCapacity - mWriteHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(mCutBuffer + mWriteHead, src, copyfirst);
+        num -= copyfirst;
+        src += copyfirst;
+        mWriteHead += copyfirst;
+        CHECK_LE(mWriteHead, mCapacity);
+        if (mWriteHead == mCapacity) mWriteHead = 0;
+        if (num) {
+            memcpy(mCutBuffer, src, num);
+            mWriteHead += num;
+        }
+    }
+}
+
+size_t SkipCutBuffer::read(char *dst, size_t num) {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+
+    available -= mBackPadding;
+    if (available <=0) {
+        return 0;
+    }
+    if (available < int32_t(num)) {
+        num = available;
+    }
+
+    size_t copyfirst = (mCapacity - mReadHead);
+    if (copyfirst > num) copyfirst = num;
+    if (copyfirst) {
+        memcpy(dst, mCutBuffer + mReadHead, copyfirst);
+        num -= copyfirst;
+        dst += copyfirst;
+        mReadHead += copyfirst;
+        CHECK_LE(mReadHead, mCapacity);
+        if (mReadHead == mCapacity) mReadHead = 0;
+        if (num) {
+            memcpy(dst, mCutBuffer, num);
+            mReadHead += num;
+        }
+    }
+    return available;
+}
+
+size_t SkipCutBuffer::size() {
+    int32_t available = (mWriteHead - mReadHead);
+    if (available < 0) available += mCapacity;
+    return available;
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/SkipCutBuffer.h b/media/codec2/sfplugin/SkipCutBuffer.h
new file mode 100644
index 0000000..0fb5690
--- /dev/null
+++ b/media/codec2/sfplugin/SkipCutBuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 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 SKIP_CUT_BUFFER_H_
+
+#define SKIP_CUT_BUFFER_H_
+
+#include <media/MediaCodecBuffer.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/foundation/ABuffer.h>
+
+namespace android {
+
+/**
+ * utility class to cut the start and end off a stream of data in MediaBuffers
+ *
+ */
+class SkipCutBuffer: public RefBase {
+ public:
+    // 'skip' is the number of frames to skip from the beginning
+    // 'cut' is the number of frames to cut from the end
+    // 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each
+    SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels);
+
+    // Submit one MediaBuffer for skipping and cutting. This may consume all or
+    // some of the data in the buffer, or it may add data to it.
+    // After this, the caller should continue processing the buffer as usual.
+    void submit(MediaBuffer *buffer);
+    void submit(const sp<ABuffer>& buffer);    // same as above, but with an ABuffer
+    void submit(const sp<MediaCodecBuffer>& buffer);    // same as above, but with an ABuffer
+    void clear();
+    size_t size(); // how many bytes are currently stored in the buffer
+
+ protected:
+    virtual ~SkipCutBuffer();
+
+ private:
+    void write(const char *src, size_t num);
+    size_t read(char *dst, size_t num);
+    template <typename T>
+    void submitInternal(const sp<T>& buffer);
+    int32_t mSkip;
+    int32_t mFrontPadding;
+    int32_t mBackPadding;
+    int32_t mWriteHead;
+    int32_t mReadHead;
+    int32_t mCapacity;
+    char* mCutBuffer;
+    DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
+};
+
+}  // namespace android
+
+#endif  // OMX_CODEC_H_
diff --git a/media/codec2/sfplugin/tests/Android.bp b/media/codec2/sfplugin/tests/Android.bp
new file mode 100644
index 0000000..b08d3d6
--- /dev/null
+++ b/media/codec2/sfplugin/tests/Android.bp
@@ -0,0 +1,52 @@
+cc_test {
+    name: "ccodec_test",
+
+    srcs: [
+        "ReflectedParamUpdater_test.cpp",
+    ],
+
+    include_dirs: [
+        "hardware/google/av/media/sfplugin",
+    ],
+
+    shared_libs: [
+        "libstagefright_ccodec",
+        "libstagefright_codec2",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
+
+cc_test {
+    name: "mc_sanity",
+
+    srcs: [
+        "MediaCodec_sanity_test.cpp",
+    ],
+
+    include_dirs: [
+        "hardware/google/av/media/sfplugin",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libgui",
+        "libmedia",
+        "libmedia_omx",
+        "libstagefright",
+        "libstagefright_ccodec",
+        "libstagefright_codec2",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
new file mode 100644
index 0000000..ba3687b
--- /dev/null
+++ b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
@@ -0,0 +1,453 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+
+#include <algorithm>
+
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <gui/Surface.h>
+#include <media/ICrypto.h>
+#include <media/MediaCodecBuffer.h>
+#include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+class MediaCodecSanityTest : public ::testing::Test {
+public:
+    MediaCodecSanityTest()
+        : looper(new ALooper),
+          cfg(new AMessage),
+          ifmt(new AMessage),
+          ofmt(new AMessage) {
+        ProcessState::self()->startThreadPool();
+        looper->start();
+    }
+
+    ~MediaCodecSanityTest() {
+        if (codec != nullptr) {
+            codec->release();
+        }
+        looper->stop();
+    }
+
+    sp<ALooper> looper;
+    sp<MediaCodec> codec;
+    sp<AMessage> cfg;
+    sp<AMessage> ifmt;
+    sp<AMessage> ofmt;
+};
+
+const static size_t kLinearBufferSize = 1048576;
+
+// data for a codec input frame
+struct FrameData {
+    const uint8_t *data;
+    size_t size;
+    template<size_t N>
+    constexpr FrameData(const uint8_t(&data_)[N]) : data(data_), size(N) { }
+};
+
+// one yellow frame of 240x180 (albeit 4:4:4)
+const uint8_t avcStream_A1[] = { // IDR frame
+    0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0d, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
+    0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xf1, 0x42, 0x99, 0x60,
+
+    0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
+
+    0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x2b, 0xff, 0xfe, 0xd8, 0xe7, 0xf3, 0x2c, 0xa5, 0x60,
+    0xca, 0xbb, 0xf1, 0x5c, 0x44, 0x7c, 0x9a, 0xa5, 0xc3, 0xab, 0x2f, 0x77, 0x0a, 0x94, 0x0d, 0x19,
+    0x43, 0x3b, 0x4f, 0x25, 0xea, 0x66, 0x00, 0x01, 0x24, 0xcd, 0x35, 0x5f, 0xc2, 0x34, 0x89, 0xd1,
+    0xa5, 0x60, 0x09, 0x98, 0x00, 0x01, 0x1b, 0x0e, 0xcb, 0x0d, 0x04, 0x86, 0x94, 0xe2, 0x32, 0x3c,
+    0xdd, 0x0f,
+};
+
+FrameData avcStream_A[] __unused = { avcStream_A1 };
+
+// AVC stream of 2 yellow frames (240x180)
+const uint8_t avcStream_B1[] = { // IDR frame
+    0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0c, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
+    0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x02, 0x80, 0xf1, 0x42, 0x99, 0x60,
+
+    0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
+
+    0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x33, 0xff, 0xfe, 0xdf, 0x32, 0xf8, 0x14, 0xd6, 0x25,
+    0xd0, 0x74, 0x42, 0x50, 0x84, 0x6f, 0xf4, 0xc2, 0x5c, 0x76, 0x37, 0x17, 0x72, 0xac, 0x52, 0xfc,
+    0xd6, 0x1f, 0xd2, 0xd0, 0x60, 0xb2, 0x20, 0x00, 0x10, 0x3d, 0x2a, 0xc0, 0xe4, 0x27, 0xcb, 0xce,
+    0xea, 0x25, 0x00, 0x81, 0x00, 0x00, 0x0f, 0x40, 0xbc, 0x81, 0x15, 0xc1, 0x65, 0x20, 0x80, 0x81,
+    0x7a, 0x57, 0x51,
+};
+
+const uint8_t avcStream_B2[] = { // P frame
+    0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0xbf, 0xfe, 0x38, 0x40, 0x00, 0x0d, 0x48,
+};
+
+FrameData avcStream_B[] = { avcStream_B1, avcStream_B2 };
+
+class MediaCodecInputBufferSizeTest : public MediaCodecSanityTest,
+        public ::testing::WithParamInterface<int32_t> {
+};
+
+TEST_P(MediaCodecInputBufferSizeTest, TestAvcDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+    if (InputSize > 0) {
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
+    }
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+TEST_P(MediaCodecInputBufferSizeTest, TestVideoDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.vp8.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_VP8);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+    if (InputSize > 0) {
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
+    }
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+TEST_P(MediaCodecInputBufferSizeTest, TestAudioDecoder) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.aac.decoder");
+    cfg->setInt32("sample-rate", 44100);
+    cfg->setInt32("channel-count", 2);
+    cfg->setString("mime", MIMETYPE_AUDIO_AAC);
+
+    const int32_t InputSize = GetParam();
+    if (InputSize >= 0) {
+        cfg->setInt32("max-input-size", InputSize);
+    }
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
+    int32_t maxInputSize;
+    if (InputSize > 0) {
+        ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
+        EXPECT_EQ(maxInputSize, InputSize);
+    } else {
+        if (ifmt->findInt32("max-input-size", &maxInputSize)) {
+            EXPECT_EQ(maxInputSize, 1 << 19); // 512 KB
+        }
+        maxInputSize = kLinearBufferSize; // input size is set by channel
+    }
+
+    EXPECT_EQ(codec->start(),  OK);
+    size_t ix;
+    EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+    sp<MediaCodecBuffer> buf;
+    EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+    EXPECT_GE(buf->size(), (size_t)maxInputSize);
+    EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
+}
+
+INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecInputBufferSizeTest, ::testing::Values(-1, 1234, 12345678));
+
+TEST_F(MediaCodecSanityTest, TestAvcDecoderHdrStaticInfo) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+    HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
+        .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
+        .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
+        .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
+        .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
+    };
+    cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    sp<ABuffer> oinfo;
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+
+    EXPECT_EQ(codec->start(),  OK);
+    // assume we can submit all input before dequeuing output
+    size_t frameIx = 0;
+    size_t ix;
+    sp<MediaCodecBuffer> buf;
+    for (const FrameData &frame : avcStream_B) {
+        EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+        EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+        ASSERT_GE(buf->capacity(), frame.size);
+        memcpy(buf->base(), frame.data, frame.size);
+        EXPECT_EQ(buf->setRange(0, frame.size), OK);
+        bool eos = ++frameIx == NELEM(avcStream_B);
+        EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
+                                          eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
+    }
+
+    size_t offset, size;
+    int64_t ts;
+    uint32_t flags;
+    bool mInfoFormatChangedOk = true;
+    bool mInfoBuffersChangedOk = true;
+    while (true) {
+        status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
+        if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
+            mInfoFormatChangedOk = false;
+        } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
+            mInfoBuffersChangedOk = false;
+        } else {
+            ASSERT_EQ(err, OK);
+            break;
+        }
+    }
+    EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
+    EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+}
+
+TEST_F(MediaCodecSanityTest, TestVideoDecoderHdrStaticInfo) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.mpeg4.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_MPEG4);
+    HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
+        .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500,  .y = 39850 },
+        .mB = { .x = 6550,  .y =  2300 }, .mW = { .x = 15635, .y = 16450 },
+        .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
+        .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
+    };
+    cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    sp<ABuffer> oinfo;
+    ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
+    ASSERT_EQ(oinfo->size(), sizeof(info));
+    EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)),  0);
+}
+
+class MediaCodecByteBufferTest : public MediaCodecSanityTest,
+        public ::testing::WithParamInterface<int32_t> {
+};
+
+TEST_P(MediaCodecByteBufferTest, TestVideoDecoder420Planar) {
+    codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
+//    codec = MediaCodec::CreateByComponentName(looper, "OMX.google.h264.decoder");
+    cfg->setInt32("width", 320);
+    cfg->setInt32("height", 240);
+    cfg->setString("mime", MIMETYPE_VIDEO_AVC);
+    const int32_t Color = GetParam();
+    if (Color >= 0) {
+        cfg->setInt32("color-format", Color);
+    }
+    int32_t xcolor = Color == -1 ? COLOR_FormatYUV420Planar : Color;
+
+    EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
+    EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
+    int32_t ocolor = -1;
+    EXPECT_TRUE(ofmt->findInt32("color-format", &ocolor));
+    EXPECT_EQ(ocolor, xcolor);
+
+    EXPECT_EQ(codec->start(),  OK);
+    // assume we can submit all input before dequeuing output
+    size_t frameIx = 0;
+    size_t ix;
+    sp<MediaCodecBuffer> buf;
+    for (const FrameData &frame : avcStream_A) {
+        EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
+        EXPECT_EQ(codec->getInputBuffer(ix, &buf),  OK);
+        ASSERT_GE(buf->capacity(), frame.size);
+        memcpy(buf->base(), frame.data, frame.size);
+        EXPECT_EQ(buf->setRange(0, frame.size), OK);
+        bool eos = ++frameIx == NELEM(avcStream_A);
+        EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
+                                          eos ? BUFFER_FLAG_END_OF_STREAM : 0),  OK);
+    }
+
+    size_t offset, size;
+    int64_t ts;
+    uint32_t flags;
+    bool mInfoFormatChangedOk = true;
+    bool mInfoBuffersChangedOk = true;
+    while (true) {
+        status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
+        if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
+            mInfoFormatChangedOk = false;
+        } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
+            mInfoBuffersChangedOk = false;
+        } else {
+            ASSERT_EQ(err, OK);
+            break;
+        }
+    }
+    EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
+    EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
+    ASSERT_TRUE(ofmt->findInt32("color-format", &ocolor));
+    EXPECT_EQ(ocolor, xcolor) << ofmt->debugString(8).c_str() << buf->meta()->debugString(8).c_str();
+    // expect an image-data in both format and meta
+    sp<ABuffer> imgBuf, imgBuf2;
+    ASSERT_TRUE(ofmt->findBuffer("image-data", &imgBuf));
+    ASSERT_TRUE(buf->meta()->findBuffer("image-data", &imgBuf2));
+    EXPECT_EQ(imgBuf->size(), sizeof(MediaImage2));
+    ASSERT_EQ(imgBuf->size(), imgBuf2->size());
+    EXPECT_EQ(0, memcmp(imgBuf->data(), imgBuf2->data(), imgBuf->size()));
+    MediaImage2 *img = (MediaImage2*)imgBuf->data();
+    EXPECT_EQ(img->mType, img->MEDIA_IMAGE_TYPE_YUV);
+    EXPECT_EQ(img->mNumPlanes, 3u);
+    EXPECT_EQ(img->mWidth, 320u);
+    EXPECT_EQ(img->mHeight, 240u);
+    EXPECT_EQ(img->mBitDepth, 8u);
+    EXPECT_EQ(img->mBitDepthAllocated, 8u);
+
+    // read strides from format
+    int32_t stride, vstride;
+    ofmt->findInt32("stride", &stride)          || ofmt->findInt32("width", &stride);
+    ofmt->findInt32("slice-height", &vstride)   || ofmt->findInt32("height", &vstride);
+
+    EXPECT_EQ(img->mPlane[img->Y].mHorizSubsampling, 1u);
+    EXPECT_EQ(img->mPlane[img->Y].mVertSubsampling, 1u);
+    EXPECT_EQ(img->mPlane[img->U].mHorizSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->U].mVertSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->V].mHorizSubsampling, 2u);
+    EXPECT_EQ(img->mPlane[img->V].mVertSubsampling, 2u);
+
+    switch (xcolor) {
+        // defined formats
+        case COLOR_FormatYUV420Planar:
+        case COLOR_FormatYUV420PackedPlanar:
+            EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
+            EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
+            EXPECT_EQ(img->mPlane[img->U].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->U].mRowInc, stride / 2);
+
+            EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride * 5 / 4));
+            EXPECT_EQ(img->mPlane[img->V].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->V].mRowInc, stride / 2);
+
+            EXPECT_GE(size, (size_t)(stride * vstride * 5 / 4 + stride / 2 * 119 + 160));
+            EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
+            break;
+
+        case COLOR_FormatYUV420SemiPlanar:
+        case COLOR_FormatYUV420PackedSemiPlanar:
+            EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
+            EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
+            EXPECT_EQ(img->mPlane[img->U].mColInc, 2);
+            EXPECT_EQ(img->mPlane[img->U].mRowInc, stride);
+
+            EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride + 1));
+            EXPECT_EQ(img->mPlane[img->V].mColInc, 2);
+            EXPECT_EQ(img->mPlane[img->V].mRowInc, stride);
+
+            EXPECT_GE(size, (size_t)(stride * vstride + stride * 119 + 320));
+            EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
+            break;
+
+        case COLOR_FormatYUV420Flexible:
+            // anything goes, but stride should match Y plane
+            EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
+
+            EXPECT_GE(size,
+                      std::max({
+                            img->mPlane[img->Y].mOffset + 239 * img->mPlane[img->Y].mRowInc
+                                    + 319 * img->mPlane[img->Y].mColInc + 1,
+                            img->mPlane[img->U].mOffset + 119 * img->mPlane[img->U].mRowInc
+                                    + 159 * img->mPlane[img->U].mColInc + 1,
+                            img->mPlane[img->V].mOffset + 119 * img->mPlane[img->V].mRowInc
+                                    + 159 * img->mPlane[img->V].mColInc + 1 }));
+            break;
+
+        default:
+            break;
+    }
+
+    // validate all pixels
+#if 0
+    fprintf(stderr, "MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }\n",
+            img->mWidth, img->mHeight,
+            img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
+            img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
+            img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
+#endif
+    for (ix = 0; ix < 3; ++ix) {
+        const static uint8_t expected[] = { 210, 16, 146 };
+        for (uint32_t y = 0; y < img->mHeight / img->mPlane[ix].mVertSubsampling ; ++y) {
+            for (uint32_t x = 0; x < img->mWidth / img->mPlane[ix].mHorizSubsampling; ++x) {
+                uint8_t val = buf->data()[img->mPlane[ix].mOffset + img->mPlane[ix].mColInc * x
+                        + img->mPlane[ix].mRowInc * y];
+                ASSERT_EQ(val, expected[ix]) << "incorrect value for plane "
+                        << ix << " at x=" << x << ", y=" << y;
+            }
+        }
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecByteBufferTest, ::testing::Values(
+        -1,
+        COLOR_FormatYUV420Planar,
+        COLOR_FormatYUV420SemiPlanar,
+        COLOR_FormatYUV420PackedPlanar,
+        COLOR_FormatYUV420PackedSemiPlanar,
+        COLOR_FormatYUV420Flexible));
+
+} // namespace android
diff --git a/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp b/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp
new file mode 100644
index 0000000..c7db0e3
--- /dev/null
+++ b/media/codec2/sfplugin/tests/ReflectedParamUpdater_test.cpp
@@ -0,0 +1,352 @@
+/*
+ * 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.
+ */
+
+#define __C2_GENERATE_GLOBAL_VARS__
+
+#include <set>
+
+#include <gtest/gtest.h>
+
+#include <C2ParamDef.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <ReflectedParamUpdater.h>
+
+namespace android {
+
+namespace {
+
+enum {
+    kParamIndexTestStart = 0x1000,
+    kParamIndexInt,
+    kParamIndexString,
+    kParamIndexComposite,
+    kParamIndexFlexString,
+
+    kParamIndexLong = C2Param::TYPE_INDEX_VENDOR_START,
+};
+
+typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexInt> C2IntInfo;
+typedef C2GlobalParam<C2Info, C2Int64Value, kParamIndexLong> C2LongInfo;
+
+struct C2FixedSizeStringStruct {
+    char value[12];
+
+    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(FixedSizeString)
+    C2FIELD(value, "value")
+};
+typedef C2GlobalParam<C2Info, C2FixedSizeStringStruct, kParamIndexString> C2StringInfo;
+
+struct C2CompositeStruct {
+    int32_t i32;
+    uint64_t u64;
+    char str[12];
+    uint8_t blob[8];
+    uint8_t flexBlob[];
+
+    C2CompositeStruct() = default;
+
+    DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(Composite, flexBlob)
+    C2FIELD(i32, "i32")
+    C2FIELD(u64, "u64")
+    C2FIELD(str, "str")
+    C2FIELD(blob, "blob")
+    C2FIELD(flexBlob, "flex-blob")
+};
+static_assert(C2CompositeStruct::FLEX_SIZE == 1, "");
+static_assert(_C2FlexHelper<C2CompositeStruct>::FLEX_SIZE == 1, "");
+typedef C2GlobalParam<C2Info, C2CompositeStruct, kParamIndexComposite> C2CompositeInfo;
+
+typedef C2GlobalParam<C2Info, C2StringValue, kParamIndexFlexString> C2FlexStringInfo;
+
+#define SUPPORTED_TYPES   \
+    C2IntInfo,            \
+    C2LongInfo,           \
+    C2StringInfo,         \
+    C2CompositeInfo,      \
+    C2FlexStringInfo
+
+template<typename... TYPES> struct describe_impl;
+template<typename T, typename... TYPES> struct describe_impl<T, TYPES...> {
+    static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex index) {
+        if (index == T::CORE_INDEX) {
+            return std::make_unique<C2StructDescriptor>(T::CORE_INDEX, T::FieldList());
+        } else {
+            return describe_impl<TYPES...>::describe(index);
+        }
+    }
+};
+
+template<> struct describe_impl<> {
+    static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex) {
+        return nullptr;
+    }
+};
+
+template<typename T> const char *GetName()        { return nullptr; }
+template<> const char *GetName<C2IntInfo>()       { return "int"; }
+template<> const char *GetName<C2LongInfo>()      { return "long"; }
+template<> const char *GetName<C2StringInfo>()    { return "string"; }
+template<> const char *GetName<C2CompositeInfo>() { return "composite"; }
+template<> const char *GetName<C2FlexStringInfo>() { return "flex-string"; }
+
+template<typename... TYPES> struct fill_descriptors_impl;
+template<typename T, typename... TYPES> struct fill_descriptors_impl<T, TYPES...> {
+    static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *vec) {
+        fill_descriptors_impl<TYPES...>::fill(vec);
+        vec->push_back(std::make_shared<C2ParamDescriptor>(
+                T::PARAM_TYPE, C2ParamDescriptor::IS_PERSISTENT, GetName<T>()));
+    }
+};
+
+template<> struct fill_descriptors_impl<> {
+    static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *) {}
+};
+
+template<typename T> T *CastParam(const std::unique_ptr<C2Param> &param) {
+    return (T *)param.get();
+}
+
+class ParamReflector : public C2ParamReflector {
+public:
+    ParamReflector() = default;
+    ~ParamReflector() override = default;
+
+    std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex paramIndex) const override {
+        return describe_impl<SUPPORTED_TYPES>::describe(paramIndex);
+    }
+};
+
+}  // namespace
+
+class ReflectedParamUpdaterTest : public ::testing::Test {
+public:
+    ReflectedParamUpdaterTest() : mReflector(new ParamReflector) {
+        fill_descriptors_impl<SUPPORTED_TYPES>::fill(&mDescriptors);
+    }
+
+    std::shared_ptr<C2ParamReflector> mReflector;
+    std::vector<std::shared_ptr<C2ParamDescriptor>> mDescriptors;
+};
+
+TEST_F(ReflectedParamUpdaterTest, SingleValueTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("int.value", int32_t(12));
+    msg.emplace("vendor.long.value", int64_t(34));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(new C2IntInfo);
+    params.emplace_back(new C2LongInfo);
+    EXPECT_EQ(0, CastParam<C2IntInfo>(params[0])->value);
+    EXPECT_EQ(0, CastParam<C2LongInfo>(params[1])->value);
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(12, CastParam<C2IntInfo>(params[0])->value);
+    EXPECT_EQ(34, CastParam<C2LongInfo>(params[1])->value);
+
+    C2Value c2Value;
+    int32_t int32Value = 0;
+    int64_t int64Value = 0;
+    msg = updater.getParams(params);
+    ASSERT_EQ(1u, msg.count("int.value"));
+    EXPECT_EQ(true, msg["int.value"].find(&c2Value));
+    EXPECT_EQ(true, c2Value.get(&int32Value));
+    EXPECT_EQ(12, int32Value);
+
+    ASSERT_EQ(1u, msg.count("vendor.long.value"));
+    EXPECT_EQ(true, msg["vendor.long.value"].find(&c2Value));
+    EXPECT_EQ(true, c2Value.get(&int64Value));
+    EXPECT_EQ(34, int64Value);
+}
+
+TEST_F(ReflectedParamUpdaterTest, StringTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("string.value", AString("56"));
+    msg.emplace("flex-string.value", AString("Some string"));
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(new C2StringInfo);
+    EXPECT_EQ(0, CastParam<C2StringInfo>(params[0])->value[0]);
+    params.emplace_back(C2FlexStringInfo::AllocUnique(0));
+    EXPECT_EQ(0u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
+    char *flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_STREQ("56", CastParam<C2StringInfo>(params[0])->value);
+    EXPECT_EQ(12u, CastParam<C2FlexStringInfo>(params[0])->flexCount());
+    EXPECT_STREQ("Some string", CastParam<C2FlexStringInfo>(params[1])->m.value);
+    EXPECT_NE(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
+    flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
+
+    // verify truncation and in-place update
+    msg["string.value"] = ReflectedParamUpdater::Value(AString("1234567890ABCDE"));
+    msg["flex-string.value"] = ReflectedParamUpdater::Value(AString("abc"));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_STREQ("1234567890A", CastParam<C2StringInfo>(params[0])->value);
+    EXPECT_EQ(4u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
+    EXPECT_STREQ("abc", CastParam<C2FlexStringInfo>(params[1])->m.value);
+    EXPECT_EQ(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
+
+    AString strValue;
+    msg = updater.getParams(params);
+    ASSERT_EQ(1u, msg.count("string.value"));
+    EXPECT_EQ(true, msg["string.value"].find(&strValue));
+    EXPECT_STREQ("1234567890A", strValue.c_str());
+
+    ASSERT_EQ(1u, msg.count("flex-string.value"));
+    EXPECT_EQ(true, msg["flex-string.value"].find(&strValue));
+    EXPECT_STREQ("abc", strValue.c_str());
+}
+
+TEST_F(ReflectedParamUpdaterTest, CompositeTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("composite.i32", int32_t(78));
+    msg.emplace("composite.u64", int64_t(910));
+    msg.emplace("composite.str", AString("1112"));
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("buffer08", 8));
+    msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("flex-buffer-14", 14));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(C2CompositeInfo::AllocUnique(0));
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
+    EXPECT_EQ(0, memcmp("\0\0\0\0\0\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    uint8_t *flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(78, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(910u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_STREQ("1112", CastParam<C2CompositeInfo>(params[0])->m.str);
+    EXPECT_EQ(0, memcmp("buffer08", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    AString hex;
+    hexdump(CastParam<C2CompositeInfo>(params[0])->m.blob, 8, 0, &hex);
+    printf("%s\n", hex.c_str());
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_NE(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+    flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
+
+    // test setting and zero extending shorter blob than allowed
+    msg.clear();
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("buf05", 5));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(0, memcmp("buf05\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+
+    // test setting and trimming larger blob than allowed
+    msg.clear();
+    msg.emplace("composite.blob", ABuffer::CreateAsCopy("ReallyLongBuffer", 16));
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(0, memcmp("ReallyLo", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
+    ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+
+    // test trimming flex blob in-place
+    msg.clear();
+    msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("buf05", 5));
+    updater.updateParamsFromMessage(msg, &params);
+    ASSERT_EQ(5u, CastParam<C2CompositeInfo>(params[0])->flexCount());
+    EXPECT_EQ(0, memcmp("buf05", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 5));
+    EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
+}
+
+TEST_F(ReflectedParamUpdaterTest, CompositePartialTest) {
+    ReflectedParamUpdater updater;
+
+    ReflectedParamUpdater::Dict msg;
+    msg.emplace("composite.i32", C2Value(1314));
+    msg.emplace("composite.str", AString("1516"));
+
+    updater.addParamDesc(mReflector, mDescriptors);
+
+    std::vector<C2Param::Index> indices;
+    updater.getParamIndicesFromMessage(msg, &indices);
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
+    EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
+    EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
+            [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
+
+    std::vector<std::unique_ptr<C2Param>> params;
+    params.emplace_back(C2CompositeInfo::AllocUnique(12u));
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
+
+    updater.updateParamsFromMessage(msg, &params);
+    EXPECT_EQ(1314, CastParam<C2CompositeInfo>(params[0])->m.i32);
+    EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
+    EXPECT_STREQ("1516", CastParam<C2CompositeInfo>(params[0])->m.str);
+}
+
+} // namespace android
diff --git a/media/codec2/sfplugin/utils/Android.bp b/media/codec2/sfplugin/utils/Android.bp
new file mode 100644
index 0000000..3dc6060
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Android.bp
@@ -0,0 +1,39 @@
+cc_library_shared {
+    name: "libstagefright_ccodec_utils",
+    vendor_available: true,
+
+    srcs: [
+        "Codec2BufferUtils.cpp",
+        "Codec2Mapper.cpp",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    export_include_dirs: [
+        ".",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "liblog",
+        "libstagefright_codec2",
+        "libstagefright_codec2_vndk",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        diag: {
+            cfi: true,
+        },
+    },
+}
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
new file mode 100644
index 0000000..b7519da
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -0,0 +1,400 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2BufferUtils"
+#include <utils/Log.h>
+
+#include <list>
+#include <mutex>
+
+#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2Debug.h>
+
+#include "Codec2BufferUtils.h"
+
+namespace android {
+
+namespace {
+
+/**
+ * A flippable, optimizable memcpy. Constructs such as (from ? src : dst) do not work as the results are
+ * always const.
+ */
+template<bool ToA, size_t S>
+struct MemCopier {
+    template<typename A, typename B>
+    inline static void copy(A *a, const B *b, size_t size) {
+        __builtin_memcpy(a, b, size);
+    }
+};
+
+template<size_t S>
+struct MemCopier<false, S> {
+    template<typename A, typename B>
+    inline static void copy(const A *a, B *b, size_t size) {
+        MemCopier<true, S>::copy(b, a, size);
+    }
+};
+
+/**
+ * Copies between a MediaImage and a graphic view.
+ *
+ * \param ToMediaImage whether to copy to (or from) the MediaImage
+ * \param view graphic view (could be ConstGraphicView or GraphicView depending on direction)
+ * \param img MediaImage data
+ * \param imgBase base of MediaImage (could be const uint8_t* or uint8_t* depending on direction)
+ */
+template<bool ToMediaImage, typename View, typename ImagePixel>
+static status_t _ImageCopy(View &view, const MediaImage2 *img, ImagePixel *imgBase) {
+    // TODO: more efficient copying --- e.g. one row at a time, copying
+    //       interleaved planes together, etc.
+    const C2PlanarLayout &layout = view.layout();
+    const size_t bpp = divUp(img->mBitDepthAllocated, 8u);
+    if (view.width() != img->mWidth
+            || view.height() != img->mHeight) {
+        return BAD_VALUE;
+    }
+    for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+        typename std::conditional<ToMediaImage, uint8_t, const uint8_t>::type *imgRow =
+            imgBase + img->mPlane[i].mOffset;
+        typename std::conditional<ToMediaImage, const uint8_t, uint8_t>::type *viewRow =
+            viewRow = view.data()[i];
+        const C2PlaneInfo &plane = layout.planes[i];
+        if (plane.colSampling != img->mPlane[i].mHorizSubsampling
+                || plane.rowSampling != img->mPlane[i].mVertSubsampling
+                || plane.allocatedDepth != img->mBitDepthAllocated
+                || plane.allocatedDepth < plane.bitDepth
+                // MediaImage only supports MSB values
+                || plane.rightShift != plane.allocatedDepth - plane.bitDepth
+                || (bpp > 1 && plane.endianness != plane.NATIVE)) {
+            return BAD_VALUE;
+        }
+
+        uint32_t planeW = img->mWidth / plane.colSampling;
+        uint32_t planeH = img->mHeight / plane.rowSampling;
+        for (uint32_t row = 0; row < planeH; ++row) {
+            decltype(imgRow) imgPtr = imgRow;
+            decltype(viewRow) viewPtr = viewRow;
+            for (uint32_t col = 0; col < planeW; ++col) {
+                MemCopier<ToMediaImage, 0>::copy(imgPtr, viewPtr, bpp);
+                imgPtr += img->mPlane[i].mColInc;
+                viewPtr += plane.colInc;
+            }
+            imgRow += img->mPlane[i].mRowInc;
+            viewRow += plane.rowInc;
+        }
+    }
+    return OK;
+}
+
+}  // namespace
+
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view) {
+    return _ImageCopy<true>(view, img, imgBase);
+}
+
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img) {
+    return _ImageCopy<false>(view, img, imgBase);
+}
+
+bool IsYUV420(const C2GraphicView &view) {
+    const C2PlanarLayout &layout = view.layout();
+    return (layout.numPlanes == 3
+            && layout.type == C2PlanarLayout::TYPE_YUV
+            && layout.planes[layout.PLANE_Y].channel == C2PlaneInfo::CHANNEL_Y
+            && layout.planes[layout.PLANE_Y].allocatedDepth == 8
+            && layout.planes[layout.PLANE_Y].bitDepth == 8
+            && layout.planes[layout.PLANE_Y].rightShift == 0
+            && layout.planes[layout.PLANE_Y].colSampling == 1
+            && layout.planes[layout.PLANE_Y].rowSampling == 1
+            && layout.planes[layout.PLANE_U].channel == C2PlaneInfo::CHANNEL_CB
+            && layout.planes[layout.PLANE_U].allocatedDepth == 8
+            && layout.planes[layout.PLANE_U].bitDepth == 8
+            && layout.planes[layout.PLANE_U].rightShift == 0
+            && layout.planes[layout.PLANE_U].colSampling == 2
+            && layout.planes[layout.PLANE_U].rowSampling == 2
+            && layout.planes[layout.PLANE_V].channel == C2PlaneInfo::CHANNEL_CR
+            && layout.planes[layout.PLANE_V].allocatedDepth == 8
+            && layout.planes[layout.PLANE_V].bitDepth == 8
+            && layout.planes[layout.PLANE_V].rightShift == 0
+            && layout.planes[layout.PLANE_V].colSampling == 2
+            && layout.planes[layout.PLANE_V].rowSampling == 2);
+}
+
+MediaImage2 CreateYUV420PlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
+    return MediaImage2 {
+        .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
+        .mNumPlanes = 3,
+        .mWidth = width,
+        .mHeight = height,
+        .mBitDepth = 8,
+        .mBitDepthAllocated = 8,
+        .mPlane = {
+            {
+                .mOffset = 0,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 1,
+                .mVertSubsampling = 1,
+            },
+            {
+                .mOffset = stride * vstride,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride / 2,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            },
+            {
+                .mOffset = stride * vstride * 5 / 4,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride / 2,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            }
+        },
+    };
+}
+
+MediaImage2 CreateYUV420SemiPlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
+    return MediaImage2 {
+        .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
+        .mNumPlanes = 3,
+        .mWidth = width,
+        .mHeight = height,
+        .mBitDepth = 8,
+        .mBitDepthAllocated = 8,
+        .mPlane = {
+            {
+                .mOffset = 0,
+                .mColInc = 1,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 1,
+                .mVertSubsampling = 1,
+            },
+            {
+                .mOffset = stride * vstride,
+                .mColInc = 2,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            },
+            {
+                .mOffset = stride * vstride + 1,
+                .mColInc = 2,
+                .mRowInc = (int32_t)stride,
+                .mHorizSubsampling = 2,
+                .mVertSubsampling = 2,
+            }
+        },
+    };
+}
+
+status_t ConvertRGBToPlanarYUV(
+        uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
+        const C2GraphicView &src) {
+    CHECK(dstY != nullptr);
+    CHECK((src.width() & 1) == 0);
+    CHECK((src.height() & 1) == 0);
+
+    if (dstStride * dstVStride * 3 / 2 > bufferSize) {
+        ALOGD("conversion buffer is too small for converting from RGB to YUV");
+        return NO_MEMORY;
+    }
+
+    uint8_t *dstU = dstY + dstStride * dstVStride;
+    uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
+
+    const C2PlanarLayout &layout = src.layout();
+    const uint8_t *pRed   = src.data()[C2PlanarLayout::PLANE_R];
+    const uint8_t *pGreen = src.data()[C2PlanarLayout::PLANE_G];
+    const uint8_t *pBlue  = src.data()[C2PlanarLayout::PLANE_B];
+
+#define CLIP3(x,y,z) (((z) < (x)) ? (x) : (((z) > (y)) ? (y) : (z)))
+    for (size_t y = 0; y < src.height(); ++y) {
+        for (size_t x = 0; x < src.width(); ++x) {
+            uint8_t red = *pRed;
+            uint8_t green = *pGreen;
+            uint8_t blue = *pBlue;
+
+            // using ITU-R BT.601 conversion matrix
+            unsigned luma =
+                CLIP3(0, (((red * 66 + green * 129 + blue * 25) >> 8) + 16), 255);
+
+            dstY[x] = luma;
+
+            if ((x & 1) == 0 && (y & 1) == 0) {
+                unsigned U =
+                    CLIP3(0, (((-red * 38 - green * 74 + blue * 112) >> 8) + 128), 255);
+
+                unsigned V =
+                    CLIP3(0, (((red * 112 - green * 94 - blue * 18) >> 8) + 128), 255);
+
+                dstU[x >> 1] = U;
+                dstV[x >> 1] = V;
+            }
+            pRed   += layout.planes[C2PlanarLayout::PLANE_R].colInc;
+            pGreen += layout.planes[C2PlanarLayout::PLANE_G].colInc;
+            pBlue  += layout.planes[C2PlanarLayout::PLANE_B].colInc;
+        }
+
+        if ((y & 1) == 0) {
+            dstU += dstStride >> 1;
+            dstV += dstStride >> 1;
+        }
+
+        pRed   -= layout.planes[C2PlanarLayout::PLANE_R].colInc * src.width();
+        pGreen -= layout.planes[C2PlanarLayout::PLANE_G].colInc * src.width();
+        pBlue  -= layout.planes[C2PlanarLayout::PLANE_B].colInc * src.width();
+        pRed   += layout.planes[C2PlanarLayout::PLANE_R].rowInc;
+        pGreen += layout.planes[C2PlanarLayout::PLANE_G].rowInc;
+        pBlue  += layout.planes[C2PlanarLayout::PLANE_B].rowInc;
+
+        dstY += dstStride;
+    }
+    return OK;
+}
+
+namespace {
+
+/**
+ * A block of raw allocated memory.
+ */
+struct MemoryBlockPoolBlock {
+    MemoryBlockPoolBlock(size_t size)
+        : mData(new uint8_t[size]), mSize(mData ? size : 0) { }
+
+    ~MemoryBlockPoolBlock() {
+        delete[] mData;
+    }
+
+    const uint8_t *data() const {
+        return mData;
+    }
+
+    size_t size() const {
+        return mSize;
+    }
+
+    C2_DO_NOT_COPY(MemoryBlockPoolBlock);
+
+private:
+    uint8_t *mData;
+    size_t mSize;
+};
+
+/**
+ * A simple raw memory block pool implementation.
+ */
+struct MemoryBlockPoolImpl {
+    void release(std::list<MemoryBlockPoolBlock>::const_iterator block) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        // return block to free blocks if it is the current size; otherwise, discard
+        if (block->size() == mCurrentSize) {
+            mFreeBlocks.splice(mFreeBlocks.begin(), mBlocksInUse, block);
+        } else {
+            mBlocksInUse.erase(block);
+        }
+    }
+
+    std::list<MemoryBlockPoolBlock>::const_iterator fetch(size_t size) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mFreeBlocks.remove_if([size](const MemoryBlockPoolBlock &block) -> bool {
+            return block.size() != size;
+        });
+        mCurrentSize = size;
+        if (mFreeBlocks.empty()) {
+            mBlocksInUse.emplace_front(size);
+        } else {
+            mBlocksInUse.splice(mBlocksInUse.begin(), mFreeBlocks, mFreeBlocks.begin());
+        }
+        return mBlocksInUse.begin();
+    }
+
+    MemoryBlockPoolImpl() = default;
+
+    C2_DO_NOT_COPY(MemoryBlockPoolImpl);
+
+private:
+    std::mutex mMutex;
+    std::list<MemoryBlockPoolBlock> mFreeBlocks;
+    std::list<MemoryBlockPoolBlock> mBlocksInUse;
+    size_t mCurrentSize;
+};
+
+} // namespace
+
+struct MemoryBlockPool::Impl : MemoryBlockPoolImpl {
+};
+
+struct MemoryBlock::Impl {
+    Impl(std::list<MemoryBlockPoolBlock>::const_iterator block,
+         std::shared_ptr<MemoryBlockPoolImpl> pool)
+        : mBlock(block), mPool(pool) {
+    }
+
+    ~Impl() {
+        mPool->release(mBlock);
+    }
+
+    const uint8_t *data() const {
+        return mBlock->data();
+    }
+
+    size_t size() const {
+        return mBlock->size();
+    }
+
+private:
+    std::list<MemoryBlockPoolBlock>::const_iterator mBlock;
+    std::shared_ptr<MemoryBlockPoolImpl> mPool;
+};
+
+MemoryBlock MemoryBlockPool::fetch(size_t size) {
+    std::list<MemoryBlockPoolBlock>::const_iterator poolBlock = mImpl->fetch(size);
+    return MemoryBlock(std::make_shared<MemoryBlock::Impl>(
+            poolBlock, std::static_pointer_cast<MemoryBlockPoolImpl>(mImpl)));
+}
+
+MemoryBlockPool::MemoryBlockPool()
+    : mImpl(std::make_shared<MemoryBlockPool::Impl>()) {
+}
+
+MemoryBlock::MemoryBlock(std::shared_ptr<MemoryBlock::Impl> impl)
+    : mImpl(impl) {
+}
+
+MemoryBlock::MemoryBlock() = default;
+
+MemoryBlock::~MemoryBlock() = default;
+
+const uint8_t* MemoryBlock::data() const {
+    return mImpl ? mImpl->data() : nullptr;
+}
+
+size_t MemoryBlock::size() const {
+    return mImpl ? mImpl->size() : 0;
+}
+
+MemoryBlock MemoryBlock::Allocate(size_t size) {
+    return MemoryBlockPool().fetch(size);
+}
+
+}  // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.h b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
new file mode 100644
index 0000000..eaf6776
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
@@ -0,0 +1,141 @@
+/*
+ * 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_BUFFER_UTILS_H_
+#define CODEC2_BUFFER_UTILS_H_
+
+#include <C2Buffer.h>
+#include <C2ParamDef.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/**
+ * Converts an RGB view to planar YUV 420 media image.
+ *
+ * \param dstY       pointer to media image buffer
+ * \param dstStride  stride in bytes
+ * \param dstVStride vertical stride in pixels
+ * \param bufferSize media image buffer size
+ * \param src source image
+ *
+ * \retval NO_MEMORY media image is too small
+ * \retval OK on success
+ */
+status_t ConvertRGBToPlanarYUV(
+        uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
+        const C2GraphicView &src);
+
+/**
+ * Returns a planar YUV 420 8-bit media image descriptor.
+ *
+ * \param width width of image in pixels
+ * \param height height of image in pixels
+ * \param stride stride of image in pixels
+ * \param vstride vertical stride of image in pixels
+ */
+MediaImage2 CreateYUV420PlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
+
+/**
+ * Returns a semiplanar YUV 420 8-bit media image descriptor.
+ *
+ * \param width width of image in pixels
+ * \param height height of image in pixels
+ * \param stride stride of image in pixels
+ * \param vstride vertical stride of image in pixels
+ */
+MediaImage2 CreateYUV420SemiPlanarMediaImage2(
+        uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
+
+/**
+ * Copies a graphic view into a media image.
+ *
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ * \param view graphic view
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
+
+/**
+ * Copies a media image into a graphic view.
+ *
+ * \param view graphic view
+ * \param imgBase base of MediaImage
+ * \param img MediaImage data
+ *
+ * \return OK on success
+ */
+status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
+
+/**
+ * Returns true iff a view has a YUV 420 888 layout.
+ */
+bool IsYUV420(const C2GraphicView &view);
+
+/**
+ * A raw memory block to use for internal buffers.
+ *
+ * TODO: replace this with C2LinearBlocks from a private C2BlockPool
+ */
+struct MemoryBlock : public C2MemoryBlock<uint8_t> {
+    virtual const uint8_t* data() const override;
+    virtual size_t size() const override;
+
+    inline uint8_t *data() {
+        return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
+    }
+
+    // allocates an unmanaged block (not in a pool)
+    static MemoryBlock Allocate(size_t);
+
+    // memory block with no actual memory (size is 0, data is null)
+    MemoryBlock();
+
+    struct Impl;
+    MemoryBlock(std::shared_ptr<Impl> impl);
+    virtual ~MemoryBlock();
+
+private:
+    std::shared_ptr<Impl> mImpl;
+};
+
+/**
+ * A raw memory mini-pool.
+ */
+struct MemoryBlockPool {
+    /**
+     * Fetches a block with a given size.
+     *
+     * \param size size in bytes
+     */
+    MemoryBlock fetch(size_t size);
+
+    MemoryBlockPool();
+    ~MemoryBlockPool() = default;
+
+private:
+    struct Impl;
+    std::shared_ptr<Impl> mImpl;
+};
+
+} // namespace android
+
+#endif  // CODEC2_BUFFER_UTILS_H_
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
new file mode 100644
index 0000000..97e17e8
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -0,0 +1,815 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2Mapper"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/SurfaceUtils.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <stdint.h>  // for INT32_MAX
+
+#include "Codec2Mapper.h"
+
+using namespace android;
+
+namespace {
+
+ALookup<C2Config::profile_t, int32_t> sAacProfiles = {
+    { C2Config::PROFILE_AAC_LC,         AACObjectLC },
+    { C2Config::PROFILE_AAC_MAIN,       AACObjectMain },
+    { C2Config::PROFILE_AAC_SSR,        AACObjectSSR },
+    { C2Config::PROFILE_AAC_LTP,        AACObjectLTP },
+    { C2Config::PROFILE_AAC_HE,         AACObjectHE },
+    { C2Config::PROFILE_AAC_SCALABLE,   AACObjectScalable },
+    { C2Config::PROFILE_AAC_ER_LC,      AACObjectERLC },
+    { C2Config::PROFILE_AAC_ER_SCALABLE, AACObjectERScalable },
+    { C2Config::PROFILE_AAC_LD,         AACObjectLD },
+    { C2Config::PROFILE_AAC_HE_PS,      AACObjectHE_PS },
+    { C2Config::PROFILE_AAC_ELD,        AACObjectELD },
+    { C2Config::PROFILE_AAC_XHE,        AACObjectXHE },
+};
+
+ALookup<C2Config::level_t, int32_t> sAvcLevels = {
+    { C2Config::LEVEL_AVC_1,    AVCLevel1 },
+    { C2Config::LEVEL_AVC_1B,   AVCLevel1b },
+    { C2Config::LEVEL_AVC_1_1,  AVCLevel11 },
+    { C2Config::LEVEL_AVC_1_2,  AVCLevel12 },
+    { C2Config::LEVEL_AVC_1_3,  AVCLevel13 },
+    { C2Config::LEVEL_AVC_2,    AVCLevel2 },
+    { C2Config::LEVEL_AVC_2_1,  AVCLevel21 },
+    { C2Config::LEVEL_AVC_2_2,  AVCLevel22 },
+    { C2Config::LEVEL_AVC_3,    AVCLevel3 },
+    { C2Config::LEVEL_AVC_3_1,  AVCLevel31 },
+    { C2Config::LEVEL_AVC_3_2,  AVCLevel32 },
+    { C2Config::LEVEL_AVC_4,    AVCLevel4 },
+    { C2Config::LEVEL_AVC_4_1,  AVCLevel41 },
+    { C2Config::LEVEL_AVC_4_2,  AVCLevel42 },
+    { C2Config::LEVEL_AVC_5,    AVCLevel5 },
+    { C2Config::LEVEL_AVC_5_1,  AVCLevel51 },
+    { C2Config::LEVEL_AVC_5_2,  AVCLevel52 },
+
+};
+
+ALookup<C2Config::profile_t, int32_t> sAvcProfiles = {
+    // treat restricted profiles as full profile if there is no equivalent - which works for
+    // decoders, but not for encoders
+    { C2Config::PROFILE_AVC_BASELINE,               AVCProfileBaseline },
+    { C2Config::PROFILE_AVC_CONSTRAINED_BASELINE,   AVCProfileConstrainedBaseline },
+    { C2Config::PROFILE_AVC_MAIN,                   AVCProfileMain },
+    { C2Config::PROFILE_AVC_EXTENDED,               AVCProfileExtended },
+    { C2Config::PROFILE_AVC_HIGH,                   AVCProfileHigh },
+    { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH,       AVCProfileHigh },
+    { C2Config::PROFILE_AVC_CONSTRAINED_HIGH,       AVCProfileConstrainedHigh },
+    { C2Config::PROFILE_AVC_HIGH_10,                AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH_10,    AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_HIGH_422,               AVCProfileHigh422 },
+    { C2Config::PROFILE_AVC_HIGH_444_PREDICTIVE,    AVCProfileHigh444 },
+    { C2Config::PROFILE_AVC_HIGH_10_INTRA,          AVCProfileHigh10 },
+    { C2Config::PROFILE_AVC_HIGH_422_INTRA,         AVCProfileHigh422 },
+    { C2Config::PROFILE_AVC_HIGH_444_INTRA,         AVCProfileHigh444 },
+    { C2Config::PROFILE_AVC_CAVLC_444_INTRA,        AVCProfileHigh444 },
+};
+
+ALookup<C2Config::bitrate_mode_t, int32_t> sBitrateModes = {
+    { C2Config::BITRATE_CONST,      BITRATE_MODE_CBR },
+    { C2Config::BITRATE_VARIABLE,   BITRATE_MODE_VBR },
+    { C2Config::BITRATE_IGNORE,     BITRATE_MODE_CQ },
+};
+
+ALookup<C2Color::matrix_t, ColorAspects::MatrixCoeffs> sColorMatricesSf = {
+    { C2Color::MATRIX_UNSPECIFIED,     ColorAspects::MatrixUnspecified },
+    { C2Color::MATRIX_BT709,           ColorAspects::MatrixBT709_5 },
+    { C2Color::MATRIX_FCC47_73_682,    ColorAspects::MatrixBT470_6M },
+    { C2Color::MATRIX_BT601,           ColorAspects::MatrixBT601_6 },
+    { C2Color::MATRIX_SMPTE240M,       ColorAspects::MatrixSMPTE240M },
+    { C2Color::MATRIX_BT2020,          ColorAspects::MatrixBT2020 },
+    { C2Color::MATRIX_BT2020_CONSTANT, ColorAspects::MatrixBT2020Constant },
+    { C2Color::MATRIX_OTHER,           ColorAspects::MatrixOther },
+};
+
+ALookup<C2Color::primaries_t, ColorAspects::Primaries> sColorPrimariesSf = {
+    { C2Color::PRIMARIES_UNSPECIFIED,  ColorAspects::PrimariesUnspecified },
+    { C2Color::PRIMARIES_BT709,        ColorAspects::PrimariesBT709_5 },
+    { C2Color::PRIMARIES_BT470_M,      ColorAspects::PrimariesBT470_6M },
+    { C2Color::PRIMARIES_BT601_625,    ColorAspects::PrimariesBT601_6_625 },
+    { C2Color::PRIMARIES_BT601_525,    ColorAspects::PrimariesBT601_6_525 },
+    { C2Color::PRIMARIES_GENERIC_FILM, ColorAspects::PrimariesGenericFilm },
+    { C2Color::PRIMARIES_BT2020,       ColorAspects::PrimariesBT2020 },
+//    { C2Color::PRIMARIES_RP431,        ColorAspects::Primaries... },
+//    { C2Color::PRIMARIES_EG432,        ColorAspects::Primaries... },
+//    { C2Color::PRIMARIES_EBU3213,      ColorAspects::Primaries... },
+    { C2Color::PRIMARIES_OTHER,        ColorAspects::PrimariesOther },
+};
+
+ALookup<C2Color::range_t, int32_t> sColorRanges = {
+    { C2Color::RANGE_FULL,    COLOR_RANGE_FULL },
+    { C2Color::RANGE_LIMITED, COLOR_RANGE_LIMITED },
+};
+
+ALookup<C2Color::range_t, ColorAspects::Range> sColorRangesSf = {
+    { C2Color::RANGE_UNSPECIFIED, ColorAspects::RangeUnspecified },
+    { C2Color::RANGE_FULL,        ColorAspects::RangeFull },
+    { C2Color::RANGE_LIMITED,     ColorAspects::RangeLimited },
+    { C2Color::RANGE_OTHER,       ColorAspects::RangeOther },
+};
+
+ALookup<C2Color::transfer_t, int32_t> sColorTransfers = {
+    { C2Color::TRANSFER_LINEAR, COLOR_TRANSFER_LINEAR },
+    { C2Color::TRANSFER_170M,   COLOR_TRANSFER_SDR_VIDEO },
+    { C2Color::TRANSFER_ST2084, COLOR_TRANSFER_ST2084 },
+    { C2Color::TRANSFER_HLG,    COLOR_TRANSFER_HLG },
+};
+
+ALookup<C2Color::transfer_t, ColorAspects::Transfer> sColorTransfersSf = {
+    { C2Color::TRANSFER_UNSPECIFIED, ColorAspects::TransferUnspecified },
+    { C2Color::TRANSFER_LINEAR,      ColorAspects::TransferLinear },
+    { C2Color::TRANSFER_SRGB,        ColorAspects::TransferSRGB },
+    { C2Color::TRANSFER_170M,        ColorAspects::TransferSMPTE170M },
+    { C2Color::TRANSFER_GAMMA22,     ColorAspects::TransferGamma22 },
+    { C2Color::TRANSFER_GAMMA28,     ColorAspects::TransferGamma28 },
+    { C2Color::TRANSFER_ST2084,      ColorAspects::TransferST2084 },
+    { C2Color::TRANSFER_HLG,         ColorAspects::TransferHLG },
+    { C2Color::TRANSFER_240M,        ColorAspects::TransferSMPTE240M },
+    { C2Color::TRANSFER_XVYCC,       ColorAspects::TransferXvYCC },
+    { C2Color::TRANSFER_BT1361,      ColorAspects::TransferBT1361 },
+    { C2Color::TRANSFER_ST428,       ColorAspects::TransferST428 },
+    { C2Color::TRANSFER_OTHER,       ColorAspects::TransferOther },
+};
+
+ALookup<C2Config::level_t, int32_t> sDolbyVisionLevels = {
+    { C2Config::LEVEL_DV_MAIN_HD_24,  DolbyVisionLevelHd24 },
+    { C2Config::LEVEL_DV_MAIN_HD_30,  DolbyVisionLevelHd30 },
+    { C2Config::LEVEL_DV_MAIN_FHD_24, DolbyVisionLevelFhd24 },
+    { C2Config::LEVEL_DV_MAIN_FHD_30, DolbyVisionLevelFhd30 },
+    { C2Config::LEVEL_DV_MAIN_FHD_60, DolbyVisionLevelFhd60 },
+    { C2Config::LEVEL_DV_MAIN_UHD_24, DolbyVisionLevelUhd24 },
+    { C2Config::LEVEL_DV_MAIN_UHD_30, DolbyVisionLevelUhd30 },
+    { C2Config::LEVEL_DV_MAIN_UHD_48, DolbyVisionLevelUhd48 },
+    { C2Config::LEVEL_DV_MAIN_UHD_60, DolbyVisionLevelUhd60 },
+
+    // high tiers are not yet supported on android, for now map them to main tier
+    { C2Config::LEVEL_DV_HIGH_HD_24,  DolbyVisionLevelHd24 },
+    { C2Config::LEVEL_DV_HIGH_HD_30,  DolbyVisionLevelHd30 },
+    { C2Config::LEVEL_DV_HIGH_FHD_24, DolbyVisionLevelFhd24 },
+    { C2Config::LEVEL_DV_HIGH_FHD_30, DolbyVisionLevelFhd30 },
+    { C2Config::LEVEL_DV_HIGH_FHD_60, DolbyVisionLevelFhd60 },
+    { C2Config::LEVEL_DV_HIGH_UHD_24, DolbyVisionLevelUhd24 },
+    { C2Config::LEVEL_DV_HIGH_UHD_30, DolbyVisionLevelUhd30 },
+    { C2Config::LEVEL_DV_HIGH_UHD_48, DolbyVisionLevelUhd48 },
+    { C2Config::LEVEL_DV_HIGH_UHD_60, DolbyVisionLevelUhd60 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sDolbyVisionProfiles = {
+    { C2Config::PROFILE_DV_AV_PER, DolbyVisionProfileDvavPer },
+    { C2Config::PROFILE_DV_AV_PEN, DolbyVisionProfileDvavPen },
+    { C2Config::PROFILE_DV_HE_DER, DolbyVisionProfileDvheDer },
+    { C2Config::PROFILE_DV_HE_DEN, DolbyVisionProfileDvheDen },
+    { C2Config::PROFILE_DV_HE_04, DolbyVisionProfileDvheDtr },
+    { C2Config::PROFILE_DV_HE_05, DolbyVisionProfileDvheStn },
+    { C2Config::PROFILE_DV_HE_DTH, DolbyVisionProfileDvheDth },
+    { C2Config::PROFILE_DV_HE_07, DolbyVisionProfileDvheDtb },
+    { C2Config::PROFILE_DV_HE_08, DolbyVisionProfileDvheSt },
+    { C2Config::PROFILE_DV_AV_09, DolbyVisionProfileDvavSe },
+};
+
+ALookup<C2Config::level_t, int32_t> sH263Levels = {
+    { C2Config::LEVEL_H263_10, H263Level10 },
+    { C2Config::LEVEL_H263_20, H263Level20 },
+    { C2Config::LEVEL_H263_30, H263Level30 },
+    { C2Config::LEVEL_H263_40, H263Level40 },
+    { C2Config::LEVEL_H263_45, H263Level45 },
+    { C2Config::LEVEL_H263_50, H263Level50 },
+    { C2Config::LEVEL_H263_60, H263Level60 },
+    { C2Config::LEVEL_H263_70, H263Level70 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sH263Profiles = {
+    { C2Config::PROFILE_H263_BASELINE,          H263ProfileBaseline },
+    { C2Config::PROFILE_H263_H320,              H263ProfileH320Coding },
+    { C2Config::PROFILE_H263_V1BC,              H263ProfileBackwardCompatible },
+    { C2Config::PROFILE_H263_ISWV2,             H263ProfileISWV2 },
+    { C2Config::PROFILE_H263_ISWV3,             H263ProfileISWV3 },
+    { C2Config::PROFILE_H263_HIGH_COMPRESSION,  H263ProfileHighCompression },
+    { C2Config::PROFILE_H263_INTERNET,          H263ProfileInternet },
+    { C2Config::PROFILE_H263_INTERLACE,         H263ProfileInterlace },
+    { C2Config::PROFILE_H263_HIGH_LATENCY,      H263ProfileHighLatency },
+};
+
+ALookup<C2Config::level_t, int32_t> sHevcLevels = {
+    { C2Config::LEVEL_HEVC_MAIN_1,      HEVCMainTierLevel1 },
+    { C2Config::LEVEL_HEVC_MAIN_2,      HEVCMainTierLevel2 },
+    { C2Config::LEVEL_HEVC_MAIN_2_1,    HEVCMainTierLevel21 },
+    { C2Config::LEVEL_HEVC_MAIN_3,      HEVCMainTierLevel3 },
+    { C2Config::LEVEL_HEVC_MAIN_3_1,    HEVCMainTierLevel31 },
+    { C2Config::LEVEL_HEVC_MAIN_4,      HEVCMainTierLevel4 },
+    { C2Config::LEVEL_HEVC_MAIN_4_1,    HEVCMainTierLevel41 },
+    { C2Config::LEVEL_HEVC_MAIN_5,      HEVCMainTierLevel5 },
+    { C2Config::LEVEL_HEVC_MAIN_5_1,    HEVCMainTierLevel51 },
+    { C2Config::LEVEL_HEVC_MAIN_5_2,    HEVCMainTierLevel52 },
+    { C2Config::LEVEL_HEVC_MAIN_6,      HEVCMainTierLevel6 },
+    { C2Config::LEVEL_HEVC_MAIN_6_1,    HEVCMainTierLevel61 },
+    { C2Config::LEVEL_HEVC_MAIN_6_2,    HEVCMainTierLevel62 },
+
+    { C2Config::LEVEL_HEVC_HIGH_4,      HEVCHighTierLevel4 },
+    { C2Config::LEVEL_HEVC_HIGH_4_1,    HEVCHighTierLevel41 },
+    { C2Config::LEVEL_HEVC_HIGH_5,      HEVCHighTierLevel5 },
+    { C2Config::LEVEL_HEVC_HIGH_5_1,    HEVCHighTierLevel51 },
+    { C2Config::LEVEL_HEVC_HIGH_5_2,    HEVCHighTierLevel52 },
+    { C2Config::LEVEL_HEVC_HIGH_6,      HEVCHighTierLevel6 },
+    { C2Config::LEVEL_HEVC_HIGH_6_1,    HEVCHighTierLevel61 },
+    { C2Config::LEVEL_HEVC_HIGH_6_2,    HEVCHighTierLevel62 },
+
+    // map high tier levels below 4 to main tier
+    { C2Config::LEVEL_HEVC_MAIN_1,      HEVCHighTierLevel1 },
+    { C2Config::LEVEL_HEVC_MAIN_2,      HEVCHighTierLevel2 },
+    { C2Config::LEVEL_HEVC_MAIN_2_1,    HEVCHighTierLevel21 },
+    { C2Config::LEVEL_HEVC_MAIN_3,      HEVCHighTierLevel3 },
+    { C2Config::LEVEL_HEVC_MAIN_3_1,    HEVCHighTierLevel31 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sHevcProfiles = {
+    { C2Config::PROFILE_HEVC_MAIN, HEVCProfileMain },
+    { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10 },
+    { C2Config::PROFILE_HEVC_MAIN_STILL, HEVCProfileMainStill },
+    { C2Config::PROFILE_HEVC_MAIN_INTRA, HEVCProfileMain },
+    { C2Config::PROFILE_HEVC_MAIN_10_INTRA, HEVCProfileMain10 },
+};
+
+ALookup<C2Config::level_t, int32_t> sMpeg2Levels = {
+    { C2Config::LEVEL_MP2V_LOW,         MPEG2LevelLL },
+    { C2Config::LEVEL_MP2V_MAIN,        MPEG2LevelML },
+    { C2Config::LEVEL_MP2V_HIGH_1440,   MPEG2LevelH14 },
+    { C2Config::LEVEL_MP2V_HIGH,        MPEG2LevelHL },
+    { C2Config::LEVEL_MP2V_HIGHP,       MPEG2LevelHP },
+};
+
+ALookup<C2Config::profile_t, int32_t> sMpeg2Profiles = {
+    { C2Config::PROFILE_MP2V_SIMPLE,                MPEG2ProfileSimple },
+    { C2Config::PROFILE_MP2V_MAIN,                  MPEG2ProfileMain },
+    { C2Config::PROFILE_MP2V_SNR_SCALABLE,          MPEG2ProfileSNR },
+    { C2Config::PROFILE_MP2V_SPATIALLY_SCALABLE,    MPEG2ProfileSpatial },
+    { C2Config::PROFILE_MP2V_HIGH,                  MPEG2ProfileHigh },
+    { C2Config::PROFILE_MP2V_422,                   MPEG2Profile422 },
+};
+
+ALookup<C2Config::level_t, int32_t> sMpeg4Levels = {
+    { C2Config::LEVEL_MP4V_0,   MPEG4Level0 },
+    { C2Config::LEVEL_MP4V_0B,  MPEG4Level0b },
+    { C2Config::LEVEL_MP4V_1,   MPEG4Level1 },
+    { C2Config::LEVEL_MP4V_2,   MPEG4Level2 },
+    { C2Config::LEVEL_MP4V_3,   MPEG4Level3 },
+    { C2Config::LEVEL_MP4V_3B,  MPEG4Level3b },
+    { C2Config::LEVEL_MP4V_4,   MPEG4Level4 },
+    { C2Config::LEVEL_MP4V_4A,  MPEG4Level4a },
+    { C2Config::LEVEL_MP4V_5,   MPEG4Level5 },
+    { C2Config::LEVEL_MP4V_6,   MPEG4Level6 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sMpeg4Profiles = {
+    { C2Config::PROFILE_MP4V_SIMPLE,            MPEG4ProfileSimple },
+    { C2Config::PROFILE_MP4V_SIMPLE_SCALABLE,   MPEG4ProfileSimpleScalable },
+    { C2Config::PROFILE_MP4V_CORE,              MPEG4ProfileCore },
+    { C2Config::PROFILE_MP4V_MAIN,              MPEG4ProfileMain },
+    { C2Config::PROFILE_MP4V_NBIT,              MPEG4ProfileNbit },
+    { C2Config::PROFILE_MP4V_ARTS,              MPEG4ProfileAdvancedRealTime },
+    { C2Config::PROFILE_MP4V_CORE_SCALABLE,     MPEG4ProfileCoreScalable },
+    { C2Config::PROFILE_MP4V_ACE,               MPEG4ProfileAdvancedCoding },
+    { C2Config::PROFILE_MP4V_ADVANCED_CORE,     MPEG4ProfileAdvancedCore },
+    { C2Config::PROFILE_MP4V_ADVANCED_SIMPLE,   MPEG4ProfileAdvancedSimple },
+};
+
+ALookup<C2Config::pcm_encoding_t, int32_t> sPcmEncodings = {
+    { C2Config::PCM_8, kAudioEncodingPcm8bit },
+    { C2Config::PCM_16, kAudioEncodingPcm16bit },
+    { C2Config::PCM_FLOAT, kAudioEncodingPcmFloat },
+};
+
+ALookup<C2Config::level_t, int32_t> sVp9Levels = {
+    { C2Config::LEVEL_VP9_1,    VP9Level1 },
+    { C2Config::LEVEL_VP9_1_1,  VP9Level11 },
+    { C2Config::LEVEL_VP9_2,    VP9Level2 },
+    { C2Config::LEVEL_VP9_2_1,  VP9Level21 },
+    { C2Config::LEVEL_VP9_3,    VP9Level3 },
+    { C2Config::LEVEL_VP9_3_1,  VP9Level31 },
+    { C2Config::LEVEL_VP9_4,    VP9Level4 },
+    { C2Config::LEVEL_VP9_4_1,  VP9Level41 },
+    { C2Config::LEVEL_VP9_5,    VP9Level5 },
+    { C2Config::LEVEL_VP9_5_1,  VP9Level51 },
+    { C2Config::LEVEL_VP9_5_2,  VP9Level52 },
+    { C2Config::LEVEL_VP9_6,    VP9Level6 },
+    { C2Config::LEVEL_VP9_6_1,  VP9Level61 },
+    { C2Config::LEVEL_VP9_6_2,  VP9Level62 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sVp9Profiles = {
+    { C2Config::PROFILE_VP9_0, VP9Profile0 },
+    { C2Config::PROFILE_VP9_1, VP9Profile1 },
+    { C2Config::PROFILE_VP9_2, VP9Profile2 },
+    { C2Config::PROFILE_VP9_3, VP9Profile3 },
+};
+
+/**
+ * A helper that passes through vendor extension profile and level values.
+ */
+struct ProfileLevelMapperHelper : C2Mapper::ProfileLevelMapper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) = 0;
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) = 0;
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) = 0;
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) = 0;
+
+    template<typename T, typename U>
+    bool passThroughMap(T from, U *to) {
+        // allow (and pass through) vendor extensions
+        if (from >= (T)C2_PROFILE_LEVEL_VENDOR_START && from < (T)INT32_MAX) {
+            *to = (U)from;
+            return true;
+        }
+        return simpleMap(from, to);
+    }
+
+    virtual bool mapLevel(C2Config::level_t from, int32_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapLevel(int32_t from, C2Config::level_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapProfile(C2Config::profile_t from, int32_t *to) {
+        return passThroughMap(from, to);
+    }
+
+    virtual bool mapProfile(int32_t from, C2Config::profile_t *to) {
+        return passThroughMap(from, to);
+    }
+};
+
+// AAC only uses profiles, map all levels to unused or 0
+struct AacProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t, int32_t *to) {
+        *to = 0;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::level_t *to) {
+        *to = C2Config::LEVEL_UNUSED;
+        return true;
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sAacProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sAacProfiles.map(from, to);
+    }
+};
+
+struct AvcProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sAvcLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sAvcLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sAvcProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sAvcProfiles.map(from, to);
+    }
+};
+
+struct DolbyVisionProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sDolbyVisionLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sDolbyVisionLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sDolbyVisionProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sDolbyVisionProfiles.map(from, to);
+    }
+};
+
+struct H263ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sH263Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sH263Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sH263Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sH263Profiles.map(from, to);
+    }
+};
+
+struct HevcProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sHevcLevels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sHevcLevels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sHevcProfiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sHevcProfiles.map(from, to);
+    }
+};
+
+struct Mpeg2ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sMpeg2Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sMpeg2Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sMpeg2Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sMpeg2Profiles.map(from, to);
+    }
+};
+
+struct Mpeg4ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sMpeg4Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sMpeg4Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sMpeg4Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sMpeg4Profiles.map(from, to);
+    }
+};
+
+// VP8 has no profiles and levels in Codec 2.0, but we use main profile and level 0 in MediaCodec
+// map all profiles and levels to that.
+struct Vp8ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t, int32_t *to) {
+        *to = VP8Level_Version0;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::level_t *to) {
+        *to = C2Config::LEVEL_UNUSED;
+        return true;
+    }
+    virtual bool simpleMap(C2Config::profile_t, int32_t *to) {
+        *to = VP8ProfileMain;
+        return true;
+    }
+    virtual bool simpleMap(int32_t, C2Config::profile_t *to) {
+        *to = C2Config::PROFILE_UNUSED;
+        return true;
+    }
+};
+
+struct Vp9ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sVp9Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sVp9Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sVp9Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sVp9Profiles.map(from, to);
+    }
+};
+
+} // namespace
+
+// static
+std::shared_ptr<C2Mapper::ProfileLevelMapper>
+C2Mapper::GetProfileLevelMapper(std::string mediaType) {
+    std::transform(mediaType.begin(), mediaType.begin(), mediaType.end(), ::tolower);
+    if (mediaType == MIMETYPE_AUDIO_AAC) {
+        return std::make_shared<AacProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_AVC) {
+        return std::make_shared<AvcProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_DOLBY_VISION) {
+        return std::make_shared<DolbyVisionProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_H263) {
+        return std::make_shared<H263ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_HEVC) {
+        return std::make_shared<HevcProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_MPEG2) {
+        return std::make_shared<Mpeg2ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
+        return std::make_shared<Mpeg4ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_VP8) {
+        return std::make_shared<Vp8ProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_VIDEO_VP9) {
+        return std::make_shared<Vp9ProfileLevelMapper>();
+    }
+    return nullptr;
+}
+
+// static
+bool C2Mapper::map(C2Config::bitrate_mode_t from, int32_t *to) {
+    return sBitrateModes.map(from, to);
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Config::bitrate_mode_t *to) {
+    return sBitrateModes.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Config::pcm_encoding_t from, int32_t *to) {
+    return sPcmEncodings.map(from, to);
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Config::pcm_encoding_t *to) {
+    return sPcmEncodings.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::range_t from, int32_t *to) {
+    bool res = true;
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorRanges.map(from, to)) {
+        ColorAspects::Range sfRange;
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorRangesSf.map(from, &sfRange)) {
+            // use static cast and ensure it is in the extension range
+            if (from < C2Color::RANGE_VENDOR_START || from > C2Color::RANGE_OTHER) {
+                sfRange = ColorAspects::RangeOther;
+                res = false;
+            }
+        }
+
+        *to = ColorUtils::wrapColorAspectsIntoColorRange(sfRange);
+    }
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Color::range_t *to) {
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorRanges.map(from, to)) {
+        ColorAspects::Range sfRange;
+        (void)ColorUtils::unwrapColorAspectsFromColorRange(from, &sfRange);
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorRangesSf.map(sfRange, to)) {
+            // use static cast and ensure it is in the extension range
+            *to = (C2Color::range_t)sfRange;
+            if (*to < C2Color::RANGE_VENDOR_START || *to > C2Color::RANGE_OTHER) {
+                *to = C2Color::RANGE_OTHER;
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// static
+bool C2Mapper::map(C2Color::range_t from, ColorAspects::Range *to) {
+    return sColorRangesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Range from, C2Color::range_t *to) {
+    return sColorRangesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::primaries_t primaries, C2Color::matrix_t matrix, int32_t *standard) {
+    ColorAspects::Primaries sfPrimaries;
+    ColorAspects::MatrixCoeffs sfMatrix;
+    bool res = true;
+
+    // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+    if (!sColorPrimariesSf.map(primaries, &sfPrimaries)) {
+        // ensure it is in the extension range and use static cast
+        if (primaries < C2Color::PRIMARIES_VENDOR_START || primaries > C2Color::PRIMARIES_OTHER) {
+            // undefined non-extension values map to 'Other'
+            sfPrimaries = ColorAspects::PrimariesOther;
+            res = false;
+        } else {
+            sfPrimaries = (ColorAspects::Primaries)primaries;
+        }
+    }
+
+    if (!sColorMatricesSf.map(matrix, &sfMatrix)) {
+        // use static cast and ensure it is in the extension range
+        if (matrix < C2Color::MATRIX_VENDOR_START || matrix > C2Color::MATRIX_OTHER) {
+            // undefined non-extension values map to 'Other'
+            sfMatrix = ColorAspects::MatrixOther;
+            res = false;
+        } else {
+            sfMatrix = (ColorAspects::MatrixCoeffs)matrix;
+        }
+    }
+
+    *standard = ColorUtils::wrapColorAspectsIntoColorStandard(sfPrimaries, sfMatrix);
+
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t standard, C2Color::primaries_t *primaries, C2Color::matrix_t *matrix) {
+    // first map to stagefright foundation aspects => these actually map nearly 1:1 to
+    // Codec 2.0 aspects
+    ColorAspects::Primaries sfPrimaries;
+    ColorAspects::MatrixCoeffs sfMatrix;
+    bool res = true;
+    (void)ColorUtils::unwrapColorAspectsFromColorStandard(standard, &sfPrimaries, &sfMatrix);
+
+    // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+    if (!sColorPrimariesSf.map(sfPrimaries, primaries)) {
+        // use static cast and ensure it is in the extension range
+        *primaries = (C2Color::primaries_t)sfPrimaries;
+        if (*primaries < C2Color::PRIMARIES_VENDOR_START || *primaries > C2Color::PRIMARIES_OTHER) {
+            *primaries = C2Color::PRIMARIES_OTHER;
+            res = false;
+        }
+    }
+
+    if (!sColorMatricesSf.map(sfMatrix, matrix)) {
+        // use static cast and ensure it is in the extension range
+        *matrix = (C2Color::matrix_t)sfMatrix;
+        if (*matrix < C2Color::MATRIX_VENDOR_START || *matrix > C2Color::MATRIX_OTHER) {
+            *matrix = C2Color::MATRIX_OTHER;
+            res = false;
+        }
+    }
+
+    return res;
+}
+
+// static
+bool C2Mapper::map(C2Color::primaries_t from, ColorAspects::Primaries *to) {
+    return sColorPrimariesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Primaries from, C2Color::primaries_t *to) {
+    return sColorPrimariesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::matrix_t from, ColorAspects::MatrixCoeffs *to) {
+    return sColorMatricesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::MatrixCoeffs from, C2Color::matrix_t *to) {
+    return sColorMatricesSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(C2Color::transfer_t from, int32_t *to) {
+    bool res = true;
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorTransfers.map(from, to)) {
+        ColorAspects::Transfer sfTransfer;
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorTransfersSf.map(from, &sfTransfer)) {
+            // use static cast and ensure it is in the extension range
+            if (from < C2Color::TRANSFER_VENDOR_START || from > C2Color::TRANSFER_OTHER) {
+                sfTransfer = ColorAspects::TransferOther;
+                res = false;
+            }
+        }
+
+        *to = ColorUtils::wrapColorAspectsIntoColorTransfer(sfTransfer);
+    }
+    return res;
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Color::transfer_t *to) {
+    // map SDK defined values directly. For other values, use wrapping from ColorUtils.
+    if (!sColorTransfers.map(from, to)) {
+        ColorAspects::Transfer sfTransfer;
+        (void)ColorUtils::unwrapColorAspectsFromColorTransfer(from, &sfTransfer);
+
+        // map known constants and keep vendor extensions. all other values are mapped to 'Other'
+        if (!sColorTransfersSf.map(sfTransfer, to)) {
+            // use static cast and ensure it is in the extension range
+            *to = (C2Color::transfer_t)sfTransfer;
+            if (*to < C2Color::TRANSFER_VENDOR_START || *to > C2Color::TRANSFER_OTHER) {
+                *to = C2Color::TRANSFER_OTHER;
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// static
+bool C2Mapper::map(
+        C2Color::range_t range, C2Color::primaries_t primaries,
+        C2Color::matrix_t matrix, C2Color::transfer_t transfer, uint32_t *dataSpace) {
+#if 0
+    // pure reimplementation
+    *dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
+
+    switch (range) {
+        case C2Color::RANGE_FULL:    *dataSpace |= HAL_DATASPACE_RANGE_FULL;    break;
+        case C2Color::RANGE_LIMITED: *dataSpace |= HAL_DATASPACE_RANGE_LIMITED; break;
+        default: break;
+    }
+
+    switch (transfer) {
+        case C2Color::TRANSFER_LINEAR:  *dataSpace |= HAL_DATASPACE_TRANSFER_LINEAR;     break;
+        case C2Color::TRANSFER_SRGB:    *dataSpace |= HAL_DATASPACE_TRANSFER_SRGB;       break;
+        case C2Color::TRANSFER_170M:    *dataSpace |= HAL_DATASPACE_TRANSFER_SMPTE_170M; break;
+        case C2Color::TRANSFER_GAMMA22: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_2;   break;
+        case C2Color::TRANSFER_GAMMA28: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_8;   break;
+        case C2Color::TRANSFER_ST2084:  *dataSpace |= HAL_DATASPACE_TRANSFER_ST2084;     break;
+        case C2Color::TRANSFER_HLG:     *dataSpace |= HAL_DATASPACE_TRANSFER_HLG;        break;
+        default: break;
+    }
+
+    switch (primaries) {
+        case C2Color::PRIMARIES_BT601_525:
+            *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
+                            || matrix == C2Color::MATRIX_BT709)
+                    ? HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED
+                    : HAL_DATASPACE_STANDARD_BT601_525;
+            break;
+        case C2Color::PRIMARIES_BT601_625:
+            *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
+                            || matrix == C2Color::MATRIX_BT709)
+                    ? HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED
+                    : HAL_DATASPACE_STANDARD_BT601_625;
+            break;
+        case C2Color::PRIMARIES_BT2020:
+            *dataSpace |= (matrix == C2Color::MATRIX_BT2020CONSTANT
+                    ? HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE
+                    : HAL_DATASPACE_STANDARD_BT2020);
+            break;
+        case C2Color::PRIMARIES_BT470_M:
+            *dataSpace |= HAL_DATASPACE_STANDARD_BT470M;
+            break;
+        case C2Color::PRIMARIES_BT709:
+            *dataSpace |= HAL_DATASPACE_STANDARD_BT709;
+            break;
+        default: break;
+    }
+#else
+    // for now use legacy implementation
+    ColorAspects aspects;
+    if (!sColorRangesSf.map(range, &aspects.mRange)) {
+        aspects.mRange = ColorAspects::RangeUnspecified;
+    }
+    if (!sColorPrimariesSf.map(primaries, &aspects.mPrimaries)) {
+        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+    }
+    if (!sColorMatricesSf.map(matrix, &aspects.mMatrixCoeffs)) {
+        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+    }
+    if (!sColorTransfersSf.map(transfer, &aspects.mTransfer)) {
+        aspects.mTransfer = ColorAspects::TransferUnspecified;
+    }
+    *dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
+#endif
+    return true;
+}
+
+// static
+bool C2Mapper::map(C2Color::transfer_t from, ColorAspects::Transfer *to) {
+    return sColorTransfersSf.map(from, to);
+}
+
+// static
+bool C2Mapper::map(ColorAspects::Transfer from, C2Color::transfer_t *to) {
+    return sColorTransfersSf.map(from, to);
+}
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.h b/media/codec2/sfplugin/utils/Codec2Mapper.h
new file mode 100644
index 0000000..1eeb92e
--- /dev/null
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.h
@@ -0,0 +1,78 @@
+/*
+ * 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 ANDROID_CODEC2_MAPPER_H_
+#define ANDROID_CODEC2_MAPPER_H_
+
+#include <C2Config.h>
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include <memory>
+
+namespace android {
+
+    /**
+     * Utility class to map Codec 2.0 values to android values.
+     */
+    struct C2Mapper {
+        struct ProfileLevelMapper {
+            virtual bool mapProfile(C2Config::profile_t, int32_t*) = 0;
+            virtual bool mapProfile(int32_t, C2Config::profile_t*) = 0;
+            virtual bool mapLevel(C2Config::level_t, int32_t*) = 0;
+            virtual bool mapLevel(int32_t, C2Config::level_t*) = 0;
+            virtual ~ProfileLevelMapper() = default;
+        };
+
+        static std::shared_ptr<ProfileLevelMapper>
+        GetProfileLevelMapper(std::string mediaType);
+
+        // convert between bitrates
+        static bool map(C2Config::bitrate_mode_t, int32_t*);
+        static bool map(int32_t, C2Config::bitrate_mode_t*);
+
+        // convert between pcm encodings
+        static bool map(C2Config::pcm_encoding_t, int32_t*);
+        static bool map(int32_t, C2Config::pcm_encoding_t*);
+
+        // convert between picture types
+        static bool map(C2Config::picture_type_t, int32_t*);
+        static bool map(int32_t, C2Config::picture_type_t*);
+
+        // convert between color aspects
+        static bool map(C2Color::range_t, int32_t*);
+        static bool map(int32_t, C2Color::range_t*);
+        static bool map(C2Color::primaries_t, C2Color::matrix_t, int32_t*);
+        static bool map(int32_t, C2Color::primaries_t*, C2Color::matrix_t*);
+        static bool map(C2Color::transfer_t, int32_t*);
+        static bool map(int32_t, C2Color::transfer_t*);
+
+        static bool map(
+                C2Color::range_t, C2Color::primaries_t, C2Color::matrix_t, C2Color::transfer_t,
+                uint32_t *dataSpace);
+
+        static bool map(C2Color::range_t, ColorAspects::Range*);
+        static bool map(ColorAspects::Range, C2Color::range_t*);
+        static bool map(C2Color::primaries_t, ColorAspects::Primaries*);
+        static bool map(ColorAspects::Primaries, C2Color::primaries_t*);
+        static bool map(C2Color::matrix_t, ColorAspects::MatrixCoeffs*);
+        static bool map(ColorAspects::MatrixCoeffs, C2Color::matrix_t*);
+        static bool map(C2Color::transfer_t, ColorAspects::Transfer*);
+        static bool map(ColorAspects::Transfer, C2Color::transfer_t*);
+    };
+}
+
+#endif  // ANDROID_CODEC2_MAPPER_H_
