diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index bd2443d..d2eee33 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -64,10 +64,87 @@
     return ICrypto::kDestinationTypeNativeHandle;
 }
 
+// Codec2Buffer
+
+bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
+        return false;
+    }
+    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->data().linearBlocks().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;
+}
+
+// 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(
+sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
         const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
     C2WriteView writeView(block->map().get());
     if (writeView.error() != C2_OK) {
@@ -76,15 +153,23 @@
     return new LinearBlockBuffer(format, std::move(writeView), block);
 }
 
-C2ConstLinearBlock LinearBlockBuffer::share() {
-    return mBlock->share(offset(), size(), C2Fence());
+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)
-    : MediaCodecBuffer(format, new ABuffer(writeView.data(), writeView.size())),
+    : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
       mWriteView(writeView),
       mBlock(block) {
 }
@@ -92,23 +177,34 @@
 // ConstLinearBlockBuffer
 
 // static
-sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::allocate(
-        const sp<AMessage> &format, const C2ConstLinearBlock &block) {
-    C2ReadView readView(block.map().get());
+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));
+    return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
 }
 
 ConstLinearBlockBuffer::ConstLinearBlockBuffer(
         const sp<AMessage> &format,
-        C2ReadView&& readView)
-    : MediaCodecBuffer(format, new ABuffer(
+        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) {
+      mReadView(readView),
+      mBufferRef(buffer) {
+}
+
+std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
+    return std::move(mBufferRef);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/CCodecBufferChannel.cpp b/media/libstagefright/CCodecBufferChannel.cpp
index 6fba890..449c6aa 100644
--- a/media/libstagefright/CCodecBufferChannel.cpp
+++ b/media/libstagefright/CCodecBufferChannel.cpp
@@ -138,7 +138,7 @@
     virtual bool registerBuffer(
             const std::shared_ptr<C2Buffer> &buffer,
             size_t *index,
-            sp<MediaCodecBuffer> *codecBuffer) = 0;
+            sp<MediaCodecBuffer> *clientBuffer) = 0;
 
     /**
      * Register codec specific data as a buffer to be consistent with
@@ -147,9 +147,7 @@
     virtual bool registerCsd(
             const C2StreamCsdInfo::output * /* csd */,
             size_t * /* index */,
-            sp<MediaCodecBuffer> * /* codecBuffer */) {
-        return false;
-    }
+            sp<MediaCodecBuffer> * /* clientBuffer */) = 0;
 
     /**
      * Release the buffer obtained from registerBuffer() and get the
@@ -181,23 +179,6 @@
 const static size_t kMinBufferArraySize = 16;
 const static size_t kLinearBufferSize = 524288;
 
-template <class T>
-ssize_t findBufferSlot(
-        std::vector<T> *buffers,
-        size_t maxSize,
-        std::function<bool(const T&)> pred) {
-    auto it = std::find_if(buffers->begin(), buffers->end(), pred);
-    if (it == buffers->end()) {
-        if (buffers->size() < maxSize) {
-            buffers->emplace_back();
-            return buffers->size() - 1;
-        } else {
-            return -1;
-        }
-    }
-    return std::distance(buffers->begin(), it);
-}
-
 sp<LinearBlockBuffer> allocateLinearBuffer(
         const std::shared_ptr<C2BlockPool> &pool,
         const sp<AMessage> &format,
@@ -205,41 +186,209 @@
         const C2MemoryUsage &usage) {
     std::shared_ptr<C2LinearBlock> block;
 
-    status_t err = pool->fetchLinearBlock(
-            size,
-            usage,
-            &block);
+    status_t err = pool->fetchLinearBlock(size, usage, &block);
     if (err != OK) {
         return nullptr;
     }
 
-    return LinearBlockBuffer::allocate(format, block);
+    return LinearBlockBuffer::Allocate(format, block);
 }
 
-class Buffer1D : public C2Buffer {
+class BuffersArrayImpl;
+
+/**
+ * Flexible buffer slots implementation.
+ */
+class FlexBuffersImpl {
 public:
-    explicit Buffer1D(C2ConstLinearBlock block) : C2Buffer({ block }) {}
+    FlexBuffersImpl() = default;
+
+    /**
+     * 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.promote() == 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.
+     * \return            C2Buffer object from |buffer|.
+     */
+    std::shared_ptr<C2Buffer> releaseSlot(const sp<MediaCodecBuffer> &buffer) {
+        sp<Codec2Buffer> c2Buffer;
+        size_t index = mBuffers.size();
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (mBuffers[i].clientBuffer.promote() == buffer) {
+                c2Buffer = mBuffers[i].clientBuffer.promote();
+                index = i;
+                break;
+            }
+        }
+        if (c2Buffer == nullptr) {
+            ALOGD("No matching buffer found");
+            return nullptr;
+        }
+        std::shared_ptr<C2Buffer> result = c2Buffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+        return result;
+    }
+
+private:
+    friend class BuffersArrayImpl;
+
+    struct Entry {
+        wp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+    };
+    std::vector<Entry> mBuffers;
 };
 
-class Buffer2D : public C2Buffer {
+/**
+ * Static buffer slots implementation based on a fixed-size array.
+ */
+class BuffersArrayImpl {
 public:
-    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
+    /**
+     * 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) {
+        for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
+            sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer.promote();
+            bool ownedByClient = (clientBuffer != nullptr);
+            if (!ownedByClient) {
+                clientBuffer = allocate();
+            }
+            mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
+        }
+        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,
+     *         NO_MEMORY    if there's no available slot meets the criteria.
+     */
+    status_t grabBuffer(
+            size_t *index,
+            sp<Codec2Buffer> *buffer,
+            std::function<bool(const sp<Codec2Buffer> &)> match =
+                [](const sp<Codec2Buffer> &) { return true; }) {
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()
+                    && match(mBuffers[i].clientBuffer)) {
+                mBuffers[i].ownedByClient = true;
+                *buffer = mBuffers[i].clientBuffer;
+                (*buffer)->meta()->clear();
+                (*buffer)->setRange(0, (*buffer)->capacity());
+                *index = i;
+                return OK;
+            }
+        }
+        return NO_MEMORY;
+    }
+
+    /**
+     * 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.
+     * \return            C2Buffer object from |buffer|.
+     */
+    std::shared_ptr<C2Buffer> returnBuffer(const sp<MediaCodecBuffer> &buffer) {
+        sp<Codec2Buffer> c2Buffer;
+        size_t index = mBuffers.size();
+        for (size_t i = 0; i < mBuffers.size(); ++i) {
+            if (mBuffers[i].clientBuffer == buffer) {
+                if (!mBuffers[i].ownedByClient) {
+                    ALOGD("Client returned a buffer it does not own according to our record: %zu", i);
+                }
+                c2Buffer = mBuffers[i].clientBuffer;
+                mBuffers[i].ownedByClient = false;
+                index = i;
+                break;
+            }
+        }
+        if (c2Buffer == nullptr) {
+            ALOGD("No matching buffer found");
+            return nullptr;
+        }
+        std::shared_ptr<C2Buffer> result = c2Buffer->asC2Buffer();
+        mBuffers[index].compBuffer = result;
+        return result;
+    }
+
+    /**
+     * 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;
+        }
+    }
+
+private:
+    struct Entry {
+        const sp<Codec2Buffer> clientBuffer;
+        std::weak_ptr<C2Buffer> compBuffer;
+        bool ownedByClient;
+    };
+    std::vector<Entry> mBuffers;
 };
 
 class InputBuffersArray : public CCodecBufferChannel::InputBuffers {
 public:
     InputBuffersArray() = default;
 
-    void add(
-            size_t index,
-            const sp<LinearBlockBuffer> &clientBuffer,
-            bool available) {
-        if (mBufferArray.size() <= index) {
-            // TODO: make this more efficient
-            mBufferArray.resize(index + 1);
-        }
-        mBufferArray[index].clientBuffer = clientBuffer;
-        mBufferArray[index].available = available;
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate) {
+        mImpl.initialize(impl, minSize, allocate);
     }
 
     bool isArrayMode() const final { return true; }
@@ -249,52 +398,30 @@
     }
 
     void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        array->clear();
-        for (const Entry &entry : mBufferArray) {
-            array->push(entry.clientBuffer);
-        }
+        mImpl.getArray(array);
     }
 
     bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            if (mBufferArray[i].available && mBufferArray[i].compBuffer.expired()) {
-                mBufferArray[i].available = false;
-                *index = i;
-                *buffer = mBufferArray[i].clientBuffer;
-                (*buffer)->meta()->clear();
-                (*buffer)->setRange(0, (*buffer)->capacity());
-                return true;
-            }
+        sp<Codec2Buffer> c2Buffer;
+        status_t err = mImpl.grabBuffer(index, &c2Buffer);
+        if (err == OK) {
+            c2Buffer->setFormat(mFormat);
+            *buffer = c2Buffer;
+            return true;
         }
         return false;
     }
 
     std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            if (!mBufferArray[i].available && mBufferArray[i].clientBuffer == buffer) {
-                std::shared_ptr<C2Buffer> buffer = std::make_shared<Buffer1D>(mBufferArray[i].clientBuffer->share());
-                mBufferArray[i].available = true;
-                mBufferArray[i].compBuffer = buffer;
-                return buffer;
-            }
-        }
-        return nullptr;
+        return mImpl.returnBuffer(buffer);
     }
 
     void flush() override {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            mBufferArray[i].available = true;
-        }
+        mImpl.flush();
     }
 
 private:
-    struct Entry {
-        sp<LinearBlockBuffer> clientBuffer;
-        std::weak_ptr<C2Buffer> compBuffer;
-        bool available;
-    };
-
-    std::vector<Entry> mBufferArray;
+    BuffersArrayImpl mImpl;
 };
 
 class LinearInputBuffers : public CCodecBufferChannel::InputBuffers {
@@ -302,68 +429,42 @@
     using CCodecBufferChannel::InputBuffers::InputBuffers;
 
     bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        *buffer = nullptr;
-        ssize_t ret = findBufferSlot<wp<LinearBlockBuffer>>(
-                &mBuffers, kMinBufferArraySize,
-                [] (const auto &elem) { return elem.promote() == nullptr; });
-        if (ret < 0) {
-            return false;
-        }
-        // TODO: proper max input size and usage
+        // TODO: proper max input size
         // TODO: read usage from intf
         C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
         sp<LinearBlockBuffer> newBuffer = allocateLinearBuffer(mPool, mFormat, kLinearBufferSize, usage);
         if (newBuffer == nullptr) {
             return false;
         }
-        mBuffers[ret] = newBuffer;
-        *index = ret;
+        *index = mImpl.assignSlot(newBuffer);
         *buffer = newBuffer;
         return true;
     }
 
     std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        auto it = std::find(mBuffers.begin(), mBuffers.end(), buffer);
-        if (it == mBuffers.end()) {
-            return nullptr;
-        }
-        sp<LinearBlockBuffer> codecBuffer = it->promote();
-        // We got sp<> reference from the caller so this should never happen..
-        CHECK(codecBuffer != nullptr);
-        return std::make_shared<Buffer1D>(codecBuffer->share());
+        return mImpl.releaseSlot(buffer);
     }
 
     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() final {
         std::unique_ptr<InputBuffersArray> array(new InputBuffersArray);
         array->setFormat(mFormat);
-        // TODO
-        const size_t size = std::max(kMinBufferArraySize, mBuffers.size());
-        mBuffers.resize(size);
-        for (size_t i = 0; i < size; ++i) {
-            sp<LinearBlockBuffer> clientBuffer = mBuffers[i].promote();
-            bool available = false;
-            if (clientBuffer == nullptr) {
-                // TODO: proper max input size
-                // TODO: read usage from intf
-                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-                clientBuffer = allocateLinearBuffer(mPool, mFormat, kLinearBufferSize, usage);
-                available = true;
-            }
-            array->add(
-                    i,
-                    clientBuffer,
-                    available);
-        }
+        array->initialize(
+                mImpl,
+                kMinBufferArraySize,
+                [pool = mPool, format = mFormat] () -> sp<Codec2Buffer> {
+                    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                    return allocateLinearBuffer(pool, format, kLinearBufferSize, usage);
+                });
         return std::move(array);
     }
 
 private:
-    // Buffers we passed to the client. The index of a buffer matches what
-    // was passed in BufferCallback::onInputBufferAvailable().
-    std::vector<wp<LinearBlockBuffer>> mBuffers;
+    FlexBuffersImpl mImpl;
 };
 
 class GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
@@ -396,18 +497,11 @@
 public:
     using CCodecBufferChannel::OutputBuffers::OutputBuffers;
 
-    void add(
-            size_t index,
-            const sp<MediaCodecBuffer> &clientBuffer,
-            const std::shared_ptr<C2Buffer> &compBuffer,
-            bool available) {
-        if (mBufferArray.size() <= index) {
-            // TODO: make this more efficient
-            mBufferArray.resize(index + 1);
-        }
-        mBufferArray[index].clientBuffer = clientBuffer;
-        mBufferArray[index].compBuffer = compBuffer;
-        mBufferArray[index].available = available;
+    void initialize(
+            const FlexBuffersImpl &impl,
+            size_t minSize,
+            std::function<sp<Codec2Buffer>()> allocate) {
+        mImpl.initialize(impl, minSize, allocate);
     }
 
     bool isArrayMode() const final { return true; }
@@ -419,125 +513,69 @@
     bool registerBuffer(
             const std::shared_ptr<C2Buffer> &buffer,
             size_t *index,
-            sp<MediaCodecBuffer> *codecBuffer) final {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            if (mBufferArray[i].available && copy(buffer, mBufferArray[i].clientBuffer)) {
-                *index = i;
-                *codecBuffer = mBufferArray[i].clientBuffer;
-                (*codecBuffer)->setFormat(mFormat);
-                (*codecBuffer)->meta()->clear();
-                mBufferArray[i].compBuffer = buffer;
-                mBufferArray[i].available = false;
-                return true;
-            }
+            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 != OK) {
+            return false;
         }
-        return false;
+        if (!c2Buffer->copy(buffer)) {
+            return false;
+        }
+        c2Buffer->setFormat(mFormat);
+        *clientBuffer = c2Buffer;
+        return true;
     }
 
     bool registerCsd(
             const C2StreamCsdInfo::output *csd,
             size_t *index,
-            sp<MediaCodecBuffer> *codecBuffer) final {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            if (mBufferArray[i].available
-                    && mBufferArray[i].clientBuffer->capacity() >= csd->flexCount()) {
-                // TODO: proper format update
-                sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy(csd->m.value, csd->flexCount());
-                mFormat = mFormat->dup();
-                mFormat->setBuffer("csd-0", csdBuffer);
-
-                memcpy(mBufferArray[i].clientBuffer->base(), csd->m.value, csd->flexCount());
-                mBufferArray[i].clientBuffer->setRange(0, csd->flexCount());
-                *index = i;
-                *codecBuffer = mBufferArray[i].clientBuffer;
-                (*codecBuffer)->setFormat(mFormat);
-                (*codecBuffer)->meta()->clear();
-                mBufferArray[i].available = false;
-                return true;
-            }
+            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 false;
         }
-        return false;
+        // TODO: proper format update
+        sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy(csd->m.value, csd->flexCount());
+        mFormat = mFormat->dup();
+        mFormat->setBuffer("csd-0", csdBuffer);
+
+        memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
+        c2Buffer->setRange(0, csd->flexCount());
+        c2Buffer->setFormat(mFormat);
+        *clientBuffer = c2Buffer;
+        return true;
     }
 
     std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) final {
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            if (!mBufferArray[i].available && mBufferArray[i].clientBuffer == buffer) {
-                mBufferArray[i].available = true;
-                return std::move(mBufferArray[i].compBuffer);
-            }
-        }
-        return nullptr;
+        return mImpl.returnBuffer(buffer);
     }
 
-    void flush(
-            const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
+    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
         (void) flushedWork;
-        for (size_t i = 0; i < mBufferArray.size(); ++i) {
-            mBufferArray[i].available = true;
-            mBufferArray[i].compBuffer.reset();
-        }
+        mImpl.flush();
     }
 
-    virtual bool copy(
-            const std::shared_ptr<C2Buffer> &buffer,
-            const sp<MediaCodecBuffer> &clientBuffer) = 0;
-
     void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        array->clear();
-        for (const Entry &entry : mBufferArray) {
-            array->push(entry.clientBuffer);
-        }
+        mImpl.getArray(array);
     }
 
 private:
-    struct Entry {
-        sp<MediaCodecBuffer> clientBuffer;
-        std::shared_ptr<C2Buffer> compBuffer;
-        bool available;
-    };
-
-    std::vector<Entry> mBufferArray;
+    BuffersArrayImpl mImpl;
 };
 
-class LinearOutputBuffersArray : public OutputBuffersArray {
-public:
-    using OutputBuffersArray::OutputBuffersArray;
-
-    bool copy(
-            const std::shared_ptr<C2Buffer> &buffer,
-            const sp<MediaCodecBuffer> &clientBuffer) final {
-        if (!buffer) {
-            clientBuffer->setRange(0u, 0u);
-            return true;
-        }
-        C2ReadView view = buffer->data().linearBlocks().front().map().get();
-        if (clientBuffer->capacity() < view.capacity()) {
-            ALOGV("view.capacity() = %u", view.capacity());
-            return false;
-        }
-        clientBuffer->setRange(0u, view.capacity());
-        memcpy(clientBuffer->data(), view.data(), view.capacity());
-        return true;
-    }
-};
-
-class GraphicOutputBuffersArray : public OutputBuffersArray {
-public:
-    using OutputBuffersArray::OutputBuffersArray;
-
-    bool copy(
-            const std::shared_ptr<C2Buffer> &buffer,
-            const sp<MediaCodecBuffer> &clientBuffer) final {
-        if (!buffer) {
-            clientBuffer->setRange(0u, 0u);
-            return true;
-        }
-        clientBuffer->setRange(0u, 1u);
-        return true;
-    }
-};
-
-// Flexible in a sense that it does not have fixed array size.
 class FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers {
 public:
     using CCodecBufferChannel::OutputBuffers::OutputBuffers;
@@ -545,56 +583,31 @@
     bool registerBuffer(
             const std::shared_ptr<C2Buffer> &buffer,
             size_t *index,
-            sp<MediaCodecBuffer> *codecBuffer) override {
-        *codecBuffer = nullptr;
-        ssize_t ret = findBufferSlot<BufferInfo>(
-                &mBuffers,
-                std::numeric_limits<size_t>::max(),
-                [] (const auto &elem) { return elem.clientBuffer.promote() == nullptr; });
-        if (ret < 0) {
-            return false;
-        }
-        sp<MediaCodecBuffer> newBuffer = convert(buffer);
-        mBuffers[ret] = { newBuffer, buffer };
-        *index = ret;
-        *codecBuffer = newBuffer;
+            sp<MediaCodecBuffer> *clientBuffer) override {
+        sp<Codec2Buffer> newBuffer = wrap(buffer);
+        *index = mImpl.assignSlot(newBuffer);
+        *clientBuffer = newBuffer;
         return true;
     }
 
     bool registerCsd(
             const C2StreamCsdInfo::output *csd,
             size_t *index,
-            sp<MediaCodecBuffer> *codecBuffer) final {
-        *codecBuffer = nullptr;
-        ssize_t ret = findBufferSlot<BufferInfo>(
-                &mBuffers,
-                std::numeric_limits<size_t>::max(),
-                [] (const auto &elem) { return elem.clientBuffer.promote() == nullptr; });
-        if (ret < 0) {
-            return false;
-        }
+            sp<MediaCodecBuffer> *clientBuffer) final {
         // TODO: proper format update
         sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy(csd->m.value, csd->flexCount());
         mFormat = mFormat->dup();
         mFormat->setBuffer("csd-0", csdBuffer);
-        sp<MediaCodecBuffer> newBuffer = new MediaCodecBuffer(mFormat, csdBuffer);
-        mBuffers[ret] = { newBuffer, nullptr };
-        *index = ret;
-        *codecBuffer = newBuffer;
+
+        sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(mFormat, csdBuffer);
+        *index = mImpl.assignSlot(newBuffer);
+        *clientBuffer = newBuffer;
         return true;
     }
 
     std::shared_ptr<C2Buffer> releaseBuffer(
             const sp<MediaCodecBuffer> &buffer) override {
-        auto it = std::find_if(
-                mBuffers.begin(), mBuffers.end(),
-                [buffer] (const auto &elem) {
-                    return elem.clientBuffer.promote() == buffer;
-                });
-        if (it == mBuffers.end()) {
-            return nullptr;
-        }
-        return std::move(it->bufferRef);
+        return mImpl.releaseSlot(buffer);
     }
 
     void flush(
@@ -604,27 +617,31 @@
         // track of the flushed work.
     }
 
-    virtual sp<MediaCodecBuffer> convert(const std::shared_ptr<C2Buffer> &buffer) = 0;
+    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() override {
+        std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray);
+        array->setFormat(mFormat);
+        array->initialize(
+                mImpl,
+                kMinBufferArraySize,
+                [this]() { return allocateArrayBuffer(); });
+        return std::move(array);
+    }
 
-protected:
-    struct BufferInfo {
-        // wp<> of MediaCodecBuffer for MediaCodec.
-        wp<MediaCodecBuffer> clientBuffer;
-        // Buffer reference to hold until clientBuffer is valid.
-        std::shared_ptr<C2Buffer> bufferRef;
-    };
-    // Buffers we passed to the client. The index of a buffer matches what
-    // was passed in BufferCallback::onInputBufferAvailable().
-    std::vector<BufferInfo> mBuffers;
+    virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
+
+    virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
+
+private:
+    FlexBuffersImpl mImpl;
 };
 
 class LinearOutputBuffers : public FlexOutputBuffers {
 public:
     using FlexOutputBuffers::FlexOutputBuffers;
 
-    virtual sp<MediaCodecBuffer> convert(const std::shared_ptr<C2Buffer> &buffer) override {
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
         if (buffer == nullptr) {
-            return new MediaCodecBuffer(mFormat, new ABuffer(nullptr, 0));
+            return new DummyContainerBuffer(mFormat, buffer);
         }
         if (buffer->data().type() != C2BufferData::LINEAR) {
             // We expect linear output buffers from the component.
@@ -634,28 +651,12 @@
             // We expect one and only one linear block from the component.
             return nullptr;
         }
-        return ConstLinearBlockBuffer::allocate(mFormat, buffer->data().linearBlocks().front());
+        return ConstLinearBlockBuffer::Allocate(mFormat, buffer);
     }
 
-    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() override {
-        std::unique_ptr<OutputBuffersArray> array(new LinearOutputBuffersArray);
-        array->setFormat(mFormat);
-
-        const size_t size = std::max(kMinBufferArraySize, mBuffers.size());
-        mBuffers.resize(size);
-        for (size_t i = 0; i < size; ++i) {
-            sp<MediaCodecBuffer> clientBuffer = mBuffers[i].clientBuffer.promote();
-            std::shared_ptr<C2Buffer> compBuffer = mBuffers[i].bufferRef;
-            bool available = false;
-            if (clientBuffer == nullptr) {
-                // TODO: proper max input size
-                clientBuffer = new MediaCodecBuffer(mFormat, new ABuffer(kLinearBufferSize));
-                available = true;
-                compBuffer.reset();
-            }
-            array->add(i, clientBuffer, compBuffer, available);
-        }
-        return std::move(array);
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        // TODO: proper max output size
+        return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
     }
 };
 
@@ -663,29 +664,12 @@
 public:
     using FlexOutputBuffers::FlexOutputBuffers;
 
-    sp<MediaCodecBuffer> convert(const std::shared_ptr<C2Buffer> &buffer) override {
-        return new MediaCodecBuffer(
-                mFormat, buffer ? new ABuffer(nullptr, 1) : new ABuffer(nullptr, 0));
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
+        return new DummyContainerBuffer(mFormat, buffer);
     }
 
-    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() override {
-        std::unique_ptr<OutputBuffersArray> array(new GraphicOutputBuffersArray);
-        array->setFormat(mFormat);
-
-        const size_t size = std::max(kMinBufferArraySize, mBuffers.size());
-        mBuffers.resize(size);
-        for (size_t i = 0; i < size; ++i) {
-            sp<MediaCodecBuffer> clientBuffer = mBuffers[i].clientBuffer.promote();
-            std::shared_ptr<C2Buffer> compBuffer = mBuffers[i].bufferRef;
-            bool available = false;
-            if (clientBuffer == nullptr) {
-                clientBuffer = new MediaCodecBuffer(mFormat, new ABuffer(nullptr, 1));
-                available = true;
-                compBuffer.reset();
-            }
-            array->add(i, clientBuffer, compBuffer, available);
-        }
-        return std::move(array);
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        return new DummyContainerBuffer(mFormat);
     }
 };
 
diff --git a/media/libstagefright/codec2/SimpleC2Component.cpp b/media/libstagefright/codec2/SimpleC2Component.cpp
index 01e9e43..aaefd31 100644
--- a/media/libstagefright/codec2/SimpleC2Component.cpp
+++ b/media/libstagefright/codec2/SimpleC2Component.cpp
@@ -366,26 +366,6 @@
     }
 }
 
-namespace {
-
-class GraphicBuffer : public C2Buffer {
-public:
-    GraphicBuffer(
-            const std::shared_ptr<C2GraphicBlock> &block,
-            const C2Rect &crop)
-        : C2Buffer({ block->share(crop, ::android::C2Fence()) }) {}
-};
-
-
-class LinearBuffer : public C2Buffer {
-public:
-    LinearBuffer(
-            const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size)
-        : C2Buffer({ block->share(offset, size, ::android::C2Fence()) }) {}
-};
-
-}  // namespace
-
 std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
         const std::shared_ptr<C2LinearBlock> &block) {
     return createLinearBuffer(block, block->offset(), block->size());
@@ -393,7 +373,7 @@
 
 std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
         const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
-    return std::make_shared<LinearBuffer>(block, offset, size);
+    return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::android::C2Fence()));
 }
 
 std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
@@ -402,9 +382,8 @@
 }
 
 std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
-        const std::shared_ptr<C2GraphicBlock> &block,
-        const C2Rect &crop) {
-    return std::make_shared<GraphicBuffer>(block, crop);
+        const std::shared_ptr<C2GraphicBlock> &block, const C2Rect &crop) {
+    return C2Buffer::CreateGraphicBuffer(block->share(crop, ::android::C2Fence()));
 }
 
 } // namespace android
diff --git a/media/libstagefright/include/Codec2Buffer.h b/media/libstagefright/include/Codec2Buffer.h
index 6d85e83..9766b41 100644
--- a/media/libstagefright/include/Codec2Buffer.h
+++ b/media/libstagefright/include/Codec2Buffer.h
@@ -24,17 +24,100 @@
 
 namespace android {
 
+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);
+};
+
+/**
+ * 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 MediaCodecBuffer {
+class LinearBlockBuffer : public Codec2Buffer {
 public:
-    static sp<LinearBlockBuffer> allocate(
+    /**
+     * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
+     */
+    static sp<LinearBlockBuffer> Allocate(
             const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
 
     virtual ~LinearBlockBuffer() = default;
 
-    C2ConstLinearBlock share();
+    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(
@@ -50,20 +133,27 @@
 /**
  * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
  */
-class ConstLinearBlockBuffer : public MediaCodecBuffer {
+class ConstLinearBlockBuffer : public Codec2Buffer {
 public:
-    static sp<ConstLinearBlockBuffer> allocate(
-            const sp<AMessage> &format, const C2ConstLinearBlock &block);
+    /**
+     * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
+     */
+    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);
+            C2ReadView &&readView,
+            const std::shared_ptr<C2Buffer> &buffer);
     ConstLinearBlockBuffer() = delete;
 
     C2ReadView mReadView;
+    std::shared_ptr<C2Buffer> mBufferRef;
 };
 
 }  // namespace android
