diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e2d5d0d..22b1e59 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -87,66 +87,6 @@
 }
 
 cc_library_shared {
-    name: "libstagefright_ccodec",
-
-    local_include_dirs: ["include"],
-
-    srcs: [
-        "C2OMXNode.cpp",
-        "CCodec.cpp",
-        "CCodecBufferChannel.cpp",
-        "Codec2Buffer.cpp",
-        "Codec2InfoBuilder.cpp",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    header_libs: [
-        "libstagefright_codec2_internal",
-    ],
-
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libgui",
-        "libhidlallocatorutils",
-        "libhidlbase",
-        "liblog",
-        "libmedia",
-        "libmedia_omx",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_codecbase",
-        "libstagefright_foundation",
-        "libstagefright_omx_utils",
-        "libstagefright_xmlparser",
-        "libui",
-        "libutils",
-        // TODO: Remove libv4l2_c2_componentstore.
-        "libv4l2_c2componentstore",
-        "android.hardware.cas.native@1.0",
-
-        // TODO: do not link directly with impl
-        "libstagefright_bufferqueue_helper",
-        "android.hardware.media.c2@1.0-service-impl",
-    ],
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        diag: {
-            cfi: true,
-        },
-    },
-}
-
-cc_library_shared {
     name: "libstagefright",
 
     srcs: [
@@ -220,7 +160,6 @@
         "libui",
         "libutils",
         "libmedia_helper",
-        "libstagefright_ccodec",
         "libstagefright_codecbase",
         "libstagefright_foundation",
         "libstagefright_omx",
diff --git a/media/libstagefright/C2OMXNode.cpp b/media/libstagefright/C2OMXNode.cpp
deleted file mode 100644
index 04faa28..0000000
--- a/media/libstagefright/C2OMXNode.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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 "include/C2OMXNode.h"
-
-namespace android {
-
-namespace {
-
-class Buffer2D : public C2Buffer {
-public:
-    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
-};
-
-}  // namespace
-
-C2OMXNode::C2OMXNode(const std::shared_ptr<C2Component> &comp) : mComp(comp) {}
-
-status_t C2OMXNode::freeNode() {
-    mComp.reset();
-    return OK;
-}
-
-status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    (void)cmd;
-    (void)param;
-    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: {
-            // TODO: read from intf()
-            OMX_U32 *usage = (OMX_U32 *)params;
-            *usage = GRALLOC_USAGE_SW_READ_OFTEN;
-            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 = 1080;
-            pDef->format.video.nFrameHeight = 1920;
-            err = OK;
-            break;
-        }
-        default:
-            break;
-    }
-    return err;
-}
-
-status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
-    (void)index;
-    (void)params;
-    (void)size;
-    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<C2Component> comp = mComp.lock();
-    if (!comp) {
-        return NO_INIT;
-    }
-
-    uint32_t c2Flags = 0;
-    std::shared_ptr<C2GraphicBlock> block;
-
-    C2Handle *handle = nullptr;
-    if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
-        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) {
-        c2Flags = C2FrameData::FLAG_END_OF_STREAM;
-    } else {
-        return BAD_VALUE;
-    }
-
-    std::unique_ptr<C2Work> work(new C2Work);
-    work->input.flags = (C2FrameData::flags_t)c2Flags;
-    work->input.ordinal.timestamp = timestamp;
-    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())),
-                [handle, buffer, source = getSource()](C2Buffer *ptr) {
-                    delete ptr;
-                    native_handle_delete(handle);
-                    // 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_nb(&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;
-    }
-    // TODO: fill intf() with info inside |msg|.
-    return OK;
-}
-
-sp<IOMXBufferSource> C2OMXNode::getSource() {
-    return mBufferSource;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/CCodec.cpp b/media/libstagefright/CCodec.cpp
deleted file mode 100644
index 322f9fd..0000000
--- a/media/libstagefright/CCodec.cpp
+++ /dev/null
@@ -1,916 +0,0 @@
-/*
- * 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 <cutils/properties.h>
-#include <utils/Log.h>
-
-#include <thread>
-
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-
-#include <android/IOMXBufferSource.h>
-#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-#include <gui/Surface.h>
-#include <media/stagefright/codec2/1.0/InputSurface.h>
-#include <media/stagefright/BufferProducerWrapper.h>
-#include <media/stagefright/CCodec.h>
-#include <media/stagefright/PersistentSurface.h>
-
-#include "include/C2OMXNode.h"
-#include "include/CCodecBufferChannel.h"
-#include "include/InputSurfaceWrapper.h"
-
-namespace android {
-
-using namespace std::chrono_literals;
-using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
-
-namespace {
-
-class CCodecWatchdog : public AHandler {
-private:
-    enum {
-        kWhatRegister,
-        kWhatWatch,
-    };
-    constexpr static int64_t kWatchIntervalUs = 3000000;  // 3 secs
-
-public:
-    static sp<CCodecWatchdog> getInstance() {
-        Mutexed<sp<CCodecWatchdog>>::Locked instance(sInstance);
-        if (*instance == nullptr) {
-            *instance = new CCodecWatchdog;
-            (*instance)->init();
-        }
-        return *instance;
-    }
-
-    ~CCodecWatchdog() = default;
-
-    void registerCodec(CCodec *codec) {
-        sp<AMessage> msg = new AMessage(kWhatRegister, this);
-        msg->setPointer("codec", codec);
-        msg->post();
-    }
-
-protected:
-    void onMessageReceived(const sp<AMessage> &msg) {
-        switch (msg->what()) {
-            case kWhatRegister: {
-                void *ptr = nullptr;
-                CHECK(msg->findPointer("codec", &ptr));
-                Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs);
-                codecs->emplace_back((CCodec *)ptr);
-                break;
-            }
-
-            case kWhatWatch: {
-                Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs);
-                for (auto it = codecs->begin(); it != codecs->end(); ) {
-                    sp<CCodec> codec = it->promote();
-                    if (codec == nullptr) {
-                        it = codecs->erase(it);
-                        continue;
-                    }
-                    codec->initiateReleaseIfStuck();
-                    ++it;
-                }
-                msg->post(kWatchIntervalUs);
-                break;
-            }
-
-            default: {
-                TRESPASS("CCodecWatchdog: unrecognized message");
-            }
-        }
-    }
-
-private:
-    CCodecWatchdog() : mLooper(new ALooper) {}
-
-    void init() {
-        mLooper->setName("CCodecWatchdog");
-        mLooper->registerHandler(this);
-        mLooper->start();
-        (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs);
-    }
-
-    static Mutexed<sp<CCodecWatchdog>> sInstance;
-
-    sp<ALooper> mLooper;
-    Mutexed<std::list<wp<CCodec>>> mCodecs;
-};
-
-Mutexed<sp<CCodecWatchdog>> CCodecWatchdog::sInstance;
-
-class CCodecListener : public C2Component::Listener {
-public:
-    explicit CCodecListener(const wp<CCodec> &codec) : mCodec(codec) {}
-
-    virtual void onWorkDone_nb(
-            std::weak_ptr<C2Component> component,
-            std::list<std::unique_ptr<C2Work>> workItems) override {
-        (void)component;
-        sp<CCodec> codec(mCodec.promote());
-        if (!codec) {
-            return;
-        }
-        codec->onWorkDone(workItems);
-    }
-
-    virtual void onTripped_nb(
-            std::weak_ptr<C2Component> component,
-            std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
-        // TODO
-        (void)component;
-        (void)settingResult;
-    }
-
-    virtual void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override {
-        // TODO
-        (void)component;
-        (void)errorCode;
-    }
-
-private:
-    wp<CCodec> mCodec;
-};
-
-class C2InputSurfaceWrapper : public InputSurfaceWrapper {
-public:
-    explicit C2InputSurfaceWrapper(const sp<InputSurface> &surface) : mSurface(surface) {}
-    ~C2InputSurfaceWrapper() override = default;
-
-    status_t connect(const std::shared_ptr<C2Component> &comp) override {
-        if (mConnection != nullptr) {
-            return ALREADY_EXISTS;
-        }
-        mConnection = mSurface->connectToComponent(comp);
-        return OK;
-    }
-
-    void disconnect() override {
-        if (mConnection != nullptr) {
-            mConnection->disconnect();
-            mConnection.clear();
-        }
-    }
-
-private:
-    sp<InputSurface> mSurface;
-    sp<InputSurfaceConnection> mConnection;
-};
-
-class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
-public:
-    explicit GraphicBufferSourceWrapper(const sp<IGraphicBufferSource> &source) : mSource(source) {}
-    ~GraphicBufferSourceWrapper() override = default;
-
-    status_t connect(const std::shared_ptr<C2Component> &comp) override {
-        // TODO: proper color aspect & dataspace
-        android_dataspace dataSpace = HAL_DATASPACE_BT709;
-
-        mNode = new C2OMXNode(comp);
-        mSource->configure(mNode, dataSpace);
-
-        // TODO: configure according to intf().
-
-        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;
-    }
-
-    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();
-    }
-
-private:
-    sp<IGraphicBufferSource> mSource;
-    sp<C2OMXNode> mNode;
-};
-
-}  // namespace
-
-CCodec::CCodec()
-    : mChannel(new CCodecBufferChannel([this] (status_t err, enum ActionCode actionCode) {
-          mCallback->onError(err, actionCode);
-      })) {
-    CCodecWatchdog::getInstance()->registerCodec(this);
-}
-
-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;
-    }
-    ALOGV("allocate(%s)", codecInfo->getCodecName());
-    mListener.reset(new CCodecListener(this));
-
-    AString componentName = codecInfo->getCodecName();
-    // TODO: use codecInfo->getOwnerName() for connecting to remote process.
-
-    std::shared_ptr<C2Component> comp;
-    c2_status_t err = GetCodec2PlatformComponentStore()->createComponent(
-            componentName.c_str(), &comp);
-    static bool v4l2Enabled =
-            property_get_bool("debug.stagefright.ccodec_v4l2", false);
-    if (err != C2_OK && v4l2Enabled) {
-        err = GetCodec2VDAComponentStore()->createComponent(
-                componentName.c_str(), &comp);
-    }
-    if (err != C2_OK) {
-        ALOGE("Failed Create component: %s", componentName.c_str());
-        Mutexed<State>::Locked state(mState);
-        state->set(RELEASED);
-        state.unlock();
-        mCallback->onError(err, ACTION_CODE_FATAL);
-        state.lock();
-        return;
-    }
-    ALOGV("Success Create component: %s", componentName.c_str());
-    comp->setListener_vb(mListener, C2_MAY_BLOCK);
-    mChannel->setComponent(comp);
-    auto setAllocated = [this, comp] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATING) {
-            state->set(RELEASED);
-            return UNKNOWN_ERROR;
-        }
-        state->set(ALLOCATED);
-        state->comp = comp;
-        return OK;
-    };
-    if (tryAndReportOnError(setAllocated) != OK) {
-        return;
-    }
-    mCallback->onComponentAllocated(comp->intf()->getName().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<C2ComponentInterface> intf;
-    auto checkAllocated = [this, &intf] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATED) {
-            state->set(RELEASED);
-            return UNKNOWN_ERROR;
-        }
-        intf = state->comp->intf();
-        return OK;
-    };
-    if (tryAndReportOnError(checkAllocated) != OK) {
-        return;
-    }
-
-    sp<AMessage> inputFormat(new AMessage);
-    sp<AMessage> outputFormat(new AMessage);
-    auto doConfig = [=] {
-        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) != (intf->getName().find("encoder") == std::string::npos)) {
-            return UNKNOWN_ERROR;
-        }
-
-        sp<RefBase> obj;
-        if (msg->findObject("native-window", &obj)) {
-            sp<Surface> surface = static_cast<Surface *>(obj.get());
-            setSurface(surface);
-        }
-
-        std::vector<std::unique_ptr<C2Param>> params;
-        std::initializer_list<C2Param::Index> indices {
-            C2PortMimeConfig::input::PARAM_TYPE,
-            C2PortMimeConfig::output::PARAM_TYPE,
-        };
-        c2_status_t c2err = intf->query_vb(
-                {},
-                indices,
-                C2_DONT_BLOCK,
-                &params);
-        if (c2err != C2_OK) {
-            ALOGE("Failed to query component interface: %d", c2err);
-            return UNKNOWN_ERROR;
-        }
-        if (params.size() != indices.size()) {
-            ALOGE("Component returns wrong number of params");
-            return UNKNOWN_ERROR;
-        }
-        if (!params[0] || !params[1]) {
-            ALOGE("Component returns null params");
-            return UNKNOWN_ERROR;
-        }
-        inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value);
-        outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value);
-
-        // XXX: hack
-        bool audio = mime.startsWithIgnoreCase("audio/");
-        if (encoder) {
-            if (audio) {
-                inputFormat->setInt32("channel-count", 1);
-                inputFormat->setInt32("sample-rate", 44100);
-                outputFormat->setInt32("channel-count", 1);
-                outputFormat->setInt32("sample-rate", 44100);
-            } else {
-                outputFormat->setInt32("width", 1080);
-                outputFormat->setInt32("height", 1920);
-            }
-        } else {
-            if (audio) {
-                outputFormat->setInt32("channel-count", 2);
-                outputFormat->setInt32("sample-rate", 44100);
-            } else {
-                int32_t tmp;
-                if (msg->findInt32("width", &tmp)) {
-                    outputFormat->setInt32("width", tmp);
-                }
-                if (msg->findInt32("height", &tmp)) {
-                    outputFormat->setInt32("height", tmp);
-                }
-            }
-        }
-
-        // TODO
-
-        return OK;
-    };
-    if (tryAndReportOnError(doConfig) != OK) {
-        return;
-    }
-
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        formats->inputFormat = inputFormat;
-        formats->outputFormat = outputFormat;
-    }
-    mCallback->onComponentConfigured(inputFormat, outputFormat);
-}
-
-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->intf()->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() {
-    // TODO: get this from codec process
-    sp<InputSurface> surface(InputSurface::Create());
-
-    // TODO: get proper error code.
-    status_t err = (surface == nullptr) ? UNKNOWN_ERROR : OK;
-    if (err != OK) {
-        ALOGE("Failed to initialize input surface: %d", err);
-        mCallback->onInputSurfaceCreationFailed(err);
-        return;
-    }
-
-    err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(surface));
-    if (err != OK) {
-        ALOGE("Failed to set up input surface: %d", err);
-        mCallback->onInputSurfaceCreationFailed(err);
-        return;
-    }
-
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    mCallback->onInputSurfaceCreated(
-            inputFormat,
-            outputFormat,
-            new BufferProducerWrapper(new H2BGraphicBufferProducer(surface)));
-}
-
-status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
-    status_t err = mChannel->setInputSurface(surface);
-    if (err != OK) {
-        return err;
-    }
-
-    // TODO: configure |surface| with other settings.
-    return OK;
-}
-
-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) {
-    status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-            surface->getBufferSource()));
-    if (err != OK) {
-        ALOGE("Failed to set up input surface: %d", err);
-        mCallback->onInputSurfaceDeclined(err);
-        return;
-    }
-
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    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<C2Component> 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) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    }
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    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 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);
-    }
-
-    (new AMessage(kWhatStop, this))->post();
-}
-
-void CCodec::stop() {
-    std::shared_ptr<C2Component> 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;
-    }
-    mChannel->stop();
-    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);
-    }
-
-    std::thread([this, sendCallback] { release(sendCallback); }).detach();
-}
-
-void CCodec::release(bool sendCallback) {
-    std::shared_ptr<C2Component> comp;
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == RELEASED) {
-            if (sendCallback) {
-                state.unlock();
-                mCallback->onReleaseCompleted();
-                state.lock();
-            }
-            return;
-        }
-        comp = state->comp;
-    }
-    mChannel->stop();
-    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;
-    }
-
-    (new AMessage(kWhatFlush, this))->post();
-}
-
-void CCodec::flush() {
-    std::shared_ptr<C2Component> 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;
-    }
-
-    mChannel->stop();
-
-    std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err = comp->flush_sm(C2Component::FLUSH_COMPONENT, &flushedWork);
-    if (err != C2_OK) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-    }
-
-    mChannel->flush(flushedWork);
-
-    {
-        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 CCodec::signalSetParameters(const sp<AMessage> &msg) {
-    // TODO
-    (void) msg;
-}
-
-void CCodec::signalEndOfInputStream() {
-    // TODO
-    mCallback->onSignaledInputEOS(INVALID_OPERATION);
-}
-
-void CCodec::signalRequestIDRFrame() {
-    // TODO
-}
-
-void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
-    Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
-    queue->splice(queue->end(), workItems);
-    (new AMessage(kWhatWorkDone, this))->post();
-}
-
-void CCodec::onMessageReceived(const sp<AMessage> &msg) {
-    TimePoint now = std::chrono::steady_clock::now();
-    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 + 50ms, "configure");
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-            configure(format);
-            break;
-        }
-        case kWhatStart: {
-            // C2Component::start() should return within 500ms.
-            setDeadline(now + 550ms, "start");
-            start();
-            break;
-        }
-        case kWhatStop: {
-            // C2Component::stop() should return within 500ms.
-            setDeadline(now + 550ms, "stop");
-            stop();
-            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 kWhatWorkDone: {
-            std::unique_ptr<C2Work> work;
-            {
-                Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
-                if (queue->empty()) {
-                    break;
-                }
-                work.swap(queue->front());
-                queue->pop_front();
-                if (!queue->empty()) {
-                    (new AMessage(kWhatWorkDone, this))->post();
-                }
-            }
-            mChannel->onWorkDone(work);
-            break;
-        }
-        default: {
-            ALOGE("unrecognized message");
-            break;
-        }
-    }
-    setDeadline(TimePoint::max(), "none");
-}
-
-void CCodec::setDeadline(const TimePoint &newDeadline, const char *name) {
-    Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
-    deadline->set(newDeadline, name);
-}
-
-void CCodec::initiateReleaseIfStuck() {
-    std::string name;
-    {
-        Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
-        if (deadline->get() >= std::chrono::steady_clock::now()) {
-            // We're not stuck.
-            return;
-        }
-        name = deadline->getName();
-    }
-
-    ALOGW("previous call to %s exceeded timeout", name.c_str());
-    initiateRelease(false);
-    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-}
-
-}  // namespace android
-
-extern "C" android::CodecBase *CreateCodec() {
-    return new android::CCodec;
-}
diff --git a/media/libstagefright/CCodecBufferChannel.cpp b/media/libstagefright/CCodecBufferChannel.cpp
deleted file mode 100644
index cbe4f16..0000000
--- a/media/libstagefright/CCodecBufferChannel.cpp
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * 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 <thread>
-
-#include <C2AllocatorGralloc.h>
-#include <C2PlatformSupport.h>
-#include <C2BlockInternal.h>
-
-#include <android/hardware/cas/native/1.0/IDescrambler.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/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/MediaCodecBuffer.h>
-#include <system/window.h>
-
-#include "include/CCodecBufferChannel.h"
-#include "include/Codec2Buffer.h"
-#include "include/SecureBuffer.h"
-#include "include/SharedMemoryBuffer.h"
-
-namespace android {
-
-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() = default;
-    virtual ~Buffers() = default;
-
-    /**
-     * Set format for MediaCodec-facing buffers.
-     */
-    void setFormat(const sp<AMessage> &format) {
-        CHECK(format != nullptr);
-        mFormat = format;
-    }
-
-    /**
-     * 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:
-    // 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() = default;
-    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 empty shared_ptr if the
-     * buffer is not on file.
-     */
-    virtual std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) = 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() = 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() = default;
-    virtual ~OutputBuffers() = default;
-
-    /**
-     * Register output C2Buffer from the component and obtain corresponding
-     * index and MediaCodecBuffer object. Returns false if registration
-     * fails.
-     */
-    virtual bool 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 bool 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 empty shared_ptr if the
-     * buffer is not on file.
-     */
-    virtual std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) = 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() = 0;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
-};
-
-namespace {
-
-// TODO: get this info from component
-const static size_t kMinBufferArraySize = 16;
-const static size_t kLinearBufferSize = 524288;
-const static size_t kMaxGraphicBufferRefCount = 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() = 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;
-};
-
-/**
- * Static buffer slots implementation based on a fixed-size array.
- */
-class BuffersArrayImpl {
-public:
-    /**
-     * 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;
-    ~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() 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;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.returnBuffer(buffer);
-    }
-
-    void flush() override {
-        mImpl.flush();
-    }
-
-private:
-    BuffersArrayImpl mImpl;
-};
-
-class LinearInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
-    using CCodecBufferChannel::InputBuffers::InputBuffers;
-
-    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        // TODO: proper max input size
-        // TODO: read usage from intf
-        sp<Codec2Buffer> newBuffer = alloc(kLinearBufferSize);
-        if (newBuffer == nullptr) {
-            return false;
-        }
-        *index = mImpl.assignSlot(newBuffer);
-        *buffer = newBuffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        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);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [this] () -> sp<Codec2Buffer> { return alloc(kLinearBufferSize); });
-        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)
-        : 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 < kMinBufferArraySize; ++i) {
-            sp<IMemory> memory = mDealer->allocate(kLinearBufferSize);
-            if (memory == nullptr) {
-                ALOGD("Failed to allocate memory from dealer: only %zu slots allocated", 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 GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
-    GraphicInputBuffers() : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {}
-    ~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;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        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);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [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() = default;
-
-    bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
-        return false;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &) override {
-        return nullptr;
-    }
-
-    void flush() override {
-    }
-
-    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() 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() = default;
-    ~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() final {
-        return nullptr;
-    }
-
-    bool 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 != OK) {
-            ALOGD("grabBuffer failed: %d", err);
-            return false;
-        }
-        c2Buffer->setFormat(mFormat);
-        if (!c2Buffer->copy(buffer)) {
-            ALOGD("copy buffer failed");
-            return false;
-        }
-        *clientBuffer = c2Buffer;
-        return true;
-    }
-
-    bool 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 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 {
-        return mImpl.returnBuffer(buffer);
-    }
-
-    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
-        (void) flushedWork;
-        mImpl.flush();
-    }
-
-    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        mImpl.getArray(array);
-    }
-
-private:
-    BuffersArrayImpl mImpl;
-};
-
-class FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers {
-public:
-    using CCodecBufferChannel::OutputBuffers::OutputBuffers;
-
-    bool 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;
-        return true;
-    }
-
-    bool registerCsd(
-            const C2StreamCsdInfo::output *csd,
-            size_t *index,
-            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<Codec2Buffer> newBuffer = new LocalLinearBuffer(mFormat, csdBuffer);
-        *index = mImpl.assignSlot(newBuffer);
-        *clientBuffer = newBuffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(
-            const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.releaseSlot(buffer);
-    }
-
-    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() override {
-        std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray);
-        array->setFormat(mFormat);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [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:
-    using FlexOutputBuffers::FlexOutputBuffers;
-
-    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
-        if (buffer == nullptr) {
-            return new DummyContainerBuffer(mFormat, buffer);
-        }
-        if (buffer->data().type() != C2BufferData::LINEAR) {
-            // We expect linear output buffers from the component.
-            return nullptr;
-        }
-        if (buffer->data().linearBlocks().size() != 1u) {
-            // We expect one and only one linear block from the component.
-            return nullptr;
-        }
-        return ConstLinearBlockBuffer::Allocate(mFormat, buffer);
-    }
-
-    sp<Codec2Buffer> allocateArrayBuffer() override {
-        // TODO: proper max output size
-        return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
-    }
-};
-
-class GraphicOutputBuffers : public FlexOutputBuffers {
-public:
-    using FlexOutputBuffers::FlexOutputBuffers;
-
-    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()
-        : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {
-    }
-    ~RawGraphicOutputBuffers() override = default;
-
-    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
-        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) {
-    std::unique_lock<std::mutex> l(mSync.mMutex);
-    // At this point it's guaranteed that mSync is not under state transition,
-    // as we are holding its mutex.
-    if (mSync.mCount == -1) {
-        mRunning = false;
-    } else {
-        ++mSync.mCount;
-        mRunning = true;
-    }
-}
-
-CCodecBufferChannel::QueueGuard::~QueueGuard() {
-    if (mRunning) {
-        // We are not holding mutex at this point so that QueueSync::stop() can
-        // keep holding the lock until mCount reaches zero.
-        --mSync.mCount;
-    }
-}
-
-void CCodecBufferChannel::QueueSync::start() {
-    std::unique_lock<std::mutex> l(mMutex);
-    // If stopped, it goes to running state; otherwise no-op.
-    int32_t expected = -1;
-    (void)mCount.compare_exchange_strong(expected, 0);
-}
-
-void CCodecBufferChannel::QueueSync::stop() {
-    std::unique_lock<std::mutex> l(mMutex);
-    if (mCount == -1) {
-        // no-op
-        return;
-    }
-    // Holding mutex 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.
-    int32_t expected = 0;
-    while (!mCount.compare_exchange_weak(expected, -1)) {
-        std::this_thread::yield();
-    }
-}
-
-CCodecBufferChannel::CCodecBufferChannel(
-        const std::function<void(status_t, enum ActionCode)> &onError)
-    : mHeapSeqNum(-1),
-      mOnError(onError),
-      mFrameIndex(0u),
-      mFirstValidFrameIndex(0u) {
-}
-
-CCodecBufferChannel::~CCodecBufferChannel() {
-    if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
-        mCrypto->unsetHeap(mHeapSeqNum);
-    }
-}
-
-void CCodecBufferChannel::setComponent(const std::shared_ptr<C2Component> &component) {
-    mComponent = component;
-}
-
-status_t CCodecBufferChannel::setInputSurface(
-        const std::shared_ptr<InputSurfaceWrapper> &surface) {
-    ALOGV("setInputSurface");
-    mInputSurface = surface;
-    return OK;
-}
-
-status_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) {
-    int64_t timeUs;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-    int32_t flags = 0;
-    int32_t tmp = 0;
-    if (buffer->meta()->findInt32("eos", &tmp) && tmp) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("input EOS");
-    }
-    if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
-        flags |= C2FrameData::FLAG_CODEC_CONFIG;
-    }
-    ALOGV("queueInputBuffer: buffer->size() = %zu", buffer->size());
-    std::unique_ptr<C2Work> work(new C2Work);
-    work->input.flags = (C2FrameData::flags_t)flags;
-    work->input.ordinal.timestamp = timeUs;
-    work->input.ordinal.frameIndex = mFrameIndex++;
-    work->input.buffers.clear();
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        std::shared_ptr<C2Buffer> c2buffer = (*buffers)->releaseBuffer(buffer);
-        if (!c2buffer) {
-            return -ENOENT;
-        }
-        work->input.buffers.push_back(c2buffer);
-    }
-    // TODO: fill info's
-
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    return mComponent->queue_nb(&items);
-}
-
-status_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
-    QueueGuard guard(mSync);
-    if (!guard.isRunning()) {
-        ALOGW("No more buffers should be queued at current state.");
-        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()) {
-        ALOGW("No more buffers should be queued at current state.");
-        return -ENOSYS;
-    }
-
-    if (!hasCryptoOrDescrambler()) {
-        return -ENOSYS;
-    }
-    sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
-
-    ssize_t result = -1;
-    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;
-
-        auto returnVoid = mDescrambler->descramble(
-                key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
-                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) {
-            ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
-                    returnVoid.description().c_str(), status, result);
-            return UNKNOWN_ERROR;
-        }
-
-        ALOGV("descramble succeeded, %zd bytes", result);
-
-        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
-            encryptedBuffer->copyDecryptedContentFromMemory(result);
-        }
-    }
-
-    buffer->setRange(0, result);
-    return queueInputBufferInternal(buffer);
-}
-
-void CCodecBufferChannel::feedInputBufferIfAvailable() {
-    sp<MediaCodecBuffer> inBuffer;
-    size_t index;
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) {
-            ALOGV("no new buffer available");
-            inBuffer = nullptr;
-            return;
-        }
-    }
-    ALOGV("new input index = %zu", index);
-    mCallback->onInputBufferAvailable(index, inBuffer);
-}
-
-status_t CCodecBufferChannel::renderOutputBuffer(
-        const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
-    ALOGV("renderOutputBuffer");
-    feedInputBufferIfAvailable();
-
-    std::shared_ptr<C2Buffer> c2Buffer;
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        c2Buffer = (*buffers)->releaseBuffer(buffer);
-    }
-
-    Mutexed<OutputSurface>::Locked output(mOutputSurface);
-    if (output->surface == nullptr) {
-        ALOGE("no surface");
-        return OK;
-    }
-
-    std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
-    if (blocks.size() != 1u) {
-        ALOGE("# of graphic blocks expected to be 1, but %zu", blocks.size());
-        return UNKNOWN_ERROR;
-    }
-
-    native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(blocks.front().handle());
-    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
-            grallocHandle,
-            GraphicBuffer::CLONE_HANDLE,
-            blocks.front().width(),
-            blocks.front().height(),
-            HAL_PIXEL_FORMAT_YCbCr_420_888,
-            // TODO
-            1,
-            (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-            // TODO
-            blocks.front().width()));
-    native_handle_delete(grallocHandle);
-
-    status_t result = output->surface->attachBuffer(graphicBuffer.get());
-    if (result != OK) {
-        ALOGE("attachBuffer failed: %d", result);
-        return result;
-    }
-
-    // TODO: read and set crop
-
-    result = native_window_set_buffers_timestamp(output->surface.get(), timestampNs);
-    ALOGW_IF(result != OK, "failed to set buffer timestamp: %d", result);
-
-    // TODO: fix after C2Fence implementation
-#if 0
-    const C2Fence &fence = blocks.front().fence();
-    result = ((ANativeWindow *)output->surface.get())->queueBuffer(
-            output->surface.get(), graphicBuffer.get(), fence.valid() ? fence.fd() : -1);
-#else
-    result = ((ANativeWindow *)output->surface.get())->queueBuffer(
-            output->surface.get(), graphicBuffer.get(), -1);
-#endif
-    if (result != OK) {
-        ALOGE("queueBuffer failed: %d", result);
-        return result;
-    }
-
-    // XXX: Hack to keep C2Buffers unreleased until the consumer is done
-    //      reading the content. Eventually IGBP-based C2BlockPool should handle
-    //      the lifecycle.
-    output->bufferRefs.push_back(c2Buffer);
-    if (output->bufferRefs.size() > output->maxBufferCount + 1) {
-        output->bufferRefs.pop_front();
-        ALOGV("%zu buffer refs remaining", output->bufferRefs.size());
-    }
-
-    return OK;
-}
-
-status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
-    ALOGV("discardBuffer: %p", buffer.get());
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        (void)(*buffers)->releaseBuffer(buffer);
-    }
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if((*buffers)->releaseBuffer(buffer)) {
-            buffers.unlock();
-            feedInputBufferIfAvailable();
-            buffers.lock();
-        }
-    }
-    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();
-    }
-
-    (*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();
-    }
-
-    (*buffers)->getArray(array);
-}
-
-status_t CCodecBufferChannel::start(
-        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
-    C2StreamFormatConfig::input iStreamFormat(0u);
-    C2StreamFormatConfig::output oStreamFormat(0u);
-    c2_status_t err = mComponent->intf()->query_vb(
-            { &iStreamFormat, &oStreamFormat },
-            {},
-            C2_DONT_BLOCK,
-            nullptr);
-    if (err != C2_OK) {
-        return UNKNOWN_ERROR;
-    }
-    bool secure = mComponent->intf()->getName().find(".secure") != std::string::npos;
-
-    if (inputFormat != nullptr) {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-
-        bool graphic = (iStreamFormat.value == C2FormatVideo);
-        if (graphic) {
-            if (mInputSurface) {
-                buffers->reset(new DummyInputBuffers);
-            } else {
-                buffers->reset(new GraphicInputBuffers);
-            }
-        } else {
-            if (hasCryptoOrDescrambler()) {
-                if (mDealer == nullptr) {
-                    mDealer = new MemoryDealer(
-                            align(kLinearBufferSize, MemoryDealer::getAllocationAlignment())
-                                * (kMinBufferArraySize + 1),
-                            "EncryptedLinearInputBuffers");
-                    mDecryptDestination = mDealer->allocate(kLinearBufferSize);
-                }
-                if (mCrypto != nullptr && mHeapSeqNum < 0) {
-                    mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
-                } else {
-                    mHeapSeqNum = -1;
-                }
-                buffers->reset(new EncryptedLinearInputBuffers(
-                        secure, mDealer, mCrypto, mHeapSeqNum));
-            } else {
-                buffers->reset(new LinearInputBuffers);
-            }
-        }
-        (*buffers)->setFormat(inputFormat);
-
-        ALOGV("graphic = %s", graphic ? "true" : "false");
-        std::shared_ptr<C2BlockPool> pool;
-        if (graphic) {
-            err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, mComponent, &pool);
-        } else {
-            err = CreateCodec2BlockPool(C2PlatformAllocatorStore::ION,
-                                        mComponent, &pool);
-        }
-        if (err == C2_OK) {
-            (*buffers)->setPool(pool);
-        } else {
-            // TODO: error
-        }
-    }
-
-    if (outputFormat != nullptr) {
-        bool hasOutputSurface = false;
-        {
-            Mutexed<OutputSurface>::Locked output(mOutputSurface);
-            hasOutputSurface = (output->surface != nullptr);
-        }
-
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
-        bool graphic = (oStreamFormat.value == C2FormatVideo);
-        if (graphic) {
-            if (hasOutputSurface) {
-                buffers->reset(new GraphicOutputBuffers);
-            } else {
-                buffers->reset(new RawGraphicOutputBuffers);
-            }
-        } else {
-            buffers->reset(new LinearOutputBuffers);
-        }
-        (*buffers)->setFormat(outputFormat);
-    }
-
-    mSync.start();
-    if (mInputSurface == nullptr) {
-        // TODO: use proper buffer depth instead of this random value
-        for (size_t i = 0; i < kMinBufferArraySize; ++i) {
-            size_t index;
-            sp<MediaCodecBuffer> buffer;
-            {
-                Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-                if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
-                    if (i == 0) {
-                        ALOGE("start: cannot allocate memory at all");
-                        return NO_MEMORY;
-                    } else {
-                        ALOGV("start: cannot allocate memory, only %zu buffers allocated", i);
-                    }
-                    break;
-                }
-            }
-            mCallback->onInputBufferAvailable(index, buffer);
-        }
-    } else {
-        (void)mInputSurface->connect(mComponent);
-    }
-    return OK;
-}
-
-void CCodecBufferChannel::stop() {
-    mSync.stop();
-    mFirstValidFrameIndex = mFrameIndex.load();
-    if (mInputSurface != nullptr) {
-        mInputSurface->disconnect();
-        mInputSurface.reset();
-    }
-}
-
-void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        (*buffers)->flush();
-    }
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        (*buffers)->flush(flushedWork);
-    }
-}
-
-void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
-    if (work->result != C2_OK) {
-        if (work->result == C2_NOT_FOUND) {
-            // TODO: Define what flushed work's result is.
-            ALOGD("flushed work; ignored.");
-            return;
-        }
-        ALOGD("work failed to complete: %d", work->result);
-        mOnError(work->result, ACTION_CODE_FATAL);
-        return;
-    }
-
-    // NOTE: MediaCodec usage supposedly have only one worklet
-    if (work->worklets.size() != 1u) {
-        ALOGE("onWorkDone: incorrect number of worklets: %zu",
-                work->worklets.size());
-        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    }
-
-    const std::unique_ptr<C2Worklet> &worklet = work->worklets.front();
-    if ((worklet->output.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
-        // Discard frames from previous generation.
-        return;
-    }
-    std::shared_ptr<C2Buffer> buffer;
-    // NOTE: MediaCodec usage supposedly have only one output stream.
-    if (worklet->output.buffers.size() > 1u) {
-        ALOGE("onWorkDone: incorrect number of output buffers: %zu",
-                worklet->output.buffers.size());
-        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    } else if (worklet->output.buffers.size() == 1u) {
-        buffer = worklet->output.buffers[0];
-        if (!buffer) {
-            ALOGW("onWorkDone: nullptr found in buffers; ignored.");
-        }
-    }
-
-    const C2StreamCsdInfo::output *csdInfo = nullptr;
-    for (const std::unique_ptr<C2Param> &info : worklet->output.configUpdate) {
-        if (info->coreIndex() == C2StreamCsdInfo::output::CORE_INDEX) {
-            ALOGV("onWorkDone: csd found");
-            csdInfo = static_cast<const C2StreamCsdInfo::output *>(info.get());
-        }
-    }
-
-    int32_t flags = 0;
-    if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= MediaCodec::BUFFER_FLAG_EOS;
-        ALOGV("onWorkDone: output EOS");
-    }
-
-    sp<MediaCodecBuffer> outBuffer;
-    size_t index;
-    if (csdInfo != nullptr) {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if ((*buffers)->registerCsd(csdInfo, &index, &outBuffer)) {
-            outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
-            outBuffer->meta()->setInt32("flags", flags | MediaCodec::BUFFER_FLAG_CODECCONFIG);
-            ALOGV("onWorkDone: csd index = %zu", index);
-
-            buffers.unlock();
-            mCallback->onOutputBufferAvailable(index, outBuffer);
-            buffers.lock();
-        } else {
-            ALOGE("onWorkDone: unable to register csd");
-            buffers.unlock();
-            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            buffers.lock();
-            return;
-        }
-    }
-
-    if (!buffer && !flags) {
-        ALOGV("onWorkDone: Not reporting output buffer");
-        return;
-    }
-
-    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<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if (!(*buffers)->registerBuffer(buffer, &index, &outBuffer)) {
-            ALOGE("onWorkDone: unable to register output buffer");
-            buffers.unlock();
-            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            buffers.lock();
-            return;
-        }
-    }
-
-    outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
-    outBuffer->meta()->setInt32("flags", flags);
-    ALOGV("onWorkDone: out buffer index = %zu", index);
-    mCallback->onOutputBufferAvailable(index, outBuffer);
-}
-
-status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
-    if (newSurface != nullptr) {
-        newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
-    }
-
-    Mutexed<OutputSurface>::Locked output(mOutputSurface);
-//    if (newSurface == nullptr) {
-//        if (*surface != nullptr) {
-//            ALOGW("cannot unset a surface");
-//            return INVALID_OPERATION;
-//        }
-//        return OK;
-//    }
-//
-//    if (*surface == nullptr) {
-//        ALOGW("component was not configured with a surface");
-//        return INVALID_OPERATION;
-//    }
-
-    output->surface = newSurface;
-    output->bufferRefs.clear();
-    // XXX: hack
-    output->maxBufferCount = kMaxGraphicBufferRefCount;
-
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/Codec2Buffer.cpp b/media/libstagefright/Codec2Buffer.cpp
deleted file mode 100644
index d2ef229..0000000
--- a/media/libstagefright/Codec2Buffer.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * 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/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include "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) {
-        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(
-        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:
-    explicit GraphicView2MediaImageConverter(const C2GraphicView &view)
-        : mInitCheck(NO_INIT),
-          mView(view),
-          mWidth(view.width()),
-          mHeight(view.height()),
-          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;
-
-        switch (layout.type) {
-            case C2PlanarLayout::TYPE_YUV:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV; break;
-            case C2PlanarLayout::TYPE_YUVA:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA; break;
-            case C2PlanarLayout::TYPE_RGB:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB; break;
-            case C2PlanarLayout::TYPE_RGBA:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA; break;
-            default:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN; break;
-        }
-        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.rightShift != 0) {
-                ALOGV("rightShift value of %u unsupported", plane.rightShift);
-                mInitCheck = BAD_VALUE;
-                return;
-            }
-            if (plane.endianness != C2PlaneInfo::NATIVE) {
-                ALOGV("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 += mWidth * mHeight
-                    / plane.rowSampling / plane.colSampling * (plane.allocatedDepth / 8);
-        }
-
-        mBackBufferSize = bufferSize;
-        mInitCheck = OK;
-    }
-
-    status_t initCheck() const { return mInitCheck; }
-
-    uint32_t backBufferSize() const { return mBackBufferSize; }
-
-    /**
-     * Convert C2GraphicView to MediaImage2. Note that if not wrapped, the content
-     * is not copied over in this function --- the caller should use
-     * CopyGraphicView2MediaImage() function to do that explicitly.
-     *
-     * \param   view[in]          source C2GraphicView object.
-     * \param   alloc[in]         allocator function for ABuffer.
-     * \param   mediaImage[out]   destination MediaImage2 object.
-     * \param   buffer[out]       new buffer object.
-     * \param   wrapped[out]      whether we wrapped around existing map or
-     *                            allocated a new buffer
-     *
-     * \return  true              if conversion succeeds,
-     *          false             otherwise; all output params should be ignored.
-     */
-    sp<ABuffer> wrap() {
-        MediaImage2 *mediaImage = getMediaImage();
-        const C2PlanarLayout &layout = mView.layout();
-        if (layout.numPlanes == 1) {
-            const C2PlaneInfo &plane = layout.planes[0];
-            ssize_t offset = plane.minOffset(mWidth, mHeight);
-            mediaImage->mPlane[0].mOffset = -offset;
-            mediaImage->mPlane[0].mColInc = plane.colInc;
-            mediaImage->mPlane[0].mRowInc = plane.rowInc;
-            mediaImage->mPlane[0].mHorizSubsampling = plane.colSampling;
-            mediaImage->mPlane[0].mVertSubsampling = plane.rowSampling;
-            return new ABuffer(
-                    const_cast<uint8_t *>(mView.data()[0] + offset),
-                    plane.maxOffset(mWidth, mHeight) - offset + 1);
-        }
-        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) * mHeight
-                    / plane.rowSampling / plane.colSampling * (mAllocatedDepth / 8);
-        }
-
-        if ((maxPtr - minPtr + 1) <= planeSize) {
-            // FIXME: this is risky as reading/writing data out of bound results in
-            //        an undefined behavior.
-            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;
-            }
-            return new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
-        }
-
-        return nullptr;
-    }
-
-    bool setBackBuffer(const sp<ABuffer> &backBuffer) {
-        if (backBuffer->capacity() < mBackBufferSize) {
-            return false;
-        }
-        backBuffer->setRange(0, mBackBufferSize);
-
-        const C2PlanarLayout &layout = mView.layout();
-        MediaImage2 *mediaImage = getMediaImage();
-        uint32_t offset = 0;
-        // TODO: keep interleaved planes together
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            mediaImage->mPlane[i].mOffset = offset;
-            mediaImage->mPlane[i].mColInc = mAllocatedDepth / 8;
-            mediaImage->mPlane[i].mRowInc =
-                mediaImage->mPlane[i].mColInc * mWidth / plane.colSampling;
-            mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
-            mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
-            offset += mediaImage->mPlane[i].mRowInc * mHeight / plane.rowSampling;
-        }
-        mBackBuffer = backBuffer;
-        return true;
-    }
-
-    /**
-     * Copy C2GraphicView to MediaImage2. This function assumes that |mediaImage| is
-     * an output from GraphicView2MediaImage(), so it mostly skips sanity check.
-     *
-     * \param   view[in]          source C2GraphicView object.
-     * \param   mediaImage[in]    destination MediaImage2 object.
-     * \param   buffer[out]       new buffer object.
-     */
-    void copy() {
-        // TODO: more efficient copying --- e.g. one row at a time, copying
-        //       interleaved planes together, etc.
-        const C2PlanarLayout &layout = mView.layout();
-        MediaImage2 *mediaImage = getMediaImage();
-        uint8_t *dst = mBackBuffer->base();
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            const uint8_t *src = mView.data()[i];
-            int32_t planeW = mWidth / plane.colSampling;
-            int32_t planeH = mHeight / plane.rowSampling;
-            for (int32_t row = 0; row < planeH; ++row) {
-                for(int32_t col = 0; col < planeW; ++col) {
-                    memcpy(dst, src, mAllocatedDepth / 8);
-                    dst += mediaImage->mPlane[i].mColInc;
-                    src += plane.colInc;
-                }
-                dst -= mediaImage->mPlane[i].mColInc * planeW;
-                dst += mediaImage->mPlane[i].mRowInc;
-                src -= plane.colInc * planeW;
-                src += plane.rowInc;
-            }
-        }
-    }
-
-    const sp<ABuffer> &imageData() const { return mMediaImage; }
-
-private:
-    status_t mInitCheck;
-
-    const C2GraphicView mView;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mAllocatedDepth;
-    uint32_t mBackBufferSize;
-    sp<ABuffer> mMediaImage;
-    std::function<sp<ABuffer>(size_t)> mAlloc;
-
-    sp<ABuffer> mBackBuffer;
-
-    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;
-    }
-    GraphicView2MediaImageConverter converter(view);
-    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) {
-    meta()->setBuffer("image-data", imageData);
-}
-
-std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
-    uint32_t width = mView.width();
-    uint32_t height = mView.height();
-    if (!mWrapped) {
-        MediaImage2 *mediaImage = imageData();
-        const C2PlanarLayout &layout = mView.layout();
-        for (uint32_t i = 0; i < mediaImage->mNumPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            int32_t planeW = width / plane.colSampling;
-            int32_t planeH = height / plane.rowSampling;
-            const uint8_t *src = base() + mediaImage->mPlane[i].mOffset;
-            uint8_t *dst = mView.data()[i];
-            for (int32_t row = 0; row < planeH; ++row) {
-                for (int32_t col = 0; col < planeW; ++col) {
-                    memcpy(dst, src, mediaImage->mBitDepthAllocated / 8);
-                    src += mediaImage->mPlane[i].mColInc;
-                    dst += plane.colInc;
-                }
-                src -= mediaImage->mPlane[i].mColInc * planeW;
-                dst -= plane.colInc * planeW;
-                src += mediaImage->mPlane[i].mRowInc;
-                dst += plane.rowInc;
-            }
-        }
-    }
-    return C2Buffer::CreateGraphicBuffer(
-            mBlock->share(C2Rect(width, height), C2Fence()));
-}
-
-// 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;
-
-    GraphicView2MediaImageConverter converter(*view);
-    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.copy();
-        // 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) {
-        meta()->setBuffer("image-data", 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;
-    }
-    GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get());
-    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;
-    }
-    GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get());
-    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.copy();
-    meta()->setBuffer("image-data", 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/libstagefright/Codec2InfoBuilder.cpp b/media/libstagefright/Codec2InfoBuilder.cpp
deleted file mode 100644
index bd749c4..0000000
--- a/media/libstagefright/Codec2InfoBuilder.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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 <C2Component.h>
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
-#include <media/stagefright/Codec2InfoBuilder.h>
-
-namespace android {
-
-using ConstTraitsPtr = std::shared_ptr<const C2Component::Traits>;
-
-struct ProfileLevel {
-    uint32_t profile;
-    uint32_t level;
-};
-static const ProfileLevel kAvcProfileLevels[] = {
-    { 0x01, 0x0001 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
-    { 0x01, 0x0002 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
-    { 0x01, 0x0004 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
-    { 0x01, 0x0008 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
-    { 0x01, 0x0010 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
-    { 0x01, 0x0020 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
-    { 0x01, 0x0040 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
-    { 0x01, 0x0080 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
-    { 0x01, 0x0100 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
-    { 0x01, 0x0200 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
-    { 0x01, 0x0400 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
-    { 0x01, 0x0800 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
-    { 0x01, 0x1000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
-    { 0x01, 0x2000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
-    { 0x01, 0x4000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5  },
-    { 0x01, 0x8000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
-
-    { 0x02, 0x0001 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1  },
-    { 0x02, 0x0002 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1b },
-    { 0x02, 0x0004 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel11 },
-    { 0x02, 0x0008 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel12 },
-    { 0x02, 0x0010 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel13 },
-    { 0x02, 0x0020 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel2  },
-    { 0x02, 0x0040 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel21 },
-    { 0x02, 0x0080 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel22 },
-    { 0x02, 0x0100 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel3  },
-    { 0x02, 0x0200 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel31 },
-    { 0x02, 0x0400 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel32 },
-    { 0x02, 0x0800 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel4  },
-    { 0x02, 0x1000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel41 },
-    { 0x02, 0x2000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel42 },
-    { 0x02, 0x4000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel5  },
-    { 0x02, 0x8000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel51 },
-
-    { 0x04, 0x0001 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1  },
-    { 0x04, 0x0002 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1b },
-    { 0x04, 0x0004 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel11 },
-    { 0x04, 0x0008 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel12 },
-    { 0x04, 0x0010 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel13 },
-    { 0x04, 0x0020 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel2  },
-    { 0x04, 0x0040 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel21 },
-    { 0x04, 0x0080 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel22 },
-    { 0x04, 0x0100 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel3  },
-    { 0x04, 0x0200 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel31 },
-    { 0x04, 0x0400 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel32 },
-    { 0x04, 0x0800 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel4  },
-    { 0x04, 0x1000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel41 },
-    { 0x04, 0x2000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel42 },
-    { 0x04, 0x4000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel5  },
-    { 0x04, 0x8000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel51 },
-};
-
-status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
-    // Obtain C2ComponentStore
-    std::shared_ptr<C2ComponentStore> store = GetCodec2PlatformComponentStore();
-    if (store == nullptr) {
-        ALOGE("Cannot find a component store.");
-        return NO_INIT;
-    }
-
-    std::vector<ConstTraitsPtr> traits = store->listComponents();
-
-    if (property_get_bool("debug.stagefright.ccodec_v4l2", false)) {
-        std::shared_ptr<C2ComponentStore> v4l2Store = GetCodec2VDAComponentStore();
-        if (v4l2Store == nullptr) {
-            ALOGD("Cannot find a V4L2 component store.");
-            // non-fatal.
-        } else {
-            std::vector<ConstTraitsPtr> v4l2Traits = v4l2Store->listComponents();
-            traits.insert(traits.end(), v4l2Traits.begin(), v4l2Traits.end());
-        }
-    }
-
-    MediaCodecsXmlParser parser(
-            MediaCodecsXmlParser::defaultSearchDirs,
-            "media_codecs_c2.xml");
-    if (parser.getParsingStatus() != OK) {
-        ALOGD("XML parser no good");
-        return OK;
-    }
-    for (const ConstTraitsPtr &trait : traits) {
-        if (parser.getCodecMap().count(trait->name.c_str()) == 0) {
-            ALOGD("%s not found in xml", trait->name.c_str());
-            continue;
-        }
-        const MediaCodecsXmlParser::CodecProperties &codec = parser.getCodecMap().at(trait->name);
-        std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
-        codecInfo->setName(trait->name.c_str());
-        codecInfo->setOwner("dummy");
-        // TODO: get this from trait->kind
-        bool encoder = (trait->name.find("encoder") != std::string::npos);
-        codecInfo->setEncoder(encoder);
-        codecInfo->setRank(trait->rank);
-        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());
-                }
-            }
-            // TODO: get this from intf(), and apply to other codecs as well.
-            if (mediaType.find("video/avc") != std::string::npos && !encoder) {
-                for (const auto& pl : kAvcProfileLevels) {
-                    caps->addProfileLevel(pl.profile, pl.level);
-                }
-            }
-            // TODO: get this from intf().
-            if (mediaType.find("video") != std::string::npos && !encoder) {
-                caps->addColorFormat(0x7F420888);  // COLOR_FormatYUV420Flexible
-            }
-        }
-    }
-    return OK;
-}
-
-}  // namespace android
-
-extern "C" android::MediaCodecListBuilderBase *CreateBuilder() {
-    return new android::Codec2InfoBuilder;
-}
diff --git a/media/libstagefright/codecs/aacdec/Android.bp b/media/libstagefright/codecs/aacdec/Android.bp
index 9931e2d..7352854 100644
--- a/media/libstagefright/codecs/aacdec/Android.bp
+++ b/media/libstagefright/codecs/aacdec/Android.bp
@@ -1,45 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2aacdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: [
-        "C2SoftAac.cpp",
-        "DrcPresModeWrap.cpp",
-    ],
-
-    cflags: ["-Werror"],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libFraunhoferAAC",
-    ],
-
-    shared_libs: [
-        "libcutils",
-        "libion",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libutils",
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_aacdec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/aacdec/C2SoftAac.cpp b/media/libstagefright/codecs/aacdec/C2SoftAac.cpp
deleted file mode 100644
index 6bd15a5..0000000
--- a/media/libstagefright/codecs/aacdec/C2SoftAac.cpp
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * 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 "C2SoftAac"
-#include <utils/Log.h>
-
-#include "C2SoftAac.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/misc.h>
-
-#include <inttypes.h>
-#include <math.h>
-#include <numeric>
-
-#define FILEREAD_MAX_LAYERS 2
-
-#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_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
-#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
-// 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"
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.aac.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_AAC)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftAac::C2SoftAac(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mAACDecoder(NULL),
-      mStreamInfo(NULL),
-      mIsADTS(false),
-      mSignalledError(false),
-      mOutputDelayRingBuffer(NULL) {
-}
-
-C2SoftAac::~C2SoftAac() {
-    onRelease();
-}
-
-c2_status_t C2SoftAac::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftAac::onStop() {
-    drainDecoder();
-    // reset the "configured" state
-    mOutputDelayCompensated = 0;
-    mOutputDelayRingBufferWritePos = 0;
-    mOutputDelayRingBufferReadPos = 0;
-    mOutputDelayRingBufferFilled = 0;
-    mBuffersInfo.clear();
-
-    // To make the codec behave the same before and after a reset, we need to invalidate the
-    // streaminfo struct. This does that:
-    mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
-
-    mSignalledError = false;
-
-    return C2_OK;
-}
-
-void C2SoftAac::onReset() {
-    (void)onStop();
-}
-
-void C2SoftAac::onRelease() {
-    if (mAACDecoder) {
-        aacDecoder_Close(mAACDecoder);
-        mAACDecoder = NULL;
-    }
-    if (mOutputDelayRingBuffer) {
-        delete[] mOutputDelayRingBuffer;
-        mOutputDelayRingBuffer = NULL;
-    }
-}
-
-status_t C2SoftAac::initDecoder() {
-    ALOGV("initDecoder()");
-    status_t status = UNKNOWN_ERROR;
-    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
-    if (mAACDecoder != NULL) {
-        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
-        if (mStreamInfo != NULL) {
-            status = OK;
-        }
-    }
-
-    mOutputDelayCompensated = 0;
-    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
-    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
-    mOutputDelayRingBufferWritePos = 0;
-    mOutputDelayRingBufferReadPos = 0;
-    mOutputDelayRingBufferFilled = 0;
-
-    if (mAACDecoder == NULL) {
-        ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
-    }
-
-    //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
-
-    //init DRC wrapper
-    mDrcWrap.setDecoderHandle(mAACDecoder);
-    mDrcWrap.submitStreamData(mStreamInfo);
-
-    // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
-    // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
-    char value[PROPERTY_VALUE_MAX];
-    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
-    if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
-        unsigned refLevel = atoi(value);
-        ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
-                DRC_DEFAULT_MOBILE_REF_LEVEL);
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
-    } else {
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
-    }
-    //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
-    if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
-        unsigned cut = atoi(value);
-        ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
-                DRC_DEFAULT_MOBILE_DRC_CUT);
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
-    } else {
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
-    }
-    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
-    if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
-        unsigned boost = atoi(value);
-        ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
-                DRC_DEFAULT_MOBILE_DRC_BOOST);
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
-    } else {
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
-    }
-    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
-    if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
-        unsigned heavy = atoi(value);
-        ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
-                DRC_DEFAULT_MOBILE_DRC_HEAVY);
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
-    } else {
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
-    }
-    // DRC_PRES_MODE_WRAP_ENCODER_TARGET
-    if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
-        unsigned encoderRefLevel = atoi(value);
-        ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
-                encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
-    } else {
-        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
-    }
-
-    // By default, the decoder creates a 5.1 channel downmix signal.
-    // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
-    aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
-
-    return status;
-}
-
-bool C2SoftAac::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
-    if (numSamples == 0) {
-        return true;
-    }
-    if (outputDelayRingBufferSpaceLeft() < numSamples) {
-        ALOGE("RING BUFFER WOULD OVERFLOW");
-        return false;
-    }
-    if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
-            && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
-                    || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
-        // faster memcopy loop without checks, if the preconditions allow this
-        for (int32_t i = 0; i < numSamples; i++) {
-            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
-        }
-
-        if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
-            mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
-        }
-    } else {
-        ALOGV("slow C2SoftAac::outputDelayRingBufferPutSamples()");
-
-        for (int32_t i = 0; i < numSamples; i++) {
-            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
-            mOutputDelayRingBufferWritePos++;
-            if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
-                mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
-            }
-        }
-    }
-    mOutputDelayRingBufferFilled += numSamples;
-    return true;
-}
-
-int32_t C2SoftAac::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
-
-    if (numSamples > mOutputDelayRingBufferFilled) {
-        ALOGE("RING BUFFER WOULD UNDERRUN");
-        return -1;
-    }
-
-    if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
-            && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
-                    || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
-        // faster memcopy loop without checks, if the preconditions allow this
-        if (samples != 0) {
-            for (int32_t i = 0; i < numSamples; i++) {
-                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
-            }
-        } else {
-            mOutputDelayRingBufferReadPos += numSamples;
-        }
-        if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
-            mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
-        }
-    } else {
-        ALOGV("slow C2SoftAac::outputDelayRingBufferGetSamples()");
-
-        for (int32_t i = 0; i < numSamples; i++) {
-            if (samples != 0) {
-                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
-            }
-            mOutputDelayRingBufferReadPos++;
-            if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
-                mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
-            }
-        }
-    }
-    mOutputDelayRingBufferFilled -= numSamples;
-    return numSamples;
-}
-
-int32_t C2SoftAac::outputDelayRingBufferSamplesAvailable() {
-    return mOutputDelayRingBufferFilled;
-}
-
-int32_t C2SoftAac::outputDelayRingBufferSpaceLeft() {
-    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
-}
-
-void C2SoftAac::drainRingBuffer(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool,
-        bool eos) {
-    while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
-            >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
-        Info &outInfo = mBuffersInfo.front();
-        ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
-        int samplesize = mStreamInfo->numChannels * sizeof(int16_t);
-
-        int available = outputDelayRingBufferSamplesAvailable();
-        int numFrames = outInfo.decodedSizes.size();
-        int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
-        if (available < numSamples) {
-            if (eos) {
-                numSamples = available;
-            } else {
-                break;
-            }
-        }
-        ALOGV("%d samples available (%d), or %d frames",
-                numSamples, available, numFrames);
-        ALOGV("getting %d from ringbuffer", numSamples);
-
-        std::shared_ptr<C2LinearBlock> block;
-        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
-            [&block, numSamples, pool, this]()
-                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
-                auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work, c2_status_t err) {
-                    work->result = err;
-                    work->worklets.front()->output.flags = work->input.flags;
-                    work->worklets.front()->output.buffers.clear();
-                    work->worklets.front()->output.ordinal = work->input.ordinal;
-                    work->workletsProcessed = 1u;
-                };
-
-                using namespace std::placeholders;
-                if (numSamples == 0) {
-                    return std::bind(fillEmptyWork, _1, C2_OK);
-                }
-
-                // TODO: error handling, proper usage, etc.
-                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-                c2_status_t err = pool->fetchLinearBlock(
-                        numSamples * sizeof(int16_t), usage, &block);
-                if (err != C2_OK) {
-                    ALOGD("failed to fetch a linear block (%d)", err);
-                    mSignalledError = true;
-                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
-                }
-                C2WriteView wView = block->map().get();
-                // TODO
-                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
-                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
-                if (ns != numSamples) {
-                    ALOGE("not a complete frame of samples available");
-                    mSignalledError = true;
-                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
-                }
-                return [buffer = createLinearBuffer(block)](const std::unique_ptr<C2Work> &work) {
-                    work->result = C2_OK;
-                    work->worklets.front()->output.flags = work->input.flags;
-                    work->worklets.front()->output.buffers.clear();
-                    work->worklets.front()->output.buffers.push_back(buffer);
-                    work->worklets.front()->output.ordinal = work->input.ordinal;
-                    work->workletsProcessed = 1u;
-                };
-            }();
-
-        if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
-            fillWork(work);
-        } else {
-            finish(outInfo.frameIndex, fillWork);
-        }
-
-        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
-        mBuffersInfo.pop_front();
-    }
-}
-
-void C2SoftAac::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->workletsProcessed = 0u;
-    work->result = C2_OK;
-    if (mSignalledError) {
-        return;
-    }
-
-    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
-    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
-    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
-
-    INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
-    C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    size_t offset = 0u;
-    size_t size = view.capacity();
-
-    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-
-    //TODO
-#if 0
-    if (mInputBufferCount == 0 && !codecConfig) {
-        ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
-        codecConfig = true;
-    }
-#endif
-    if (codecConfig) {
-        // const_cast because of libAACdec method signature.
-        inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
-        inBufferLength[0] = size;
-
-        AAC_DECODER_ERROR decoderErr =
-            aacDecoder_ConfigRaw(mAACDecoder,
-                                 inBuffer,
-                                 inBufferLength);
-
-        if (decoderErr != AAC_DEC_OK) {
-            ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
-            mSignalledError = true;
-            // TODO: error
-            return;
-        }
-
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->worklets.front()->output.buffers.clear();
-
-        return;
-    }
-
-    Info inInfo;
-    inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
-    inInfo.timestamp = work->input.ordinal.timestamp.peeku();
-    inInfo.bufferSize = size;
-    inInfo.decodedSizes.clear();
-    while (size > 0u) {
-        ALOGV("size = %zu", size);
-        if (mIsADTS) {
-            size_t adtsHeaderSize = 0;
-            // skip 30 bits, aac_frame_length follows.
-            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
-
-            const uint8_t *adtsHeader = view.data() + offset;
-
-            bool signalError = false;
-            if (size < 7) {
-                ALOGE("Audio data too short to contain even the ADTS header. "
-                        "Got %zu bytes.", size);
-                hexdump(adtsHeader, size);
-                signalError = true;
-            } else {
-                bool protectionAbsent = (adtsHeader[1] & 1);
-
-                unsigned aac_frame_length =
-                    ((adtsHeader[3] & 3) << 11)
-                    | (adtsHeader[4] << 3)
-                    | (adtsHeader[5] >> 5);
-
-                if (size < aac_frame_length) {
-                    ALOGE("Not enough audio data for the complete frame. "
-                            "Got %zu bytes, frame size according to the ADTS "
-                            "header is %u bytes.",
-                            size, aac_frame_length);
-                    hexdump(adtsHeader, size);
-                    signalError = true;
-                } else {
-                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
-                    if (aac_frame_length < adtsHeaderSize) {
-                        signalError = true;
-                    } else {
-                        // const_cast because of libAACdec method signature.
-                        inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
-                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
-
-                        offset += adtsHeaderSize;
-                        size -= adtsHeaderSize;
-                    }
-                }
-            }
-
-            if (signalError) {
-                mSignalledError = true;
-                // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
-                return;
-            }
-        } else {
-            // const_cast because of libAACdec method signature.
-            inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
-            inBufferLength[0] = size;
-        }
-
-        // Fill and decode
-        bytesValid[0] = inBufferLength[0];
-
-        INT prevSampleRate = mStreamInfo->sampleRate;
-        INT prevNumChannels = mStreamInfo->numChannels;
-
-        aacDecoder_Fill(mAACDecoder,
-                        inBuffer,
-                        inBufferLength,
-                        bytesValid);
-
-        // run DRC check
-        mDrcWrap.submitStreamData(mStreamInfo);
-        mDrcWrap.update();
-
-        UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
-        size -= inBufferUsedLength;
-        offset += inBufferUsedLength;
-
-        AAC_DECODER_ERROR decoderErr;
-        do {
-            if (outputDelayRingBufferSpaceLeft() <
-                    (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
-                ALOGV("skipping decode: not enough space left in ringbuffer");
-                break;
-            }
-
-            int numConsumed = mStreamInfo->numTotalBytes;
-            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
-                                       tmpOutBuffer,
-                                       2048 * MAX_CHANNEL_COUNT,
-                                       0 /* flags */);
-
-            numConsumed = mStreamInfo->numTotalBytes - numConsumed;
-
-            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
-                break;
-            }
-            inInfo.decodedSizes.push_back(numConsumed);
-
-            if (decoderErr != AAC_DEC_OK) {
-                ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
-            }
-
-            if (bytesValid[0] != 0) {
-                ALOGE("bytesValid[0] != 0 should never happen");
-                mSignalledError = true;
-                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                return;
-            }
-
-            size_t numOutBytes =
-                mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
-
-            if (decoderErr == AAC_DEC_OK) {
-                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
-                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
-                    mSignalledError = true;
-                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-                    return;
-                }
-            } else {
-                ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
-
-                memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
-
-                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
-                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
-                    mSignalledError = true;
-                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-                    return;
-                }
-
-                // Discard input buffer.
-                size = 0;
-
-                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
-
-                // After an error, replace bufferSize with the sum of the
-                // decodedSizes to resynchronize the in/out lists.
-                inInfo.decodedSizes.pop_back();
-                inInfo.bufferSize = std::accumulate(
-                        inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
-
-                // fall through
-            }
-
-            /*
-             * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
-             * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
-             * rate system and the sampling rate in the final output is actually
-             * doubled compared with the core AAC decoder sampling rate.
-             *
-             * Explicit signalling is done by explicitly defining SBR audio object
-             * type in the bitstream. Implicit signalling is done by embedding
-             * SBR content in AAC extension payload specific to SBR, and hence
-             * requires an AAC decoder to perform pre-checks on actual audio frames.
-             *
-             * Thus, we could not say for sure whether a stream is
-             * AAC+/eAAC+ until the first data frame is decoded.
-             */
-            if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
-                // TODO:
-#if 0
-                if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
-                    ALOGW("Invalid AAC stream");
-                    mSignalledError = true;
-                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-                    return false;
-                }
-#endif
-            }
-            ALOGV("size = %zu", size);
-        } while (decoderErr == AAC_DEC_OK);
-    }
-
-    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
-
-    mBuffersInfo.push_back(std::move(inInfo));
-
-    if (!eos && mOutputDelayCompensated < outputDelay) {
-        // discard outputDelay at the beginning
-        int32_t toCompensate = outputDelay - mOutputDelayCompensated;
-        int32_t discard = outputDelayRingBufferSamplesAvailable();
-        if (discard > toCompensate) {
-            discard = toCompensate;
-        }
-        int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
-        mOutputDelayCompensated += discarded;
-        return;
-    }
-
-    if (eos) {
-        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
-    } else {
-        drainRingBuffer(work, pool, false /* not EOS */);
-    }
-}
-
-c2_status_t C2SoftAac::drainInternal(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work) {
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
-
-    drainDecoder();
-    drainRingBuffer(work, pool, eos);
-
-    if (eos) {
-        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
-            work->worklets.front()->output.flags = work->input.flags;
-            work->worklets.front()->output.buffers.clear();
-            work->worklets.front()->output.ordinal = work->input.ordinal;
-            work->workletsProcessed = 1u;
-        };
-        while (mBuffersInfo.size() > 1u) {
-            finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
-            mBuffersInfo.pop_front();
-        }
-        if (work->workletsProcessed == 0u) {
-            fillEmptyWork(work);
-        }
-        mBuffersInfo.clear();
-    }
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftAac::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    return drainInternal(drainMode, pool, nullptr);
-}
-
-c2_status_t C2SoftAac::onFlush_sm() {
-    drainDecoder();
-    mBuffersInfo.clear();
-
-    int avail;
-    while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
-        if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
-            avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
-        }
-        int32_t ns = outputDelayRingBufferGetSamples(0, avail);
-        if (ns != avail) {
-            ALOGW("not a complete frame of samples available");
-            break;
-        }
-    }
-    mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
-
-    return C2_OK;
-}
-
-void C2SoftAac::drainDecoder() {
-    // flush decoder until outputDelay is compensated
-    while (mOutputDelayCompensated > 0) {
-        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
-        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
-
-        // run DRC check
-        mDrcWrap.submitStreamData(mStreamInfo);
-        mDrcWrap.update();
-
-        AAC_DECODER_ERROR decoderErr =
-            aacDecoder_DecodeFrame(mAACDecoder,
-                                   tmpOutBuffer,
-                                   2048 * MAX_CHANNEL_COUNT,
-                                   AACDEC_FLUSH);
-        if (decoderErr != AAC_DEC_OK) {
-            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
-        }
-
-        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
-        if (tmpOutBufferSamples > mOutputDelayCompensated) {
-            tmpOutBufferSamples = mOutputDelayCompensated;
-        }
-        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
-
-        mOutputDelayCompensated -= tmpOutBufferSamples;
-    }
-}
-
-class C2SoftAacDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAac(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAacDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAacDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/aacdec/C2SoftAac.h b/media/libstagefright/codecs/aacdec/C2SoftAac.h
deleted file mode 100644
index b877635..0000000
--- a/media/libstagefright/codecs/aacdec/C2SoftAac.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 C2_SOFT_AAC_H_
-#define C2_SOFT_AAC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-#include "aacdecoder_lib.h"
-#include "DrcPresModeWrap.h"
-
-namespace android {
-
-struct C2SoftAac : public SimpleC2Component {
-    C2SoftAac(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAac();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    enum {
-        kNumDelayBlocksMax      = 8,
-    };
-
-    HANDLE_AACDECODER mAACDecoder;
-    CStreamInfo *mStreamInfo;
-    bool mIsADTS;
-    bool mIsFirst;
-    size_t mInputBufferCount;
-    size_t mOutputBufferCount;
-    bool mSignalledError;
-    struct Info {
-        uint64_t frameIndex;
-        size_t bufferSize;
-        uint64_t timestamp;
-        std::vector<int32_t> decodedSizes;
-    };
-    std::list<Info> mBuffersInfo;
-
-    CDrcPresModeWrapper mDrcWrap;
-
-    enum {
-        NONE,
-        AWAITING_DISABLED,
-        AWAITING_ENABLED
-    } mOutputPortSettingsChange;
-
-    void initPorts();
-    status_t initDecoder();
-    bool isConfigured() const;
-    void drainDecoder();
-
-    void drainRingBuffer(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool,
-            bool eos);
-    c2_status_t drainInternal(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-
-//      delay compensation
-    bool mEndOfInput;
-    bool mEndOfOutput;
-    int32_t mOutputDelayCompensated;
-    int32_t mOutputDelayRingBufferSize;
-    short *mOutputDelayRingBuffer;
-    int32_t mOutputDelayRingBufferWritePos;
-    int32_t mOutputDelayRingBufferReadPos;
-    int32_t mOutputDelayRingBufferFilled;
-    bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
-    int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
-    int32_t outputDelayRingBufferSamplesAvailable();
-    int32_t outputDelayRingBufferSpaceLeft();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAac);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_AAC_H_
diff --git a/media/libstagefright/codecs/aacenc/Android.bp b/media/libstagefright/codecs/aacenc/Android.bp
index 9386c6e..9342351 100644
--- a/media/libstagefright/codecs/aacenc/Android.bp
+++ b/media/libstagefright/codecs/aacenc/Android.bp
@@ -1,42 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2aacenc",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftAacEnc.cpp"],
-
-    cflags: ["-Werror"],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libFraunhoferAAC",
-    ],
-
-    shared_libs: [
-        "libcutils",
-        "libion",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libutils",
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_aacenc",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/aacenc/C2SoftAacEnc.cpp b/media/libstagefright/codecs/aacenc/C2SoftAacEnc.cpp
deleted file mode 100644
index 70f6817..0000000
--- a/media/libstagefright/codecs/aacenc/C2SoftAacEnc.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * 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 "C2SoftAacEnc"
-#include <utils/Log.h>
-
-#include <inttypes.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include "C2SoftAacEnc.h"
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.aac.encoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatAudio)
-            .outputFormat(C2FormatCompressed)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_AAC)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftAacEnc::C2SoftAacEnc(
-        const char *name,
-        c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mAACEncoder(NULL),
-      mNumChannels(1),
-      mSampleRate(44100),
-      mBitRate(64000),
-      mSBRMode(-1),
-      mSBRRatio(0),
-      mAACProfile(AOT_AAC_LC),
-      mNumBytesPerInputFrame(0u),
-      mOutBufferSize(0u),
-      mSentCodecSpecificData(false),
-      mInputSize(0),
-      mInputTimeUs(-1ll),
-      mSignalledError(false) {
-}
-
-C2SoftAacEnc::~C2SoftAacEnc() {
-    onReset();
-}
-
-c2_status_t C2SoftAacEnc::onInit() {
-    status_t err = initEncoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-status_t C2SoftAacEnc::initEncoder() {
-    if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) {
-        ALOGE("Failed to init AAC encoder");
-        return UNKNOWN_ERROR;
-    }
-    return setAudioParams();
-}
-
-c2_status_t C2SoftAacEnc::onStop() {
-    mSentCodecSpecificData = false;
-    mInputSize = 0u;
-    mInputTimeUs = -1ll;
-    mSignalledError = false;
-    return C2_OK;
-}
-
-void C2SoftAacEnc::onReset() {
-    (void)onStop();
-    aacEncClose(&mAACEncoder);
-}
-
-void C2SoftAacEnc::onRelease() {
-    // no-op
-}
-
-c2_status_t C2SoftAacEnc::onFlush_sm() {
-    mSentCodecSpecificData = false;
-    mInputSize = 0u;
-    return C2_OK;
-}
-
-static CHANNEL_MODE getChannelMode(uint32_t nChannels) {
-    CHANNEL_MODE chMode = MODE_INVALID;
-    switch (nChannels) {
-        case 1: chMode = MODE_1; break;
-        case 2: chMode = MODE_2; break;
-        case 3: chMode = MODE_1_2; break;
-        case 4: chMode = MODE_1_2_1; break;
-        case 5: chMode = MODE_1_2_2; break;
-        case 6: chMode = MODE_1_2_2_1; break;
-        default: chMode = MODE_INVALID;
-    }
-    return chMode;
-}
-
-//static AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) {
-//    if (profile == OMX_AUDIO_AACObjectLC) {
-//        return AOT_AAC_LC;
-//    } else if (profile == OMX_AUDIO_AACObjectHE) {
-//        return AOT_SBR;
-//    } else if (profile == OMX_AUDIO_AACObjectHE_PS) {
-//        return AOT_PS;
-//    } else if (profile == OMX_AUDIO_AACObjectLD) {
-//        return AOT_ER_AAC_LD;
-//    } else if (profile == OMX_AUDIO_AACObjectELD) {
-//        return AOT_ER_AAC_ELD;
-//    } else {
-//        ALOGW("Unsupported AAC profile - defaulting to AAC-LC");
-//        return AOT_AAC_LC;
-//    }
-//}
-
-status_t C2SoftAacEnc::setAudioParams() {
-    // We call this whenever sample rate, number of channels, bitrate or SBR mode change
-    // in reponse to setParameter calls.
-
-    ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
-         mSampleRate, mNumChannels, mBitRate, mSBRMode, mSBRRatio);
-
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT, mAACProfile)) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mSampleRate)) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mBitRate)) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE,
-            getChannelMode(mNumChannels))) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-
-    if (mSBRMode != -1 && mAACProfile == AOT_ER_AAC_ELD) {
-        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) {
-            ALOGE("Failed to set AAC encoder parameters");
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    /* SBR ratio parameter configurations:
-       0: Default configuration wherein SBR ratio is configured depending on audio object type by
-          the FDK.
-       1: Downsampled SBR (default for ELD)
-       2: Dualrate SBR (default for HE-AAC)
-     */
-    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) {
-        ALOGE("Failed to set AAC encoder parameters");
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-void C2SoftAacEnc::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-
-    if (mSignalledError) {
-        return;
-    }
-    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-
-    if (!mSentCodecSpecificData) {
-        // The very first thing we want to output is the codec specific
-        // data.
-
-        if (AACENC_OK != aacEncEncode(mAACEncoder, NULL, NULL, NULL, NULL)) {
-            ALOGE("Unable to initialize encoder for profile / sample-rate / bit-rate / channels");
-            // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            mSignalledError = true;
-            return;
-        }
-
-        uint32_t actualBitRate = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE);
-        if (mBitRate != actualBitRate) {
-            ALOGW("Requested bitrate %u unsupported, using %u", mBitRate, actualBitRate);
-        }
-
-        AACENC_InfoStruct encInfo;
-        if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) {
-            ALOGE("Failed to get AAC encoder info");
-            // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            mSignalledError = true;
-            return;
-        }
-
-        std::unique_ptr<C2StreamCsdInfo::output> csd =
-            C2StreamCsdInfo::output::AllocUnique(encInfo.confSize, 0u);
-        // TODO: check NO_MEMORY
-        memcpy(csd->m.value, encInfo.confBuf, encInfo.confSize);
-        ALOGV("put csd");
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
-        hexdump(csd->m.value, csd->flexCount());
-#endif
-        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
-
-        mOutBufferSize = encInfo.maxOutBufBytes;
-        mNumBytesPerInputFrame = encInfo.frameLength * mNumChannels * sizeof(int16_t);
-        mInputTimeUs = work->input.ordinal.timestamp;
-
-        mSentCodecSpecificData = true;
-    }
-
-    C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    uint64_t timestamp = mInputTimeUs.peeku();
-
-    size_t numFrames = (view.capacity() + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
-            / mNumBytesPerInputFrame;
-    ALOGV("capacity = %u; mInputSize = %zu; numFrames = %zu", view.capacity(), mInputSize, numFrames);
-
-    std::shared_ptr<C2LinearBlock> block;
-    std::unique_ptr<C2WriteView> wView;
-    uint8_t *outPtr = nullptr;
-    size_t outAvailable = 0u;
-
-    if (numFrames) {
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        // TODO: error handling, proper usage, etc.
-        c2_status_t err = pool->fetchLinearBlock(mOutBufferSize * numFrames, usage, &block);
-        if (err != C2_OK) {
-            ALOGE("err = %d", err);
-        }
-
-        wView.reset(new C2WriteView(block->map().get()));
-        outPtr = wView->data();
-        outAvailable = wView->size();
-    }
-
-    AACENC_InArgs inargs;
-    AACENC_OutArgs outargs;
-    memset(&inargs, 0, sizeof(inargs));
-    memset(&outargs, 0, sizeof(outargs));
-    inargs.numInSamples = view.capacity() / sizeof(int16_t);
-
-    void* inBuffer[]        = { (unsigned char *)view.data() };
-    INT   inBufferIds[]     = { IN_AUDIO_DATA };
-    INT   inBufferSize[]    = { (INT)view.capacity() };
-    INT   inBufferElSize[]  = { sizeof(int16_t) };
-
-    AACENC_BufDesc inBufDesc;
-    inBufDesc.numBufs           = sizeof(inBuffer) / sizeof(void*);
-    inBufDesc.bufs              = (void**)&inBuffer;
-    inBufDesc.bufferIdentifiers = inBufferIds;
-    inBufDesc.bufSizes          = inBufferSize;
-    inBufDesc.bufElSizes        = inBufferElSize;
-
-    void* outBuffer[]       = { outPtr };
-    INT   outBufferIds[]    = { OUT_BITSTREAM_DATA };
-    INT   outBufferSize[]   = { 0 };
-    INT   outBufferElSize[] = { sizeof(UCHAR) };
-
-    AACENC_BufDesc outBufDesc;
-    outBufDesc.numBufs           = sizeof(outBuffer) / sizeof(void*);
-    outBufDesc.bufs              = (void**)&outBuffer;
-    outBufDesc.bufferIdentifiers = outBufferIds;
-    outBufDesc.bufSizes          = outBufferSize;
-    outBufDesc.bufElSizes        = outBufferElSize;
-
-    // Encode the mInputFrame, which is treated as a modulo buffer
-    AACENC_ERROR encoderErr = AACENC_OK;
-    size_t nOutputBytes = 0;
-
-    while (encoderErr == AACENC_OK && inargs.numInSamples > 0) {
-        memset(&outargs, 0, sizeof(outargs));
-
-        outBuffer[0] = outPtr;
-        outBufferSize[0] = outAvailable - nOutputBytes;
-
-        encoderErr = aacEncEncode(mAACEncoder,
-                                  &inBufDesc,
-                                  &outBufDesc,
-                                  &inargs,
-                                  &outargs);
-
-        if (encoderErr == AACENC_OK) {
-            if (outargs.numOutBytes > 0) {
-                mInputSize = 0;
-                int consumed = ((view.capacity() / sizeof(int16_t)) - inargs.numInSamples);
-                mInputTimeUs = work->input.ordinal.timestamp
-                        + (consumed * 1000000ll / mNumChannels / mSampleRate);
-            } else {
-                mInputSize += outargs.numInSamples * sizeof(int16_t);
-                mInputTimeUs += outargs.numInSamples * 1000000ll / mNumChannels / mSampleRate;
-            }
-            outPtr += outargs.numOutBytes;
-            nOutputBytes += outargs.numOutBytes;
-
-            if (outargs.numInSamples > 0) {
-                inBuffer[0] = (int16_t *)inBuffer[0] + outargs.numInSamples;
-                inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
-                inargs.numInSamples -= outargs.numInSamples;
-            }
-        }
-        ALOGV("nOutputBytes = %zu; inargs.numInSamples = %d", nOutputBytes, inargs.numInSamples);
-    }
-
-    if (eos && inBufferSize[0] > 0) {
-        memset(&outargs, 0, sizeof(outargs));
-
-        outBuffer[0] = outPtr;
-        outBufferSize[0] = outAvailable - nOutputBytes;
-
-        // Flush
-        inargs.numInSamples = -1;
-
-        (void)aacEncEncode(mAACEncoder,
-                           &inBufDesc,
-                           &outBufDesc,
-                           &inargs,
-                           &outargs);
-
-        nOutputBytes += outargs.numOutBytes;
-    }
-
-    work->worklets.front()->output.flags =
-        (C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0);
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->worklets.front()->output.ordinal.timestamp = timestamp;
-    work->workletsProcessed = 1u;
-    if (nOutputBytes) {
-        work->worklets.front()->output.buffers.push_back(
-                createLinearBuffer(block, 0, nOutputBytes));
-    }
-
-#if 0
-    ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)",
-          nOutputBytes, mInputTimeUs.peekll(), outHeader->nFlags);
-
-    hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
-#endif
-}
-
-c2_status_t C2SoftAacEnc::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    switch (drainMode) {
-        case DRAIN_COMPONENT_NO_EOS:  // fall-through
-        case NO_DRAIN:
-            // no-op
-            return C2_OK;
-        case DRAIN_CHAIN:
-            return C2_OMITTED;
-        case DRAIN_COMPONENT_WITH_EOS:
-            break;
-        default:
-            return C2_BAD_VALUE;
-    }
-
-    (void)pool;
-    mSentCodecSpecificData = false;
-    mInputSize = 0u;
-
-    // TODO: we don't have any pending work at this time to drain.
-    return C2_OK;
-}
-
-class C2SoftAacEncFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAacEnc(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAacEncFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAacEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/aacenc/C2SoftAacEnc.h b/media/libstagefright/codecs/aacenc/C2SoftAacEnc.h
deleted file mode 100644
index c9f440f..0000000
--- a/media/libstagefright/codecs/aacenc/C2SoftAacEnc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 C2_SOFT_AAC_ENC_H_
-
-#define C2_SOFT_AAC_ENC_H_
-
-#include <SimpleC2Component.h>
-#include <media/stagefright/foundation/ABase.h>
-
-#include "aacenc_lib.h"
-
-namespace android {
-
-class C2SoftAacEnc : public SimpleC2Component {
-public:
-    C2SoftAacEnc(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAacEnc();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    HANDLE_AACENCODER mAACEncoder;
-
-    uint32_t mNumChannels;
-    uint32_t mSampleRate;
-    uint32_t mBitRate;
-    int32_t mSBRMode;
-    int32_t mSBRRatio;
-    AUDIO_OBJECT_TYPE mAACProfile;
-    UINT mNumBytesPerInputFrame;
-    UINT mOutBufferSize;
-
-    bool mSentCodecSpecificData;
-    size_t mInputSize;
-    c2_cntr64_t mInputTimeUs;
-
-    bool mSignalledError;
-
-    status_t initEncoder();
-
-    status_t setAudioParams();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAacEnc);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_AAC_ENC_H_
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index f97af89..880f161 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -41,7 +41,7 @@
     ],
 
     include_dirs: ["frameworks/av/media/libstagefright/include"],
-    local_include_dirs: ["src"],
+    export_include_dirs: ["src"],
 
     cflags: [
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
@@ -138,100 +138,3 @@
     //    ],
     //},
 }
-
-//###############################################################################
-cc_library_shared {
-    name: "libstagefright_soft_c2amrnbdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftAMR.cpp",],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codecs/amrwb/src",
-    ],
-
-    local_include_dirs: ["src"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-DAMRNB",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libstagefright_amrnbdec",
-        "libstagefright_amrwbdec",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libstagefright_amrnb_common",
-    ],
-}
-
-//###############################################################################
-cc_library_shared {
-    name: "libstagefright_soft_c2amrwbdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftAMR.cpp",],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codecs/amrwb/src",
-    ],
-
-    local_include_dirs: ["src"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libstagefright_amrnbdec",
-        "libstagefright_amrwbdec",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libstagefright_amrnb_common",
-    ],
-}
\ No newline at end of file
diff --git a/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.cpp
deleted file mode 100644
index 1d4928a..0000000
--- a/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * 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 "C2SoftAMR"
-#include <utils/Log.h>
-
-#include "C2SoftAMR.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include "gsmamr_dec.h"
-#include "pvamrwbdecoder.h"
-
-namespace android {
-
-#ifdef AMRNB
-  constexpr char kComponentName[] = "c2.google.amrnb.decoder";
-#else
-  constexpr char kComponentName[] = "c2.google.amrwb.decoder";
-#endif
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(
-#ifdef AMRNB
-                    MEDIA_MIMETYPE_AUDIO_AMR_NB
-#else
-                    MEDIA_MIMETYPE_AUDIO_AMR_WB
-#endif
-            )
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftAMR::C2SoftAMR(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mAmrHandle(nullptr),
-      mDecoderBuf(nullptr),
-      mDecoderCookie(nullptr) {
-}
-
-C2SoftAMR::~C2SoftAMR() {
-    (void)onRelease();
-}
-
-c2_status_t C2SoftAMR::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftAMR::onStop() {
-    if (!mIsWide) {
-        Speech_Decode_Frame_reset(mAmrHandle);
-    } else {
-        pvDecoder_AmrWb_Reset(mAmrHandle, 0 /* reset_all */);
-    }
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return C2_OK;
-}
-
-void C2SoftAMR::onReset() {
-    (void)onStop();
-}
-
-void C2SoftAMR::onRelease() {
-    if (!mIsWide) {
-        GSMDecodeFrameExit(&mAmrHandle);
-        mAmrHandle = nullptr;
-    } else {
-        free(mDecoderBuf);
-        mDecoderBuf = nullptr;
-
-        mAmrHandle = nullptr;
-        mDecoderCookie = nullptr;
-    }
-}
-
-c2_status_t C2SoftAMR::onFlush_sm() {
-    return onStop();
-}
-
-status_t C2SoftAMR::initDecoder() {
-#ifdef AMRNB
-    mIsWide = false;
-#else
-    mIsWide = true;
-#endif
-    if (!mIsWide) {
-        if (GSMInitDecode(&mAmrHandle, (int8_t *)"AMRNBDecoder"))
-            return UNKNOWN_ERROR;
-    } else {
-        uint32_t memReq = pvDecoder_AmrWbMemRequirements();
-        mDecoderBuf = malloc(memReq);
-        if (mDecoderBuf) {
-            pvDecoder_AmrWb_Init(&mAmrHandle, mDecoderBuf, &mDecoderCookie);
-        }
-        else {
-            return NO_MEMORY;
-        }
-    }
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return OK;
-}
-
-static size_t getFrameSize(bool isWide, unsigned FM) {
-    static const size_t kFrameSizeNB[16] = {
-        12, 13, 15, 17, 19, 20, 26, 31,
-        5, 6, 5, 5, // SID
-        0, 0, 0, // future use
-        0 // no data
-    };
-    static const size_t kFrameSizeWB[16] = {
-        17, 23, 32, 36, 40, 46, 50, 58, 60,
-        5, // SID
-        0, 0, 0, 0, // future use
-        0, // speech lost
-        0 // no data
-    };
-
-    if (FM > 15 || (isWide && FM > 9 && FM < 14) || (!isWide && FM > 11 && FM < 15)) {
-        ALOGE("illegal AMR frame mode %d", FM);
-        return 0;
-    }
-    // add 1 for header byte
-    return (isWide ? kFrameSizeWB[FM] : kFrameSizeNB[FM]) + 1;
-}
-
-static status_t calculateNumFrames(const uint8 *input, size_t inSize,
-                                   std::vector<size_t> *frameSizeList, bool isWide) {
-    for (size_t k = 0; k < inSize;) {
-        int16_t FM = ((input[0] >> 3) & 0x0f);
-        size_t frameSize = getFrameSize(isWide, FM);
-        if (frameSize == 0) return UNKNOWN_ERROR;
-        if ((inSize - k) >= frameSize) {
-            input += frameSize;
-            k += frameSize;
-        }
-        else break;
-        frameSizeList->push_back(frameSize);
-    }
-    return OK;
-}
-
-void C2SoftAMR::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer =
-            work->input.buffers[0]->data().linearBlocks().front();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-    if (inSize == 0) {
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    std::vector<size_t> frameSizeList;
-    if (OK != calculateNumFrames(rView.data() + inOffset, inSize, &frameSizeList,
-                                 mIsWide)) {
-        work->result = C2_CORRUPTED;
-        mSignalledError = true;
-        return;
-    }
-    if (frameSizeList.empty()) {
-        ALOGE("input size smaller than expected");
-        work->result = C2_CORRUPTED;
-        mSignalledError = true;
-        return;
-    }
-
-    int16_t outSamples = mIsWide ? kNumSamplesPerFrameWB : kNumSamplesPerFrameNB;
-    size_t calOutSize = outSamples * frameSizeList.size() * sizeof(int16_t);
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = wView.error();
-        return;
-    }
-
-    int16_t *output = reinterpret_cast<int16_t *>(wView.data());
-    auto it = frameSizeList.begin();
-    const uint8_t *inPtr = rView.data() + inOffset;
-    size_t inPos = 0;
-    while (inPos < inSize) {
-        if (it == frameSizeList.end()) {
-            ALOGD("unexpected trailing bytes, ignoring them");
-            break;
-        }
-        uint8_t *input = const_cast<uint8_t *>(inPtr + inPos);
-        int16_t FM = ((*input >> 3) & 0x0f);
-        if (!mIsWide) {
-            int32_t numBytesRead = AMRDecode(mAmrHandle,
-                                             (Frame_Type_3GPP) FM,
-                                             input + 1, output, MIME_IETF);
-            if (static_cast<size_t>(numBytesRead + 1) != *it) {
-                ALOGE("panic, parsed size does not match decoded size");
-                work->result = C2_CORRUPTED;
-                mSignalledError = true;
-                return;
-            }
-        } else {
-            if (FM >= 9) {
-                // Produce silence instead of comfort noise and for
-                // speech lost/no data.
-                memset(output, 0, outSamples * sizeof(int16_t));
-            } else {
-                int16_t FT;
-                RX_State_wb rx_state;
-                int16_t numRecSamples;
-
-                mime_unsorting(const_cast<uint8_t *>(&input[1]),
-                               mInputSampleBuffer, &FT, &FM, 1, &rx_state);
-                pvDecoder_AmrWb(FM, mInputSampleBuffer, output, &numRecSamples,
-                                mDecoderBuf, FT, mDecoderCookie);
-                if (numRecSamples != outSamples) {
-                    ALOGE("Sample output per frame incorrect");
-                    work->result = C2_CORRUPTED;
-                    mSignalledError = true;
-                    return;
-                }
-                /* Delete the 2 LSBs (14-bit output) */
-                for (int i = 0; i < numRecSamples; ++i) {
-                    output[i] &= 0xfffC;
-                }
-            }
-        }
-        inPos += *it;
-        output += outSamples;
-        ++it;
-    }
-
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-c2_status_t C2SoftAMR::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-    return C2_OK;
-}
-
-class C2SoftAMRDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAMR(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAMRDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAMRDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.h b/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.h
deleted file mode 100644
index 69fe213..0000000
--- a/media/libstagefright/codecs/amrnb/dec/C2SoftAMR.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 C2_SOFT_AMR_H_
-#define C2_SOFT_AMR_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct C2SoftAMR : public SimpleC2Component {
-    C2SoftAMR(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAMR();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-private:
-    enum {
-        kSampleRateNB           = 8000,
-        kSampleRateWB           = 16000,
-        kNumSamplesPerFrameNB   = 160,
-        kNumSamplesPerFrameWB   = 320,
-    };
-
-    void *mAmrHandle;
-    void *mDecoderBuf;
-    int16_t *mDecoderCookie;
-
-    int16_t mInputSampleBuffer[477];
-
-    bool mIsWide;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-
-    status_t initDecoder();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAMR);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_AMR_H_
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index 4001d46..19fd4a8 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -63,7 +63,7 @@
     ],
 
     include_dirs: ["frameworks/av/media/libstagefright/include"],
-    local_include_dirs: ["src"],
+    export_include_dirs: ["src"],
 
     cflags: [
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
@@ -122,50 +122,6 @@
 
 //###############################################################################
 
-cc_library_shared {
-    name: "libstagefright_soft_c2amrnbenc",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftAmrNbEnc.cpp"],
-
-    local_include_dirs: ["src"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libstagefright_amrnbenc",
-    ],
-
-    shared_libs: [
-        "libutils",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libstagefright_amrnb_common",
-    ],
-}
-
-//###############################################################################
-
 cc_test {
     name: "libstagefright_amrnbenc_test",
     gtest: false,
diff --git a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp b/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp
deleted file mode 100644
index 406d1ca..0000000
--- a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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 "C2SoftAmrNbEnc"
-#include <utils/Log.h>
-
-#include "gsmamr_enc.h"
-
-#include "C2SoftAmrNbEnc.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.amrnb.encoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatAudio)
-            .outputFormat(C2FormatCompressed)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_AMR_NB)
-            .build();
-}
-
-C2SoftAmrNbEnc::C2SoftAmrNbEnc(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mEncState(nullptr),
-      mSidState(nullptr) {
-}
-
-C2SoftAmrNbEnc::~C2SoftAmrNbEnc() {
-    onRelease();
-}
-
-c2_status_t C2SoftAmrNbEnc::onInit() {
-    bool dtx_enable = false;
-
-    if (AMREncodeInit(&mEncState, &mSidState, dtx_enable) != 0)
-        return C2_CORRUPTED;
-    mMode = MR795;
-    mIsFirst = true;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-    mFilledLen = 0;
-
-    return C2_OK;
-}
-
-void C2SoftAmrNbEnc::onRelease() {
-    if (mEncState) {
-        AMREncodeExit(&mEncState, &mSidState);
-        mEncState = mSidState = nullptr;
-    }
-}
-
-c2_status_t C2SoftAmrNbEnc::onStop() {
-    if (AMREncodeReset(mEncState, mSidState) != 0)
-        return C2_CORRUPTED;
-    mIsFirst = true;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-    mFilledLen = 0;
-
-    return C2_OK;
-}
-
-void C2SoftAmrNbEnc::onReset() {
-    (void) onStop();
-}
-
-c2_status_t C2SoftAmrNbEnc::onFlush_sm() {
-    return onStop();
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftAmrNbEnc::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
-    size_t outCapacity = kNumBytesPerInputFrame;
-    outCapacity += mFilledLen + inSize;
-    std::shared_ptr<C2LinearBlock> outputBlock;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = outputBlock->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    uint64_t outTimeStamp = mProcessedSamples * 1000000ll / kSampleRate;
-    const uint8_t *inPtr = rView.data() + inOffset;
-    size_t inPos = 0;
-    size_t outPos = 0;
-    while (inPos < inSize) {
-        int validSamples = mFilledLen / sizeof(int16_t);
-        if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
-            memcpy(mInputFrame + validSamples, inPtr + inPos,
-                   (kNumBytesPerInputFrame - mFilledLen));
-            inPos += (kNumBytesPerInputFrame - mFilledLen);
-        } else {
-            memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
-            mFilledLen += (inSize - inPos);
-            inPos += (inSize - inPos);
-            if (eos) {
-                validSamples = mFilledLen / sizeof(int16_t);
-                memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
-            } else break;
-        }
-        Frame_Type_3GPP frameType;
-        int numEncBytes = AMREncode(mEncState, mSidState, mMode, mInputFrame,
-                                    wView.data() + outPos, &frameType,
-                                    AMR_TX_WMF);
-        if (numEncBytes < 0 || numEncBytes > ((int)outCapacity - (int)outPos)) {
-            ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        // Convert header byte from WMF to IETF format.
-        if (numEncBytes > 0)
-            wView.data()[outPos] = ((wView.data()[outPos] << 3) | 4) & 0x7c;
-        outPos += numEncBytes;
-        mProcessedSamples += kNumSamplesPerFrame;
-        mFilledLen = 0;
-    }
-    ALOGV("causal sample size %d", mFilledLen);
-    if (mIsFirst) {
-        mIsFirst = false;
-        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
-    }
-    fillEmptyWork(work);
-    if (outPos != 0) {
-        work->worklets.front()->output.buffers.push_back(
-                createLinearBuffer(std::move(outputBlock), 0, outPos));
-        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-    }
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-        if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
-    }
-}
-
-c2_status_t C2SoftAmrNbEnc::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    onFlush_sm();
-    return C2_OK;
-}
-
-class C2SoftAmrNbEncFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAmrNbEnc(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAmrNbEncFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAmrNbEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.h b/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.h
deleted file mode 100644
index 9ced921..0000000
--- a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 C2_SOFT_AMRNB_ENC_H_
-#define C2_SOFT_AMRNB_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-namespace android {
-
-class C2SoftAmrNbEnc : public SimpleC2Component {
-public:
-    C2SoftAmrNbEnc(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAmrNbEnc();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    static const int32_t kNumSamplesPerFrame = L_FRAME;
-    static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
-    static const int32_t kSampleRate = 8000;
-
-    void *mEncState;
-    void *mSidState;
-    Mode mMode;
-    bool mIsFirst;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-    uint64_t mAnchorTimeStamp;
-    uint64_t mProcessedSamples;
-    int32_t mFilledLen;
-    int16_t mInputFrame[kNumSamplesPerFrame];
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAmrNbEnc);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_AMRNB_ENC_H_
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/libstagefright/codecs/amrwb/Android.bp
index 14a73d6..9fefd81 100644
--- a/media/libstagefright/codecs/amrwb/Android.bp
+++ b/media/libstagefright/codecs/amrwb/Android.bp
@@ -45,8 +45,11 @@
     ],
 
     include_dirs: ["frameworks/av/media/libstagefright/include"],
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
+
+    export_include_dirs: [
+        "src",
+        "include",
+    ],
 
     cflags: [
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 88e9206..ebe08c6 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -185,46 +185,4 @@
 
 //###############################################################################
 
-cc_library_shared {
-    name: "libstagefright_soft_c2amrwbenc",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftAmrWbEnc.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libstagefright_amrwbenc",
-    ],
-
-    shared_libs: [
-        "libutils",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libstagefright_enc_common",
-    ],
-}
-
-//###############################################################################
-
 subdirs = ["SampleCode"]
diff --git a/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.cpp b/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.cpp
deleted file mode 100644
index 2a831e5..0000000
--- a/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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 "C2SoftAmrWbEnc"
-#include <utils/Log.h>
-
-#include "C2SoftAmrWbEnc.h"
-
-#include "cmnMemory.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.amrwb.encoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatAudio)
-            .outputFormat(C2FormatCompressed)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_AMR_WB)
-            .build();
-}
-
-C2SoftAmrWbEnc::C2SoftAmrWbEnc(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mEncoderHandle(nullptr),
-      mApiHandle(nullptr),
-      mMemOperator(nullptr) {
-}
-
-C2SoftAmrWbEnc::~C2SoftAmrWbEnc() {
-    onRelease();
-}
-
-c2_status_t C2SoftAmrWbEnc::onInit() {
-    status_t err = initEncoder();
-    mMode = VOAMRWB_MD2305;
-    mIsFirst = true;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-    mFilledLen = 0;
-
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-void C2SoftAmrWbEnc::onRelease() {
-    if (mEncoderHandle) {
-        CHECK_EQ((VO_U32)VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
-        mEncoderHandle = nullptr;
-    }
-    if (mApiHandle) {
-        delete mApiHandle;
-        mApiHandle = nullptr;
-    }
-    if (mMemOperator) {
-        delete mMemOperator;
-        mMemOperator = nullptr;
-    }
-}
-
-c2_status_t C2SoftAmrWbEnc::onStop() {
-    for (int i = 0; i < kNumSamplesPerFrame; i++) {
-        mInputFrame[i] = 0x0008; /* EHF_MASK */
-    }
-    uint8_t outBuffer[kNumBytesPerInputFrame];
-    (void) encodeInput(outBuffer, kNumBytesPerInputFrame);
-    mIsFirst = true;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-    mFilledLen = 0;
-
-    return C2_OK;
-}
-
-void C2SoftAmrWbEnc::onReset() {
-    (void) onStop();
-}
-
-c2_status_t C2SoftAmrWbEnc::onFlush_sm() {
-    return onStop();
-}
-
-status_t C2SoftAmrWbEnc::initEncoder() {
-    mApiHandle = new VO_AUDIO_CODECAPI;
-    if (!mApiHandle) return NO_MEMORY;
-
-    if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) {
-        ALOGE("Failed to get api handle");
-        return UNKNOWN_ERROR;
-    }
-
-    mMemOperator = new VO_MEM_OPERATOR;
-    if (!mMemOperator) return NO_MEMORY;
-
-    mMemOperator->Alloc = cmnMemAlloc;
-    mMemOperator->Copy = cmnMemCopy;
-    mMemOperator->Free = cmnMemFree;
-    mMemOperator->Set = cmnMemSet;
-    mMemOperator->Check = cmnMemCheck;
-
-    VO_CODEC_INIT_USERDATA userData;
-    memset(&userData, 0, sizeof(userData));
-    userData.memflag = VO_IMF_USERMEMOPERATOR;
-    userData.memData = (VO_PTR) mMemOperator;
-
-    if (VO_ERR_NONE != mApiHandle->Init(
-                &mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) {
-        ALOGE("Failed to init AMRWB encoder");
-        return UNKNOWN_ERROR;
-    }
-
-    VOAMRWBFRAMETYPE type = VOAMRWB_RFC3267;
-    if (VO_ERR_NONE != mApiHandle->SetParam(
-                mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &type)) {
-        ALOGE("Failed to set AMRWB encoder frame type to %d", type);
-        return UNKNOWN_ERROR;
-    }
-
-    if (VO_ERR_NONE !=
-            mApiHandle->SetParam(
-                    mEncoderHandle, VO_PID_AMRWB_MODE,  &mMode)) {
-        ALOGE("Failed to set AMRWB encoder mode to %d", mMode);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-int C2SoftAmrWbEnc::encodeInput(uint8_t *buffer, uint32_t length) {
-    VO_CODECBUFFER inputData;
-    memset(&inputData, 0, sizeof(inputData));
-    inputData.Buffer = (unsigned char *) mInputFrame;
-    inputData.Length = kNumBytesPerInputFrame;
-
-    CHECK_EQ((VO_U32)VO_ERR_NONE,
-             mApiHandle->SetInputData(mEncoderHandle, &inputData));
-
-    VO_AUDIO_OUTPUTINFO outputInfo;
-    memset(&outputInfo, 0, sizeof(outputInfo));
-    VO_CODECBUFFER outputData;
-    memset(&outputData, 0, sizeof(outputData));
-    outputData.Buffer = buffer;
-    outputData.Length = length;
-    VO_U32 ret = mApiHandle->GetOutputData(
-            mEncoderHandle, &outputData, &outputInfo);
-    if (ret != VO_ERR_NONE && ret != VO_ERR_INPUT_BUFFER_SMALL) {
-        ALOGD("encountered error during encode call");
-        return -1;
-    }
-    return outputData.Length;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftAmrWbEnc::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
-    size_t outCapacity = kNumBytesPerInputFrame;
-    outCapacity += mFilledLen + inSize;
-    std::shared_ptr<C2LinearBlock> outputBlock;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = outputBlock->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = wView.error();
-        return;
-    }
-
-    uint64_t outTimeStamp = mProcessedSamples * 1000000ll / kSampleRate;
-    const uint8_t *inPtr = rView.data() + inOffset;
-    size_t inPos = 0;
-    size_t outPos = 0;
-    while (inPos < inSize) {
-        int validSamples = mFilledLen / sizeof(int16_t);
-        if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
-            memcpy(mInputFrame + validSamples, inPtr + inPos,
-                   (kNumBytesPerInputFrame - mFilledLen));
-            inPos += (kNumBytesPerInputFrame - mFilledLen);
-        } else {
-            memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
-            mFilledLen += (inSize - inPos);
-            inPos += (inSize - inPos);
-            if (eos) {
-                validSamples = mFilledLen / sizeof(int16_t);
-                memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
-            } else break;
-        }
-        int numEncBytes = encodeInput((wView.data() + outPos), outCapacity - outPos);
-        if (numEncBytes < 0) {
-            ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        outPos += numEncBytes;
-        mProcessedSamples += kNumSamplesPerFrame;
-        mFilledLen = 0;
-    }
-    ALOGV("causal sample size %d", mFilledLen);
-    if (mIsFirst) {
-        mIsFirst = false;
-        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
-    }
-    fillEmptyWork(work);
-    if (outPos != 0) {
-        work->worklets.front()->output.buffers.push_back(
-                createLinearBuffer(std::move(outputBlock), 0, outPos));
-        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-    }
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-        if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
-    }
-}
-
-c2_status_t C2SoftAmrWbEnc::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    onFlush_sm();
-    return C2_OK;
-}
-
-class C2SoftAmrWbEncFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAmrWbEnc(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAmrWbEncFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAmrWbEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.h b/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.h
deleted file mode 100644
index 29e68ac..0000000
--- a/media/libstagefright/codecs/amrwbenc/C2SoftAmrWbEnc.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 C2_SOFT_AMRWB_ENC_H_
-#define C2_SOFT_AMRWB_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-#include "voAMRWB.h"
-
-namespace android {
-
-class C2SoftAmrWbEnc : public SimpleC2Component {
-public:
-    C2SoftAmrWbEnc(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAmrWbEnc();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    static const int32_t kNumSamplesPerFrame = 320;
-    static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
-    static const int32_t kSampleRate = 16000;
-
-    void *mEncoderHandle;
-    VO_AUDIO_CODECAPI *mApiHandle;
-    VO_MEM_OPERATOR *mMemOperator;
-    VOAMRWBMODE mMode;
-    bool mIsFirst;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-    uint64_t mAnchorTimeStamp;
-    uint64_t mProcessedSamples;
-    int32_t mFilledLen;
-    int16_t mInputFrame[kNumSamplesPerFrame];
-
-    status_t initEncoder();
-    int encodeInput(uint8_t *buffer, uint32_t length);
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAmrWbEnc);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_AMRWB_ENC_H_
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index d789096..cf50a04 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -42,44 +42,3 @@
     ldflags: ["-Wl,-Bsymbolic"],
     compile_multilib: "32",
 }
-
-cc_library_shared {
-    name: "libstagefright_soft_c2avcdec",
-
-    static_libs: [
-        "libavcdec",
-    ],
-    srcs: ["C2SoftAvcDec.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    include_dirs: [
-        "external/libavc/decoder",
-        "external/libavc/common",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libmedia",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: false, // true,
-        diag: {
-            cfi: false, // true,
-        },
-    },
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
diff --git a/media/libstagefright/codecs/avcdec/C2AvcConfig.h b/media/libstagefright/codecs/avcdec/C2AvcConfig.h
deleted file mode 100644
index a7e0d95..0000000
--- a/media/libstagefright/codecs/avcdec/C2AvcConfig.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 C2AVCCONFIG_H_
-#define C2AVCCONFIG_H_
-
-#include <C2Config.h>
-
-namespace android {
-
-enum : uint32_t {
-    kParamIndexAvcProfile = kParamIndexParamStart + 1,
-    kParamIndexAvcLevel,
-    kParamIndexBlockSize,
-    kParamIndexAlignment,
-    kParamIndexFramerate,
-    kParamIndexBlocksPerSecond,
-};
-
-enum C2AvcProfileIdc : uint32_t {
-    kAvcProfileUnknown  = 0,
-    kAvcProfileBaseline = 66,
-    kAvcProfileMain     = 77,
-    kAvcProfileExtended = 88,
-    kAvcProfileHigh     = 100,
-    kAvcProfileHigh10   = 110,
-    kAvcProfileHigh422  = 122,
-    kAvcProfileHigh444  = 144,
-};
-
-enum C2AvcLevelIdc : uint32_t {
-    kAvcLevelUnknown = 0,
-    kAvcLevel10      = 10,
-    kAvcLevel1b      = 9,
-    kAvcLevel11      = 11,
-    kAvcLevel12      = 12,
-    kAvcLevel13      = 13,
-    kAvcLevel20      = 20,
-    kAvcLevel21      = 21,
-    kAvcLevel22      = 22,
-    kAvcLevel30      = 30,
-    kAvcLevel31      = 31,
-    kAvcLevel32      = 32,
-    kAvcLevel40      = 40,
-    kAvcLevel41      = 41,
-    kAvcLevel42      = 42,
-    kAvcLevel50      = 50,
-    kAvcLevel51      = 51,
-    kAvcLevel52      = 52,
-};
-
-// profile for AVC video decoder [IN]
-typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2AvcProfileIdc>, kParamIndexAvcProfile>
-    C2AvcProfileInfo;
-
-// level for AVC video decoder [IN]
-typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2AvcLevelIdc>, kParamIndexAvcLevel>
-    C2AvcLevelInfo;
-
-// block size [OUT]
-typedef C2StreamParam<C2Info, C2VideoSizeStruct, kParamIndexBlockSize> C2BlockSizeInfo;
-
-// alignment [OUT]
-typedef C2StreamParam<C2Info, C2VideoSizeStruct, kParamIndexAlignment> C2AlignmentInfo;
-
-// frame rate [OUT, hint]
-typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexFramerate> C2FrameRateInfo;
-
-// blocks-per-second [OUT, hint]
-typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexBlocksPerSecond> C2BlocksPerSecondInfo;
-
-} // namespace android
-
-#endif  // C2AVCCONFIG_H_
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
deleted file mode 100644
index 1fc2c8c..0000000
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * 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 "C2SoftAvcDec"
-#include <utils/Log.h>
-
-#include <cmath>
-#include <thread>
-#include <cinttypes>
-
-#include "ih264_typedefs.h"
-#include "iv.h"
-#include "ivd.h"
-#include "ih264d.h"
-#include "C2SoftAvcDec.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <utils/misc.h>
-
-#include "ih264d_defs.h"
-
-namespace android {
-
-struct iv_obj_t : public ::iv_obj_t {};
-struct ivd_video_decode_ip_t : public ::ivd_video_decode_ip_t {};
-struct ivd_video_decode_op_t : public ::ivd_video_decode_op_t {};
-
-#define PRINT_TIME  ALOGV
-
-constexpr char kComponentName[] = "c2.google.avc.decoder";
-// #define codingType                      OMX_VIDEO_CodingAVC
-#define CODEC_MIME_TYPE                 MEDIA_MIMETYPE_VIDEO_AVC
-
-/** Function and structure definitions to keep code similar for each codec */
-#define ivdec_api_function              ih264d_api_function
-#define ivdext_create_ip_t              ih264d_create_ip_t
-#define ivdext_create_op_t              ih264d_create_op_t
-#define ivdext_delete_ip_t              ih264d_delete_ip_t
-#define ivdext_delete_op_t              ih264d_delete_op_t
-#define ivdext_ctl_set_num_cores_ip_t   ih264d_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t   ih264d_ctl_set_num_cores_op_t
-
-#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
-        (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
-namespace {
-
-std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatVideo)
-            .inputMediaType(MEDIA_MIMETYPE_VIDEO_AVC)
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .build();
-}
-
-void CopyPlane(
-        uint8_t *dst, const C2PlaneInfo &plane,
-        const uint8_t *src, uint32_t width, uint32_t height) {
-    for (uint32_t row = 0; row < height; ++row) {
-        for (uint32_t col = 0; col < width; ++col) {
-            *dst = *src;
-            dst += plane.colInc;
-            ++src;
-        }
-        dst -= plane.colInc * width;
-        dst += plane.rowInc;
-    }
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    uint32_t flags = 0;
-    if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM)) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-    }
-    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-}  // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-
-C2SoftAvcDec::C2SoftAvcDec(
-        const char *name,
-        c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mCodecCtx(NULL),
-      mOutBuffer(NULL),
-      mIvColorFormat(IV_YUV_420P),
-      mChangingResolution(false),
-      mSignalledError(false),
-      mWidth(320),
-      mHeight(240),
-      mInputOffset(0) {
-    ALOGV("in %s", __func__);
-    GETTIME(&mTimeStart, NULL);
-
-    // If input dump is enabled, then open create an empty file
-    GENERATE_FILE_NAMES();
-    CREATE_DUMP_FILE(mInFile);
-}
-
-C2SoftAvcDec::~C2SoftAvcDec() {
-    ALOGV("in %s", __func__);
-    CHECK_EQ(deInitDecoder(), (status_t)OK);
-}
-
-c2_status_t C2SoftAvcDec::onInit() {
-    // TODO: initialize using intf
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcDec::onStop() {
-    ALOGV("onStop");
-    mSignalledError = false;
-    resetDecoder();
-    resetPlugin();
-
-    return C2_OK;
-}
-
-void C2SoftAvcDec::onReset() {
-    ALOGV("onReset");
-    (void)onStop();
-}
-
-void C2SoftAvcDec::onRelease() {
-    (void)deInitDecoder();
-}
-
-c2_status_t C2SoftAvcDec::onFlush_sm() {
-    setFlushMode();
-
-    while (true) {
-        ivd_video_decode_ip_t s_dec_ip;
-        ivd_video_decode_op_t s_dec_op;
-        IV_API_CALL_STATUS_T status;
-        // size_t sizeY, sizeUV;
-
-        setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, 0, 0u);
-
-        status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
-        if (0 == s_dec_op.u4_output_present) {
-            resetPlugin();
-            break;
-        }
-    }
-
-    if (mOutBuffer) {
-        free(mOutBuffer);
-        mOutBuffer = NULL;
-    }
-    return C2_OK;
-}
-
-static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
-    (void) ctxt;
-    return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *ctxt, void *buf) {
-    (void) ctxt;
-    free(buf);
-    return;
-}
-
-static size_t GetCPUCoreCount() {
-    long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
-    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    // _SC_NPROC_ONLN must be defined...
-    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
-    CHECK(cpuCoreCount >= 1);
-    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
-    return (size_t)cpuCoreCount;
-}
-
-void C2SoftAvcDec::logVersion() {
-    ivd_ctl_getversioninfo_ip_t s_ctl_ip;
-    ivd_ctl_getversioninfo_op_t s_ctl_op;
-    UWORD8 au1_buf[512];
-    IV_API_CALL_STATUS_T status;
-
-    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
-    s_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
-    s_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
-    s_ctl_ip.pv_version_buffer = au1_buf;
-    s_ctl_ip.u4_version_buffer_size = sizeof(au1_buf);
-
-    status =
-        ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGE("Error in getting version number: 0x%x",
-                s_ctl_op.u4_error_code);
-    } else {
-        ALOGV("Ittiam decoder version number: %s",
-                (char *)s_ctl_ip.pv_version_buffer);
-    }
-    return;
-}
-
-status_t C2SoftAvcDec::setParams(size_t stride) {
-    ivd_ctl_set_config_ip_t s_ctl_ip;
-    ivd_ctl_set_config_op_t s_ctl_op;
-    IV_API_CALL_STATUS_T status;
-    s_ctl_ip.u4_disp_wd = (UWORD32)stride;
-    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
-
-    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
-    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
-    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
-    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
-    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
-
-    ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride);
-    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGE("Error in setting the run-time parameters: 0x%x",
-                s_ctl_op.u4_error_code);
-
-        return UNKNOWN_ERROR;
-    }
-
-    if (mOutBuffer != NULL) {
-        free(mOutBuffer);
-    }
-    uint32_t bufferSize = mWidth * mHeight * 3 / 2;
-    mOutBuffer = (uint8_t *)memalign(128, bufferSize);
-    if (NULL == mOutBuffer) {
-        ALOGE("Could not allocate output buffer of size %u", bufferSize);
-        return C2_NO_MEMORY;
-    }
-    return OK;
-}
-
-status_t C2SoftAvcDec::resetPlugin() {
-    mInputOffset = 0;
-
-    /* Initialize both start and end times */
-    gettimeofday(&mTimeStart, NULL);
-    gettimeofday(&mTimeEnd, NULL);
-
-    return OK;
-}
-
-status_t C2SoftAvcDec::resetDecoder() {
-    ivd_ctl_reset_ip_t s_ctl_ip;
-    ivd_ctl_reset_op_t s_ctl_op;
-    IV_API_CALL_STATUS_T status;
-
-    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
-    s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
-    s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
-
-    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("Error in reset: 0x%x", s_ctl_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    mSignalledError = false;
-
-    /* Set number of cores/threads to be used by the codec */
-    setNumCores();
-
-    mStride = 0;
-    return OK;
-}
-
-status_t C2SoftAvcDec::setNumCores() {
-    ivdext_ctl_set_num_cores_ip_t s_set_cores_ip;
-    ivdext_ctl_set_num_cores_op_t s_set_cores_op;
-    IV_API_CALL_STATUS_T status;
-    s_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
-    s_set_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_NUM_CORES);
-    s_set_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
-    s_set_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
-    status = ivdec_api_function(
-            mCodecCtx, (void *)&s_set_cores_ip, (void *)&s_set_cores_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("Error in setting number of cores: 0x%x",
-                s_set_cores_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    return OK;
-}
-
-status_t C2SoftAvcDec::setFlushMode() {
-    ALOGV("setFlushMode");
-    IV_API_CALL_STATUS_T status;
-    ivd_ctl_flush_ip_t s_video_flush_ip;
-    ivd_ctl_flush_op_t s_video_flush_op;
-
-    s_video_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_video_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
-    s_video_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
-    s_video_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
-
-    /* Set the decoder in Flush mode, subsequent decode() calls will flush */
-    status = ivdec_api_function(
-            mCodecCtx, (void *)&s_video_flush_ip, (void *)&s_video_flush_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGE("Error in setting the decoder in flush mode: (%d) 0x%x", status,
-                s_video_flush_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftAvcDec::initDecoder() {
-    IV_API_CALL_STATUS_T status;
-
-    mNumCores = GetCPUCoreCount();
-    mCodecCtx = NULL;
-
-    mStride = mWidth;
-
-    /* Initialize the decoder */
-    {
-        ivdext_create_ip_t s_create_ip;
-        ivdext_create_op_t s_create_op;
-
-        void *dec_fxns = (void *)ivdec_api_function;
-
-        s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
-        s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
-        s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
-        s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
-        s_create_ip.s_ivd_create_ip_t.e_output_format = (IV_COLOR_FORMAT_T)mIvColorFormat;
-        s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
-        s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
-        s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
-
-        status = ivdec_api_function(mCodecCtx, (void *)&s_create_ip, (void *)&s_create_op);
-
-        mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
-        mCodecCtx->pv_fxns = dec_fxns;
-        mCodecCtx->u4_size = sizeof(iv_obj_t);
-
-        if (status != IV_SUCCESS) {
-            ALOGE("Error in create: 0x%x",
-                    s_create_op.s_ivd_create_op_t.u4_error_code);
-            deInitDecoder();
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    /* Reset the plugin state */
-    resetPlugin();
-
-    /* Set the run time (dynamic) parameters */
-    setParams(mStride);
-
-    /* Set number of cores/threads to be used by the codec */
-    setNumCores();
-
-    /* Get codec version */
-    logVersion();
-
-    mFlushNeeded = false;
-    return OK;
-}
-
-status_t C2SoftAvcDec::deInitDecoder() {
-    IV_API_CALL_STATUS_T status;
-
-    if (mCodecCtx) {
-        ivdext_delete_ip_t s_delete_ip;
-        ivdext_delete_op_t s_delete_op;
-
-        s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
-        s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
-
-        s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
-
-        status = ivdec_api_function(mCodecCtx, (void *)&s_delete_ip, (void *)&s_delete_op);
-        if (status != IV_SUCCESS) {
-            ALOGE("Error in delete: 0x%x",
-                    s_delete_op.s_ivd_delete_op_t.u4_error_code);
-            return UNKNOWN_ERROR;
-        }
-        mCodecCtx = NULL;
-    }
-
-    mChangingResolution = false;
-
-    return OK;
-}
-
-bool C2SoftAvcDec::getVUIParams() {
-    IV_API_CALL_STATUS_T status;
-    ih264d_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
-    ih264d_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
-
-    s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_ctl_get_vui_params_ip.e_sub_cmd =
-        (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_GET_VUI_PARAMS;
-
-    s_ctl_get_vui_params_ip.u4_size =
-        sizeof(ih264d_ctl_get_vui_params_ip_t);
-
-    s_ctl_get_vui_params_op.u4_size = sizeof(ih264d_ctl_get_vui_params_op_t);
-
-    status = ivdec_api_function(
-            (iv_obj_t *)mCodecCtx, (void *)&s_ctl_get_vui_params_ip,
-            (void *)&s_ctl_get_vui_params_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGW("Error in getting VUI params: 0x%x",
-                s_ctl_get_vui_params_op.u4_error_code);
-        return false;
-    }
-
-    int32_t primaries = s_ctl_get_vui_params_op.u1_colour_primaries;
-    int32_t transfer = s_ctl_get_vui_params_op.u1_tfr_chars;
-    int32_t coeffs = s_ctl_get_vui_params_op.u1_matrix_coeffs;
-    bool fullRange = s_ctl_get_vui_params_op.u1_video_full_range_flag;
-
-    ColorAspects colorAspects;
-    ColorUtils::convertIsoColorAspectsToCodecAspects(
-            primaries, transfer, coeffs, fullRange, colorAspects);
-
-    // Update color aspects if necessary.
-    if (colorAspectsDiffer(colorAspects, mBitstreamColorAspects)) {
-        mBitstreamColorAspects = colorAspects;
-        status_t err = handleColorAspectsChange();
-        CHECK(err == OK);
-    }
-    return true;
-}
-
-bool C2SoftAvcDec::setDecodeArgs(
-        ivd_video_decode_ip_t *ps_dec_ip,
-        ivd_video_decode_op_t *ps_dec_op,
-        C2ReadView *inBuffer,
-        C2GraphicView *outBuffer,
-        uint32_t workIndex,
-        size_t inOffset) {
-    size_t width = mWidth;
-    size_t height = mHeight;
-    size_t sizeY = width * height;
-    size_t sizeUV;
-
-    ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t);
-    ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
-    ps_dec_op->u4_output_present = 0;
-
-    ps_dec_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
-
-    /* When in flush and after EOS with zero byte input,
-     * inBuffer is set to zero. Hence check for non-null */
-    if (inBuffer) {
-        ps_dec_ip->u4_ts = workIndex;
-        ps_dec_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data()) + inOffset;
-        ps_dec_ip->u4_num_Bytes = inBuffer->capacity() - inOffset;
-    } else {
-        ps_dec_ip->u4_ts = 0;
-        ps_dec_ip->pv_stream_buffer = NULL;
-        ps_dec_ip->u4_num_Bytes = 0;
-    }
-
-    sizeUV = sizeY / 4;
-    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY;
-    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV;
-    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV;
-
-    if (outBuffer) {
-        if (outBuffer->width() < width ||
-                outBuffer->height() < height) {
-            ALOGE("Output buffer too small: provided (%dx%d) required (%zux%zu)",
-                  outBuffer->width(), outBuffer->height(), width, height);
-            return false;
-        }
-        ALOGV("width = %u, stride[0] = %u, stride[1] = %u, stride[2] = %u",
-                outBuffer->width(),
-                outBuffer->layout().planes[0].rowInc,
-                outBuffer->layout().planes[1].rowInc,
-                outBuffer->layout().planes[2].rowInc);
-        const C2PlanarLayout &layout = outBuffer->layout();
-        ps_dec_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[0];
-        if (layout.planes[0].rowInc != (int32_t)mWidth || layout.planes[1].colInc != 1) {
-            ps_dec_ip->s_out_buffer.pu1_bufs[0] = mOutBuffer;
-        }
-        ps_dec_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[1];
-        if (layout.planes[1].rowInc != (int32_t)mWidth / 2 || layout.planes[1].colInc != 1) {
-            ps_dec_ip->s_out_buffer.pu1_bufs[1] = mOutBuffer + sizeY;
-        }
-        ps_dec_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[2];
-        if (layout.planes[2].rowInc != (int32_t)mWidth / 2 || layout.planes[2].colInc != 1) {
-            ps_dec_ip->s_out_buffer.pu1_bufs[2] = mOutBuffer + sizeY + sizeUV;
-        }
-    } else {
-        // mOutBuffer always has the right size.
-        ps_dec_ip->s_out_buffer.pu1_bufs[0] = mOutBuffer;
-        ps_dec_ip->s_out_buffer.pu1_bufs[1] = mOutBuffer + sizeY;
-        ps_dec_ip->s_out_buffer.pu1_bufs[2] = mOutBuffer + sizeY + sizeUV;
-    }
-
-    ps_dec_ip->s_out_buffer.u4_num_bufs = 3;
-    return true;
-}
-
-c2_status_t C2SoftAvcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
-    if (NULL == mCodecCtx) {
-        if (OK != initDecoder()) {
-            ALOGE("Failed to initialize decoder");
-            // TODO: notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
-            mSignalledError = true;
-            return C2_CORRUPTED;
-        }
-    }
-    if (mWidth != mStride) {
-        /* Set the run-time (dynamic) parameters */
-        mStride = mWidth;
-        setParams(mStride);
-    }
-
-    if (!mAllocatedBlock) {
-        // TODO: error handling
-        // TODO: format & usage
-        uint32_t format = HAL_PIXEL_FORMAT_YV12;
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        ALOGV("using allocator %u", pool->getAllocatorId());
-
-        (void)pool->fetchGraphicBlock(
-                mWidth, mHeight, format, usage, &mAllocatedBlock);
-        ALOGV("provided (%dx%d) required (%dx%d)",
-                mAllocatedBlock->width(), mAllocatedBlock->height(), mWidth, mHeight);
-    }
-    return C2_OK;
-}
-
-void C2SoftAvcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(mAllocatedBlock);
-    mAllocatedBlock.reset();
-    auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
-        uint32_t flags = 0;
-        if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
-            ALOGV("EOS");
-        }
-        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    };
-    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
-        fillWork(work);
-    } else {
-        finish(index, fillWork);
-    }
-}
-
-void C2SoftAvcDec::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    bool eos = false;
-
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-
-    const C2ConstLinearBlock buffer =
-        work->input.buffers[0]->data().linearBlocks().front();
-    if (buffer.size() == 0) {
-        ALOGV("empty input: %llu", work->input.ordinal.frameIndex.peekull());
-        // TODO: result?
-        fillEmptyWork(work);
-        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM)) {
-            eos = true;
-        }
-        return;
-    } else if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        ALOGV("input EOS: %llu", work->input.ordinal.frameIndex.peekull());
-        eos = true;
-    }
-
-    C2ReadView input = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (input.error() != C2_OK) {
-        work->result = input.error();
-        fillEmptyWork(work);
-        ALOGD("map error: %d", input.error());
-        return;
-    }
-    ALOGV("buffer.size() = %u, input.capacity() = %u", buffer.size(), input.capacity());
-    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
-    size_t inOffset = 0u;
-
-    while (inOffset < input.capacity()) {
-        if (mSignalledError) {
-            break;
-        }
-        (void)ensureDecoderState(pool);
-        ivd_video_decode_ip_t s_dec_ip;
-        ivd_video_decode_op_t s_dec_op;
-        WORD32 timeDelay, timeTaken;
-        //size_t sizeY, sizeUV;
-
-        {
-            C2GraphicView output = mAllocatedBlock->map().get();
-            if (output.error() != C2_OK) {
-                ALOGE("mapped err = %d", output.error());
-                work->result = output.error();
-                fillEmptyWork(work);
-                return;
-            }
-            if (!setDecodeArgs(&s_dec_ip, &s_dec_op, &input, &output, workIndex, inOffset)) {
-                ALOGE("Decoder arg setup failed");
-                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                mSignalledError = true;
-                break;
-            }
-            ALOGV("Decoder arg setup succeeded");
-            // If input dump is enabled, then write to file
-            DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes, mInputOffset);
-
-            GETTIME(&mTimeStart, NULL);
-            /* Compute time elapsed between end of previous decode()
-             * to start of current decode() */
-            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
-
-            IV_API_CALL_STATUS_T status;
-            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
-            ALOGV("status = %d, error_code = %d", status, (s_dec_op.u4_error_code & 0xFF));
-            if (s_dec_op.u4_output_present) {
-                const C2PlanarLayout &layout = output.layout();
-                if (layout.planes[0].rowInc != (int32_t)mWidth || layout.planes[1].colInc != 1) {
-                    CopyPlane(output.data()[0], layout.planes[0], mOutBuffer, mWidth, mHeight);
-                }
-                if (layout.planes[1].rowInc != (int32_t)mWidth / 2 || layout.planes[1].colInc != 1) {
-                    CopyPlane(
-                            output.data()[1], layout.planes[1],
-                            mOutBuffer + (mWidth * mHeight), mWidth / 2, mHeight / 2);
-                }
-                if (layout.planes[2].rowInc != (int32_t)mWidth / 2 || layout.planes[2].colInc != 1) {
-                    CopyPlane(
-                            output.data()[2], layout.planes[2],
-                            mOutBuffer + (mWidth * mHeight * 5 / 4), mWidth / 2, mHeight / 2);
-                }
-            }
-        }
-
-        bool unsupportedResolution =
-            (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
-
-        /* Check for unsupported dimensions */
-        if (unsupportedResolution) {
-            ALOGE("Unsupported resolution : %dx%d", mWidth, mHeight);
-            // TODO: notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
-            mSignalledError = true;
-            break;
-        }
-
-        bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
-        if (allocationFailed) {
-            ALOGE("Allocation failure in decoder");
-            // TODO: notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
-            mSignalledError = true;
-            break;
-        }
-
-        bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
-
-        getVUIParams();
-
-        GETTIME(&mTimeEnd, NULL);
-        /* Compute time taken for decode() */
-        TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
-
-        PRINT_TIME("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
-               s_dec_op.u4_num_bytes_consumed);
-        ALOGV("bytes total=%u", input.capacity());
-        if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
-            mFlushNeeded = true;
-        }
-
-        if (1 != s_dec_op.u4_frame_decoded_flag) {
-            /* If the input did not contain picture data, return work without
-             * buffer */
-            ALOGV("no picture data: %u", workIndex);
-            fillEmptyWork(work);
-        }
-
-        if (resChanged) {
-            ALOGV("res changed");
-            if (mFlushNeeded) {
-                drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
-            }
-            resetDecoder();
-            resetPlugin();
-            mStride = mWidth;
-            setParams(mStride);
-            continue;
-        }
-
-        if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) {
-            uint32_t width = s_dec_op.u4_pic_wd;
-            uint32_t height = s_dec_op.u4_pic_ht;
-            ALOGV("width = %u height = %u", width, height);
-            if (width != mWidth || height != mHeight) {
-                mAllocatedBlock.reset();
-                mWidth = width;
-                mHeight = height;
-            }
-            // TODO: continue?
-        }
-
-        if (mUpdateColorAspects) {
-            //notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
-            //    kDescribeColorAspectsIndex, NULL);
-            ALOGV("update color aspect");
-            mUpdateColorAspects = false;
-        }
-
-        if (s_dec_op.u4_output_present) {
-            ALOGV("output_present: %d", s_dec_op.u4_ts);
-            finishWork(s_dec_op.u4_ts, work);
-        }
-
-        inOffset += s_dec_op.u4_num_bytes_consumed;
-    }
-    if (inOffset >= input.capacity()) {
-        /* If input EOS is seen, drain the decoder.
-         * There can be a case where EOS is sent along with last picture data
-         * In that case, only after decoding that input data, decoder has to be
-         * put in flush. This case is handled here  */
-        if (eos) {
-            drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
-        }
-    }
-}
-
-c2_status_t C2SoftAvcDec::drainInternal(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work) {
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-    setFlushMode();
-
-    while (true) {
-        (void)ensureDecoderState(pool);
-        C2GraphicView output = mAllocatedBlock->map().get();
-        if (output.error() != OK) {
-            ALOGE("mapped err = %d", output.error());
-        }
-
-        ivd_video_decode_ip_t s_dec_ip;
-        ivd_video_decode_op_t s_dec_op;
-
-        setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, &output, 0, 0u);
-
-        (void)ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
-
-        if (s_dec_op.u4_output_present) {
-            ALOGV("output_present: %d", s_dec_op.u4_ts);
-            finishWork(s_dec_op.u4_ts, work);
-        } else {
-            break;
-        }
-    }
-
-    if (drainMode == DRAIN_COMPONENT_WITH_EOS
-            && work && work->workletsProcessed == 0u) {
-        fillEmptyWork(work);
-    }
-
-    return C2_OK;
-}
-
-bool C2SoftAvcDec::colorAspectsDiffer(
-        const ColorAspects &a, const ColorAspects &b) {
-    if (a.mRange != b.mRange
-        || a.mPrimaries != b.mPrimaries
-        || a.mTransfer != b.mTransfer
-        || a.mMatrixCoeffs != b.mMatrixCoeffs) {
-        return true;
-    }
-    return false;
-}
-
-c2_status_t C2SoftAvcDec::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    return drainInternal(drainMode, pool, nullptr);
-}
-
-void C2SoftAvcDec::updateFinalColorAspects(
-        const ColorAspects &otherAspects, const ColorAspects &preferredAspects) {
-    Mutex::Autolock autoLock(mColorAspectsLock);
-    ColorAspects newAspects;
-    newAspects.mRange = preferredAspects.mRange != ColorAspects::RangeUnspecified ?
-        preferredAspects.mRange : otherAspects.mRange;
-    newAspects.mPrimaries = preferredAspects.mPrimaries != ColorAspects::PrimariesUnspecified ?
-        preferredAspects.mPrimaries : otherAspects.mPrimaries;
-    newAspects.mTransfer = preferredAspects.mTransfer != ColorAspects::TransferUnspecified ?
-        preferredAspects.mTransfer : otherAspects.mTransfer;
-    newAspects.mMatrixCoeffs = preferredAspects.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
-        preferredAspects.mMatrixCoeffs : otherAspects.mMatrixCoeffs;
-
-    // Check to see if need update mFinalColorAspects.
-    if (colorAspectsDiffer(mFinalColorAspects, newAspects)) {
-        mFinalColorAspects = newAspects;
-        mUpdateColorAspects = true;
-    }
-}
-
-status_t C2SoftAvcDec::handleColorAspectsChange() {
-//    int perference = getColorAspectPreference();
-//    ALOGD("Color Aspects preference: %d ", perference);
-//
-//     if (perference == kPreferBitstream) {
-//         updateFinalColorAspects(mDefaultColorAspects, mBitstreamColorAspects);
-//     } else if (perference == kPreferContainer) {
-//         updateFinalColorAspects(mBitstreamColorAspects, mDefaultColorAspects);
-//     } else {
-//         return OMX_ErrorUnsupportedSetting;
-//     }
-    updateFinalColorAspects(mDefaultColorAspects, mBitstreamColorAspects);
-    return C2_OK;
-}
-
-class C2SoftAvcDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAvcDec(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAvcDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAvcDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
deleted file mode 100644
index d324a0f..0000000
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * 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 C2_SOFT_H264_DEC_H_
-
-#define C2_SOFT_H264_DEC_H_
-
-#include <condition_variable>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <set>
-#include <unordered_map>
-
-#include <util/C2ParamUtils.h>
-
-#include <C2Component.h>
-#include <C2Param.h>
-#include <SimpleC2Component.h>
-
-#include "C2AvcConfig.h"
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/ColorUtils.h>
-
-#include <sys/time.h>
-
-namespace android {
-
-struct iv_obj_t;
-struct ivd_video_decode_ip_t;
-struct ivd_video_decode_op_t;
-
-/** Number of entries in the time-stamp array */
-#define MAX_PENDING_WORKS 64
-
-/** Maximum number of cores supported by the codec */
-#define CODEC_MAX_NUM_CORES 4
-
-#define CODEC_MAX_WIDTH     1920
-
-#define CODEC_MAX_HEIGHT    1088
-
-/** Input buffer size */
-#define INPUT_BUF_SIZE (1024 * 1024)
-
-#define MIN(a, b) ((a) < (b)) ? (a) : (b)
-
-/** Get time */
-#define GETTIME(a, b) gettimeofday(a, b);
-
-/** Compute difference between start and end */
-#define TIME_DIFF(start, end, diff) \
-    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
-            ((end).tv_usec - (start).tv_usec);
-
-#if 0
-class C2SoftAvcDecIntf : public C2ComponentInterface {
-public:
-    struct SupportedValuesWithFields {
-        C2FieldSupportedValues supported;
-        std::set<C2ParamField> restrictingFields;
-
-        SupportedValuesWithFields(const C2FieldSupportedValues &supported) : supported(supported) {}
-    };
-
-    C2SoftAvcDecIntf(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAvcDecIntf() override;
-
-    // From C2ComponentInterface
-    virtual C2String getName() const override;
-    virtual c2_node_id_t getId() const override;
-    virtual c2_status_t query_vb(
-            const std::vector<C2Param*> &stackParams,
-            const std::vector<C2Param::Index> &heapParamIndices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
-    virtual c2_status_t config_vb(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
-    virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) override;
-    virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) override;
-    // TODO: move this into some common store class
-    std::shared_ptr<C2ParamReflector> getParamReflector() const;
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override;
-    virtual c2_status_t querySupportedValues_vb(
-            std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const override;
-
-private:
-    class ParamReflector;
-
-    const C2String mName;
-    const c2_node_id_t mId;
-
-    C2ComponentDomainInfo mDomainInfo;
-    // TODO: config desc
-    std::unique_ptr<C2PortMimeConfig::input> mInputPortMime;
-    C2PortStreamCountConfig::input mInputStreamCount;
-    std::unique_ptr<C2PortMimeConfig::output> mOutputPortMime;
-    C2PortStreamCountConfig::output mOutputStreamCount;
-    // TODO: C2StreamMimeConfig mInputStreamMime;
-    // TODO: C2StreamMimeConfig mOutputStreamMime;
-    C2StreamFormatConfig::input mInputStreamFormat;
-    std::unique_ptr<C2PortBlockPoolsTuning::output> mOutputBlockPools;
-    C2StreamFormatConfig::output mOutputStreamFormat;
-    C2VideoSizeStreamInfo::output mVideoSize;
-    C2MaxVideoSizeHintPortSetting::input mMaxVideoSizeHint;
-    C2AvcProfileInfo::input mProfile;
-    C2AvcLevelInfo::input mLevel;
-    C2BlockSizeInfo::output mBlockSize;
-    C2AlignmentInfo::output mAlignment;
-    C2FrameRateInfo::output mFrameRate;
-    C2BlocksPerSecondInfo::output mBlocksPerSecond;
-
-    std::shared_ptr<C2ParamReflector> mParamReflector;
-
-    std::unordered_map<uint32_t, C2Param *> mParams;
-    // C2ParamField is LessThanComparable
-    std::map<C2ParamField, SupportedValuesWithFields> mSupportedValues;
-    std::unordered_map<
-            uint32_t, std::function<std::unique_ptr<C2SettingResult>(C2Param *)>> mFieldVerifiers;
-    std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
-
-    void updateSupportedValues();
-    friend class C2SoftAvcDec;
-};
-#endif
-
-class C2SoftAvcDec : public SimpleC2Component {
-public:
-    C2SoftAvcDec(const char *name, c2_node_id_t id);
-    virtual ~C2SoftAvcDec();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    Mutex mColorAspectsLock;
-    // color aspects passed from the framework.
-    ColorAspects mDefaultColorAspects;
-    // color aspects parsed from the bitstream.
-    ColorAspects mBitstreamColorAspects;
-    // final color aspects after combining the above two aspects.
-    ColorAspects mFinalColorAspects;
-    bool mUpdateColorAspects;
-
-    bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
-
-    // This functions takes two color aspects and updates the mFinalColorAspects
-    // based on |preferredAspects|.
-    void updateFinalColorAspects(
-            const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
-
-    // This function will update the mFinalColorAspects based on codec preference.
-    status_t handleColorAspectsChange();
-
-    std::shared_ptr<C2GraphicBlock> mAllocatedBlock;
-
-    iv_obj_t *mCodecCtx;         // Codec context
-
-    size_t mNumCores;            // Number of cores to be uesd by the codec
-
-    struct timeval mTimeStart;   // Time at the start of decode()
-    struct timeval mTimeEnd;     // Time at the end of decode()
-
-    // Internal buffer to be used to flush out the buffers from decoder
-    uint8_t *mOutBuffer;
-
-#ifdef FILE_DUMP_ENABLE
-    char mInFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
-    int mIvColorFormat;        // Ittiam Color format
-
-    bool mIsInFlush;        // codec is flush mode
-    bool mReceivedEOS;      // EOS is receieved on input port
-
-    // The input stream has changed to a different resolution, which is still supported by the
-    // codec. So the codec is switching to decode the new resolution.
-    bool mChangingResolution;
-    bool mFlushNeeded;
-    bool mSignalledError;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mStride;
-    size_t mInputOffset;
-
-    status_t initDecoder();
-    status_t deInitDecoder();
-    status_t setFlushMode();
-    status_t setParams(size_t stride);
-    void logVersion();
-    status_t setNumCores();
-    status_t resetDecoder();
-    status_t resetPlugin();
-
-    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
-    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
-    c2_status_t drainInternal(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-
-    bool setDecodeArgs(
-            ivd_video_decode_ip_t *ps_dec_ip,
-            ivd_video_decode_op_t *ps_dec_op,
-            C2ReadView *inBuffer,
-            C2GraphicView *outBuffer,
-            uint32_t timeStampIx,
-            size_t inOffset);
-
-    bool getVUIParams();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAvcDec);
-};
-
-#ifdef FILE_DUMP_ENABLE
-
-#define INPUT_DUMP_PATH     "/sdcard/media/avcd_input"
-#define INPUT_DUMP_EXT      "h264"
-
-#define GENERATE_FILE_NAMES() {                         \
-    GETTIME(&mTimeStart, NULL);                         \
-    strcpy(mInFile, "");                                \
-    sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
-            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
-            INPUT_DUMP_EXT);                            \
-}
-
-#define CREATE_DUMP_FILE(m_filename) {                  \
-    FILE *fp = fopen(m_filename, "wb");                 \
-    if (fp != NULL) {                                   \
-        fclose(fp);                                     \
-    } else {                                            \
-        ALOGD("Could not open file %s", m_filename);    \
-    }                                                   \
-}
-#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)\
-{                                                       \
-    FILE *fp = fopen(m_filename, "ab");                 \
-    if (fp != NULL && m_buf != NULL && m_offset == 0) { \
-        int i;                                          \
-        i = fwrite(m_buf, 1, m_size, fp);               \
-        ALOGD("fwrite ret %d to write %d", i, m_size);  \
-        if (i != (int) m_size) {                        \
-            ALOGD("Error in fwrite, returned %d", i);   \
-            perror("Error in write to file");           \
-        }                                               \
-    } else if (fp == NULL) {                            \
-        ALOGD("Could not write to file %s", m_filename);\
-    }                                                   \
-    if (fp) {                                           \
-        fclose(fp);                                     \
-    }                                                   \
-}
-#else /* FILE_DUMP_ENABLE */
-#define INPUT_DUMP_PATH
-#define INPUT_DUMP_EXT
-#define OUTPUT_DUMP_PATH
-#define OUTPUT_DUMP_EXT
-#define GENERATE_FILE_NAMES()
-#define CREATE_DUMP_FILE(m_filename)
-#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)
-#endif /* FILE_DUMP_ENABLE */
-
-} // namespace android
-
-#endif  // C2_SOFT_H264_DEC_H_
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 67a2fdc..cefe77c 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -1,48 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2avcenc",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    static_libs: [ "libavcenc" ],
-    srcs: ["C2SoftAvcEnc.cpp"],
-
-    include_dirs: [
-        "external/libavc/encoder",
-        "external/libavc/common",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/native/include/media/hardware",
-    ],
-
-    shared_libs: [
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libutils",
-        "liblog",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-variable",
-    ],
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_avcenc",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp b/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp
deleted file mode 100644
index d75e4c1..0000000
--- a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp
+++ /dev/null
@@ -1,1253 +0,0 @@
-/*
- * 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 "C2SoftAvcEnc"
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "ih264_typedefs.h"
-#include "ih264e.h"
-#include "ih264e_error.h"
-#include "iv2.h"
-#include "ive2.h"
-#include "C2SoftAvcEnc.h"
-
-namespace android {
-
-#define ive_api_function  ih264e_api_function
-
-constexpr char kComponentName[] = "c2.google.avc.encoder";
-
-namespace {
-
-// From external/libavc/encoder/ih264e_bitstream.h
-constexpr uint32_t MIN_STREAM_SIZE = 0x800;
-
-static size_t GetCPUCoreCount() {
-    long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
-    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    // _SC_NPROC_ONLN must be defined...
-    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
-    CHECK(cpuCoreCount >= 1);
-    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
-    return (size_t)cpuCoreCount;
-}
-
-std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatVideo)
-            .outputFormat(C2FormatCompressed)
-            .inputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_AVC)
-            .build();
-}
-
-void ConvertRGBToPlanarYUV(
-        uint8_t *dstY, size_t dstStride, size_t dstVStride,
-        const C2GraphicView &src) {
-    CHECK((src.width() & 1) == 0);
-    CHECK((src.height() & 1) == 0);
-
-    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];
-
-    for (size_t y = 0; y < src.height(); ++y) {
-        for (size_t x = 0; x < src.width(); ++x) {
-            unsigned red   = *pRed;
-            unsigned green = *pGreen;
-            unsigned blue  = *pBlue;
-
-            // using ITU-R BT.601 conversion matrix
-            unsigned luma =
-                ((red * 66 + green * 129 + blue * 25) >> 8) + 16;
-
-            dstY[x] = luma;
-
-            if ((x & 1) == 0 && (y & 1) == 0) {
-                unsigned U =
-                    ((-red * 38 - green * 74 + blue * 112) >> 8) + 128;
-
-                unsigned V =
-                    ((red * 112 - green * 94 - blue * 18) >> 8) + 128;
-
-                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;
-    }
-}
-
-}  // namespace
-
-C2SoftAvcEnc::C2SoftAvcEnc(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mUpdateFlag(0),
-      mIvVideoColorFormat(IV_YUV_420P),
-      mAVCEncProfile(IV_PROFILE_BASE),
-      mAVCEncLevel(41),
-      mStarted(false),
-      mSawInputEOS(false),
-      mSawOutputEOS(false),
-      mSignalledError(false),
-      mCodecCtx(NULL),
-      mWidth(1080),
-      mHeight(1920),
-      mFramerate(60),
-      mBitrate(20000),
-      // TODO: output buffer size
-      mOutBufferSize(524288) {
-
-    // If dump is enabled, then open create an empty file
-    GENERATE_FILE_NAMES();
-    CREATE_DUMP_FILE(mInFile);
-    CREATE_DUMP_FILE(mOutFile);
-
-    initEncParams();
-}
-
-C2SoftAvcEnc::~C2SoftAvcEnc() {
-    releaseEncoder();
-}
-
-c2_status_t C2SoftAvcEnc::onInit() {
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::onStop() {
-    return C2_OK;
-}
-
-void C2SoftAvcEnc::onReset() {
-    // TODO: use IVE_CMD_CTL_RESET?
-    releaseEncoder();
-    initEncParams();
-}
-
-void C2SoftAvcEnc::onRelease() {
-    releaseEncoder();
-}
-
-c2_status_t C2SoftAvcEnc::onFlush_sm() {
-    // TODO: use IVE_CMD_CTL_FLUSH?
-    return C2_OK;
-}
-
-void  C2SoftAvcEnc::initEncParams() {
-    mCodecCtx = NULL;
-    mMemRecords = NULL;
-    mNumMemRecords = DEFAULT_MEM_REC_CNT;
-    mHeaderGenerated = 0;
-    mNumCores = GetCPUCoreCount();
-    mArch = DEFAULT_ARCH;
-    mSliceMode = DEFAULT_SLICE_MODE;
-    mSliceParam = DEFAULT_SLICE_PARAM;
-    mHalfPelEnable = DEFAULT_HPEL;
-    mIInterval = DEFAULT_I_INTERVAL;
-    mIDRInterval = DEFAULT_IDR_INTERVAL;
-    mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL;
-    mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;
-    mEnableAltRef = DEFAULT_ENABLE_ALT_REF;
-    mEncSpeed = DEFAULT_ENC_SPEED;
-    mIntra4x4 = DEFAULT_INTRA4x4;
-    mConstrainedIntraFlag = DEFAULT_CONSTRAINED_INTRA;
-    mAIRMode = DEFAULT_AIR;
-    mAIRRefreshPeriod = DEFAULT_AIR_REFRESH_PERIOD;
-    mPSNREnable = DEFAULT_PSNR_ENABLE;
-    mReconEnable = DEFAULT_RECON_ENABLE;
-    mEntropyMode = DEFAULT_ENTROPY_MODE;
-    mBframes = DEFAULT_B_FRAMES;
-
-    gettimeofday(&mTimeStart, NULL);
-    gettimeofday(&mTimeEnd, NULL);
-}
-
-c2_status_t C2SoftAvcEnc::setDimensions() {
-    ive_ctl_set_dimensions_ip_t s_dimensions_ip;
-    ive_ctl_set_dimensions_op_t s_dimensions_op;
-    IV_STATUS_T status;
-
-    s_dimensions_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_dimensions_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
-    s_dimensions_ip.u4_ht = mHeight;
-    s_dimensions_ip.u4_wd = mWidth;
-
-    s_dimensions_ip.u4_timestamp_high = -1;
-    s_dimensions_ip.u4_timestamp_low = -1;
-
-    s_dimensions_ip.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
-    s_dimensions_op.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_dimensions_ip, &s_dimensions_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set frame dimensions = 0x%x\n",
-                s_dimensions_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setNumCores() {
-    IV_STATUS_T status;
-    ive_ctl_set_num_cores_ip_t s_num_cores_ip;
-    ive_ctl_set_num_cores_op_t s_num_cores_op;
-    s_num_cores_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_num_cores_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
-    s_num_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_CORES);
-    s_num_cores_ip.u4_timestamp_high = -1;
-    s_num_cores_ip.u4_timestamp_low = -1;
-    s_num_cores_ip.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
-
-    s_num_cores_op.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
-
-    status = ive_api_function(
-            mCodecCtx, (void *) &s_num_cores_ip, (void *) &s_num_cores_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set processor params = 0x%x\n",
-                s_num_cores_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setFrameRate() {
-    ive_ctl_set_frame_rate_ip_t s_frame_rate_ip;
-    ive_ctl_set_frame_rate_op_t s_frame_rate_op;
-    IV_STATUS_T status;
-
-    s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
-
-    s_frame_rate_ip.u4_src_frame_rate = mFramerate;
-    s_frame_rate_ip.u4_tgt_frame_rate = mFramerate;
-
-    s_frame_rate_ip.u4_timestamp_high = -1;
-    s_frame_rate_ip.u4_timestamp_low = -1;
-
-    s_frame_rate_ip.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
-    s_frame_rate_op.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_frame_rate_ip, &s_frame_rate_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set frame rate = 0x%x\n",
-                s_frame_rate_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setIpeParams() {
-    ive_ctl_set_ipe_params_ip_t s_ipe_params_ip;
-    ive_ctl_set_ipe_params_op_t s_ipe_params_op;
-    IV_STATUS_T status;
-
-    s_ipe_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_ipe_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
-
-    s_ipe_params_ip.u4_enable_intra_4x4 = mIntra4x4;
-    s_ipe_params_ip.u4_enc_speed_preset = mEncSpeed;
-    s_ipe_params_ip.u4_constrained_intra_pred = mConstrainedIntraFlag;
-
-    s_ipe_params_ip.u4_timestamp_high = -1;
-    s_ipe_params_ip.u4_timestamp_low = -1;
-
-    s_ipe_params_ip.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
-    s_ipe_params_op.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_ipe_params_ip, &s_ipe_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set ipe params = 0x%x\n",
-                s_ipe_params_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setBitRate() {
-    ive_ctl_set_bitrate_ip_t s_bitrate_ip;
-    ive_ctl_set_bitrate_op_t s_bitrate_op;
-    IV_STATUS_T status;
-
-    s_bitrate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_bitrate_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
-
-    s_bitrate_ip.u4_target_bitrate = mBitrate;
-
-    s_bitrate_ip.u4_timestamp_high = -1;
-    s_bitrate_ip.u4_timestamp_low = -1;
-
-    s_bitrate_ip.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
-    s_bitrate_op.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_bitrate_ip, &s_bitrate_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set bit rate = 0x%x\n", s_bitrate_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {
-    ive_ctl_set_frame_type_ip_t s_frame_type_ip;
-    ive_ctl_set_frame_type_op_t s_frame_type_op;
-    IV_STATUS_T status;
-    s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
-
-    s_frame_type_ip.e_frame_type = e_frame_type;
-
-    s_frame_type_ip.u4_timestamp_high = -1;
-    s_frame_type_ip.u4_timestamp_low = -1;
-
-    s_frame_type_ip.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
-    s_frame_type_op.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_frame_type_ip, &s_frame_type_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set frame type = 0x%x\n",
-                s_frame_type_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setQp() {
-    ive_ctl_set_qp_ip_t s_qp_ip;
-    ive_ctl_set_qp_op_t s_qp_op;
-    IV_STATUS_T status;
-
-    s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
-
-    s_qp_ip.u4_i_qp = DEFAULT_I_QP;
-    s_qp_ip.u4_i_qp_max = DEFAULT_QP_MAX;
-    s_qp_ip.u4_i_qp_min = DEFAULT_QP_MIN;
-
-    s_qp_ip.u4_p_qp = DEFAULT_P_QP;
-    s_qp_ip.u4_p_qp_max = DEFAULT_QP_MAX;
-    s_qp_ip.u4_p_qp_min = DEFAULT_QP_MIN;
-
-    s_qp_ip.u4_b_qp = DEFAULT_P_QP;
-    s_qp_ip.u4_b_qp_max = DEFAULT_QP_MAX;
-    s_qp_ip.u4_b_qp_min = DEFAULT_QP_MIN;
-
-    s_qp_ip.u4_timestamp_high = -1;
-    s_qp_ip.u4_timestamp_low = -1;
-
-    s_qp_ip.u4_size = sizeof(ive_ctl_set_qp_ip_t);
-    s_qp_op.u4_size = sizeof(ive_ctl_set_qp_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_qp_ip, &s_qp_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set qp 0x%x\n", s_qp_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setEncMode(IVE_ENC_MODE_T e_enc_mode) {
-    IV_STATUS_T status;
-    ive_ctl_set_enc_mode_ip_t s_enc_mode_ip;
-    ive_ctl_set_enc_mode_op_t s_enc_mode_op;
-
-    s_enc_mode_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_enc_mode_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
-
-    s_enc_mode_ip.e_enc_mode = e_enc_mode;
-
-    s_enc_mode_ip.u4_timestamp_high = -1;
-    s_enc_mode_ip.u4_timestamp_low = -1;
-
-    s_enc_mode_ip.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
-    s_enc_mode_op.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_enc_mode_ip, &s_enc_mode_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set in header encode mode = 0x%x\n",
-                s_enc_mode_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setVbvParams() {
-    ive_ctl_set_vbv_params_ip_t s_vbv_ip;
-    ive_ctl_set_vbv_params_op_t s_vbv_op;
-    IV_STATUS_T status;
-
-    s_vbv_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_vbv_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
-
-    s_vbv_ip.u4_vbv_buf_size = 0;
-    s_vbv_ip.u4_vbv_buffer_delay = 1000;
-
-    s_vbv_ip.u4_timestamp_high = -1;
-    s_vbv_ip.u4_timestamp_low = -1;
-
-    s_vbv_ip.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
-    s_vbv_op.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_vbv_ip, &s_vbv_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set VBV params = 0x%x\n", s_vbv_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setAirParams() {
-    ive_ctl_set_air_params_ip_t s_air_ip;
-    ive_ctl_set_air_params_op_t s_air_op;
-    IV_STATUS_T status;
-
-    s_air_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_air_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
-
-    s_air_ip.e_air_mode = mAIRMode;
-    s_air_ip.u4_air_refresh_period = mAIRRefreshPeriod;
-
-    s_air_ip.u4_timestamp_high = -1;
-    s_air_ip.u4_timestamp_low = -1;
-
-    s_air_ip.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
-    s_air_op.u4_size = sizeof(ive_ctl_set_air_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_air_ip, &s_air_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set air params = 0x%x\n", s_air_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setMeParams() {
-    IV_STATUS_T status;
-    ive_ctl_set_me_params_ip_t s_me_params_ip;
-    ive_ctl_set_me_params_op_t s_me_params_op;
-
-    s_me_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_me_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
-
-    s_me_params_ip.u4_enable_fast_sad = mEnableFastSad;
-    s_me_params_ip.u4_enable_alt_ref = mEnableAltRef;
-
-    s_me_params_ip.u4_enable_hpel = mHalfPelEnable;
-    s_me_params_ip.u4_enable_qpel = DEFAULT_QPEL;
-    s_me_params_ip.u4_me_speed_preset = DEFAULT_ME_SPEED;
-    s_me_params_ip.u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
-    s_me_params_ip.u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
-
-    s_me_params_ip.u4_timestamp_high = -1;
-    s_me_params_ip.u4_timestamp_low = -1;
-
-    s_me_params_ip.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
-    s_me_params_op.u4_size = sizeof(ive_ctl_set_me_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_me_params_ip, &s_me_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set me params = 0x%x\n", s_me_params_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setGopParams() {
-    IV_STATUS_T status;
-    ive_ctl_set_gop_params_ip_t s_gop_params_ip;
-    ive_ctl_set_gop_params_op_t s_gop_params_op;
-
-    s_gop_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_gop_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
-
-    s_gop_params_ip.u4_i_frm_interval = mIInterval;
-    s_gop_params_ip.u4_idr_frm_interval = mIDRInterval;
-
-    s_gop_params_ip.u4_timestamp_high = -1;
-    s_gop_params_ip.u4_timestamp_low = -1;
-
-    s_gop_params_ip.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
-    s_gop_params_op.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_gop_params_ip, &s_gop_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set GOP params = 0x%x\n",
-                s_gop_params_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setProfileParams() {
-    IV_STATUS_T status;
-    ive_ctl_set_profile_params_ip_t s_profile_params_ip;
-    ive_ctl_set_profile_params_op_t s_profile_params_op;
-
-    s_profile_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
-
-    s_profile_params_ip.e_profile = DEFAULT_EPROFILE;
-    s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode;
-    s_profile_params_ip.u4_timestamp_high = -1;
-    s_profile_params_ip.u4_timestamp_low = -1;
-
-    s_profile_params_ip.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
-    s_profile_params_op.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_profile_params_ip, &s_profile_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to set profile params = 0x%x\n",
-                s_profile_params_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setDeblockParams() {
-    IV_STATUS_T status;
-    ive_ctl_set_deblock_params_ip_t s_deblock_params_ip;
-    ive_ctl_set_deblock_params_op_t s_deblock_params_op;
-
-    s_deblock_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_deblock_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
-
-    s_deblock_params_ip.u4_disable_deblock_level = mDisableDeblkLevel;
-
-    s_deblock_params_ip.u4_timestamp_high = -1;
-    s_deblock_params_ip.u4_timestamp_low = -1;
-
-    s_deblock_params_ip.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
-    s_deblock_params_op.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
-
-    status = ive_api_function(mCodecCtx, &s_deblock_params_ip, &s_deblock_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to enable/disable deblock params = 0x%x\n",
-                s_deblock_params_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-void C2SoftAvcEnc::logVersion() {
-    ive_ctl_getversioninfo_ip_t s_ctl_ip;
-    ive_ctl_getversioninfo_op_t s_ctl_op;
-    UWORD8 au1_buf[512];
-    IV_STATUS_T status;
-
-    s_ctl_ip.e_cmd = IVE_CMD_VIDEO_CTL;
-    s_ctl_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
-    s_ctl_ip.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
-    s_ctl_op.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
-    s_ctl_ip.pu1_version = au1_buf;
-    s_ctl_ip.u4_version_bufsize = sizeof(au1_buf);
-
-    status = ive_api_function(mCodecCtx, (void *) &s_ctl_ip, (void *) &s_ctl_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGE("Error in getting version: 0x%x", s_ctl_op.u4_error_code);
-    } else {
-        ALOGV("Ittiam encoder version: %s", (char *)s_ctl_ip.pu1_version);
-    }
-    return;
-}
-
-c2_status_t C2SoftAvcEnc::initEncoder() {
-    IV_STATUS_T status;
-    WORD32 level;
-    uint32_t displaySizeY;
-
-    CHECK(!mStarted);
-
-    c2_status_t errType = C2_OK;
-
-    displaySizeY = mWidth * mHeight;
-    if (displaySizeY > (1920 * 1088)) {
-        level = 50;
-    } else if (displaySizeY > (1280 * 720)) {
-        level = 40;
-    } else if (displaySizeY > (720 * 576)) {
-        level = 31;
-    } else if (displaySizeY > (624 * 320)) {
-        level = 30;
-    } else if (displaySizeY > (352 * 288)) {
-        level = 21;
-    } else if (displaySizeY > (176 * 144)) {
-        level = 20;
-    } else {
-        level = 10;
-    }
-    mAVCEncLevel = MAX(level, mAVCEncLevel);
-
-    mStride = mWidth;
-
-    // TODO
-    mIvVideoColorFormat = IV_YUV_420P;
-
-    ALOGD("Params width %d height %d level %d colorFormat %d", mWidth,
-            mHeight, mAVCEncLevel, mIvVideoColorFormat);
-
-    /* Getting Number of MemRecords */
-    {
-        iv_num_mem_rec_ip_t s_num_mem_rec_ip;
-        iv_num_mem_rec_op_t s_num_mem_rec_op;
-
-        s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t);
-        s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t);
-
-        s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
-
-        status = ive_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op);
-
-        if (status != IV_SUCCESS) {
-            ALOGE("Get number of memory records failed = 0x%x\n",
-                    s_num_mem_rec_op.u4_error_code);
-            return C2_CORRUPTED;
-        }
-
-        mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
-    }
-
-    /* Allocate array to hold memory records */
-    if (mNumMemRecords > SIZE_MAX / sizeof(iv_mem_rec_t)) {
-        ALOGE("requested memory size is too big.");
-        return C2_CORRUPTED;
-    }
-    mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
-    if (NULL == mMemRecords) {
-        ALOGE("Unable to allocate memory for hold memory records: Size %zu",
-                mNumMemRecords * sizeof(iv_mem_rec_t));
-        mSignalledError = true;
-        return C2_CORRUPTED;
-    }
-
-    {
-        iv_mem_rec_t *ps_mem_rec;
-        ps_mem_rec = mMemRecords;
-        for (size_t i = 0; i < mNumMemRecords; i++) {
-            ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
-            ps_mem_rec->pv_base = NULL;
-            ps_mem_rec->u4_mem_size = 0;
-            ps_mem_rec->u4_mem_alignment = 0;
-            ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
-
-            ps_mem_rec++;
-        }
-    }
-
-    /* Getting MemRecords Attributes */
-    {
-        iv_fill_mem_rec_ip_t s_fill_mem_rec_ip;
-        iv_fill_mem_rec_op_t s_fill_mem_rec_op;
-
-        s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t);
-        s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t);
-
-        s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
-        s_fill_mem_rec_ip.ps_mem_rec = mMemRecords;
-        s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords;
-        s_fill_mem_rec_ip.u4_max_wd = mWidth;
-        s_fill_mem_rec_ip.u4_max_ht = mHeight;
-        s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel;
-        s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT;
-        s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
-        s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
-        s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
-        s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
-
-        status = ive_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op);
-
-        if (status != IV_SUCCESS) {
-            ALOGE("Fill memory records failed = 0x%x\n",
-                    s_fill_mem_rec_op.u4_error_code);
-            return C2_CORRUPTED;
-        }
-    }
-
-    /* Allocating Memory for Mem Records */
-    {
-        WORD32 total_size;
-        iv_mem_rec_t *ps_mem_rec;
-        total_size = 0;
-        ps_mem_rec = mMemRecords;
-
-        for (size_t i = 0; i < mNumMemRecords; i++) {
-            ps_mem_rec->pv_base = ive_aligned_malloc(
-                    ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
-            if (ps_mem_rec->pv_base == NULL) {
-                ALOGE("Allocation failure for mem record id %zu size %u\n", i,
-                        ps_mem_rec->u4_mem_size);
-                return C2_CORRUPTED;
-
-            }
-            total_size += ps_mem_rec->u4_mem_size;
-
-            ps_mem_rec++;
-        }
-    }
-
-    /* Codec Instance Creation */
-    {
-        ive_init_ip_t s_init_ip;
-        ive_init_op_t s_init_op;
-
-        mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
-        mCodecCtx->u4_size = sizeof(iv_obj_t);
-        mCodecCtx->pv_fxns = (void *)ive_api_function;
-
-        s_init_ip.u4_size = sizeof(ive_init_ip_t);
-        s_init_op.u4_size = sizeof(ive_init_op_t);
-
-        s_init_ip.e_cmd = IV_CMD_INIT;
-        s_init_ip.u4_num_mem_rec = mNumMemRecords;
-        s_init_ip.ps_mem_rec = mMemRecords;
-        s_init_ip.u4_max_wd = mWidth;
-        s_init_ip.u4_max_ht = mHeight;
-        s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
-        s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
-        s_init_ip.u4_max_level = mAVCEncLevel;
-        s_init_ip.e_inp_color_fmt = mIvVideoColorFormat;
-
-        if (mReconEnable || mPSNREnable) {
-            s_init_ip.u4_enable_recon = 1;
-        } else {
-            s_init_ip.u4_enable_recon = 0;
-        }
-        s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
-        s_init_ip.e_rc_mode = DEFAULT_RC_MODE;
-        s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;
-        s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE;
-        s_init_ip.u4_num_bframes = mBframes;
-        s_init_ip.e_content_type = IV_PROGRESSIVE;
-        s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
-        s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
-        s_init_ip.e_slice_mode = mSliceMode;
-        s_init_ip.u4_slice_param = mSliceParam;
-        s_init_ip.e_arch = mArch;
-        s_init_ip.e_soc = DEFAULT_SOC;
-
-        status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op);
-
-        if (status != IV_SUCCESS) {
-            ALOGE("Init encoder failed = 0x%x\n", s_init_op.u4_error_code);
-            return C2_CORRUPTED;
-        }
-    }
-
-    /* Get Codec Version */
-    logVersion();
-
-    /* set processor details */
-    setNumCores();
-
-    /* Video control Set Frame dimensions */
-    setDimensions();
-
-    /* Video control Set Frame rates */
-    setFrameRate();
-
-    /* Video control Set IPE Params */
-    setIpeParams();
-
-    /* Video control Set Bitrate */
-    setBitRate();
-
-    /* Video control Set QP */
-    setQp();
-
-    /* Video control Set AIR params */
-    setAirParams();
-
-    /* Video control Set VBV params */
-    setVbvParams();
-
-    /* Video control Set Motion estimation params */
-    setMeParams();
-
-    /* Video control Set GOP params */
-    setGopParams();
-
-    /* Video control Set Deblock params */
-    setDeblockParams();
-
-    /* Video control Set Profile params */
-    setProfileParams();
-
-    /* Video control Set in Encode header mode */
-    setEncMode(IVE_ENC_MODE_HEADER);
-
-    ALOGV("init_codec successfull");
-
-    mSpsPpsHeaderReceived = false;
-    mStarted = true;
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::releaseEncoder() {
-    IV_STATUS_T status = IV_SUCCESS;
-    iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
-    iv_retrieve_mem_rec_op_t s_retrieve_mem_op;
-    iv_mem_rec_t *ps_mem_rec;
-
-    if (!mStarted) {
-        return C2_OK;
-    }
-
-    s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
-    s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
-    s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
-    s_retrieve_mem_ip.ps_mem_rec = mMemRecords;
-
-    status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op);
-
-    if (status != IV_SUCCESS) {
-        ALOGE("Unable to retrieve memory records = 0x%x\n",
-                s_retrieve_mem_op.u4_error_code);
-        return C2_CORRUPTED;
-    }
-
-    /* Free memory records */
-    ps_mem_rec = mMemRecords;
-    for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {
-        ive_aligned_free(ps_mem_rec->pv_base);
-        ps_mem_rec++;
-    }
-
-    free(mMemRecords);
-
-    // clear other pointers into the space being free()d
-    mCodecCtx = NULL;
-
-    mStarted = false;
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setEncodeArgs(
-        ive_video_encode_ip_t *ps_encode_ip,
-        ive_video_encode_op_t *ps_encode_op,
-        const C2GraphicView *const input,
-        uint8_t *base,
-        uint32_t capacity,
-        uint64_t timestamp) {
-    iv_raw_buf_t *ps_inp_raw_buf;
-
-    ps_inp_raw_buf = &ps_encode_ip->s_inp_buf;
-    ps_encode_ip->s_out_buf.pv_buf = base;
-    ps_encode_ip->s_out_buf.u4_bytes = 0;
-    ps_encode_ip->s_out_buf.u4_bufsize = capacity;
-    ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t);
-    ps_encode_op->u4_size = sizeof(ive_video_encode_op_t);
-
-    ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
-    ps_encode_ip->pv_bufs = NULL;
-    ps_encode_ip->pv_mb_info = NULL;
-    ps_encode_ip->pv_pic_info = NULL;
-    ps_encode_ip->u4_mb_info_type = 0;
-    ps_encode_ip->u4_pic_info_type = 0;
-    ps_encode_ip->u4_is_last = 0;
-    ps_encode_ip->u4_timestamp_high = timestamp >> 32;
-    ps_encode_ip->u4_timestamp_low = timestamp & 0xFFFFFFFF;
-    ps_encode_op->s_out_buf.pv_buf = NULL;
-
-    /* Initialize color formats */
-    memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t));
-    ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t);
-    ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
-    if (input == nullptr) {
-        if (mSawInputEOS){
-            ps_encode_ip->u4_is_last = 1;
-        }
-        return C2_OK;
-    }
-
-    ALOGV("width = %d, height = %d", input->width(), input->height());
-    if (mWidth != input->width() || mHeight != input->height()) {
-        return C2_BAD_VALUE;
-    }
-    const C2PlanarLayout &layout = input->layout();
-    uint8_t *yPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_Y]);
-    uint8_t *uPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_U]);
-    uint8_t *vPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_V]);
-    int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
-    int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
-    int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
-
-    switch (layout.type) {
-        case C2PlanarLayout::TYPE_RGB:
-            // fall-through
-        case C2PlanarLayout::TYPE_RGBA: {
-            size_t yPlaneSize = input->width() * input->height();
-            std::unique_ptr<uint8_t[]> freeBuffer;
-            if (mFreeConversionBuffers.empty()) {
-                freeBuffer.reset(new uint8_t[yPlaneSize * 3 / 2]);
-            } else {
-                freeBuffer.swap(mFreeConversionBuffers.front());
-                mFreeConversionBuffers.pop_front();
-            }
-            yPlane = freeBuffer.get();
-            mConversionBuffersInUse.push_back(std::move(freeBuffer));
-            uPlane = yPlane + yPlaneSize;
-            vPlane = uPlane + yPlaneSize / 4;
-            yStride = input->width();
-            uStride = vStride = input->width() / 2;
-            ConvertRGBToPlanarYUV(yPlane, yStride, input->height(), *input);
-            break;
-        }
-        case C2PlanarLayout::TYPE_YUV:
-            // fall-through
-        case C2PlanarLayout::TYPE_YUVA:
-            // Do nothing
-            break;
-        default:
-            ALOGE("Unrecognized plane type: %d", layout.type);
-            return C2_BAD_VALUE;
-    }
-
-    switch (mIvVideoColorFormat) {
-        case IV_YUV_420P:
-        {
-            // input buffer is supposed to be const but Ittiam API wants bare pointer.
-            ps_inp_raw_buf->apv_bufs[0] = yPlane;
-            ps_inp_raw_buf->apv_bufs[1] = uPlane;
-            ps_inp_raw_buf->apv_bufs[2] = vPlane;
-
-            ps_inp_raw_buf->au4_wd[0] = input->width();
-            ps_inp_raw_buf->au4_wd[1] = input->width() / 2;
-            ps_inp_raw_buf->au4_wd[2] = input->width() / 2;
-
-            ps_inp_raw_buf->au4_ht[0] = input->height();
-            ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
-            ps_inp_raw_buf->au4_ht[2] = input->height() / 2;
-
-            ps_inp_raw_buf->au4_strd[0] = yStride;
-            ps_inp_raw_buf->au4_strd[1] = uStride;
-            ps_inp_raw_buf->au4_strd[2] = vStride;
-            break;
-        }
-
-        case IV_YUV_422ILE:
-        {
-            // TODO
-            // ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
-            // ps_inp_raw_buf->au4_wd[0] = mWidth * 2;
-            // ps_inp_raw_buf->au4_ht[0] = mHeight;
-            // ps_inp_raw_buf->au4_strd[0] = mStride * 2;
-            break;
-        }
-
-        case IV_YUV_420SP_UV:
-        case IV_YUV_420SP_VU:
-        default:
-        {
-            ps_inp_raw_buf->apv_bufs[0] = yPlane;
-            ps_inp_raw_buf->apv_bufs[1] = uPlane;
-
-            ps_inp_raw_buf->au4_wd[0] = input->width();
-            ps_inp_raw_buf->au4_wd[1] = input->width();
-
-            ps_inp_raw_buf->au4_ht[0] = input->height();
-            ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
-
-            ps_inp_raw_buf->au4_strd[0] = yStride;
-            ps_inp_raw_buf->au4_strd[1] = uStride;
-            break;
-        }
-    }
-    return C2_OK;
-}
-
-void C2SoftAvcEnc::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-
-    IV_STATUS_T status;
-    WORD32 timeDelay, timeTaken;
-    uint64_t timestamp = work->input.ordinal.timestamp.peekull();
-
-    // Initialize encoder if not already initialized
-    if (mCodecCtx == NULL) {
-        if (C2_OK != initEncoder()) {
-            ALOGE("Failed to initialize encoder");
-            work->workletsProcessed = 1u;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-    }
-    if (mSignalledError) {
-        return;
-    }
-
-    // while (!mSawOutputEOS && !outQueue.empty()) {
-    c2_status_t error;
-    ive_video_encode_ip_t s_encode_ip;
-    ive_video_encode_op_t s_encode_op;
-
-    if (!mSpsPpsHeaderReceived) {
-        constexpr uint32_t kHeaderLength = MIN_STREAM_SIZE;
-        uint8_t header[kHeaderLength];
-        error = setEncodeArgs(
-                &s_encode_ip, &s_encode_op, NULL, header, kHeaderLength, timestamp);
-        if (error != C2_OK) {
-            mSignalledError = true;
-            work->workletsProcessed = 1u;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
-
-        if (IV_SUCCESS != status) {
-            ALOGE("Encode header failed = 0x%x\n",
-                    s_encode_op.u4_error_code);
-            return;
-        } else {
-            ALOGV("Bytes Generated in header %d\n",
-                    s_encode_op.s_out_buf.u4_bytes);
-        }
-
-        mSpsPpsHeaderReceived = true;
-
-        std::unique_ptr<C2StreamCsdInfo::output> csd =
-            C2StreamCsdInfo::output::AllocUnique(s_encode_op.s_out_buf.u4_bytes, 0u);
-        memcpy(csd->m.value, header, s_encode_op.s_out_buf.u4_bytes);
-        work->worklets.front()->output.configUpdate.push_back(std::move(csd));
-
-        DUMP_TO_FILE(
-                mOutFile, csd->m.value, csd->flexCount());
-    }
-
-    if (mUpdateFlag) {
-        if (mUpdateFlag & kUpdateBitrate) {
-            setBitRate();
-        }
-        if (mUpdateFlag & kRequestKeyFrame) {
-            setFrameType(IV_IDR_FRAME);
-        }
-        if (mUpdateFlag & kUpdateAIRMode) {
-            setAirParams();
-            // notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
-            //         OMX_IndexConfigAndroidIntraRefresh, NULL);
-        }
-        mUpdateFlag = 0;
-    }
-
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        mSawInputEOS = true;
-    }
-
-    /* In normal mode, store inputBufferInfo and this will be returned
-       when encoder consumes this input */
-    // if (!mInputDataIsMeta && (inputBufferInfo != NULL)) {
-    //     for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) {
-    //         if (NULL == mInputBufferInfo[i]) {
-    //             mInputBufferInfo[i] = inputBufferInfo;
-    //             break;
-    //         }
-    //     }
-    // }
-    const C2GraphicView view =
-        work->input.buffers[0]->data().graphicBlocks().front().map().get();
-    if (view.error() != C2_OK) {
-        ALOGE("graphic view map err = %d", view.error());
-        return;
-    }
-
-    std::shared_ptr<C2LinearBlock> block;
-
-    do {
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        // TODO: error handling, proper usage, etc.
-        c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
-        if (err != C2_OK) {
-            ALOGE("fetch linear block err = %d", err);
-            work->workletsProcessed = 1u;
-            work->result = err;
-            return;
-        }
-        C2WriteView wView = block->map().get();
-        if (wView.error() != C2_OK) {
-            ALOGE("write view map err = %d", wView.error());
-            work->workletsProcessed = 1u;
-            work->result = wView.error();
-            return;
-        }
-
-        error = setEncodeArgs(
-                &s_encode_ip, &s_encode_op, &view, wView.base(), wView.capacity(), timestamp);
-        if (error != C2_OK) {
-            mSignalledError = true;
-            ALOGE("setEncodeArgs failed : %d", error);
-            work->workletsProcessed = 1u;
-            work->result = error;
-            return;
-        }
-
-        // DUMP_TO_FILE(
-        //         mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
-        //         (mHeight * mStride * 3 / 2));
-
-        GETTIME(&mTimeStart, NULL);
-        /* Compute time elapsed between end of previous decode()
-         * to start of current decode() */
-        TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
-        status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
-
-        if (IV_SUCCESS != status) {
-            if ((s_encode_op.u4_error_code & 0xFF) == IH264E_BITSTREAM_BUFFER_OVERFLOW) {
-                // TODO: use IVE_CMD_CTL_GETBUFINFO for proper max input size?
-                mOutBufferSize *= 2;
-                continue;
-            }
-            ALOGE("Encode Frame failed = 0x%x\n",
-                    s_encode_op.u4_error_code);
-            mSignalledError = true;
-            work->workletsProcessed = 1u;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-    } while (IV_SUCCESS != status);
-
-    // Hold input buffer reference
-    mBuffers[s_encode_ip.s_inp_buf.apv_bufs[0]] = work->input.buffers[0];
-
-    GETTIME(&mTimeEnd, NULL);
-    /* Compute time taken for decode() */
-    TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
-
-    ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
-            s_encode_op.s_out_buf.u4_bytes);
-
-    void *freed = s_encode_op.s_inp_buf.apv_bufs[0];
-    /* If encoder frees up an input buffer, mark it as free */
-    if (freed != NULL) {
-        if (mBuffers.count(freed) == 0u) {
-            work->workletsProcessed = 1u;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        // Release input buffer reference
-        mBuffers.erase(freed);
-
-        auto it = std::find_if(
-                mConversionBuffersInUse.begin(), mConversionBuffersInUse.end(),
-                [freed](const auto &elem) { return elem.get() == freed; });
-        if (it != mConversionBuffersInUse.end()) {
-            mFreeConversionBuffers.push_back(std::move(*it));
-            mConversionBuffersInUse.erase(it);
-        }
-    }
-
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->worklets.front()->output.ordinal.timestamp =
-        ((uint64_t)s_encode_op.u4_timestamp_high << 32) | s_encode_op.u4_timestamp_low;
-    work->worklets.front()->output.buffers.clear();
-    std::shared_ptr<C2Buffer> buffer =
-        createLinearBuffer(block, 0, s_encode_op.s_out_buf.u4_bytes);
-    work->worklets.front()->output.buffers.push_back(buffer);
-    work->workletsProcessed = 1u;
-
-    if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) {
-        buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
-                0u /* stream id */, C2PictureTypeKeyFrame));
-    }
-
-    if (s_encode_op.u4_is_last) {
-        // outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
-        mSawOutputEOS = true;
-    } else {
-        // outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
-    }
-}
-
-c2_status_t C2SoftAvcEnc::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    // TODO: use IVE_CMD_CTL_FLUSH?
-    (void)drainMode;
-    (void)pool;
-    return C2_OK;
-}
-
-
-class C2SoftAvcEncFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftAvcEnc(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftAvcEncFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftAvcEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.h b/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.h
deleted file mode 100644
index a113436..0000000
--- a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * 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_SOFT_AVC_ENC_H__
-#define C2_SOFT_AVC_ENC_H__
-
-#include <map>
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/Vector.h>
-
-#include <SimpleC2Component.h>
-
-namespace android {
-
-#define CODEC_MAX_CORES          4
-#define LEN_STATUS_BUFFER        (10  * 1024)
-#define MAX_VBV_BUFF_SIZE        (120 * 16384)
-#define MAX_NUM_IO_BUFS           3
-
-#define DEFAULT_MAX_REF_FRM         2
-#define DEFAULT_MAX_REORDER_FRM     0
-#define DEFAULT_QP_MIN              10
-#define DEFAULT_QP_MAX              40
-#define DEFAULT_MAX_BITRATE         20000000
-#define DEFAULT_MAX_SRCH_RANGE_X    256
-#define DEFAULT_MAX_SRCH_RANGE_Y    256
-#define DEFAULT_MAX_FRAMERATE       120000
-#define DEFAULT_NUM_CORES           1
-#define DEFAULT_NUM_CORES_PRE_ENC   0
-#define DEFAULT_FPS                 30
-#define DEFAULT_ENC_SPEED           IVE_NORMAL
-
-#define DEFAULT_MEM_REC_CNT         0
-#define DEFAULT_RECON_ENABLE        0
-#define DEFAULT_CHKSUM_ENABLE       0
-#define DEFAULT_START_FRM           0
-#define DEFAULT_NUM_FRMS            0xFFFFFFFF
-#define DEFAULT_INP_COLOR_FORMAT       IV_YUV_420SP_VU
-#define DEFAULT_RECON_COLOR_FORMAT     IV_YUV_420P
-#define DEFAULT_LOOPBACK            0
-#define DEFAULT_SRC_FRAME_RATE      30
-#define DEFAULT_TGT_FRAME_RATE      30
-#define DEFAULT_MAX_WD              1920
-#define DEFAULT_MAX_HT              1920
-#define DEFAULT_MAX_LEVEL           41
-#define DEFAULT_STRIDE              0
-#define DEFAULT_WD                  1280
-#define DEFAULT_HT                  720
-#define DEFAULT_PSNR_ENABLE         0
-#define DEFAULT_ME_SPEED            100
-#define DEFAULT_ENABLE_FAST_SAD     0
-#define DEFAULT_ENABLE_ALT_REF      0
-#define DEFAULT_RC_MODE             IVE_RC_STORAGE
-#define DEFAULT_BITRATE             6000000
-#define DEFAULT_I_QP                22
-#define DEFAULT_I_QP_MAX            DEFAULT_QP_MAX
-#define DEFAULT_I_QP_MIN            DEFAULT_QP_MIN
-#define DEFAULT_P_QP                28
-#define DEFAULT_P_QP_MAX            DEFAULT_QP_MAX
-#define DEFAULT_P_QP_MIN            DEFAULT_QP_MIN
-#define DEFAULT_B_QP                22
-#define DEFAULT_B_QP_MAX            DEFAULT_QP_MAX
-#define DEFAULT_B_QP_MIN            DEFAULT_QP_MIN
-#define DEFAULT_AIR                 IVE_AIR_MODE_NONE
-#define DEFAULT_AIR_REFRESH_PERIOD  30
-#define DEFAULT_SRCH_RNG_X          64
-#define DEFAULT_SRCH_RNG_Y          48
-#define DEFAULT_I_INTERVAL          30
-#define DEFAULT_IDR_INTERVAL        1000
-#define DEFAULT_B_FRAMES            0
-#define DEFAULT_DISABLE_DEBLK_LEVEL 0
-#define DEFAULT_HPEL                1
-#define DEFAULT_QPEL                1
-#define DEFAULT_I4                  1
-#define DEFAULT_EPROFILE            IV_PROFILE_BASE
-#define DEFAULT_ENTROPY_MODE        0
-#define DEFAULT_SLICE_MODE          IVE_SLICE_MODE_NONE
-#define DEFAULT_SLICE_PARAM         256
-#define DEFAULT_ARCH                ARCH_ARM_A9Q
-#define DEFAULT_SOC                 SOC_GENERIC
-#define DEFAULT_INTRA4x4            0
-#define STRLENGTH                   500
-#define DEFAULT_CONSTRAINED_INTRA   0
-
-#define MIN(a, b) ((a) < (b))? (a) : (b)
-#define MAX(a, b) ((a) > (b))? (a) : (b)
-#define ALIGN16(x) ((((x) + 15) >> 4) << 4)
-#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
-#define ALIGN4096(x) ((((x) + 4095) >> 12) << 12)
-
-/** Used to remove warnings about unused parameters */
-#define UNUSED(x) ((void)(x))
-
-/** Get time */
-#define GETTIME(a, b) gettimeofday(a, b);
-
-/** Compute difference between start and end */
-#define TIME_DIFF(start, end, diff) \
-    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
-            ((end).tv_usec - (start).tv_usec);
-
-#define ive_aligned_malloc(alignment, size) memalign(alignment, size)
-#define ive_aligned_free(buf) free(buf)
-
-struct C2SoftAvcEnc : public SimpleC2Component {
-    C2SoftAvcEnc(const char *name, c2_node_id_t id);
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-protected:
-    virtual ~C2SoftAvcEnc();
-
-private:
-    enum {
-        kUpdateBitrate            = 1 << 0,
-        kRequestKeyFrame          = 1 << 1,
-        kUpdateAIRMode            = 1 << 2,
-    };
-
-    // OMX input buffer's timestamp and flags
-    typedef struct {
-        int64_t mTimeUs;
-        int32_t mFlags;
-    } InputBufferInfo;
-
-    int32_t mStride;
-
-    struct timeval mTimeStart;   // Time at the start of decode()
-    struct timeval mTimeEnd;     // Time at the end of decode()
-
-    int mUpdateFlag;
-
-#ifdef FILE_DUMP_ENABLE
-    char mInFile[200];
-    char mOutFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
-    IV_COLOR_FORMAT_T mIvVideoColorFormat;
-
-    IV_PROFILE_T mAVCEncProfile;
-    WORD32   mAVCEncLevel;
-    bool     mStarted;
-    bool     mSpsPpsHeaderReceived;
-
-    bool     mSawInputEOS;
-    bool     mSawOutputEOS;
-    bool     mSignalledError;
-    bool     mIntra4x4;
-    bool     mEnableFastSad;
-    bool     mEnableAltRef;
-    bool     mReconEnable;
-    bool     mPSNREnable;
-    bool     mEntropyMode;
-    bool     mConstrainedIntraFlag;
-    IVE_SPEED_CONFIG     mEncSpeed;
-
-    iv_obj_t *mCodecCtx;         // Codec context
-    iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
-    size_t mNumMemRecords;       // Number of memory records requested by codec
-    size_t mNumCores;            // Number of cores used by the codec
-
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mFramerate;
-    uint32_t mBitrate;
-    uint32_t mOutBufferSize;
-    UWORD32 mHeaderGenerated;
-    UWORD32 mBframes;
-    IV_ARCH_T mArch;
-    IVE_SLICE_MODE_T mSliceMode;
-    UWORD32 mSliceParam;
-    bool mHalfPelEnable;
-    UWORD32 mIInterval;
-    UWORD32 mIDRInterval;
-    UWORD32 mDisableDeblkLevel;
-    IVE_AIR_MODE_T mAIRMode;
-    UWORD32 mAIRRefreshPeriod;
-    std::map<const void *, std::shared_ptr<C2Buffer>> mBuffers;
-    std::list<std::unique_ptr<uint8_t[]>> mFreeConversionBuffers;
-    std::list<std::unique_ptr<uint8_t[]>> mConversionBuffersInUse;
-
-    void initEncParams();
-    c2_status_t initEncoder();
-    c2_status_t releaseEncoder();
-
-    c2_status_t setFrameType(IV_PICTURE_CODING_TYPE_T  e_frame_type);
-    c2_status_t setQp();
-    c2_status_t setEncMode(IVE_ENC_MODE_T e_enc_mode);
-    c2_status_t setDimensions();
-    c2_status_t setNumCores();
-    c2_status_t setFrameRate();
-    c2_status_t setIpeParams();
-    c2_status_t setBitRate();
-    c2_status_t setAirParams();
-    c2_status_t setMeParams();
-    c2_status_t setGopParams();
-    c2_status_t setProfileParams();
-    c2_status_t setDeblockParams();
-    c2_status_t setVbvParams();
-    void logVersion();
-    c2_status_t setEncodeArgs(
-            ive_video_encode_ip_t *ps_encode_ip,
-            ive_video_encode_op_t *ps_encode_op,
-            const C2GraphicView *const input,
-            uint8_t *base,
-            uint32_t capacity,
-            uint64_t timestamp);
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftAvcEnc);
-};
-
-#ifdef FILE_DUMP_ENABLE
-
-#define INPUT_DUMP_PATH     "/sdcard/media/avce_input"
-#define INPUT_DUMP_EXT      "yuv"
-#define OUTPUT_DUMP_PATH    "/sdcard/media/avce_output"
-#define OUTPUT_DUMP_EXT     "h264"
-
-#define GENERATE_FILE_NAMES() {                         \
-    GETTIME(&mTimeStart, NULL);                         \
-    strcpy(mInFile, "");                                \
-    sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
-            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
-            INPUT_DUMP_EXT);                            \
-    strcpy(mOutFile, "");                               \
-    sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
-            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
-            OUTPUT_DUMP_EXT);                           \
-}
-
-#define CREATE_DUMP_FILE(m_filename) {                  \
-    FILE *fp = fopen(m_filename, "wb");                 \
-    if (fp != NULL) {                                   \
-        ALOGD("Opened file %s", m_filename);            \
-        fclose(fp);                                     \
-    } else {                                            \
-        ALOGD("Could not open file %s", m_filename);    \
-    }                                                   \
-}
-#define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
-{                                                       \
-    FILE *fp = fopen(m_filename, "ab");                 \
-    if (fp != NULL && m_buf != NULL) {                  \
-        int i;                                          \
-        i = fwrite(m_buf, 1, m_size, fp);               \
-        ALOGD("fwrite ret %d to write %d", i, m_size);  \
-        if (i != (int)m_size) {                         \
-            ALOGD("Error in fwrite, returned %d", i);   \
-            perror("Error in write to file");           \
-        }                                               \
-        fclose(fp);                                     \
-    } else {                                            \
-        ALOGD("Could not write to file %s", m_filename);\
-        if (fp != NULL)                                 \
-            fclose(fp);                                 \
-    }                                                   \
-}
-#else /* FILE_DUMP_ENABLE */
-#define INPUT_DUMP_PATH
-#define INPUT_DUMP_EXT
-#define OUTPUT_DUMP_PATH
-#define OUTPUT_DUMP_EXT
-#define GENERATE_FILE_NAMES()
-#define CREATE_DUMP_FILE(m_filename)
-#define DUMP_TO_FILE(m_filename, m_buf, m_size)
-#endif /* FILE_DUMP_ENABLE */
-
-}  // namespace android
-
-#endif  // C2_SOFT_AVC_ENC_H__
diff --git a/media/libstagefright/codecs/cmds/Android.bp b/media/libstagefright/codecs/cmds/Android.bp
deleted file mode 100644
index 6dba0a3..0000000
--- a/media/libstagefright/codecs/cmds/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-cc_binary {
-    name: "codec2",
-
-    srcs: [
-        "codec2.cpp",
-    ],
-
-    include_dirs: [
-    ],
-
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libgui",
-        "liblog",
-        "libmediaextractor",
-        "libstagefright",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libui",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-std=c++14",
-    ],
-
-//    sanitize: {
-//        cfi: true,
-//        misc_undefined: [
-//            "unsigned-integer-overflow",
-//            "signed-integer-overflow",
-//        ],
-//        diag: {
-//            cfi: true,
-//        },
-//    },
-}
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
deleted file mode 100644
index 295a5b0..0000000
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * 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.
- */
-
-#include <inttypes.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <thread>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "codec2"
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <media/DataSource.h>
-#include <media/ICrypto.h>
-#include <media/IMediaHTTPService.h>
-#include <media/MediaExtractor.h>
-#include <media/MediaSource.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaExtractorFactory.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-#include <gui/GLConsumer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <util/C2ParamUtils.h>
-#include <C2AllocatorGralloc.h>
-#include <C2Buffer.h>
-#include <C2BufferPriv.h>
-#include <C2Component.h>
-#include <C2PlatformSupport.h>
-#include <C2Work.h>
-
-using namespace android;
-using namespace std::chrono_literals;
-
-namespace {
-
-class LinearBuffer : public C2Buffer {
-public:
-    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock> &block)
-        : C2Buffer({ block->share(block->offset(), block->size(), ::C2Fence()) }) {}
-};
-
-class Listener;
-
-class SimplePlayer {
-public:
-    SimplePlayer();
-    ~SimplePlayer();
-
-    void onWorkDone(std::weak_ptr<C2Component> component,
-                    std::list<std::unique_ptr<C2Work>> workItems);
-    void onTripped(std::weak_ptr<C2Component> component,
-                   std::vector<std::shared_ptr<C2SettingResult>> settingResult);
-    void onError(std::weak_ptr<C2Component> component, uint32_t errorCode);
-
-    void play(const sp<IMediaSource> &source);
-
-private:
-    typedef std::unique_lock<std::mutex> ULock;
-
-    std::shared_ptr<Listener> mListener;
-    std::shared_ptr<C2Component> mComponent;
-
-    sp<IProducerListener> mProducerListener;
-
-    std::atomic_int mLinearPoolId;
-
-    std::shared_ptr<C2Allocator> mAllocIon;
-    std::shared_ptr<C2BlockPool> mLinearPool;
-
-    std::mutex mQueueLock;
-    std::condition_variable mQueueCondition;
-    std::list<std::unique_ptr<C2Work>> mWorkQueue;
-
-    std::mutex mProcessedLock;
-    std::condition_variable mProcessedCondition;
-    std::list<std::unique_ptr<C2Work>> mProcessedWork;
-
-    sp<Surface> mSurface;
-    sp<SurfaceComposerClient> mComposerClient;
-    sp<SurfaceControl> mControl;
-};
-
-class Listener : public C2Component::Listener {
-public:
-    explicit Listener(SimplePlayer *thiz) : mThis(thiz) {}
-    virtual ~Listener() = default;
-
-    virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
-                            std::list<std::unique_ptr<C2Work>> workItems) override {
-        mThis->onWorkDone(component, std::move(workItems));
-    }
-
-    virtual void onTripped_nb(std::weak_ptr<C2Component> component,
-                           std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
-        mThis->onTripped(component, settingResult);
-    }
-
-    virtual void onError_nb(std::weak_ptr<C2Component> component,
-                         uint32_t errorCode) override {
-        mThis->onError(component, errorCode);
-    }
-
-private:
-    SimplePlayer * const mThis;
-};
-
-
-SimplePlayer::SimplePlayer()
-    : mListener(new Listener(this)),
-      mProducerListener(new DummyProducerListener),
-      mLinearPoolId(C2BlockPool::PLATFORM_START),
-      mComposerClient(new SurfaceComposerClient) {
-    CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
-
-    std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
-    CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
-    mLinearPool = std::make_shared<C2PooledBlockPool>(mAllocIon, mLinearPoolId++);
-
-    mControl = mComposerClient->createSurface(
-            String8("A Surface"),
-            1280,
-            800,
-            HAL_PIXEL_FORMAT_YV12);
-            //PIXEL_FORMAT_RGB_565);
-
-    CHECK(mControl != NULL);
-    CHECK(mControl->isValid());
-
-    SurfaceComposerClient::Transaction{}
-            .setLayer(mControl, INT_MAX)
-            .show(mControl)
-            .apply();
-
-    mSurface = mControl->getSurface();
-    CHECK(mSurface != NULL);
-    mSurface->connect(NATIVE_WINDOW_API_CPU, mProducerListener);
-}
-
-SimplePlayer::~SimplePlayer() {
-    mComposerClient->dispose();
-}
-
-void SimplePlayer::onWorkDone(
-        std::weak_ptr<C2Component> component, std::list<std::unique_ptr<C2Work>> workItems) {
-    ALOGV("SimplePlayer::onWorkDone");
-    (void) component;
-    ULock l(mProcessedLock);
-    for (auto & item : workItems) {
-        mProcessedWork.push_back(std::move(item));
-    }
-    mProcessedCondition.notify_all();
-}
-
-void SimplePlayer::onTripped(
-        std::weak_ptr<C2Component> component,
-        std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
-    (void) component;
-    (void) settingResult;
-    // TODO
-}
-
-void SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) {
-    (void) component;
-    (void) errorCode;
-    // TODO
-}
-
-void SimplePlayer::play(const sp<IMediaSource> &source) {
-    ALOGV("SimplePlayer::play");
-    sp<AMessage> format;
-    (void) convertMetaDataToMessage(source->getFormat(), &format);
-
-    sp<ABuffer> csd0, csd1;
-    format->findBuffer("csd-0", &csd0);
-    format->findBuffer("csd-1", &csd1);
-
-    status_t err = source->start();
-
-    if (err != OK) {
-        fprintf(stderr, "source returned error %d (0x%08x)\n", err, err);
-        return;
-    }
-
-    std::shared_ptr<C2ComponentStore> store = GetCodec2PlatformComponentStore();
-    std::shared_ptr<C2Component> component;
-    (void)store->createComponent("c2.google.avc.decoder", &component);
-
-    (void)component->setListener_vb(mListener, C2_DONT_BLOCK);
-    std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
-        C2PortBlockPoolsTuning::output::AllocUnique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
-    std::vector<std::unique_ptr<C2SettingResult>> result;
-    (void)component->intf()->config_vb({pools.get()}, C2_DONT_BLOCK, &result);
-    component->start();
-
-    for (int i = 0; i < 8; ++i) {
-        mWorkQueue.emplace_back(new C2Work);
-    }
-
-    std::atomic_bool running(true);
-    std::thread surfaceThread([this, &running]() {
-        const sp<IGraphicBufferProducer> &igbp = mSurface->getIGraphicBufferProducer();
-        while (running) {
-            std::unique_ptr<C2Work> work;
-            {
-                ULock l(mProcessedLock);
-                if (mProcessedWork.empty()) {
-                    mProcessedCondition.wait_for(l, 100ms);
-                    if (mProcessedWork.empty()) {
-                        continue;
-                    }
-                }
-                work.swap(mProcessedWork.front());
-                mProcessedWork.pop_front();
-            }
-            int slot;
-            sp<Fence> fence;
-            ALOGV("Render: Frame #%lld", work->worklets.front()->output.ordinal.frameIndex.peekll());
-            const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0];
-            if (output) {
-                const C2ConstGraphicBlock block = output->data().graphicBlocks().front();
-                native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle());
-                sp<GraphicBuffer> buffer(new GraphicBuffer(
-                        grallocHandle,
-                        GraphicBuffer::CLONE_HANDLE,
-                        block.width(),
-                        block.height(),
-                        HAL_PIXEL_FORMAT_YV12,
-                        1,
-                        (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-                        block.width()));
-                native_handle_delete(grallocHandle);
-
-                status_t err = igbp->attachBuffer(&slot, buffer);
-
-                IGraphicBufferProducer::QueueBufferInput qbi(
-                        (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll(),
-                        false,
-                        HAL_DATASPACE_UNKNOWN,
-                        Rect(block.width(), block.height()),
-                        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
-                        0,
-                        Fence::NO_FENCE,
-                        0);
-                IGraphicBufferProducer::QueueBufferOutput qbo;
-                err = igbp->queueBuffer(slot, qbi, &qbo);
-            }
-
-            work->input.buffers.clear();
-            work->worklets.clear();
-
-            ULock l(mQueueLock);
-            mWorkQueue.push_back(std::move(work));
-            mQueueCondition.notify_all();
-        }
-        ALOGV("render loop finished");
-    });
-
-    long numFrames = 0;
-    mLinearPool.reset(new C2PooledBlockPool(mAllocIon, mLinearPoolId++));
-
-    for (;;) {
-        size_t size = 0u;
-        void *data = nullptr;
-        int64_t timestamp = 0u;
-        MediaBufferBase *buffer = nullptr;
-        sp<ABuffer> csd;
-        if (csd0 != nullptr) {
-            csd = csd0;
-            csd0 = nullptr;
-        } else if (csd1 != nullptr) {
-            csd = csd1;
-            csd1 = nullptr;
-        } else {
-            status_t err = source->read(&buffer);
-            if (err != OK) {
-                CHECK(buffer == NULL);
-
-                if (err == INFO_FORMAT_CHANGED) {
-                    continue;
-                }
-
-                break;
-            }
-            MetaDataBase &meta = buffer->meta_data();
-            CHECK(meta.findInt64(kKeyTime, &timestamp));
-
-            size = buffer->size();
-            data = buffer->data();
-        }
-
-        if (csd != nullptr) {
-            size = csd->size();
-            data = csd->data();
-        }
-
-        // Prepare C2Work
-
-        std::unique_ptr<C2Work> work;
-        while (!work) {
-            ULock l(mQueueLock);
-            if (!mWorkQueue.empty()) {
-                work.swap(mWorkQueue.front());
-                mWorkQueue.pop_front();
-            } else {
-                mQueueCondition.wait_for(l, 100ms);
-            }
-        }
-        work->input.flags = (C2FrameData::flags_t)0;
-        work->input.ordinal.timestamp = timestamp;
-        work->input.ordinal.frameIndex = numFrames;
-
-        std::shared_ptr<C2LinearBlock> block;
-        mLinearPool->fetchLinearBlock(
-                size,
-                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                &block);
-        C2WriteView view = block->map().get();
-        if (view.error() != C2_OK) {
-            fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
-            break;
-        }
-        memcpy(view.base(), data, size);
-
-        work->input.buffers.clear();
-        work->input.buffers.emplace_back(new LinearBuffer(block));
-        work->worklets.clear();
-        work->worklets.emplace_back(new C2Worklet);
-
-        std::list<std::unique_ptr<C2Work>> items;
-        items.push_back(std::move(work));
-
-        ALOGV("Frame #%ld size = %zu", numFrames, size);
-        // DO THE DECODING
-        component->queue_nb(&items);
-
-        if (buffer) {
-            buffer->release();
-            buffer = NULL;
-        }
-
-        ++numFrames;
-    }
-    ALOGV("main loop finished");
-    source->stop();
-    running.store(false);
-    surfaceThread.join();
-
-    component->release();
-    printf("\n");
-}
-
-}  // namespace
-
-static void usage(const char *me) {
-    fprintf(stderr, "usage: %s [options] [input_filename]\n", me);
-    fprintf(stderr, "       -h(elp)\n");
-}
-
-int main(int argc, char **argv) {
-    android::ProcessState::self()->startThreadPool();
-
-    int res;
-    while ((res = getopt(argc, argv, "h")) >= 0) {
-        switch (res) {
-            case 'h':
-            default:
-            {
-                usage(argv[0]);
-                exit(1);
-                break;
-            }
-        }
-    }
-
-    argc -= optind;
-    argv += optind;
-
-    if (argc < 1) {
-        fprintf(stderr, "No input file specified\n");
-        return 1;
-    }
-
-    status_t err = OK;
-    SimplePlayer player;
-
-    for (int k = 0; k < argc && err == OK; ++k) {
-        const char *filename = argv[k];
-
-        sp<DataSource> dataSource =
-            DataSourceFactory::CreateFromURI(NULL /* httpService */, filename);
-
-        if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) {
-            fprintf(stderr, "Unable to create data source.\n");
-            return 1;
-        }
-
-        Vector<sp<IMediaSource> > mediaSources;
-        sp<IMediaSource> mediaSource;
-
-        sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
-
-        if (extractor == NULL) {
-            fprintf(stderr, "could not create extractor.\n");
-            return -1;
-        }
-
-        sp<MetaData> meta = extractor->getMetaData();
-
-        if (meta != NULL) {
-            const char *mime;
-            if (!meta->findCString(kKeyMIMEType, &mime)) {
-                fprintf(stderr, "extractor did not provide MIME type.\n");
-                return -1;
-            }
-        }
-
-        size_t numTracks = extractor->countTracks();
-
-        size_t i;
-        for (i = 0; i < numTracks; ++i) {
-            meta = extractor->getTrackMetaData(
-                    i, MediaExtractor::kIncludeExtensiveMetaData);
-
-            if (meta == NULL) {
-                break;
-            }
-            const char *mime;
-            meta->findCString(kKeyMIMEType, &mime);
-
-            // TODO: allowing AVC only for the time being
-            if (!strncasecmp(mime, "video/avc", 9)) {
-                break;
-            }
-
-            meta = NULL;
-        }
-
-        if (meta == NULL) {
-            fprintf(stderr, "No AVC track found.\n");
-            return -1;
-        }
-
-        mediaSource = extractor->getTrack(i);
-        if (mediaSource == nullptr) {
-            fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
-            return -1;
-        }
-
-        player.play(mediaSource);
-    }
-
-    return 0;
-}
diff --git a/media/libstagefright/codecs/flac/dec/Android.bp b/media/libstagefright/codecs/flac/dec/Android.bp
index 68fdd15..9af086b 100644
--- a/media/libstagefright/codecs/flac/dec/Android.bp
+++ b/media/libstagefright/codecs/flac/dec/Android.bp
@@ -1,48 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2flacdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: [
-        "C2SoftFlacDecoder.cpp",
-    ],
-
-    include_dirs: [
-        "external/flac/include",
-        "frameworks/av/media/libstagefright/flac/dec",
-    ],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_flacdec",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-}
-
-
-cc_library_shared {
     name: "libstagefright_soft_flacdec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp
deleted file mode 100644
index 87138af..0000000
--- a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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 "C2SoftFlacDecoder"
-#include <utils/Log.h>
-
-#include "C2SoftFlacDecoder.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.flac.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_FLAC)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftFlacDecoder::C2SoftFlacDecoder(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mFLACDecoder(nullptr) {
-}
-
-C2SoftFlacDecoder::~C2SoftFlacDecoder() {
-    delete mFLACDecoder;
-}
-
-c2_status_t C2SoftFlacDecoder::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftFlacDecoder::onStop() {
-    if (mFLACDecoder) mFLACDecoder->flush();
-    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
-    mHasStreamInfo = false;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mInputBufferCount = 0;
-    return C2_OK;
-}
-
-void C2SoftFlacDecoder::onReset() {
-    (void)onStop();
-}
-
-void C2SoftFlacDecoder::onRelease() {
-}
-
-c2_status_t C2SoftFlacDecoder::onFlush_sm() {
-    return onStop();
-}
-
-status_t C2SoftFlacDecoder::initDecoder() {
-    if (mFLACDecoder) {
-        delete mFLACDecoder;
-    }
-    mFLACDecoder = FLACDecoder::Create();
-    if (!mFLACDecoder) {
-        ALOGE("initDecoder: failed to create FLACDecoder");
-        mSignalledError = true;
-        return NO_MEMORY;
-    }
-
-    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
-    mHasStreamInfo = false;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mInputBufferCount = 0;
-
-    return OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-// (TODO) add multiframe support, in plugin and FLACDecoder.cpp
-void C2SoftFlacDecoder::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    if (inSize == 0) {
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    if (mInputBufferCount == 0 && !codecConfig) {
-        ALOGV("First frame has to include configuration, forcing config");
-        codecConfig = true;
-    }
-
-    uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
-    if (codecConfig) {
-        status_t decoderErr = mFLACDecoder->parseMetadata(input, inSize);
-        if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
-            ALOGE("process: FLACDecoder parseMetaData returns error %d", decoderErr);
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-
-        mInputBufferCount++;
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-
-        if (decoderErr == WOULD_BLOCK) {
-            ALOGV("process: parseMetadata is Blocking, Continue %d", decoderErr);
-        } else {
-            mStreamInfo = mFLACDecoder->getStreamInfo();
-            if (mStreamInfo.max_blocksize && mStreamInfo.channels)
-                mHasStreamInfo = true;
-            ALOGD("process: decoder configuration : %d Hz, %d channels, %d samples,"
-                  " %d block size", mStreamInfo.sample_rate, mStreamInfo.channels,
-                  (int)mStreamInfo.total_samples, mStreamInfo.max_blocksize);
-        }
-        return;
-    }
-
-    size_t outSize;
-    if (mHasStreamInfo)
-        outSize = mStreamInfo.max_blocksize * mStreamInfo.channels * sizeof(short);
-    else
-        outSize = kMaxBlockSize * FLACDecoder::kMaxChannels * sizeof(short);
-
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    short *output = reinterpret_cast<short *>(wView.data());
-    status_t decoderErr = mFLACDecoder->decodeOneFrame(
-                            input, inSize, output, &outSize);
-    if (decoderErr != OK) {
-        ALOGE("process: FLACDecoder decodeOneFrame returns error %d", decoderErr);
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    mInputBufferCount++;
-    ALOGV("out buffer attr. size %zu", outSize);
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-c2_status_t C2SoftFlacDecoder::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    if (mFLACDecoder) mFLACDecoder->flush();
-
-    return C2_OK;
-}
-
-class C2SoftFlacDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftFlacDecoder(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftFlacDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftFlacDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.h b/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.h
deleted file mode 100644
index 43d913b..0000000
--- a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 C2_SOFT_FLAC_DECODER_H_
-#define C2_SOFT_FLAC_DECODER_H_
-
-#include <SimpleC2Component.h>
-
-#include "FLACDecoder.h"
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct C2SoftFlacDecoder : public SimpleC2Component {
-    C2SoftFlacDecoder(const char *name, c2_node_id_t id);
-    virtual ~C2SoftFlacDecoder();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    enum {
-        kMaxBlockSize   = 4096
-    };
-
-    FLACDecoder *mFLACDecoder;
-    FLAC__StreamMetadata_StreamInfo mStreamInfo;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-    bool mHasStreamInfo;
-    size_t mInputBufferCount;
-
-    status_t initDecoder();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftFlacDecoder);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_FLAC_DECODER_H_
diff --git a/media/libstagefright/codecs/flac/enc/Android.bp b/media/libstagefright/codecs/flac/enc/Android.bp
index bb705dd..46b974d 100644
--- a/media/libstagefright/codecs/flac/enc/Android.bp
+++ b/media/libstagefright/codecs/flac/enc/Android.bp
@@ -1,43 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2flacenc",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftFlacEnc.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libFLAC",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libutils",
-    ],
-}
-
-cc_library_shared {
 
     srcs: ["SoftFlacEncoder.cpp"],
 
diff --git a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp b/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp
deleted file mode 100644
index f94ed49..0000000
--- a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * 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 "C2SoftFlacEnc"
-#include <utils/Log.h>
-
-#include "C2SoftFlacEnc.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.flac.encoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatAudio)
-            .outputFormat(C2FormatCompressed)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_FLAC)
-            .build();
-}
-
-C2SoftFlacEnc::C2SoftFlacEnc(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mFlacStreamEncoder(nullptr),
-      mInputBufferPcm32(nullptr) {
-}
-
-C2SoftFlacEnc::~C2SoftFlacEnc() {
-    onRelease();
-}
-
-c2_status_t C2SoftFlacEnc::onInit() {
-    mFlacStreamEncoder = FLAC__stream_encoder_new();
-    if (!mFlacStreamEncoder) return C2_CORRUPTED;
-
-    mInputBufferPcm32 = (FLAC__int32*) malloc(
-            kInBlockSize * kMaxNumChannels * sizeof(FLAC__int32));
-    if (!mInputBufferPcm32) return C2_NO_MEMORY;
-
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mNumChannels = 1;
-    mSampleRate = 44100;
-    mCompressionLevel = FLAC_COMPRESSION_LEVEL_DEFAULT;
-    mIsFirstFrame = true;
-    mAnchorTimeStamp = 0ull;
-    mProcessedSamples = 0u;
-    mEncoderWriteData = false;
-    mEncoderReturnedNbBytes = 0;
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    mHeaderOffset = 0;
-    mWroteHeader = false;
-#endif
-
-    status_t err = configureEncoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-void C2SoftFlacEnc::onRelease() {
-    if (mFlacStreamEncoder) {
-        FLAC__stream_encoder_delete(mFlacStreamEncoder);
-        mFlacStreamEncoder = nullptr;
-    }
-
-    if (mInputBufferPcm32) {
-        free(mInputBufferPcm32);
-        mInputBufferPcm32 = nullptr;
-    }
-}
-
-void C2SoftFlacEnc::onReset() {
-    mNumChannels = 1;
-    mSampleRate = 44100;
-    mCompressionLevel = FLAC_COMPRESSION_LEVEL_DEFAULT;
-    (void) onStop();
-}
-
-c2_status_t C2SoftFlacEnc::onStop() {
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mIsFirstFrame = true;
-    mAnchorTimeStamp = 0ull;
-    mProcessedSamples = 0u;
-    mEncoderWriteData = false;
-    mEncoderReturnedNbBytes = 0;
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    mHeaderOffset = 0;
-    mWroteHeader = false;
-#endif
-
-    c2_status_t status = drain(DRAIN_COMPONENT_NO_EOS, nullptr);
-    if (C2_OK != status) return status;
-
-    status_t err = configureEncoder();
-    if (err != OK) mSignalledError = true;
-    return C2_OK;
-}
-
-c2_status_t C2SoftFlacEnc::onFlush_sm() {
-    return onStop();
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftFlacEnc::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-              inSize, (int)work->input.ordinal.timestamp.peeku(),
-              (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-    if (mIsFirstFrame && inSize) {
-        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
-        mIsFirstFrame = false;
-    }
-    uint64_t outTimeStamp = mProcessedSamples * 1000000ll / mSampleRate;
-
-    size_t outCapacity = inSize;
-    outCapacity += mBlockSize * mNumChannels * sizeof(int16_t);
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    outCapacity += FLAC_HEADER_SIZE;
-#endif
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &mOutputBlock);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = mOutputBlock->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    mEncoderWriteData = true;
-    mEncoderReturnedNbBytes = 0;
-    size_t inPos = 0;
-    const uint8_t *inPtr = rView.data() + inOffset;
-    while (inPos < inSize) {
-        size_t processSize = MIN(kInBlockSize * mNumChannels * sizeof(int16_t), (inSize - inPos));
-        const unsigned nbInputFrames = processSize / (mNumChannels * sizeof(int16_t));
-        const unsigned nbInputSamples = processSize / sizeof(int16_t);
-        const int16_t *pcm16 = reinterpret_cast<const int16_t *>(inPtr + inPos);
-        ALOGV("about to encode %zu bytes", processSize);
-
-        for (unsigned i = 0; i < nbInputSamples; i++) {
-            mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
-        }
-
-        FLAC__bool ok = FLAC__stream_encoder_process_interleaved(
-                mFlacStreamEncoder, mInputBufferPcm32, nbInputFrames);
-        if (!ok) {
-            ALOGE("error encountered during encoding");
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            mOutputBlock.reset();
-            return;
-        }
-        inPos += processSize;
-    }
-    if (eos && !drain(DRAIN_COMPONENT_WITH_EOS, pool)) {
-        ALOGE("error encountered during encoding");
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        mOutputBlock.reset();
-        return;
-    }
-    fillEmptyWork(work);
-    if (mEncoderReturnedNbBytes != 0) {
-        std::shared_ptr<C2Buffer> buffer = createLinearBuffer(std::move(mOutputBlock), 0, mEncoderReturnedNbBytes);
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-    } else {
-        ALOGV("encoder process_interleaved returned without data to write");
-    }
-    mOutputBlock = nullptr;
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-    mEncoderWriteData = false;
-    mEncoderReturnedNbBytes = 0;
-}
-
-FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::onEncodedFlacAvailable(
-        const FLAC__byte buffer[], size_t bytes, unsigned samples,
-        unsigned current_frame) {
-    (void) current_frame;
-    ALOGV("%s (bytes=%zu, samples=%u, curr_frame=%u)", __func__, bytes, samples,
-          current_frame);
-
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    if (samples == 0) {
-        ALOGI("saving %zu bytes of header", bytes);
-        memcpy(mHeader + mHeaderOffset, buffer, bytes);
-        mHeaderOffset += bytes;// will contain header size when finished receiving header
-        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-    }
-#endif
-
-    if ((samples == 0) || !mEncoderWriteData) {
-        // called by the encoder because there's header data to save, but it's not the role
-        // of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined)
-        ALOGV("ignoring %zu bytes of header data (samples=%d)", bytes, samples);
-        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-    }
-
-    // write encoded data
-    C2WriteView wView = mOutputBlock->map().get();
-    uint8_t* outData = wView.data();
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    if (!mWroteHeader) {
-        ALOGI("writing %d bytes of header on output", mHeaderOffset);
-        memcpy(outData + mEncoderReturnedNbBytes, mHeader, mHeaderOffset);
-        mEncoderReturnedNbBytes += mHeaderOffset;
-        mWroteHeader = true;
-    }
-#endif
-    ALOGV("writing %zu bytes of encoded data on output", bytes);
-    // increment mProcessedSamples to maintain audio synchronization during
-    // play back
-    mProcessedSamples += samples;
-    if (bytes + mEncoderReturnedNbBytes > mOutputBlock->capacity()) {
-        ALOGE("not enough space left to write encoded data, dropping %zu bytes", bytes);
-        // a fatal error would stop the encoding
-        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-    }
-    memcpy(outData + mEncoderReturnedNbBytes, buffer, bytes);
-    mEncoderReturnedNbBytes += bytes;
-    return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-}
-
-
-status_t C2SoftFlacEnc::configureEncoder() {
-    ALOGV("%s numChannel=%d, sampleRate=%d", __func__, mNumChannels, mSampleRate);
-
-    if (mSignalledError || !mFlacStreamEncoder) {
-        ALOGE("can't configure encoder: no encoder or invalid state");
-        return UNKNOWN_ERROR;
-    }
-
-    FLAC__bool ok = true;
-    ok = ok && FLAC__stream_encoder_set_channels(mFlacStreamEncoder, mNumChannels);
-    ok = ok && FLAC__stream_encoder_set_sample_rate(mFlacStreamEncoder, mSampleRate);
-    ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, 16);
-    ok = ok && FLAC__stream_encoder_set_compression_level(mFlacStreamEncoder, mCompressionLevel);
-    ok = ok && FLAC__stream_encoder_set_verify(mFlacStreamEncoder, false);
-    if (!ok) {
-        ALOGE("unknown error when configuring encoder");
-        return UNKNOWN_ERROR;
-    }
-
-    ok &= FLAC__STREAM_ENCODER_INIT_STATUS_OK ==
-            FLAC__stream_encoder_init_stream(mFlacStreamEncoder,
-                    flacEncoderWriteCallback    /*write_callback*/,
-                    nullptr /*seek_callback*/,
-                    nullptr /*tell_callback*/,
-                    nullptr /*metadata_callback*/,
-                    (void *) this /*client_data*/);
-
-    if (!ok) {
-        ALOGE("unknown error when configuring encoder");
-        return UNKNOWN_ERROR;
-    }
-
-    mBlockSize = FLAC__stream_encoder_get_blocksize(mFlacStreamEncoder);
-
-    ALOGV("encoder successfully configured");
-    return OK;
-}
-
-FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::flacEncoderWriteCallback(
-            const FLAC__StreamEncoder *,
-            const FLAC__byte buffer[],
-            size_t bytes,
-            unsigned samples,
-            unsigned current_frame,
-            void *client_data) {
-    return ((C2SoftFlacEnc*) client_data)->onEncodedFlacAvailable(
-            buffer, bytes, samples, current_frame);
-}
-
-c2_status_t C2SoftFlacEnc::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    switch (drainMode) {
-        case NO_DRAIN:
-            ALOGW("drain with NO_DRAIN: no-op");
-            return C2_OK;
-        case DRAIN_CHAIN:
-            ALOGW("DRAIN_CHAIN not supported");
-            return C2_OMITTED;
-        case DRAIN_COMPONENT_WITH_EOS:
-            // TODO: This flag is not being sent back to the client
-            // because there are no items in PendingWork queue as all the
-            // inputs are being sent back with emptywork or valid encoded data
-            // mSignalledOutputEos = true;
-        case DRAIN_COMPONENT_NO_EOS:
-            break;
-        default:
-            return C2_BAD_VALUE;
-    }
-    FLAC__bool ok = FLAC__stream_encoder_finish(mFlacStreamEncoder);
-    if (!ok) return C2_CORRUPTED;
-    mIsFirstFrame = true;
-    mAnchorTimeStamp = 0ull;
-    mProcessedSamples = 0u;
-
-    return C2_OK;
-}
-
-class C2SoftFlacEncFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftFlacEnc(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftFlacEncFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftFlacEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.h b/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.h
deleted file mode 100644
index cc8cb86..0000000
--- a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 C2_SOFT_FLAC_ENC_H_
-#define C2_SOFT_FLAC_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include "FLAC/stream_encoder.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-
-// use this symbol to have the first output buffer start with FLAC frame header so a dump of
-// all the output buffers can be opened as a .flac file
-//#define WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-
-#define FLAC_COMPRESSION_LEVEL_MIN     0
-#define FLAC_COMPRESSION_LEVEL_DEFAULT 5
-#define FLAC_COMPRESSION_LEVEL_MAX     8
-
-#define FLAC_HEADER_SIZE               128
-
-#define MIN(a, b)                      (((a) < (b)) ? (a) : (b))
-
-namespace android {
-
-class C2SoftFlacEnc : public SimpleC2Component {
-public:
-    C2SoftFlacEnc(const char *name, c2_node_id_t id);
-    virtual ~C2SoftFlacEnc();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    status_t configureEncoder();
-    static FLAC__StreamEncoderWriteStatus flacEncoderWriteCallback(
-            const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
-            size_t bytes, unsigned samples, unsigned current_frame,
-            void *client_data);
-    FLAC__StreamEncoderWriteStatus onEncodedFlacAvailable(
-            const FLAC__byte buffer[], size_t bytes, unsigned samples,
-            unsigned current_frame);
-
-    const unsigned int kInBlockSize = 1152;
-    const unsigned int kMaxNumChannels = 2;
-    FLAC__StreamEncoder* mFlacStreamEncoder;
-    FLAC__int32* mInputBufferPcm32;
-    std::shared_ptr<C2LinearBlock> mOutputBlock;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-    uint32_t mNumChannels;
-    uint32_t mSampleRate;
-    uint32_t mCompressionLevel;
-    uint32_t mBlockSize;
-    bool mIsFirstFrame;
-    uint64_t mAnchorTimeStamp;
-    uint64_t mProcessedSamples;
-    // should the data received by the callback be written to the output port
-    bool mEncoderWriteData;
-    size_t mEncoderReturnedNbBytes;
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    unsigned mHeaderOffset;
-    bool mWroteHeader;
-    char mHeader[FLAC_HEADER_SIZE];
-#endif
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftFlacEnc);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_FLAC_ENC_H_
diff --git a/media/libstagefright/codecs/g711/dec/Android.bp b/media/libstagefright/codecs/g711/dec/Android.bp
index 58a0a4d..3d97d8c 100644
--- a/media/libstagefright/codecs/g711/dec/Android.bp
+++ b/media/libstagefright/codecs/g711/dec/Android.bp
@@ -1,79 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2g711alawdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: [
-        "C2SoftG711.cpp",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-DALAW",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-}
-
-cc_library_shared {
-    name: "libstagefright_soft_c2g711mlawdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: [
-        "C2SoftG711.cpp",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_g711dec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp b/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp
deleted file mode 100644
index 1049420..0000000
--- a/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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 "C2SoftG711"
-#include <utils/Log.h>
-
-#include "C2SoftG711.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-#ifdef ALAW
-constexpr char kComponentName[] = "c2.google.g711.alaw.decoder";
-#else
-constexpr char kComponentName[] = "c2.google.g711.mlaw.decoder";
-#endif
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(
-#ifdef ALAW
-                    MEDIA_MIMETYPE_AUDIO_G711_ALAW
-#else
-                    MEDIA_MIMETYPE_AUDIO_G711_MLAW
-#endif
-            )
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-
-C2SoftG711::C2SoftG711(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)) {
-}
-
-C2SoftG711::~C2SoftG711() {
-    onRelease();
-}
-
-c2_status_t C2SoftG711::onInit() {
-    mSignalledOutputEos = false;
-    return C2_OK;
-}
-
-c2_status_t C2SoftG711::onStop() {
-    mSignalledOutputEos = false;
-    return C2_OK;
-}
-
-void C2SoftG711::onReset() {
-    (void)onStop();
-}
-
-void C2SoftG711::onRelease() {
-}
-
-c2_status_t C2SoftG711::onFlush_sm() {
-    return onStop();
-}
-
-void C2SoftG711::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer =
-        work->input.buffers[0]->data().linearBlocks().front();
-    C2ReadView rView = inBuffer.map().get();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    int outSize =  inSize * sizeof(int16_t);
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    if (inSize == 0) {
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    uint8_t *inputptr = const_cast<uint8_t *>(rView.data() + inOffset);
-
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    int16_t *outputptr = reinterpret_cast<int16_t *>(wView.data());
-
-#ifdef ALAW
-    DecodeALaw(outputptr, inputptr, inSize);
-#else
-    DecodeMLaw(outputptr, inputptr, inSize);
-#endif
-
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-c2_status_t C2SoftG711::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-#ifdef ALAW
-void C2SoftG711::DecodeALaw(
-        int16_t *out, const uint8_t *in, size_t inSize) {
-    while (inSize > 0) {
-        inSize--;
-        int32_t x = *in++;
-
-        int32_t ix = x ^ 0x55;
-        ix &= 0x7f;
-
-        int32_t iexp = ix >> 4;
-        int32_t mant = ix & 0x0f;
-
-        if (iexp > 0) {
-            mant += 16;
-        }
-
-        mant = (mant << 4) + 8;
-
-        if (iexp > 1) {
-            mant = mant << (iexp - 1);
-        }
-
-        *out++ = (x > 127) ? mant : -mant;
-    }
-}
-#else
-void C2SoftG711::DecodeMLaw(
-        int16_t *out, const uint8_t *in, size_t inSize) {
-    while (inSize > 0) {
-        inSize--;
-        int32_t x = *in++;
-
-        int32_t mantissa = ~x;
-        int32_t exponent = (mantissa >> 4) & 7;
-        int32_t segment = exponent + 1;
-        mantissa &= 0x0f;
-
-        int32_t step = 4 << segment;
-
-        int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
-
-        *out++ = (x < 0x80) ? -abs : abs;
-    }
-}
-#endif
-
-class C2SoftG711DecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftG711(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftG711DecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftG711DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/g711/dec/C2SoftG711.h b/media/libstagefright/codecs/g711/dec/C2SoftG711.h
deleted file mode 100644
index eed38c9..0000000
--- a/media/libstagefright/codecs/g711/dec/C2SoftG711.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 C2_SOFT_G711_H_
-#define C2_SOFT_G711_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct C2SoftG711 : public SimpleC2Component {
-    C2SoftG711(const char *name, c2_node_id_t id);
-    virtual ~C2SoftG711();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-private:
-    bool mSignalledOutputEos;
-
-#ifdef ALAW
-    void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
-#else
-    void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
-#endif
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftG711);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_G711_H_
diff --git a/media/libstagefright/codecs/gsm/dec/Android.bp b/media/libstagefright/codecs/gsm/dec/Android.bp
index c057d8a..1c3208b 100644
--- a/media/libstagefright/codecs/gsm/dec/Android.bp
+++ b/media/libstagefright/codecs/gsm/dec/Android.bp
@@ -1,45 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2gsmdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: [
-        "C2SoftGSM.cpp"
-    ],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    static_libs: [
-        "libgsm"
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_gsmdec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/gsm/dec/C2SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/C2SoftGSM.cpp
deleted file mode 100644
index d021768..0000000
--- a/media/libstagefright/codecs/gsm/dec/C2SoftGSM.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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 "C2SoftGSM"
-#include <utils/Log.h>
-
-#include "C2SoftGSM.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.gsm.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_MSGSM)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftGSM::C2SoftGSM(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mGsm(nullptr) {
-}
-
-C2SoftGSM::~C2SoftGSM() {
-    onRelease();
-}
-
-c2_status_t C2SoftGSM::onInit() {
-    if (!mGsm) mGsm = gsm_create();
-    if (!mGsm) return C2_NO_MEMORY;
-    int msopt = 1;
-    (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
-    mSignalledError = false;
-    mSignalledEos = false;
-    return C2_OK;
-}
-
-c2_status_t C2SoftGSM::onStop() {
-    if (mGsm) {
-        gsm_destroy(mGsm);
-        mGsm = nullptr;
-    }
-    if (!mGsm) mGsm = gsm_create();
-    if (!mGsm) return C2_NO_MEMORY;
-    int msopt = 1;
-    (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
-    mSignalledError = false;
-    mSignalledEos = false;
-    return C2_OK;
-}
-
-void C2SoftGSM::onReset() {
-    (void)onStop();
-}
-
-void C2SoftGSM::onRelease() {
-    if (mGsm) {
-        gsm_destroy(mGsm);
-        mGsm = nullptr;
-    }
-}
-
-c2_status_t C2SoftGSM::onFlush_sm() {
-    return onStop();
-}
-
-static size_t decodeGSM(gsm handle, int16_t *out, size_t outCapacity,
-                        uint8_t *in, size_t inSize) {
-    size_t outSize = 0;
-
-    if (inSize % MSGSM_IN_FRM_SZ == 0
-            && (inSize / MSGSM_IN_FRM_SZ * MSGSM_OUT_FRM_SZ * sizeof(*out)
-                    <= outCapacity)) {
-        while (inSize > 0) {
-            gsm_decode(handle, in, out);
-            in += FRGSM_IN_FRM_SZ;
-            inSize -= FRGSM_IN_FRM_SZ;
-            out += FRGSM_OUT_FRM_SZ;
-            outSize += FRGSM_OUT_FRM_SZ;
-
-            gsm_decode(handle, in, out);
-            in += FRGSM_IN_FRM_SZ_MINUS_1;
-            inSize -= FRGSM_IN_FRM_SZ_MINUS_1;
-            out += FRGSM_OUT_FRM_SZ;
-            outSize += FRGSM_OUT_FRM_SZ;
-        }
-    }
-
-    return outSize * sizeof(int16_t);
-}
-
-void C2SoftGSM::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-
-    if (inSize == 0) {
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-        if (eos) {
-            mSignalledEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    size_t outCapacity = (inSize / MSGSM_IN_FRM_SZ ) * MSGSM_OUT_FRM_SZ * sizeof(int16_t);
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = wView.error();
-        return;
-    }
-
-    int16_t *output = reinterpret_cast<int16_t *>(wView.data());
-    uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
-    size_t outSize = decodeGSM(mGsm, output, outCapacity, input, inSize);
-    if (!outSize) {
-        ALOGE("encountered improper insize or outsize");
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    ALOGV("out buffer attr. size %zu", outSize);
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-    if (eos) {
-        mSignalledEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-c2_status_t C2SoftGSM::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-class C2SoftGSMDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftGSM(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftGSMDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftGSMDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/gsm/dec/C2SoftGSM.h b/media/libstagefright/codecs/gsm/dec/C2SoftGSM.h
deleted file mode 100644
index 597711c..0000000
--- a/media/libstagefright/codecs/gsm/dec/C2SoftGSM.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 C2_SOFT_GSM_H_
-#define C2_SOFT_GSM_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-extern "C" {
-    #include "gsm.h"
-}
-
-namespace android {
-
-#define FRGSM_IN_FRM_SZ             33
-#define FRGSM_IN_FRM_SZ_MINUS_1     32
-#define FRGSM_OUT_FRM_SZ            160
-#define MSGSM_IN_FRM_SZ             (FRGSM_IN_FRM_SZ + FRGSM_IN_FRM_SZ_MINUS_1)
-#define MSGSM_OUT_FRM_SZ            (FRGSM_OUT_FRM_SZ * 2)
-
-struct C2SoftGSM : public SimpleC2Component {
-    C2SoftGSM(const char *name, c2_node_id_t id);
-    virtual ~C2SoftGSM();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
- private:
-    gsm mGsm;
-    bool mSignalledError;
-    bool mSignalledEos;
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftGSM);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_GSM_H_
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index 385807a..45920e6 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -46,48 +46,3 @@
     ldflags: ["-Wl,-Bsymbolic"],
     compile_multilib: "32",
 }
-
-cc_library_shared {
-    name: "libstagefright_soft_c2hevcdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftHevcDec.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    include_dirs: [
-        "external/libhevc/decoder",
-        "external/libhevc/common",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: false, // true,
-        diag: {
-            cfi: false, // true,
-        },
-    },
-
-    static_libs: ["libhevcdec"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libmedia",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    ldflags: ["-Wl,-Bsymbolic"],
-
-}
diff --git a/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.cpp b/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.cpp
deleted file mode 100644
index 6d208bd..0000000
--- a/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.cpp
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * 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 "C2SoftHevcDec"
-#include <utils/Log.h>
-
-#include "ihevc_typedefs.h"
-#include "iv.h"
-#include "ivd.h"
-#include "ihevcd_cxa.h"
-#include "C2SoftHevcDec.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.hevc.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatVideo)
-            .inputMediaType(MEDIA_MIMETYPE_VIDEO_HEVC)
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .build();
-}
-
-static size_t getCpuCoreCount() {
-    long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
-    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    // _SC_NPROC_ONLN must be defined...
-    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
-    CHECK(cpuCoreCount >= 1);
-    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
-    return (size_t)cpuCoreCount;
-}
-
-static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
-    (void) ctxt;
-    return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *ctxt, void *mem) {
-    (void) ctxt;
-    free(mem);
-}
-
-C2SoftHevcDec::C2SoftHevcDec(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-            mDecHandle(nullptr),
-            mOutBufferFlush(nullptr),
-            mIvColorformat(IV_YUV_420P),
-            mWidth(320),
-            mHeight(240) {
-}
-
-C2SoftHevcDec::~C2SoftHevcDec() {
-    onRelease();
-}
-
-c2_status_t C2SoftHevcDec::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftHevcDec::onStop() {
-    if (OK != resetDecoder()) return C2_CORRUPTED;
-    resetPlugin();
-    return C2_OK;
-}
-
-void C2SoftHevcDec::onReset() {
-    (void) onStop();
-}
-
-void C2SoftHevcDec::onRelease() {
-    (void) deleteDecoder();
-    if (mOutBufferFlush) {
-        ivd_aligned_free(nullptr, mOutBufferFlush);
-        mOutBufferFlush = nullptr;
-    }
-    if (mOutBlock) {
-        mOutBlock.reset();
-    }
-}
-
-c2_status_t C2SoftHevcDec::onFlush_sm() {
-    if (OK != setFlushMode()) return C2_CORRUPTED;
-
-    uint32_t displayStride = mStride;
-    uint32_t displayHeight = mHeight;
-    uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
-    mOutBufferFlush = (uint8_t *)ivd_aligned_malloc(nullptr, 128, bufferSize);
-    if (!mOutBufferFlush) {
-        ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
-        return C2_NO_MEMORY;
-    }
-
-    while (true) {
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-
-        setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        if (0 == s_decode_op.u4_output_present) {
-            resetPlugin();
-            break;
-        }
-    }
-
-    ivd_aligned_free(nullptr, mOutBufferFlush);
-    mOutBufferFlush = nullptr;
-
-    return C2_OK;
-}
-
-status_t C2SoftHevcDec::createDecoder() {
-    ivdext_create_ip_t s_create_ip;
-    ivdext_create_op_t s_create_op;
-
-    s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
-    s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
-    s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
-    s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
-    s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
-    s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
-    s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
-    s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_create_ip,
-                                                     &s_create_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__,
-              s_create_op.s_ivd_create_op_t.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    mDecHandle = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
-    mDecHandle->pv_fxns = (void *)ivdec_api_function;
-    mDecHandle->u4_size = sizeof(iv_obj_t);
-
-    return OK;
-}
-
-status_t C2SoftHevcDec::setNumCores() {
-    ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
-    ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
-
-    s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
-    s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
-    s_set_num_cores_ip.u4_num_cores = mNumCores;
-    s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_num_cores_ip,
-                                                     &s_set_num_cores_op);
-    if (IV_SUCCESS != status) {
-        ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftHevcDec::setParams(size_t stride) {
-    ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
-    ivd_ctl_set_config_op_t s_set_dyn_params_op;
-
-    s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
-    s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
-    s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
-    s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
-    s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
-    s_set_dyn_params_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
-    s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_dyn_params_ip,
-                                                     &s_set_dyn_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftHevcDec::getVersion() {
-    ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
-    ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
-    UWORD8 au1_buf[512];
-
-    s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
-    s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
-    s_get_versioninfo_ip.pv_version_buffer = au1_buf;
-    s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
-    s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_get_versioninfo_ip,
-                                                     &s_get_versioninfo_op);
-    if (status != IV_SUCCESS) {
-        ALOGD("error in %s: 0x%x", __func__,
-              s_get_versioninfo_op.u4_error_code);
-    } else {
-        ALOGV("ittiam decoder version number: %s",
-              (char *) s_get_versioninfo_ip.pv_version_buffer);
-    }
-
-    return OK;
-}
-
-status_t C2SoftHevcDec::initDecoder() {
-    if (OK != createDecoder()) return UNKNOWN_ERROR;
-    mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
-    mStride = ALIGN64(mWidth);
-    mSignalledError = false;
-    mPreference = kPreferBitstream;
-    memset(&mDefaultColorAspects, 0, sizeof(ColorAspects));
-    memset(&mBitstreamColorAspects, 0, sizeof(ColorAspects));
-    memset(&mFinalColorAspects, 0, sizeof(ColorAspects));
-    mUpdateColorAspects = false;
-    resetPlugin();
-    (void) setNumCores();
-    if (OK != setParams(mStride)) return UNKNOWN_ERROR;
-    (void) getVersion();
-
-    return OK;
-}
-
-bool C2SoftHevcDec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
-                                  ivd_video_decode_op_t *ps_decode_op,
-                                  C2ReadView *inBuffer,
-                                  C2GraphicView *outBuffer,
-                                  size_t inOffset,
-                                  size_t inSize,
-                                  uint32_t tsMarker) {
-    uint32_t displayStride = mStride;
-    uint32_t displayHeight = mHeight;
-    size_t lumaSize = displayStride * displayHeight;
-    size_t chromaSize = lumaSize >> 2;
-
-    ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
-    ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
-    if (inBuffer) {
-        ps_decode_ip->u4_ts = tsMarker;
-        ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
-        ps_decode_ip->u4_num_Bytes = inSize;
-    } else {
-        ps_decode_ip->u4_ts = 0;
-        ps_decode_ip->pv_stream_buffer = nullptr;
-        ps_decode_ip->u4_num_Bytes = 0;
-    }
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
-    if (outBuffer) {
-        if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
-            ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
-                  outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
-            return false;
-        }
-        ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
-        ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
-        ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
-    } else {
-        ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferFlush;
-        ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferFlush + lumaSize;
-        ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferFlush + lumaSize + chromaSize;
-    }
-    ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
-    ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
-    ps_decode_op->u4_output_present = 0;
-
-    return true;
-}
-
-bool C2SoftHevcDec::colorAspectsDiffer(
-        const ColorAspects &a, const ColorAspects &b) {
-    if (a.mRange != b.mRange
-        || a.mPrimaries != b.mPrimaries
-        || a.mTransfer != b.mTransfer
-        || a.mMatrixCoeffs != b.mMatrixCoeffs) {
-        return true;
-    }
-    return false;
-}
-
-void C2SoftHevcDec::updateFinalColorAspects(
-        const ColorAspects &otherAspects, const ColorAspects &preferredAspects) {
-    Mutex::Autolock autoLock(mColorAspectsLock);
-    ColorAspects newAspects;
-    newAspects.mRange = preferredAspects.mRange != ColorAspects::RangeUnspecified ?
-        preferredAspects.mRange : otherAspects.mRange;
-    newAspects.mPrimaries = preferredAspects.mPrimaries != ColorAspects::PrimariesUnspecified ?
-        preferredAspects.mPrimaries : otherAspects.mPrimaries;
-    newAspects.mTransfer = preferredAspects.mTransfer != ColorAspects::TransferUnspecified ?
-        preferredAspects.mTransfer : otherAspects.mTransfer;
-    newAspects.mMatrixCoeffs = preferredAspects.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
-        preferredAspects.mMatrixCoeffs : otherAspects.mMatrixCoeffs;
-
-    // Check to see if need update mFinalColorAspects.
-    if (colorAspectsDiffer(mFinalColorAspects, newAspects)) {
-        mFinalColorAspects = newAspects;
-        mUpdateColorAspects = true;
-    }
-}
-
-status_t C2SoftHevcDec::handleColorAspectsChange() {
-    if (mPreference == kPreferBitstream) {
-        updateFinalColorAspects(mDefaultColorAspects, mBitstreamColorAspects);
-    } else if (mPreference == kPreferContainer) {
-        updateFinalColorAspects(mBitstreamColorAspects, mDefaultColorAspects);
-    } else {
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-bool C2SoftHevcDec::getVuiParams() {
-    ivdext_ctl_get_vui_params_ip_t s_get_vui_params_ip;
-    ivdext_ctl_get_vui_params_op_t s_get_vui_params_op;
-
-    s_get_vui_params_ip.u4_size = sizeof(ivdext_ctl_get_vui_params_ip_t);
-    s_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_get_vui_params_ip.e_sub_cmd =
-            (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS;
-    s_get_vui_params_op.u4_size = sizeof(ivdext_ctl_get_vui_params_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_get_vui_params_ip,
-                                                     &s_get_vui_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGD("error in %s: 0x%x", __func__, s_get_vui_params_op.u4_error_code);
-        return false;
-    }
-
-    int32_t primaries = s_get_vui_params_op.u1_colour_primaries;
-    int32_t transfer = s_get_vui_params_op.u1_transfer_characteristics;
-    int32_t coeffs = s_get_vui_params_op.u1_matrix_coefficients;
-    bool full_range = s_get_vui_params_op.u1_video_full_range_flag;
-
-    ColorAspects colorAspects;
-    ColorUtils::convertIsoColorAspectsToCodecAspects(
-            primaries, transfer, coeffs, full_range, colorAspects);
-    // Update color aspects if necessary.
-    if (colorAspectsDiffer(colorAspects, mBitstreamColorAspects)) {
-        mBitstreamColorAspects = colorAspects;
-        status_t err = handleColorAspectsChange();
-        CHECK(err == OK);
-    }
-
-    return true;
-}
-
-status_t C2SoftHevcDec::setFlushMode() {
-    ivd_ctl_flush_ip_t s_set_flush_ip;
-    ivd_ctl_flush_op_t s_set_flush_op;
-
-    s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
-    s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
-    s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_flush_ip,
-                                                     &s_set_flush_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftHevcDec::resetDecoder() {
-    ivd_ctl_reset_ip_t s_reset_ip;
-    ivd_ctl_reset_op_t s_reset_op;
-
-    s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
-    s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
-    s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_reset_ip,
-                                                     &s_reset_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    mStride = 0;
-    (void) setNumCores();
-    mSignalledError = false;
-
-    return OK;
-}
-
-void C2SoftHevcDec::resetPlugin() {
-    mSignalledOutputEos = false;
-    gettimeofday(&mTimeStart, nullptr);
-    gettimeofday(&mTimeEnd, nullptr);
-}
-
-status_t C2SoftHevcDec::deleteDecoder() {
-    if (mDecHandle) {
-        ivdext_delete_ip_t s_delete_ip;
-        ivdext_delete_op_t s_delete_op;
-
-        s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
-        s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
-        s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
-        IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                         &s_delete_ip,
-                                                         &s_delete_op);
-        if (status != IV_SUCCESS) {
-            ALOGE("error in %s: 0x%x", __func__,
-                  s_delete_op.s_ivd_delete_op_t.u4_error_code);
-            return UNKNOWN_ERROR;
-        }
-        mDecHandle = nullptr;
-    }
-
-    return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    uint32_t flags = 0;
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("signalling eos");
-    }
-    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftHevcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
-                                                           C2Rect(mWidth, mHeight));
-    mOutBlock = nullptr;
-    auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
-        uint32_t flags = 0;
-        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
-                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
-            ALOGV("signalling eos");
-        }
-        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    };
-    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
-        fillWork(work);
-    } else {
-        finish(index, fillWork);
-    }
-}
-
-c2_status_t C2SoftHevcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
-    if (!mDecHandle) {
-        ALOGE("not supposed to be here, invalid decoder context");
-        return C2_CORRUPTED;
-    }
-    if (mStride != ALIGN64(mWidth)) {
-        mStride = ALIGN64(mWidth);
-        if (OK != setParams(mStride)) return C2_CORRUPTED;
-    }
-    if (mOutBlock &&
-            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
-        mOutBlock.reset();
-    }
-    if (!mOutBlock) {
-        uint32_t format = HAL_PIXEL_FORMAT_YV12;
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
-        if (err != C2_OK) {
-            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
-            return err;
-        }
-        ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
-    }
-
-    return C2_OK;
-}
-
-// TODO: can overall error checking be improved?
-// TODO: allow configuration of color format and usage for graphic buffers instead
-//       of hard coding them to HAL_PIXEL_FORMAT_YV12
-// TODO: pass coloraspects information to surface
-// TODO: test support for dynamic change in resolution
-// TODO: verify if the decoder sent back all frames
-void C2SoftHevcDec::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    bool hasPicture = false;
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-    size_t inPos = 0;
-    while (inPos < inSize) {
-        if (C2_OK != ensureDecoderState(pool)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        C2GraphicView wView = mOutBlock->map().get();
-        if (wView.error()) {
-            ALOGE("graphic view map failed %d", wView.error());
-            work->result = wView.error();
-            return;
-        }
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
-                           inOffset + inPos, inSize - inPos, workIndex)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        WORD32 delay;
-        GETTIME(&mTimeStart, NULL);
-        TIME_DIFF(mTimeEnd, mTimeStart, delay);
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        WORD32 decodeTime;
-        GETTIME(&mTimeEnd, nullptr);
-        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
-        ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
-              s_decode_op.u4_num_bytes_consumed);
-        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & 0xFF)) {
-            ALOGE("allocation failure in decoder");
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & 0xFF)) {
-            ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
-            ALOGV("resolution changed");
-            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
-            resetDecoder();
-            resetPlugin();
-            continue;
-        }
-        if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
-            if (s_decode_op.u4_pic_wd != mWidth ||  s_decode_op.u4_pic_ht != mHeight) {
-                mWidth = s_decode_op.u4_pic_wd;
-                mHeight = s_decode_op.u4_pic_ht;
-                CHECK_EQ(0u, s_decode_op.u4_output_present);
-            }
-        }
-        (void) getVuiParams();
-        if (mUpdateColorAspects) {
-            mUpdateColorAspects = false;
-        }
-        hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
-        if (s_decode_op.u4_output_present) {
-            finishWork(s_decode_op.u4_ts, work);
-        }
-        inPos += s_decode_op.u4_num_bytes_consumed;
-        if (hasPicture && (inSize - inPos)) {
-            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
-                  (int)inSize - (int)inPos);
-            break;
-        }
-    }
-
-    if (eos) {
-        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
-        mSignalledOutputEos = true;
-    } else if (!hasPicture) {
-        fillEmptyWork(work);
-    }
-}
-
-c2_status_t C2SoftHevcDec::drainInternal(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work) {
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    if (OK != setFlushMode()) return C2_CORRUPTED;
-    while (true) {
-        if (C2_OK != ensureDecoderState(pool)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return C2_CORRUPTED;
-        }
-        C2GraphicView wView = mOutBlock->map().get();
-        if (wView.error()) {
-            ALOGE("graphic view map failed %d", wView.error());
-            return C2_CORRUPTED;
-        }
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
-            mSignalledError = true;
-            return C2_CORRUPTED;
-        }
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        if (s_decode_op.u4_output_present) {
-            finishWork(s_decode_op.u4_ts, work);
-        } else {
-            break;
-        }
-    }
-
-    if (drainMode == DRAIN_COMPONENT_WITH_EOS &&
-            work && work->workletsProcessed == 0u) {
-        fillEmptyWork(work);
-    }
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftHevcDec::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftHevcDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftHevcDec(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftHevcDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftHevcDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.h b/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.h
deleted file mode 100644
index 28a5a78..0000000
--- a/media/libstagefright/codecs/hevcdec/C2SoftHevcDec.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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 C2_SOFT_HEVC_DEC_H_
-#define C2_SOFT_HEVC_DEC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/ColorUtils.h>
-
-namespace android {
-
-#define ivdec_api_function              ihevcd_cxa_api_function
-#define ivdext_create_ip_t              ihevcd_cxa_create_ip_t
-#define ivdext_create_op_t              ihevcd_cxa_create_op_t
-#define ivdext_delete_ip_t              ihevcd_cxa_delete_ip_t
-#define ivdext_delete_op_t              ihevcd_cxa_delete_op_t
-#define ivdext_ctl_set_num_cores_ip_t   ihevcd_cxa_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t   ihevcd_cxa_ctl_set_num_cores_op_t
-#define ivdext_ctl_get_vui_params_ip_t  ihevcd_cxa_ctl_get_vui_params_ip_t
-#define ivdext_ctl_get_vui_params_op_t  ihevcd_cxa_ctl_get_vui_params_op_t
-#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
-#define MAX_NUM_CORES                   4
-#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
-        (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
-#define MIN(a, b)                       (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b)                   gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff)     \
-    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
-            ((end).tv_usec - (start).tv_usec);
-
-
-struct C2SoftHevcDec : public SimpleC2Component {
-    C2SoftHevcDec(const char *name, c2_node_id_t id);
-    virtual ~C2SoftHevcDec();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
- private:
-    status_t createDecoder();
-    status_t setNumCores();
-    status_t setParams(size_t stride);
-    status_t getVersion();
-    status_t initDecoder();
-    bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
-                       ivd_video_decode_op_t *ps_decode_op,
-                       C2ReadView *inBuffer,
-                       C2GraphicView *outBuffer,
-                       size_t inOffset,
-                       size_t inSize,
-                       uint32_t tsMarker);
-    bool getVuiParams();
-    // TODO:This is not the right place for colorAspects functions. These should
-    // be part of c2-vndk so that they can be accessed by all video plugins
-    // until then, make them feel at home
-    bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
-    void updateFinalColorAspects(
-            const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
-    status_t handleColorAspectsChange();
-    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
-    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
-    status_t setFlushMode();
-    c2_status_t drainInternal(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-    status_t resetDecoder();
-    void resetPlugin();
-    status_t deleteDecoder();
-
-    // TODO:This is not the right place for this enum. These should
-    // be part of c2-vndk so that they can be accessed by all video plugins
-    // until then, make them feel at home
-    enum {
-        kNotSupported,
-        kPreferBitstream,
-        kPreferContainer,
-    };
-
-    iv_obj_t *mDecHandle;
-    std::shared_ptr<C2GraphicBlock> mOutBlock;
-    uint8_t *mOutBufferFlush;
-
-    size_t mNumCores;
-    IV_COLOR_FORMAT_T mIvColorformat;
-
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mStride;
-    bool mSignalledOutputEos;
-    bool mSignalledError;
-
-    // ColorAspects
-    Mutex mColorAspectsLock;
-    int mPreference;
-    ColorAspects mDefaultColorAspects;
-    ColorAspects mBitstreamColorAspects;
-    ColorAspects mFinalColorAspects;
-    bool mUpdateColorAspects;
-
-    // profile
-    struct timeval mTimeStart;
-    struct timeval mTimeEnd;
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftHevcDec);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_HEVC_DEC_H_
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index d24a116..ca70cc2 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -112,91 +112,3 @@
     },
     compile_multilib: "32",
 }
-
-//###############################################################################
-
-cc_library_shared {
-    name: "libstagefright_soft_c2mpeg4dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftMpeg4Dec.cpp"],
-
-    cflags: [
-        "-DOSCL_IMPORT_REF=",
-        "-DMPEG4",
-        "-Wall",
-        "-Werror",
-    ],
-
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: ["libstagefright_m4vh263dec"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-//###############################################################################
-cc_library_shared {
-    name: "libstagefright_soft_c2h263dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftMpeg4Dec.cpp"],
-
-    cflags: [
-        "-DOSCL_IMPORT_REF=",
-        "-Wall",
-        "-Werror",
-    ],
-
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: ["libstagefright_m4vh263dec"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp b/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp
deleted file mode 100644
index eaef532..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * 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 "C2SoftMpeg4Dec"
-#include <utils/Log.h>
-
-#include "C2SoftMpeg4Dec.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include "mp4dec_api.h"
-
-namespace android {
-
-#ifdef MPEG4
-constexpr char kComponentName[] = "c2.google.mpeg4.decoder";
-#else
-constexpr char kComponentName[] = "c2.google.h263.decoder";
-#endif
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatVideo)
-            .inputMediaType(
-#ifdef MPEG4
-                    MEDIA_MIMETYPE_VIDEO_MPEG4
-#else
-                    MEDIA_MIMETYPE_VIDEO_H263
-#endif
-            )
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .build();
-}
-
-C2SoftMpeg4Dec::C2SoftMpeg4Dec(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mDecHandle(nullptr),
-      mOutputBuffer{} {
-}
-
-C2SoftMpeg4Dec::~C2SoftMpeg4Dec() {
-    onRelease();
-}
-
-c2_status_t C2SoftMpeg4Dec::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftMpeg4Dec::onStop() {
-    if (mInitialized) {
-        PVCleanUpVideoDecoder(mDecHandle);
-        mInitialized = false;
-    }
-    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
-        if (mOutputBuffer[i]) {
-            free(mOutputBuffer[i]);
-            mOutputBuffer[i] = nullptr;
-        }
-    }
-    mNumSamplesOutput = 0;
-    mFramesConfigured = false;
-    mSignalledOutputEos = false;
-    mSignalledError = false;
-
-    return C2_OK;
-}
-
-void C2SoftMpeg4Dec::onReset() {
-    (void) onStop();
-}
-
-void C2SoftMpeg4Dec::onRelease() {
-    if (mInitialized) {
-        PVCleanUpVideoDecoder(mDecHandle);
-        mInitialized = false;
-    }
-    if (mOutBlock) {
-        mOutBlock.reset();
-    }
-    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
-        if (mOutputBuffer[i]) {
-            free(mOutputBuffer[i]);
-            mOutputBuffer[i] = nullptr;
-        }
-    }
-
-    delete mDecHandle;
-    mDecHandle = nullptr;
-}
-
-c2_status_t C2SoftMpeg4Dec::onFlush_sm() {
-    if (mInitialized) {
-        if (PV_TRUE != PVResetVideoDecoder(mDecHandle)) return C2_CORRUPTED;
-    }
-    mSignalledOutputEos = false;
-    mSignalledError = false;
-    return C2_OK;
-}
-
-status_t C2SoftMpeg4Dec::initDecoder() {
-#ifdef MPEG4
-    mIsMpeg4 = true;
-#else
-    mIsMpeg4 = false;
-#endif
-    if (!mDecHandle) {
-        mDecHandle = new tagvideoDecControls;
-    }
-    memset(mDecHandle, 0, sizeof(tagvideoDecControls));
-
-    /* TODO: bring these values to 352 and 288. It cannot be done as of now
-     * because, h263 doesn't seem to allow port reconfiguration. In OMX, the
-     * problem of larger width and height than default width and height is
-     * overcome by adaptivePlayBack() api call. This call gets width and height
-     * information from extractor. Such a thing is not possible here.
-     * So we are configuring to larger values.*/
-    mWidth = 1408;
-    mHeight = 1152;
-    mNumSamplesOutput = 0;
-    mInitialized = false;
-    mFramesConfigured = false;
-    mSignalledOutputEos = false;
-    mSignalledError = false;
-
-    return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    uint32_t flags = 0;
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("signalling eos");
-    }
-    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftMpeg4Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
-                                                           C2Rect(mWidth, mHeight));
-    mOutBlock = nullptr;
-    auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
-        uint32_t flags = 0;
-        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
-                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
-            ALOGV("signalling eos");
-        }
-        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    };
-    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
-        fillWork(work);
-    } else {
-        finish(index, fillWork);
-    }
-}
-
-c2_status_t C2SoftMpeg4Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
-    if (!mDecHandle) {
-        ALOGE("not supposed to be here, invalid decoder context");
-        return C2_CORRUPTED;
-    }
-
-    uint32_t outSize = align(mWidth, 16) * align(mHeight, 16) * 3 / 2;
-    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
-        if (!mOutputBuffer[i]) {
-            mOutputBuffer[i] = (uint8_t *)malloc(outSize * sizeof(uint8_t));
-            if (!mOutputBuffer[i]) return C2_NO_MEMORY;
-        }
-    }
-    if (mOutBlock &&
-            (mOutBlock->width() != align(mWidth, 16) || mOutBlock->height() != mHeight)) {
-        mOutBlock.reset();
-    }
-    if (!mOutBlock) {
-        uint32_t format = HAL_PIXEL_FORMAT_YV12;
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &mOutBlock);
-        if (err != C2_OK) {
-            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
-            return err;
-        }
-        ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mWidth, mHeight);
-    }
-    return C2_OK;
-}
-
-bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) {
-    uint32_t disp_width, disp_height;
-    PVGetVideoDimensions(mDecHandle, (int32 *)&disp_width, (int32 *)&disp_height);
-
-    uint32_t buf_width, buf_height;
-    PVGetBufferDimensions(mDecHandle, (int32 *)&buf_width, (int32 *)&buf_height);
-
-    CHECK_LE(disp_width, buf_width);
-    CHECK_LE(disp_height, buf_height);
-
-    ALOGV("display size (%dx%d), buffer size (%dx%d)",
-           disp_width, disp_height, buf_width, buf_height);
-
-    bool resChanged = false;
-    if (disp_width != mWidth || disp_height != mHeight) {
-        mWidth = disp_width;
-        mHeight = disp_height;
-        resChanged = true;
-        for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
-            if (mOutputBuffer[i]) {
-                free(mOutputBuffer[i]);
-                mOutputBuffer[i] = nullptr;
-            }
-        }
-
-        if (!mIsMpeg4) {
-            PVCleanUpVideoDecoder(mDecHandle);
-
-            uint8_t *vol_data[1]{};
-            int32_t vol_size = 0;
-
-            if (!PVInitVideoDecoder(
-                    mDecHandle, vol_data, &vol_size, 1, mWidth, mHeight, H263_MODE)) {
-                ALOGE("Error in PVInitVideoDecoder H263_MODE while resChanged was set to true");
-                work->result = C2_CORRUPTED;
-                mSignalledError = true;
-                return true;
-            }
-        }
-        mFramesConfigured = false;
-    }
-    return resChanged;
-}
-
-/* TODO: can remove temporary copy after library supports writing to display
- * buffer Y, U and V plane pointers using stride info. */
-static void copyOutputBufferToYV12Frame(uint8_t *dst, uint8_t *src, size_t dstYStride,
-                                        size_t srcYStride, uint32_t width, uint32_t height) {
-    size_t dstUVStride = align(dstYStride / 2, 16);
-    size_t srcUVStride = srcYStride / 2;
-    uint8_t *srcStart = src;
-    uint8_t *dstStart = dst;
-    size_t vStride = align(height, 16);
-    for (size_t i = 0; i < height; ++i) {
-         memcpy(dst, src, width);
-         src += srcYStride;
-         dst += dstYStride;
-    }
-    /* U buffer */
-    src = srcStart + vStride * srcYStride;
-    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
-    for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, src, width / 2);
-         src += srcUVStride;
-         dst += dstUVStride;
-    }
-    /* V buffer */
-    src = srcStart + vStride * srcYStride * 5 / 4;
-    dst = dstStart + (dstYStride * height);
-    for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, src, width / 2);
-         src += srcUVStride;
-         dst += dstUVStride;
-    }
-}
-
-void C2SoftMpeg4Dec::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    if (inSize == 0) {
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-        }
-        return;
-    }
-
-    uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
-    uint32_t *start_code = (uint32_t *)bitstream;
-    bool volHeader = *start_code == 0xB0010000;
-    if (volHeader) {
-        PVCleanUpVideoDecoder(mDecHandle);
-        mInitialized = false;
-    }
-
-    if (!mInitialized) {
-        uint8_t *vol_data[1]{};
-        int32_t vol_size = 0;
-
-        bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-        if (codecConfig || volHeader) {
-            vol_data[0] = bitstream;
-            vol_size = inSize;
-        }
-        MP4DecodingMode mode = (mIsMpeg4) ? MPEG4_MODE : H263_MODE;
-
-        if (!PVInitVideoDecoder(
-                mDecHandle, vol_data, &vol_size, 1,
-                mWidth, mHeight, mode)) {
-            ALOGE("PVInitVideoDecoder failed. Unsupported content?");
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-        mInitialized = true;
-        MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
-        if (mode != actualMode) {
-            ALOGE("Decoded mode not same as actual mode of the decoder");
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-
-        PVSetPostProcType(mDecHandle, 0);
-        (void) handleResChange(work);
-        if (codecConfig) {
-            fillEmptyWork(work);
-            return;
-        }
-    }
-
-    size_t inPos = 0;
-    while (inPos < inSize) {
-        c2_status_t err = ensureDecoderState(pool);
-        if (C2_OK != err) {
-            mSignalledError = true;
-            work->result = err;
-            return;
-        }
-        C2GraphicView wView = mOutBlock->map().get();
-        if (wView.error()) {
-            ALOGE("graphic view map failed %d", wView.error());
-            work->result = C2_CORRUPTED;
-            return;
-        }
-
-        uint32_t outSize = align(mWidth, 16) * align(mHeight, 16) * 3 / 2;
-        uint32_t yFrameSize = sizeof(uint8) * mDecHandle->size;
-        if (outSize < yFrameSize * 3 / 2){
-            ALOGE("Too small output buffer: %d bytes", outSize);
-            work->result = C2_NO_MEMORY;
-            mSignalledError = true;
-            return;
-        }
-
-        if (!mFramesConfigured) {
-            PVSetReferenceYUV(mDecHandle,mOutputBuffer[1]);
-            mFramesConfigured = true;
-        }
-
-        // Need to check if header contains new info, e.g., width/height, etc.
-        VopHeaderInfo header_info;
-        uint32_t useExtTimestamp = (inPos == 0);
-        int32_t tmpInSize = (int32_t)inSize;
-        uint8_t *bitstreamTmp = bitstream;
-        uint32_t timestamp = workIndex;
-        if (PVDecodeVopHeader(
-                    mDecHandle, &bitstreamTmp, &timestamp, &tmpInSize,
-                    &header_info, &useExtTimestamp,
-                    mOutputBuffer[mNumSamplesOutput & 1]) != PV_TRUE) {
-            ALOGE("failed to decode vop header.");
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-
-        // H263 doesn't have VOL header, the frame size information is in short header, i.e. the
-        // decoder may detect size change after PVDecodeVopHeader.
-        bool resChange = handleResChange(work);
-        if (mIsMpeg4 && resChange) {
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        } else if (resChange) {
-            continue;
-        }
-
-        if (PVDecodeVopBody(mDecHandle, &tmpInSize) != PV_TRUE) {
-            ALOGE("failed to decode video frame.");
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-        if (handleResChange(work)) {
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-
-        uint8_t *outputBufferY = wView.data()[C2PlanarLayout::PLANE_Y];
-        (void)copyOutputBufferToYV12Frame(outputBufferY, mOutputBuffer[mNumSamplesOutput & 1],
-                                          wView.width(), align(mWidth, 16), mWidth, mHeight);
-
-        inPos += inSize - (size_t)tmpInSize;
-        finishWork(workIndex, work);
-        ++mNumSamplesOutput;
-        if (inSize - inPos != 0) {
-            ALOGD("decoded frame, ignoring further trailing bytes %d",
-                  (int)inSize - (int)inPos);
-            break;
-        }
-    }
-}
-
-c2_status_t C2SoftMpeg4Dec::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-    return C2_OK;
-}
-
-class C2SoftMpeg4DecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftMpeg4Dec(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftMpeg4DecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftMpeg4DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.h b/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.h
deleted file mode 100644
index 8eb316e..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 C2_SOFT_MPEG4_DEC_H_
-#define C2_SOFT_MPEG4_DEC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-struct tagvideoDecControls;
-
-namespace android {
-
-struct C2SoftMpeg4Dec : public SimpleC2Component {
-    C2SoftMpeg4Dec(const char *name, c2_node_id_t id);
-    virtual ~C2SoftMpeg4Dec();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
- private:
-    enum {
-        kNumOutputBuffers = 2,
-    };
-
-    status_t initDecoder();
-    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
-    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
-    bool handleResChange(const std::unique_ptr<C2Work> &work);
-
-    tagvideoDecControls *mDecHandle;
-    std::shared_ptr<C2GraphicBlock> mOutBlock;
-    uint8_t *mOutputBuffer[kNumOutputBuffers];
-
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mNumSamplesOutput;
-
-    bool mIsMpeg4;
-    bool mInitialized;
-    bool mFramesConfigured;
-    bool mSignalledOutputEos;
-    bool mSignalledError;
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftMpeg4Dec);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_MPEG4_DEC_H_
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 9e41d17..9fa9a4c 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -65,8 +65,11 @@
     },
 
     include_dirs: ["frameworks/av/media/libstagefright/include"],
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
+
+    export_include_dirs: [
+        "include",
+        "src",
+    ],
 
     cflags: [
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
@@ -119,50 +122,6 @@
     compile_multilib: "32",
 }
 
-cc_library_shared {
-    name: "libstagefright_soft_c2mp3dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftMP3.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    local_include_dirs: [
-        "src",
-        "include",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    static_libs: [
-        "libstagefright_mp3dec"
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-}
-
 //###############################################################################
 cc_test {
     name: "libstagefright_mp3dec_test",
diff --git a/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp
deleted file mode 100644
index 51b9656..0000000
--- a/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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 "C2SoftMP3"
-#include <utils/Log.h>
-
-#include "pvmp3decoder_api.h"
-
-#include "C2SoftMP3.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <numeric>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.mp3.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_MPEG)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftMP3::C2SoftMP3(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mConfig(nullptr),
-      mDecoderBuf(nullptr) {
-}
-
-C2SoftMP3::~C2SoftMP3() {
-    onRelease();
-}
-
-c2_status_t C2SoftMP3::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftMP3::onStop() {
-    // Make sure that the next buffer output does not still
-    // depend on fragments from the last one decoded.
-    pvmp3_InitDecoder(mConfig, mDecoderBuf);
-    mSignalledError = false;
-    mIsFirst = true;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-
-    return C2_OK;
-}
-
-void C2SoftMP3::onReset() {
-    (void)onStop();
-}
-
-void C2SoftMP3::onRelease() {
-    if (mDecoderBuf) {
-        free(mDecoderBuf);
-        mDecoderBuf = nullptr;
-    }
-
-    if (mConfig) {
-        delete mConfig;
-        mConfig = nullptr;
-    }
-}
-
-status_t C2SoftMP3::initDecoder() {
-    mConfig = new tPVMP3DecoderExternal{};
-    if (!mConfig) return NO_MEMORY;
-    mConfig->equalizerType = flat;
-    mConfig->crcEnabled = false;
-
-    size_t memRequirements = pvmp3_decoderMemRequirements();
-    mDecoderBuf = malloc(memRequirements);
-    if (!mDecoderBuf) return NO_MEMORY;
-
-    pvmp3_InitDecoder(mConfig, mDecoderBuf);
-
-    mNumChannels = 2;
-    mSamplingRate = 44100;
-    mIsFirst = true;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    mAnchorTimeStamp = 0;
-    mProcessedSamples = 0;
-
-    return OK;
-}
-
-/* The below code is borrowed from ./test/mp3reader.cpp */
-static bool parseMp3Header(uint32_t header, size_t *frame_size,
-                           uint32_t *out_sampling_rate = nullptr,
-                           uint32_t *out_channels = nullptr,
-                           uint32_t *out_bitrate = nullptr,
-                           uint32_t *out_num_samples = nullptr) {
-    *frame_size = 0;
-    if (out_sampling_rate) *out_sampling_rate = 0;
-    if (out_channels) *out_channels = 0;
-    if (out_bitrate) *out_bitrate = 0;
-    if (out_num_samples) *out_num_samples = 1152;
-
-    if ((header & 0xffe00000) != 0xffe00000) return false;
-
-    unsigned version = (header >> 19) & 3;
-    if (version == 0x01) return false;
-
-    unsigned layer = (header >> 17) & 3;
-    if (layer == 0x00) return false;
-
-    unsigned bitrate_index = (header >> 12) & 0x0f;
-    if (bitrate_index == 0 || bitrate_index == 0x0f) return false;
-
-    unsigned sampling_rate_index = (header >> 10) & 3;
-    if (sampling_rate_index == 3) return false;
-
-    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
-    int sampling_rate = kSamplingRateV1[sampling_rate_index];
-    if (version == 2 /* V2 */) {
-        sampling_rate /= 2;
-    } else if (version == 0 /* V2.5 */) {
-        sampling_rate /= 4;
-    }
-
-    unsigned padding = (header >> 9) & 1;
-
-    if (layer == 3) { // layer I
-        static const int kBitrateV1[] =
-        {
-            32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
-        };
-        static const int kBitrateV2[] =
-        {
-            32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
-        };
-
-        int bitrate = (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] :
-                kBitrateV2[bitrate_index - 1];
-
-        if (out_bitrate) {
-            *out_bitrate = bitrate;
-        }
-        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
-        if (out_num_samples) {
-            *out_num_samples = 384;
-        }
-    } else { // layer II or III
-        static const int kBitrateV1L2[] =
-        {
-            32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
-        };
-
-        static const int kBitrateV1L3[] =
-        {
-            32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
-        };
-
-        static const int kBitrateV2[] =
-        {
-            8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
-        };
-
-        int bitrate;
-        if (version == 3 /* V1 */) {
-            bitrate = (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] :
-                    kBitrateV1L3[bitrate_index - 1];
-
-            if (out_num_samples) {
-                *out_num_samples = 1152;
-            }
-        } else { // V2 (or 2.5)
-            bitrate = kBitrateV2[bitrate_index - 1];
-            if (out_num_samples) {
-                *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
-            }
-        }
-
-        if (out_bitrate) {
-            *out_bitrate = bitrate;
-        }
-
-        if (version == 3 /* V1 */) {
-            *frame_size = 144000 * bitrate / sampling_rate + padding;
-        } else { // V2 or V2.5
-            size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
-            *frame_size = tmp * bitrate / sampling_rate + padding;
-        }
-    }
-
-    if (out_sampling_rate) {
-        *out_sampling_rate = sampling_rate;
-    }
-
-    if (out_channels) {
-        int channel_mode = (header >> 6) & 3;
-
-        *out_channels = (channel_mode == 3) ? 1 : 2;
-    }
-
-    return true;
-}
-
-static uint32_t U32_AT(const uint8_t *ptr) {
-    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
-}
-
-static status_t calculateOutSize(uint8 *header, size_t inSize,
-                                 std::vector<size_t> *decodedSizes) {
-    uint32_t channels;
-    uint32_t numSamples;
-    size_t frameSize;
-    size_t totalInSize = 0;
-
-    while (totalInSize + 4 < inSize) {
-        if (!parseMp3Header(U32_AT(header + totalInSize), &frameSize,
-                            nullptr, &channels, nullptr, &numSamples)) {
-            ALOGE("Error in parse mp3 header during outSize estimation");
-            return UNKNOWN_ERROR;
-        }
-        totalInSize += frameSize;
-        decodedSizes->push_back(numSamples * channels * sizeof(int16_t));
-    }
-
-    if (decodedSizes->empty()) return UNKNOWN_ERROR;
-
-    return OK;
-}
-
-c2_status_t C2SoftMP3::onFlush_sm() {
-    return onStop();
-}
-
-c2_status_t C2SoftMP3::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-// TODO: Can overall error checking be improved? As in the check for validity of
-//       work, pool ptr, work->input.buffers.size() == 1, ...
-// TODO: Blind removal of 529 samples from the output may not work. Because
-//       mpeg layer 1 frame size is 384 samples per frame. This should introduce
-//       negative values and can cause SEG faults. Soft omx mp3 plugin can have
-//       this problem (CHECK!)
-void C2SoftMP3::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-
-    if (inSize == 0) {
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    size_t calOutSize;
-    std::vector<size_t> decodedSizes;
-    const uint8_t *inPtr = rView.data() + inOffset;
-    if (OK != calculateOutSize(const_cast<uint8 *>(inPtr), inSize, &decodedSizes)) {
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    calOutSize = std::accumulate(decodedSizes.begin(), decodedSizes.end(), 0);
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = wView.error();
-        return;
-    }
-
-    int outSize = 0;
-    int outOffset = 0;
-    auto it = decodedSizes.begin();
-    size_t inPos = 0;
-    while (inPos < inSize) {
-        if (it == decodedSizes.end()) {
-            ALOGE("unexpected trailing bytes, ignoring them");
-            break;
-        }
-
-        mConfig->pInputBuffer = const_cast<uint8 *>(inPtr + inPos);
-        mConfig->inputBufferCurrentLength = (inSize - inPos);
-        mConfig->inputBufferMaxLength = 0;
-        mConfig->inputBufferUsedLength = 0;
-        mConfig->outputFrameSize = (calOutSize - outSize);
-        mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize);
-
-        ERROR_CODE decoderErr;
-        if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
-                != NO_DECODING_ERROR) {
-            ALOGE("mp3 decoder returned error %d", decoderErr);
-            if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
-                    && decoderErr != SIDE_INFO_ERROR) {
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-
-            // This is recoverable, just ignore the current frame and
-            // play silence instead.
-            ALOGV("ignoring error and sending silence");
-            if (mConfig->outputFrameSize == 0) {
-                mConfig->outputFrameSize = *it / sizeof(int16_t);
-            }
-            memset(mConfig->pOutputBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t));
-        } else if (mConfig->samplingRate != mSamplingRate
-                || mConfig->num_channels != mNumChannels) {
-            mSamplingRate = mConfig->samplingRate;
-            mNumChannels = mConfig->num_channels;
-        }
-        if (*it != mConfig->outputFrameSize * sizeof(int16_t)) {
-            ALOGE("panic, parsed size does not match decoded size");
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        outSize += mConfig->outputFrameSize * sizeof(int16_t);
-        inPos += mConfig->inputBufferUsedLength;
-        it++;
-    }
-    if (mIsFirst) {
-        mIsFirst = false;
-        // The decoder delay is 529 samples, so trim that many samples off
-        // the start of the first output buffer. This essentially makes this
-        // decoder have zero delay, which the rest of the pipeline assumes.
-        outOffset = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
-        mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
-    }
-    uint64_t outTimeStamp = mProcessedSamples * 1000000ll / mSamplingRate;
-    mProcessedSamples += ((outSize - outOffset) / (mNumChannels * sizeof(int16_t)));
-    ALOGV("out buffer attr. offset %d size %d timestamp %u", outOffset, outSize - outOffset,
-          (uint32_t)(mAnchorTimeStamp + outTimeStamp));
-    decodedSizes.clear();
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.buffers.push_back(
-            createLinearBuffer(block, outOffset, outSize - outOffset));
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-    work->workletsProcessed = 1u;
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-class C2SoftMp3DecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftMP3(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftMp3DecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftMp3DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
-
diff --git a/media/libstagefright/codecs/mp3dec/C2SoftMP3.h b/media/libstagefright/codecs/mp3dec/C2SoftMP3.h
deleted file mode 100644
index 6e9a571..0000000
--- a/media/libstagefright/codecs/mp3dec/C2SoftMP3.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 C2_SOFT_MP3_H_
-#define C2_SOFT_MP3_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-struct tPVMP3DecoderExternal;
-
-bool parseMp3Header(uint32_t header, size_t *frame_size,
-                    uint32_t *out_sampling_rate = nullptr,
-                    uint32_t *out_channels = nullptr,
-                    uint32_t *out_bitrate = nullptr,
-                    uint32_t *out_num_samples = nullptr);
-
-namespace android {
-
-struct C2SoftMP3 : public SimpleC2Component {
-    C2SoftMP3(const char *name, c2_node_id_t id);
-    virtual ~C2SoftMP3();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
-    enum {
-        kPVMP3DecoderDelay = 529 // samples
-    };
-
-    tPVMP3DecoderExternal *mConfig;
-    void *mDecoderBuf;
-
-    int32_t mNumChannels;
-    int32_t mSamplingRate;
-    bool mIsFirst;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-    uint64_t mAnchorTimeStamp;
-    uint64_t mProcessedSamples;
-
-    status_t initDecoder();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftMP3);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_MP3_H_
diff --git a/media/libstagefright/codecs/mpeg2dec/Android.bp b/media/libstagefright/codecs/mpeg2dec/Android.bp
index 3123376..fb0db8f 100644
--- a/media/libstagefright/codecs/mpeg2dec/Android.bp
+++ b/media/libstagefright/codecs/mpeg2dec/Android.bp
@@ -1,47 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2mpeg2dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftMpeg2Dec.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    include_dirs: [
-        "external/libmpeg2/decoder",
-        "external/libmpeg2/common",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: false, // true,
-        diag: {
-            cfi: false, // true,
-        },
-    },
-
-    static_libs: ["libmpeg2dec"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_mpeg2dec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp b/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp
deleted file mode 100644
index f8008aa..0000000
--- a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * 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 "C2SoftMpeg2Dec"
-#include <utils/Log.h>
-
-#include "iv_datatypedef.h"
-#include "iv.h"
-#include "ivd.h"
-#include "impeg2d.h"
-#include "C2SoftMpeg2Dec.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.mpeg2.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatVideo)
-            .inputMediaType(MEDIA_MIMETYPE_VIDEO_MPEG2)
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .build();
-}
-
-static size_t getCpuCoreCount() {
-    long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
-    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    // _SC_NPROC_ONLN must be defined...
-    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
-    CHECK(cpuCoreCount >= 1);
-    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
-    return (size_t)cpuCoreCount;
-}
-
-static void *ivd_aligned_malloc(WORD32 alignment, WORD32 size) {
-    return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *mem) {
-    free(mem);
-}
-
-C2SoftMpeg2Dec::C2SoftMpeg2Dec(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-            mDecHandle(nullptr),
-            mMemRecords(nullptr),
-            mOutBufferDrain(nullptr),
-            mIvColorformat(IV_YUV_420P),
-            mWidth(320),
-            mHeight(240) {
-    // If input dump is enabled, then open create an empty file
-    GENERATE_FILE_NAMES();
-    CREATE_DUMP_FILE(mInFile);
-}
-
-C2SoftMpeg2Dec::~C2SoftMpeg2Dec() {
-    onRelease();
-}
-
-c2_status_t C2SoftMpeg2Dec::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftMpeg2Dec::onStop() {
-    if (OK != resetDecoder()) return C2_CORRUPTED;
-    resetPlugin();
-    return C2_OK;
-}
-
-void C2SoftMpeg2Dec::onReset() {
-    (void) onStop();
-}
-
-void C2SoftMpeg2Dec::onRelease() {
-    (void) deleteDecoder();
-    if (mOutBufferDrain) {
-        ivd_aligned_free(mOutBufferDrain);
-        mOutBufferDrain = nullptr;
-    }
-    if (mOutBlock) {
-        mOutBlock.reset();
-    }
-    if (mMemRecords) {
-        ivd_aligned_free(mMemRecords);
-        mMemRecords = nullptr;
-    }
-}
-
-c2_status_t C2SoftMpeg2Dec::onFlush_sm() {
-    if (OK != setFlushMode()) return C2_CORRUPTED;
-
-    uint32_t displayStride = mStride;
-    uint32_t displayHeight = mHeight;
-    uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
-    mOutBufferDrain = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
-    if (!mOutBufferDrain) {
-        ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
-        return C2_NO_MEMORY;
-    }
-
-    while (true) {
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-
-        setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        if (0 == s_decode_op.u4_output_present) {
-            resetPlugin();
-            break;
-        }
-    }
-
-    ivd_aligned_free(mOutBufferDrain);
-    mOutBufferDrain = nullptr;
-
-    return C2_OK;
-}
-
-status_t C2SoftMpeg2Dec::getNumMemRecords() {
-    iv_num_mem_rec_ip_t s_num_mem_rec_ip;
-    iv_num_mem_rec_op_t s_num_mem_rec_op;
-
-    s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip);
-    s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
-    s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op);
-
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_num_mem_rec_ip,
-                                                     &s_num_mem_rec_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("Error in getting mem records: 0x%x", s_num_mem_rec_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::fillMemRecords() {
-    iv_mem_rec_t *ps_mem_rec = (iv_mem_rec_t *) ivd_aligned_malloc(
-            128, mNumMemRecords * sizeof(iv_mem_rec_t));
-    if (!ps_mem_rec) {
-        ALOGE("Allocation failure");
-        return NO_MEMORY;
-    }
-    memset(ps_mem_rec, 0, mNumMemRecords * sizeof(iv_mem_rec_t));
-    for (size_t i = 0; i < mNumMemRecords; i++)
-        ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
-    mMemRecords = ps_mem_rec;
-
-    ivdext_fill_mem_rec_ip_t s_fill_mem_ip;
-    ivdext_fill_mem_rec_op_t s_fill_mem_op;
-
-    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t);
-    s_fill_mem_ip.u4_share_disp_buf = 0;
-    s_fill_mem_ip.e_output_format = mIvColorformat;
-    s_fill_mem_ip.u4_deinterlace = 1;
-    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
-    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
-    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = mWidth;
-    s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = mHeight;
-    s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(ivdext_fill_mem_rec_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_fill_mem_ip,
-                                                     &s_fill_mem_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("Error in filling mem records: 0x%x",
-              s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    CHECK_EQ(mNumMemRecords, s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
-    for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
-        ps_mem_rec->pv_base = ivd_aligned_malloc(
-                ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
-        if (!ps_mem_rec->pv_base) {
-            ALOGE("Allocation failure for memory record #%zu of size %u",
-                  i, ps_mem_rec->u4_mem_size);
-            return NO_MEMORY;
-        }
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::createDecoder() {
-    ivdext_init_ip_t s_init_ip;
-    ivdext_init_op_t s_init_op;
-
-    s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
-    s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
-    s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
-    s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = mWidth;
-    s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
-    s_init_ip.u4_share_disp_buf = 0;
-    s_init_ip.u4_deinterlace = 1;
-    s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
-    s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorformat;
-    s_init_op.s_ivd_init_op_t.u4_size = sizeof(ivdext_init_op_t);
-
-    mDecHandle = (iv_obj_t *)mMemRecords[0].pv_base;
-    mDecHandle->pv_fxns = (void *)ivdec_api_function;
-    mDecHandle->u4_size = sizeof(iv_obj_t);
-
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_init_ip,
-                                                     &s_init_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__,
-              s_init_op.s_ivd_init_op_t.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::setNumCores() {
-    ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
-    ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
-
-    s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
-    s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
-    s_set_num_cores_ip.u4_num_cores = mNumCores;
-    s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_num_cores_ip,
-                                                     &s_set_num_cores_op);
-    if (status != IV_SUCCESS) {
-        ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::setParams(size_t stride) {
-    ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
-    ivd_ctl_set_config_op_t s_set_dyn_params_op;
-
-    s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
-    s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
-    s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
-    s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
-    s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
-    s_set_dyn_params_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
-    s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_dyn_params_ip,
-                                                     &s_set_dyn_params_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::getVersion() {
-    ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
-    ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
-    UWORD8 au1_buf[512];
-
-    s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
-    s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
-    s_get_versioninfo_ip.pv_version_buffer = au1_buf;
-    s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
-    s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_get_versioninfo_ip,
-                                                     &s_get_versioninfo_op);
-    if (status != IV_SUCCESS) {
-        ALOGD("error in %s: 0x%x", __func__,
-              s_get_versioninfo_op.u4_error_code);
-    } else {
-        ALOGV("ittiam decoder version number: %s",
-              (char *) s_get_versioninfo_ip.pv_version_buffer);
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::initDecoder() {
-    status_t ret = getNumMemRecords();
-    if (OK != ret) return ret;
-
-    ret = fillMemRecords();
-    if (OK != ret) return ret;
-
-    if (OK != createDecoder()) return UNKNOWN_ERROR;
-
-    mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
-    mStride = ALIGN64(mWidth);
-    mSignalledError = false;
-    mPreference = kPreferBitstream;
-    memset(&mDefaultColorAspects, 0, sizeof(ColorAspects));
-    memset(&mBitstreamColorAspects, 0, sizeof(ColorAspects));
-    memset(&mFinalColorAspects, 0, sizeof(ColorAspects));
-    mUpdateColorAspects = false;
-    resetPlugin();
-    (void) setNumCores();
-    if (OK != setParams(mStride)) return UNKNOWN_ERROR;
-    (void) getVersion();
-
-    return OK;
-}
-
-bool C2SoftMpeg2Dec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
-                                   ivd_video_decode_op_t *ps_decode_op,
-                                   C2ReadView *inBuffer,
-                                   C2GraphicView *outBuffer,
-                                   size_t inOffset,
-                                   size_t inSize,
-                                   uint32_t tsMarker) {
-    uint32_t displayStride = mStride;
-    uint32_t displayHeight = mHeight;
-    size_t lumaSize = displayStride * displayHeight;
-    size_t chromaSize = lumaSize >> 2;
-
-    ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
-    ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
-    if (inBuffer) {
-        ps_decode_ip->u4_ts = tsMarker;
-        ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
-        ps_decode_ip->u4_num_Bytes = inSize;
-    } else {
-        ps_decode_ip->u4_ts = 0;
-        ps_decode_ip->pv_stream_buffer = nullptr;
-        ps_decode_ip->u4_num_Bytes = 0;
-    }
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
-    ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
-    if (outBuffer) {
-        if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
-            ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
-                  outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
-            return false;
-        }
-        ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
-        ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
-        ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
-    } else {
-        ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferDrain;
-        ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferDrain + lumaSize;
-        ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferDrain + lumaSize + chromaSize;
-    }
-    ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
-    ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
-
-    return true;
-}
-
-bool C2SoftMpeg2Dec::colorAspectsDiffer(
-        const ColorAspects &a, const ColorAspects &b) {
-    if (a.mRange != b.mRange
-        || a.mPrimaries != b.mPrimaries
-        || a.mTransfer != b.mTransfer
-        || a.mMatrixCoeffs != b.mMatrixCoeffs) {
-        return true;
-    }
-    return false;
-}
-
-void C2SoftMpeg2Dec::updateFinalColorAspects(
-        const ColorAspects &otherAspects, const ColorAspects &preferredAspects) {
-    Mutex::Autolock autoLock(mColorAspectsLock);
-    ColorAspects newAspects;
-    newAspects.mRange = preferredAspects.mRange != ColorAspects::RangeUnspecified ?
-        preferredAspects.mRange : otherAspects.mRange;
-    newAspects.mPrimaries = preferredAspects.mPrimaries != ColorAspects::PrimariesUnspecified ?
-        preferredAspects.mPrimaries : otherAspects.mPrimaries;
-    newAspects.mTransfer = preferredAspects.mTransfer != ColorAspects::TransferUnspecified ?
-        preferredAspects.mTransfer : otherAspects.mTransfer;
-    newAspects.mMatrixCoeffs = preferredAspects.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
-        preferredAspects.mMatrixCoeffs : otherAspects.mMatrixCoeffs;
-
-    // Check to see if need update mFinalColorAspects.
-    if (colorAspectsDiffer(mFinalColorAspects, newAspects)) {
-        mFinalColorAspects = newAspects;
-        mUpdateColorAspects = true;
-    }
-}
-
-status_t C2SoftMpeg2Dec::handleColorAspectsChange() {
-    if (mPreference == kPreferBitstream) {
-        updateFinalColorAspects(mDefaultColorAspects, mBitstreamColorAspects);
-    } else if (mPreference == kPreferContainer) {
-        updateFinalColorAspects(mBitstreamColorAspects, mDefaultColorAspects);
-    } else {
-        return C2_CORRUPTED;
-    }
-    return C2_OK;
-}
-
-bool C2SoftMpeg2Dec::getSeqInfo() {
-    ivdext_ctl_get_seq_info_ip_t s_ctl_get_seq_info_ip;
-    ivdext_ctl_get_seq_info_op_t s_ctl_get_seq_info_op;
-
-    s_ctl_get_seq_info_ip.u4_size = sizeof(ivdext_ctl_get_seq_info_ip_t);
-    s_ctl_get_seq_info_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_ctl_get_seq_info_ip.e_sub_cmd =
-        (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_GET_SEQ_INFO;
-    s_ctl_get_seq_info_op.u4_size = sizeof(ivdext_ctl_get_seq_info_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_ctl_get_seq_info_ip,
-                                                     &s_ctl_get_seq_info_op);
-    if (status != IV_SUCCESS) {
-        ALOGW("Error in getting Sequence info: 0x%x", s_ctl_get_seq_info_op.u4_error_code);
-        return false;
-    }
-
-    int32_t primaries = s_ctl_get_seq_info_op.u1_colour_primaries;
-    int32_t transfer = s_ctl_get_seq_info_op.u1_transfer_characteristics;
-    int32_t coeffs = s_ctl_get_seq_info_op.u1_matrix_coefficients;
-    bool full_range =  false;  // mpeg2 video has limited range.
-
-    ColorAspects colorAspects;
-    ColorUtils::convertIsoColorAspectsToCodecAspects(
-            primaries, transfer, coeffs, full_range, colorAspects);
-    // Update color aspects if necessary.
-    if (colorAspectsDiffer(colorAspects, mBitstreamColorAspects)) {
-        mBitstreamColorAspects = colorAspects;
-        status_t err = handleColorAspectsChange();
-        CHECK(err == OK);
-    }
-
-    return true;
-}
-
-status_t C2SoftMpeg2Dec::setFlushMode() {
-    ivd_ctl_flush_ip_t s_set_flush_ip;
-    ivd_ctl_flush_op_t s_set_flush_op;
-
-    s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
-    s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
-    s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_set_flush_ip,
-                                                     &s_set_flush_op);
-    if (status != IV_SUCCESS) {
-        ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::resetDecoder() {
-    ivd_ctl_reset_ip_t s_reset_ip;
-    ivd_ctl_reset_op_t s_reset_op;
-
-    s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
-    s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-    s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
-    s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
-    IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
-                                                     &s_reset_ip,
-                                                     &s_reset_op);
-    if (IV_SUCCESS != status) {
-        ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
-        return UNKNOWN_ERROR;
-    }
-    (void) setNumCores();
-    mStride = 0;
-    mSignalledError = false;
-
-    return OK;
-}
-
-void C2SoftMpeg2Dec::resetPlugin() {
-    mSignalledOutputEos = false;
-    gettimeofday(&mTimeStart, nullptr);
-    gettimeofday(&mTimeEnd, nullptr);
-}
-
-status_t C2SoftMpeg2Dec::deleteDecoder() {
-    if (mMemRecords) {
-        iv_mem_rec_t *ps_mem_rec = mMemRecords;
-
-        for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
-            if (ps_mem_rec->pv_base) {
-                ivd_aligned_free(ps_mem_rec->pv_base);
-            }
-        }
-        ivd_aligned_free(mMemRecords);
-        mMemRecords = nullptr;
-    }
-    mDecHandle = nullptr;
-
-    return OK;
-}
-
-status_t C2SoftMpeg2Dec::reInitDecoder() {
-    deleteDecoder();
-
-    status_t ret = initDecoder();
-    if (OK != ret) {
-        ALOGE("Failed to initialize decoder");
-        deleteDecoder();
-        return ret;
-    }
-    return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    uint32_t flags = 0;
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("signalling eos");
-    }
-    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftMpeg2Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
-                                                           C2Rect(mWidth, mHeight));
-    mOutBlock = nullptr;
-    auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
-        uint32_t flags = 0;
-        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
-                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
-            ALOGV("signalling eos");
-        }
-        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    };
-    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
-        fillWork(work);
-    } else {
-        finish(index, fillWork);
-    }
-}
-
-c2_status_t C2SoftMpeg2Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
-    if (!mDecHandle) {
-        ALOGE("not supposed to be here, invalid decoder context");
-        return C2_CORRUPTED;
-    }
-    if (mStride != ALIGN64(mWidth)) {
-        mStride = ALIGN64(mWidth);
-        if (OK != setParams(mStride)) return C2_CORRUPTED;
-    }
-    if (mOutBlock &&
-            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
-        mOutBlock.reset();
-    }
-    if (!mOutBlock) {
-        uint32_t format = HAL_PIXEL_FORMAT_YV12;
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
-        if (err != C2_OK) {
-            ALOGE("fetchGraphicBlock for Output failed with status %d", err);
-            return err;
-        }
-        ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
-    }
-
-    return C2_OK;
-}
-
-// TODO: can overall error checking be improved?
-// TODO: allow configuration of color format and usage for graphic buffers instead
-//       of hard coding them to HAL_PIXEL_FORMAT_YV12
-// TODO: pass coloraspects information to surface
-// TODO: test support for dynamic change in resolution
-// TODO: verify if the decoder sent back all frames
-void C2SoftMpeg2Dec::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    bool hasPicture = false;
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-    size_t inPos = 0;
-    while (inPos < inSize) {
-        if (C2_OK != ensureDecoderState(pool)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        C2GraphicView wView = mOutBlock->map().get();
-        if (wView.error()) {
-            ALOGE("graphic view map failed %d", wView.error());
-            work->result = C2_CORRUPTED;
-            return;
-        }
-
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
-                           inOffset + inPos, inSize - inPos, workIndex)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-        // If input dump is enabled, then write to file
-        DUMP_TO_FILE(mInFile, s_decode_ip.pv_stream_buffer, s_decode_ip.u4_num_Bytes);
-        WORD32 delay;
-        GETTIME(&mTimeStart, NULL);
-        TIME_DIFF(mTimeEnd, mTimeStart, delay);
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        WORD32 decodeTime;
-        GETTIME(&mTimeEnd, nullptr);
-        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
-        ALOGV("decodeTime=%6d delay=%6d numBytes=%6d ", decodeTime, delay,
-              s_decode_op.u4_num_bytes_consumed);
-        if (IMPEG2D_UNSUPPORTED_DIMENSIONS == s_decode_op.u4_error_code) {
-            ALOGV("unsupported resolution : %dx%d", s_decode_op.u4_pic_wd, s_decode_op.u4_pic_ht);
-            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
-            resetPlugin();
-            mWidth = s_decode_op.u4_pic_wd;
-            mHeight = s_decode_op.u4_pic_ht;
-            if (OK != reInitDecoder()) {
-                ALOGE("Failed to reinitialize decoder");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            continue;
-        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
-            ALOGV("resolution changed");
-            drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
-            resetDecoder();
-            resetPlugin();
-            mWidth = s_decode_op.u4_pic_wd;
-            mHeight = s_decode_op.u4_pic_ht;
-            continue;
-        }
-
-        (void) getSeqInfo();
-        if (mUpdateColorAspects) {
-            mUpdateColorAspects = false;
-        }
-        hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
-        if (s_decode_op.u4_output_present) {
-            finishWork(s_decode_op.u4_ts, work);
-        }
-        inPos += s_decode_op.u4_num_bytes_consumed;
-        if (hasPicture && (inSize - inPos) != 0) {
-            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
-                  (int)inSize - (int)inPos);
-            break;
-        }
-    }
-
-    if (eos) {
-        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
-        mSignalledOutputEos = true;
-    } else if (!hasPicture) {
-        fillEmptyWork(work);
-    }
-}
-
-c2_status_t C2SoftMpeg2Dec::drainInternal(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work) {
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    if (OK != setFlushMode()) return C2_CORRUPTED;
-    while (true) {
-        if (C2_OK != ensureDecoderState(pool)) {
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return C2_CORRUPTED;
-        }
-        C2GraphicView wView = mOutBlock->map().get();
-        if (wView.error()) {
-            ALOGE("graphic view map failed %d", wView.error());
-            return C2_CORRUPTED;
-        }
-        ivd_video_decode_ip_t s_decode_ip;
-        ivd_video_decode_op_t s_decode_op;
-        if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
-            mSignalledError = true;
-            return C2_CORRUPTED;
-        }
-        (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
-        if (s_decode_op.u4_output_present) {
-            finishWork(s_decode_op.u4_ts, work);
-        } else {
-            break;
-        }
-    }
-    if (drainMode == DRAIN_COMPONENT_WITH_EOS &&
-            work && work->workletsProcessed == 0u) {
-        fillEmptyWork(work);
-    }
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftMpeg2Dec::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftMpeg2DecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftMpeg2Dec(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftMpeg2DecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftMpeg2DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.h b/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.h
deleted file mode 100644
index 64e5b05..0000000
--- a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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 C2_SOFT_MPEG2_DEC_H_
-#define C2_SOFT_MPEG2_DEC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/ColorUtils.h>
-
-namespace android {
-
-#define ivdec_api_function              impeg2d_api_function
-#define ivdext_init_ip_t                impeg2d_init_ip_t
-#define ivdext_init_op_t                impeg2d_init_op_t
-#define ivdext_fill_mem_rec_ip_t        impeg2d_fill_mem_rec_ip_t
-#define ivdext_fill_mem_rec_op_t        impeg2d_fill_mem_rec_op_t
-#define ivdext_ctl_set_num_cores_ip_t   impeg2d_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t   impeg2d_ctl_set_num_cores_op_t
-#define ivdext_ctl_get_seq_info_ip_t    impeg2d_ctl_get_seq_info_ip_t
-#define ivdext_ctl_get_seq_info_op_t    impeg2d_ctl_get_seq_info_op_t
-#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
-#define MAX_NUM_CORES                   4
-#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
-        (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
-#define MIN(a, b)                       (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b)                   gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff)     \
-    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
-            ((end).tv_usec - (start).tv_usec);
-
-#ifdef FILE_DUMP_ENABLE
-    #define INPUT_DUMP_PATH     "/sdcard/clips/mpeg2d_input"
-    #define INPUT_DUMP_EXT      "m2v"
-    #define GENERATE_FILE_NAMES() {                         \
-        GETTIME(&mTimeStart, NULL);                         \
-        strcpy(mInFile, "");                                \
-        sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
-                mTimeStart.tv_sec, mTimeStart.tv_usec,      \
-                INPUT_DUMP_EXT);                            \
-    }
-    #define CREATE_DUMP_FILE(m_filename) {                  \
-        FILE *fp = fopen(m_filename, "wb");                 \
-        if (fp != NULL) {                                   \
-            fclose(fp);                                     \
-        } else {                                            \
-            ALOGD("Could not open file %s", m_filename);    \
-        }                                                   \
-    }
-    #define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
-    {                                                       \
-        FILE *fp = fopen(m_filename, "ab");                 \
-        if (fp != NULL && m_buf != NULL) {                  \
-            uint32_t i;                                     \
-            i = fwrite(m_buf, 1, m_size, fp);               \
-            ALOGD("fwrite ret %d to write %d", i, m_size);  \
-            if (i != (uint32_t)m_size) {                    \
-                ALOGD("Error in fwrite, returned %d", i);   \
-                perror("Error in write to file");           \
-            }                                               \
-            fclose(fp);                                     \
-        } else {                                            \
-            ALOGD("Could not write to file %s", m_filename);\
-        }                                                   \
-    }
-#else /* FILE_DUMP_ENABLE */
-    #define INPUT_DUMP_PATH
-    #define INPUT_DUMP_EXT
-    #define OUTPUT_DUMP_PATH
-    #define OUTPUT_DUMP_EXT
-    #define GENERATE_FILE_NAMES()
-    #define CREATE_DUMP_FILE(m_filename)
-    #define DUMP_TO_FILE(m_filename, m_buf, m_size)
-#endif /* FILE_DUMP_ENABLE */
-
-struct C2SoftMpeg2Dec : public SimpleC2Component {
-    C2SoftMpeg2Dec(const char *name, c2_node_id_t id);
-    virtual ~C2SoftMpeg2Dec();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
- private:
-    status_t getNumMemRecords();
-    status_t fillMemRecords();
-    status_t createDecoder();
-    status_t setNumCores();
-    status_t setParams(size_t stride);
-    status_t getVersion();
-    status_t initDecoder();
-    bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
-                       ivd_video_decode_op_t *ps_decode_op,
-                       C2ReadView *inBuffer,
-                       C2GraphicView *outBuffer,
-                       size_t inOffset,
-                       size_t inSize,
-                       uint32_t tsMarker);
-    bool getSeqInfo();
-    // TODO:This is not the right place for colorAspects functions. These should
-    // be part of c2-vndk so that they can be accessed by all video plugins
-    // until then, make them feel at home
-    bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
-    void updateFinalColorAspects(
-            const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
-    status_t handleColorAspectsChange();
-    c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
-    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
-    status_t setFlushMode();
-    c2_status_t drainInternal(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-    status_t resetDecoder();
-    void resetPlugin();
-    status_t deleteDecoder();
-    status_t reInitDecoder();
-
-    // TODO:This is not the right place for this enum. These should
-    // be part of c2-vndk so that they can be accessed by all video plugins
-    // until then, make them feel at home
-    enum {
-        kNotSupported,
-        kPreferBitstream,
-        kPreferContainer,
-    };
-
-    iv_obj_t *mDecHandle;
-    iv_mem_rec_t *mMemRecords;
-    size_t mNumMemRecords;
-    std::shared_ptr<C2GraphicBlock> mOutBlock;
-    uint8_t *mOutBufferDrain;
-
-    size_t mNumCores;
-    IV_COLOR_FORMAT_T mIvColorformat;
-
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mStride;
-    bool mSignalledOutputEos;
-    bool mSignalledError;
-
-    // ColorAspects
-    Mutex mColorAspectsLock;
-    int mPreference;
-    ColorAspects mDefaultColorAspects;
-    ColorAspects mBitstreamColorAspects;
-    ColorAspects mFinalColorAspects;
-    bool mUpdateColorAspects;
-
-    // profile
-    struct timeval mTimeStart;
-    struct timeval mTimeEnd;
-#ifdef FILE_DUMP_ENABLE
-    char mInFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftMpeg2Dec);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_MPEG2_DEC_H_
diff --git a/media/libstagefright/codecs/on2/dec/Android.bp b/media/libstagefright/codecs/on2/dec/Android.bp
index 03f0c05..8a9399a 100644
--- a/media/libstagefright/codecs/on2/dec/Android.bp
+++ b/media/libstagefright/codecs/on2/dec/Android.bp
@@ -37,82 +37,3 @@
     },
     compile_multilib: "32",
 }
-
-cc_library_shared {
-    name: "libstagefright_soft_c2vp9dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftVpx.cpp"],
-
-    static_libs: ["libvpx"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    cflags: [
-        "-DVP9",
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-cc_library_shared {
-    name: "libstagefright_soft_c2vp8dec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftVpx.cpp"],
-
-    static_libs: ["libvpx"],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
diff --git a/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp b/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp
deleted file mode 100644
index 8528f26..0000000
--- a/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * 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 "C2SoftVpx"
-#include <utils/Log.h>
-
-#include "C2SoftVpx.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-#ifdef VP9
-constexpr char kComponentName[] = "c2.google.vp9.decoder";
-#else
-constexpr char kComponentName[] = "c2.google.vp8.decoder";
-#endif
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatVideo)
-            .inputMediaType(
-#ifdef VP9
-                    MEDIA_MIMETYPE_VIDEO_VP9
-#else
-                    MEDIA_MIMETYPE_VIDEO_VP8
-#endif
-            )
-            .outputMediaType(MEDIA_MIMETYPE_VIDEO_RAW)
-            .build();
-}
-
-C2SoftVpx::C2SoftVpx(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mCodecCtx(nullptr) {
-}
-
-C2SoftVpx::~C2SoftVpx() {
-    onRelease();
-}
-
-c2_status_t C2SoftVpx::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftVpx::onStop() {
-    (void) onFlush_sm();
-    destroyDecoder();
-
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return C2_OK;
-}
-
-void C2SoftVpx::onReset() {
-    (void) onStop();
-    (void) initDecoder();
-}
-
-void C2SoftVpx::onRelease() {
-    destroyDecoder();
-}
-
-c2_status_t C2SoftVpx::onFlush_sm() {
-    if (mFrameParallelMode) {
-        // Flush decoder by passing nullptr data ptr and 0 size.
-        // Ideally, this should never fail.
-        if (vpx_codec_decode(mCodecCtx, nullptr, 0, nullptr, 0)) {
-            ALOGE("Failed to flush on2 decoder.");
-            return C2_CORRUPTED;
-        }
-    }
-
-    // Drop all the decoded frames in decoder.
-    vpx_codec_iter_t iter = nullptr;
-    while (vpx_codec_get_frame(mCodecCtx, &iter)) {
-    }
-
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-    return C2_OK;
-}
-
-static int GetCPUCoreCount() {
-    int cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
-    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    // _SC_NPROC_ONLN must be defined...
-    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
-    CHECK(cpuCoreCount >= 1);
-    ALOGV("Number of CPU cores: %d", cpuCoreCount);
-    return cpuCoreCount;
-}
-
-status_t C2SoftVpx::initDecoder() {
-#ifdef VP9
-    mMode = MODE_VP9;
-#else
-    mMode = MODE_VP8;
-#endif
-
-    mWidth = 320;
-    mHeight = 240;
-    mFrameParallelMode = false;
-    mSignalledOutputEos = false;
-    mSignalledError = false;
-
-    mCodecCtx = new vpx_codec_ctx_t;
-
-    vpx_codec_dec_cfg_t cfg;
-    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
-    cfg.threads = GetCPUCoreCount();
-
-    vpx_codec_flags_t flags;
-    memset(&flags, 0, sizeof(vpx_codec_flags_t));
-    if (mFrameParallelMode) flags |= VPX_CODEC_USE_FRAME_THREADING;
-
-    vpx_codec_err_t vpx_err;
-    if ((vpx_err = vpx_codec_dec_init(
-                 mCodecCtx, mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo,
-                 &cfg, flags))) {
-        ALOGE("on2 decoder failed to initialize. (%d)", vpx_err);
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2SoftVpx::destroyDecoder() {
-    if  (mCodecCtx) {
-        vpx_codec_destroy(mCodecCtx);
-        delete mCodecCtx;
-        mCodecCtx = nullptr;
-    }
-
-    return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    uint32_t flags = 0;
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("signalling eos");
-    }
-    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-void C2SoftVpx::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
-                           const std::shared_ptr<C2GraphicBlock> &block) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block,
-                                                           C2Rect(mWidth, mHeight));
-    auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
-        uint32_t flags = 0;
-        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
-                (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
-            ALOGV("signalling eos");
-        }
-        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(buffer);
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    };
-    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
-        fillWork(work);
-    } else {
-        finish(index, fillWork);
-    }
-}
-
-void C2SoftVpx::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) !=0);
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
-          inSize, (int)work->input.ordinal.timestamp.peeku(),
-          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
-    // Software VP9 Decoder does not need the Codec Specific Data (CSD)
-    // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
-    // it was passed.
-    if (codecConfig) {
-        // Ignore CSD buffer for VP9.
-        if (mMode == MODE_VP9) {
-            fillEmptyWork(work);
-            return;
-        } else {
-            // Tolerate the CSD buffer for VP8. This is a workaround
-            // for b/28689536. continue
-            ALOGW("WARNING: Got CSD buffer for VP8. Continue");
-        }
-    }
-
-    uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
-    int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
-
-    if (inSize) {
-        vpx_codec_err_t err = vpx_codec_decode(
-                mCodecCtx, bitstream, inSize, &frameIndex, 0);
-        if (err != VPX_CODEC_OK) {
-            ALOGE("on2 decoder failed to decode frame. err: %d", err);
-            work->result = C2_CORRUPTED;
-            mSignalledError = true;
-            return;
-        }
-    }
-
-    (void)outputBuffer(pool, work);
-
-    if (eos) {
-        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
-        mSignalledOutputEos = true;
-    } else if (!inSize) {
-        fillEmptyWork(work);
-    }
-}
-
-static void copyOutputBufferToYV12Frame(uint8_t *dst,
-        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
-        size_t srcYStride, size_t srcUStride, size_t srcVStride,
-        uint32_t width, uint32_t height, int32_t bpp) {
-    size_t dstYStride = align(width, 16) * bpp ;
-    size_t dstUVStride = align(dstYStride / 2, 16);
-    uint8_t *dstStart = dst;
-
-    for (size_t i = 0; i < height; ++i) {
-         memcpy(dst, srcY, width * bpp);
-         srcY += srcYStride;
-         dst += dstYStride;
-    }
-
-    dst = dstStart + dstYStride * height;
-    for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcV, width / 2 * bpp);
-         srcV += srcVStride;
-         dst += dstUVStride;
-    }
-
-    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
-    for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcU, width / 2 * bpp);
-         srcU += srcUStride;
-         dst += dstUVStride;
-    }
-}
-
-bool C2SoftVpx::outputBuffer(
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work)
-{
-    if (!(work && pool)) return false;
-
-    vpx_codec_iter_t iter = nullptr;
-    vpx_image_t *img = vpx_codec_get_frame(mCodecCtx, &iter);
-
-    if (!img) return false;
-
-    mWidth = img->d_w;
-    mHeight = img->d_h;
-
-    CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
-    int32_t bpp = 1;
-    if (img->fmt == VPX_IMG_FMT_I42016) {
-        bpp = 2;
-    }
-
-    std::shared_ptr<C2GraphicBlock> block;
-    uint32_t format = HAL_PIXEL_FORMAT_YV12;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16) * bpp, mHeight, format, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchGraphicBlock for Output failed with status %d", err);
-        work->result = err;
-        return false;
-    }
-
-    C2GraphicView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("graphic view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return false;
-    }
-
-    ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d",
-           block->width(), block->height(), mWidth, mHeight, (int)*(int64_t *)img->user_priv);
-
-    uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
-    size_t srcYStride = img->stride[VPX_PLANE_Y];
-    size_t srcUStride = img->stride[VPX_PLANE_U];
-    size_t srcVStride = img->stride[VPX_PLANE_V];
-    const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
-    const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
-    const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
-    copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV,
-                                srcYStride, srcUStride, srcVStride, mWidth, mHeight, bpp);
-
-    finishWork(*(int64_t *)img->user_priv, work, std::move(block));
-    return true;
-}
-
-c2_status_t C2SoftVpx::drainInternal(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool,
-        const std::unique_ptr<C2Work> &work) {
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    while ((outputBuffer(pool, work))) {
-    }
-
-    if (drainMode == DRAIN_COMPONENT_WITH_EOS &&
-            work && work->workletsProcessed == 0u) {
-        fillEmptyWork(work);
-    }
-
-    return C2_OK;
-}
-c2_status_t C2SoftVpx::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftVpxFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftVpx(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftVpxFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftVpxFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/on2/dec/C2SoftVpx.h b/media/libstagefright/codecs/on2/dec/C2SoftVpx.h
deleted file mode 100644
index b5d4e21..0000000
--- a/media/libstagefright/codecs/on2/dec/C2SoftVpx.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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 C2_SOFT_VPX_H_
-#define C2_SOFT_VPX_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-#include "vpx/vpx_decoder.h"
-#include "vpx/vp8dx.h"
-
-namespace android {
-
-struct C2SoftVpx : public SimpleC2Component {
-    C2SoftVpx(const char *name, c2_node_id_t id);
-    virtual ~C2SoftVpx();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
- private:
-    enum {
-        MODE_VP8,
-        MODE_VP9,
-    } mMode;
-
-    vpx_codec_ctx_t *mCodecCtx;
-    bool mFrameParallelMode;  // Frame parallel is only supported by VP9 decoder.
-
-    uint32_t mWidth;
-    uint32_t mHeight;
-    bool mSignalledOutputEos;
-    bool mSignalledError;
-
-    status_t initDecoder();
-    status_t destroyDecoder();
-    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
-                    const std::shared_ptr<C2GraphicBlock> &block);
-    bool outputBuffer(
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-    c2_status_t drainInternal(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool,
-            const std::unique_ptr<C2Work> &work);
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftVpx);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_VPX_H_
diff --git a/media/libstagefright/codecs/opus/dec/Android.bp b/media/libstagefright/codecs/opus/dec/Android.bp
index 38d72e6..43318f2 100644
--- a/media/libstagefright/codecs/opus/dec/Android.bp
+++ b/media/libstagefright/codecs/opus/dec/Android.bp
@@ -1,40 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2opusdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftOpus.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libopus",
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_opusdec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp
deleted file mode 100644
index 47fb6de..0000000
--- a/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * 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 "C2SoftOpus"
-#include <utils/Log.h>
-
-#include "C2SoftOpus.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-extern "C" {
-    #include <opus.h>
-    #include <opus_multistream.h>
-}
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.opus.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_OPUS)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftOpus::C2SoftOpus(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mDecoder(nullptr) {
-}
-
-C2SoftOpus::~C2SoftOpus() {
-    onRelease();
-}
-
-c2_status_t C2SoftOpus::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftOpus::onStop() {
-    if (mDecoder) {
-        opus_multistream_decoder_destroy(mDecoder);
-        mDecoder = nullptr;
-    }
-    memset(&mHeader, 0, sizeof(mHeader));
-    mCodecDelay = 0;
-    mSeekPreRoll = 0;
-    mSamplesToDiscard = 0;
-    mInputBufferCount = 0;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return C2_OK;
-}
-
-void C2SoftOpus::onReset() {
-    (void)onStop();
-}
-
-void C2SoftOpus::onRelease() {
-    if (mDecoder) {
-        opus_multistream_decoder_destroy(mDecoder);
-        mDecoder = nullptr;
-    }
-}
-
-status_t C2SoftOpus::initDecoder() {
-    memset(&mHeader, 0, sizeof(mHeader));
-    mCodecDelay = 0;
-    mSeekPreRoll = 0;
-    mSamplesToDiscard = 0;
-    mInputBufferCount = 0;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return OK;
-}
-
-c2_status_t C2SoftOpus::onFlush_sm() {
-    if (mDecoder) {
-        opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
-        mSamplesToDiscard = mSeekPreRoll;
-        mSignalledOutputEos = false;
-    }
-    return C2_OK;
-}
-
-c2_status_t C2SoftOpus::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-static uint16_t ReadLE16(const uint8_t *data, size_t data_size,
-                         uint32_t read_offset) {
-    if (read_offset + 1 > data_size)
-        return 0;
-    uint16_t val;
-    val = data[read_offset];
-    val |= data[read_offset + 1] << 8;
-    return val;
-}
-
-static const int kRate = 48000;
-
-// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
-// mappings for up to 8 channels. This information is part of the Vorbis I
-// Specification:
-// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
-static const int kMaxChannels = 8;
-
-// Maximum packet size used in Xiph's opusdec.
-static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
-
-// Default audio output channel layout. Used to initialize |stream_map| in
-// OpusHeader, and passed to opus_multistream_decoder_create() when the header
-// does not contain mapping information. The values are valid only for mono and
-// stereo output: Opus streams with more than 2 channels require a stream map.
-static const int kMaxChannelsWithDefaultLayout = 2;
-static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
-
-// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
-static bool ParseOpusHeader(const uint8_t *data, size_t data_size,
-                            OpusHeader* header) {
-    // Size of the Opus header excluding optional mapping information.
-    const size_t kOpusHeaderSize = 19;
-
-    // Offset to the channel count byte in the Opus header.
-    const size_t kOpusHeaderChannelsOffset = 9;
-
-    // Offset to the pre-skip value in the Opus header.
-    const size_t kOpusHeaderSkipSamplesOffset = 10;
-
-    // Offset to the gain value in the Opus header.
-    const size_t kOpusHeaderGainOffset = 16;
-
-    // Offset to the channel mapping byte in the Opus header.
-    const size_t kOpusHeaderChannelMappingOffset = 18;
-
-    // Opus Header contains a stream map. The mapping values are in the header
-    // beyond the always present |kOpusHeaderSize| bytes of data. The mapping
-    // data contains stream count, coupling information, and per channel mapping
-    // values:
-    //   - Byte 0: Number of streams.
-    //   - Byte 1: Number coupled.
-    //   - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
-    //             values.
-    const size_t kOpusHeaderNumStreamsOffset = kOpusHeaderSize;
-    const size_t kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1;
-    const size_t kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2;
-
-    if (data_size < kOpusHeaderSize) {
-        ALOGE("Header size is too small.");
-        return false;
-    }
-    header->channels = *(data + kOpusHeaderChannelsOffset);
-    if (header->channels <= 0 || header->channels > kMaxChannels) {
-        ALOGE("Invalid Header, wrong channel count: %d", header->channels);
-        return false;
-    }
-
-    header->skip_samples = ReadLE16(data,
-                                    data_size,
-                                    kOpusHeaderSkipSamplesOffset);
-
-    header->gain_db = static_cast<int16_t>(ReadLE16(data,
-                                                    data_size,
-                                                    kOpusHeaderGainOffset));
-
-    header->channel_mapping = *(data + kOpusHeaderChannelMappingOffset);
-    if (!header->channel_mapping) {
-        if (header->channels > kMaxChannelsWithDefaultLayout) {
-            ALOGE("Invalid Header, missing stream map.");
-            return false;
-        }
-        header->num_streams = 1;
-        header->num_coupled = header->channels > 1;
-        header->stream_map[0] = 0;
-        header->stream_map[1] = 1;
-        return true;
-    }
-    if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
-        ALOGE("Invalid stream map; insufficient data for current channel "
-              "count: %d", header->channels);
-        return false;
-    }
-    header->num_streams = *(data + kOpusHeaderNumStreamsOffset);
-    header->num_coupled = *(data + kOpusHeaderNumCoupledOffset);
-    if (header->num_streams + header->num_coupled != header->channels) {
-        ALOGE("Inconsistent channel mapping.");
-        return false;
-    }
-    for (int i = 0; i < header->channels; ++i)
-        header->stream_map[i] = *(data + kOpusHeaderStreamMapOffset + i);
-    return true;
-}
-
-// Convert nanoseconds to number of samples.
-static uint64_t ns_to_samples(uint64_t ns, int rate) {
-    return static_cast<double>(ns) * rate / 1000000000;
-}
-
-void C2SoftOpus::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    if (inSize == 0) {
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-    const uint8_t *data = rView.data() + inOffset;
-    if (mInputBufferCount < 3) {
-        if (mInputBufferCount == 0) {
-            if (!ParseOpusHeader(data, inSize, &mHeader)) {
-                ALOGE("Encountered error while Parsing Opus Header.");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            uint8_t channel_mapping[kMaxChannels] = {0};
-            if (mHeader.channels <= kMaxChannelsWithDefaultLayout) {
-                memcpy(&channel_mapping,
-                       kDefaultOpusChannelLayout,
-                       kMaxChannelsWithDefaultLayout);
-            } else {
-                memcpy(&channel_mapping,
-                       mHeader.stream_map,
-                       mHeader.channels);
-            }
-            int status = OPUS_INVALID_STATE;
-            mDecoder = opus_multistream_decoder_create(kRate,
-                                                       mHeader.channels,
-                                                       mHeader.num_streams,
-                                                       mHeader.num_coupled,
-                                                       channel_mapping,
-                                                       &status);
-            if (!mDecoder || status != OPUS_OK) {
-                ALOGE("opus_multistream_decoder_create failed status = %s",
-                      opus_strerror(status));
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            status = opus_multistream_decoder_ctl(mDecoder,
-                                                  OPUS_SET_GAIN(mHeader.gain_db));
-            if (status != OPUS_OK) {
-                ALOGE("Failed to set OPUS header gain; status = %s",
-                      opus_strerror(status));
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-        } else {
-            if (inSize < 8) {
-                ALOGE("Input sample size is too small.");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            int64_t samples = ns_to_samples( *(reinterpret_cast<int64_t*>
-                              (const_cast<uint8_t *> (data))), kRate);
-            if (mInputBufferCount == 1) {
-                mCodecDelay = samples;
-                mSamplesToDiscard = mCodecDelay;
-            }
-            else {
-                mSeekPreRoll = samples;
-            }
-        }
-
-        ++mInputBufferCount;
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    // Ignore CSD re-submissions.
-    if ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
-        fillEmptyWork(work);
-        return;
-    }
-
-    // When seeking to zero, |mCodecDelay| samples has to be discarded
-    // instead of |mSeekPreRoll| samples (as we would when seeking to any
-    // other timestamp).
-    if (work->input.ordinal.timestamp.peeku() == 0) mSamplesToDiscard = mCodecDelay;
-
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(
-                          kMaxNumSamplesPerBuffer * kMaxChannels * sizeof(int16_t),
-                          usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    int numSamples = opus_multistream_decode(mDecoder,
-                                             data,
-                                             inSize,
-                                             reinterpret_cast<int16_t *> (wView.data()),
-                                             kMaxOpusOutputPacketSizeSamples,
-                                             0);
-    if (numSamples < 0) {
-        ALOGE("opus_multistream_decode returned numSamples %d", numSamples);
-        numSamples = 0;
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
-    }
-
-    int outOffset = 0;
-    if (mSamplesToDiscard > 0) {
-        if (mSamplesToDiscard > numSamples) {
-            mSamplesToDiscard -= numSamples;
-            numSamples = 0;
-        } else {
-            numSamples -= mSamplesToDiscard;
-            outOffset = mSamplesToDiscard * sizeof(int16_t) * mHeader.channels;
-            mSamplesToDiscard = 0;
-        }
-    }
-
-    if (numSamples) {
-        int outSize = numSamples * sizeof(int16_t) * mHeader.channels;
-        ALOGV("out buffer attr. offset %d size %d ", outOffset, outSize);
-
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, outOffset, outSize));
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    } else {
-        fillEmptyWork(work);
-        block.reset();
-    }
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-class C2SoftOpusDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftOpus(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftOpusDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftOpusDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/opus/dec/C2SoftOpus.h b/media/libstagefright/codecs/opus/dec/C2SoftOpus.h
deleted file mode 100644
index 70ad2de..0000000
--- a/media/libstagefright/codecs/opus/dec/C2SoftOpus.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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 C2_SOFT_OPUS_H_
-#define C2_SOFT_OPUS_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-struct OpusMSDecoder;
-
-namespace android {
-
-struct OpusHeader {
-  int channels;
-  int skip_samples;
-  int channel_mapping;
-  int num_streams;
-  int num_coupled;
-  int16_t gain_db;
-  uint8_t stream_map[8];
-};
-
-struct C2SoftOpus : public SimpleC2Component {
-    C2SoftOpus(const char *name, c2_node_id_t id);
-    virtual ~C2SoftOpus();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-private:
-    enum {
-        kMaxNumSamplesPerBuffer = 960 * 6
-    };
-
-    OpusMSDecoder *mDecoder;
-    OpusHeader mHeader;
-
-    int64_t mCodecDelay;
-    int64_t mSeekPreRoll;
-    int64_t mSamplesToDiscard;
-    size_t mInputBufferCount;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-
-    status_t initDecoder();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftOpus);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_OPUS_H_
diff --git a/media/libstagefright/codecs/raw/Android.bp b/media/libstagefright/codecs/raw/Android.bp
index c431c18..c8d7d00 100644
--- a/media/libstagefright/codecs/raw/Android.bp
+++ b/media/libstagefright/codecs/raw/Android.bp
@@ -35,38 +35,3 @@
     ],
     compile_multilib: "32",
 }
-
-cc_library_shared {
-    name: "libstagefright_soft_c2rawdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftRaw.cpp",],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-    ],
-}
diff --git a/media/libstagefright/codecs/raw/C2SoftRaw.cpp b/media/libstagefright/codecs/raw/C2SoftRaw.cpp
deleted file mode 100644
index 91b920d..0000000
--- a/media/libstagefright/codecs/raw/C2SoftRaw.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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 "C2SoftRAW"
-#include <utils/Log.h>
-
-#include "C2SoftRaw.h"
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.raw.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftRaw::C2SoftRaw(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)) {
-}
-
-C2SoftRaw::~C2SoftRaw() {
-    onRelease();
-}
-
-c2_status_t C2SoftRaw::onInit() {
-    mSignalledEos = false;
-    return C2_OK;
-}
-
-c2_status_t C2SoftRaw::onStop() {
-    mSignalledEos = false;
-    return C2_OK;
-}
-
-void C2SoftRaw::onReset() {
-    (void)onStop();
-}
-
-void C2SoftRaw::onRelease() {
-}
-
-c2_status_t C2SoftRaw::onFlush_sm() {
-    return onStop();
-}
-
-void C2SoftRaw::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void)pool;
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    size_t inSize = inBuffer.size();
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    if (inSize != 0) {
-        work->worklets.front()->output.buffers.push_back(work->input.buffers[0]);
-    }
-    work->workletsProcessed = 1u;
-    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        mSignalledEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-c2_status_t C2SoftRaw::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-class C2SoftRawDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftRaw(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftRawDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftRawDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/raw/C2SoftRaw.h b/media/libstagefright/codecs/raw/C2SoftRaw.h
deleted file mode 100644
index f7d2cfd..0000000
--- a/media/libstagefright/codecs/raw/C2SoftRaw.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 C2_SOFT_RAW_H_
-#define C2_SOFT_RAW_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct C2SoftRaw : public SimpleC2Component {
-    C2SoftRaw(const char *name, c2_node_id_t id);
-    virtual ~C2SoftRaw();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-private:
-    bool mSignalledEos;
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftRaw);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_RAW_H_
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.bp b/media/libstagefright/codecs/vorbis/dec/Android.bp
index 78dd61b..a9265cb 100644
--- a/media/libstagefright/codecs/vorbis/dec/Android.bp
+++ b/media/libstagefright/codecs/vorbis/dec/Android.bp
@@ -1,40 +1,4 @@
 cc_library_shared {
-    name: "libstagefright_soft_c2vorbisdec",
-//    vendor_available: true,
-//    vndk: {
-//        enabled: true,
-//    },
-
-    srcs: ["C2SoftVorbis.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-            "unsigned-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-        "libstagefright_simple_c2component",
-        "libvorbisidec",
-    ],
-}
-
-cc_library_shared {
     name: "libstagefright_soft_vorbisdec",
     vendor_available: true,
     vndk: {
diff --git a/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.cpp
deleted file mode 100644
index 8342725..0000000
--- a/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * 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 "C2SoftVorbis"
-#include <utils/Log.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include "C2SoftVorbis.h"
-
-extern "C" {
-    #include <Tremolo/codec_internal.h>
-
-    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
-    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
-    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
-}
-
-namespace android {
-
-constexpr char kComponentName[] = "c2.google.vorbis.decoder";
-
-static std::shared_ptr<C2ComponentInterface> BuildIntf(
-        const char *name, c2_node_id_t id,
-        std::function<void(C2ComponentInterface*)> deleter =
-            std::default_delete<C2ComponentInterface>()) {
-    return SimpleC2Interface::Builder(name, id, deleter)
-            .inputFormat(C2FormatCompressed)
-            .outputFormat(C2FormatAudio)
-            .inputMediaType(MEDIA_MIMETYPE_AUDIO_VORBIS)
-            .outputMediaType(MEDIA_MIMETYPE_AUDIO_RAW)
-            .build();
-}
-
-C2SoftVorbis::C2SoftVorbis(const char *name, c2_node_id_t id)
-    : SimpleC2Component(BuildIntf(name, id)),
-      mState(nullptr),
-      mVi(nullptr) {
-}
-
-C2SoftVorbis::~C2SoftVorbis() {
-    onRelease();
-}
-
-c2_status_t C2SoftVorbis::onInit() {
-    status_t err = initDecoder();
-    return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftVorbis::onStop() {
-    if (mState) vorbis_dsp_clear(mState);
-    if (mVi) vorbis_info_clear(mVi);
-    mNumFramesLeftOnPage = -1;
-    mNumChannels = 1;
-    mSamplingRate = 48000;
-    mInputBufferCount = 0;
-    mSignalledOutputEos = false;
-    mSignalledError = false;
-
-    return C2_OK;
-}
-
-void C2SoftVorbis::onReset() {
-    (void)onStop();
-}
-
-void C2SoftVorbis::onRelease() {
-    if (mState) {
-        vorbis_dsp_clear(mState);
-        delete mState;
-        mState = nullptr;
-    }
-
-    if (mVi) {
-        vorbis_info_clear(mVi);
-        delete mVi;
-        mVi = nullptr;
-    }
-}
-
-status_t C2SoftVorbis::initDecoder() {
-    mVi = new vorbis_info{};
-    if (!mVi) return NO_MEMORY;
-    vorbis_info_clear(mVi);
-
-    mState = new vorbis_dsp_state{};
-    if (!mState) return NO_MEMORY;
-    vorbis_dsp_clear(mState);
-
-    mNumFramesLeftOnPage = -1;
-    mNumChannels = 1;
-    mSamplingRate = 48000;
-    mInputBufferCount = 0;
-    mSignalledError = false;
-    mSignalledOutputEos = false;
-
-    return OK;
-}
-
-c2_status_t C2SoftVorbis::onFlush_sm() {
-    mNumFramesLeftOnPage = -1;
-    mSignalledOutputEos = false;
-    if (mState) vorbis_dsp_restart(mState);
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftVorbis::drain(
-        uint32_t drainMode,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    (void) pool;
-    if (drainMode == NO_DRAIN) {
-        ALOGW("drain with NO_DRAIN: no-op");
-        return C2_OK;
-    }
-    if (drainMode == DRAIN_CHAIN) {
-        ALOGW("DRAIN_CHAIN not supported");
-        return C2_OMITTED;
-    }
-
-    return C2_OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
-    work->worklets.front()->output.flags = work->input.flags;
-    work->worklets.front()->output.buffers.clear();
-    work->worklets.front()->output.ordinal = work->input.ordinal;
-    work->workletsProcessed = 1u;
-}
-
-static void makeBitReader(
-        const void *data, size_t size,
-        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
-    buf->data = (uint8_t *)data;
-    buf->size = size;
-    buf->refcount = 1;
-    buf->ptr.owner = nullptr;
-
-    ref->buffer = buf;
-    ref->begin = 0;
-    ref->length = size;
-    ref->next = nullptr;
-
-    oggpack_readinit(bits, ref);
-}
-
-// (CHECK!) multiframe is tricky. decode call doesnt return the number of bytes
-// consumed by the component. Also it is unclear why numPageFrames is being
-// tagged at the end of input buffers for new pages. Refer lines 297-300 in
-// SimpleDecodingSource.cpp
-void C2SoftVorbis::process(
-        const std::unique_ptr<C2Work> &work,
-        const std::shared_ptr<C2BlockPool> &pool) {
-    work->result = C2_OK;
-    work->workletsProcessed = 0u;
-    if (mSignalledError || mSignalledOutputEos) {
-        work->result = C2_BAD_VALUE;
-        return;
-    }
-
-    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
-    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-    size_t inOffset = inBuffer.offset();
-    size_t inSize = inBuffer.size();
-    C2ReadView rView = inBuffer.map().get();
-    if (inSize && rView.error()) {
-        ALOGE("read view map failed %d", rView.error());
-        work->result = rView.error();
-        return;
-    }
-
-    if (inSize == 0) {
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-
-    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
-          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-    const uint8_t *data = rView.data() + inOffset;
-    if (mInputBufferCount < 2) {
-        if (inSize < 7 || memcmp(&data[1], "vorbis", 6)) {
-            ALOGE("unexpected first 7 bytes in CSD");
-            mSignalledError = true;
-            work->result = C2_CORRUPTED;
-            return;
-        }
-
-        ogg_buffer buf;
-        ogg_reference ref;
-        oggpack_buffer bits;
-
-        // skip 7 <type + "vorbis"> bytes
-        makeBitReader((const uint8_t *)data + 7, inSize - 7, &buf, &ref, &bits);
-        if (mInputBufferCount == 0) {
-            if (data[0] != 1) {
-                ALOGE("unexpected type received %d", data[0]);
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            vorbis_info_init(mVi);
-            if (0 != _vorbis_unpack_info(mVi, &bits)) {
-                ALOGE("Encountered error while unpacking info");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            if (mVi->rate != mSamplingRate ||
-                    mVi->channels != mNumChannels) {
-                ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
-                mSamplingRate = mVi->rate;
-                mNumChannels = mVi->channels;
-            }
-        } else {
-            if (data[0] != 5) {
-                ALOGE("unexpected type received %d", data[0]);
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            if (0 != _vorbis_unpack_books(mVi, &bits)) {
-                ALOGE("Encountered error while unpacking books");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-            if (0 != vorbis_dsp_init(mState, mVi)) {
-                ALOGE("Encountered error while dsp init");
-                mSignalledError = true;
-                work->result = C2_CORRUPTED;
-                return;
-            }
-        }
-        ++mInputBufferCount;
-        fillEmptyWork(work);
-        if (eos) {
-            mSignalledOutputEos = true;
-            ALOGV("signalled EOS");
-        }
-        return;
-    }
-    int32_t numPageFrames = 0;
-    if (inSize < sizeof(numPageFrames)) {
-        ALOGE("input header has size %zu, expected %zu", inSize, sizeof(numPageFrames));
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
-    }
-    memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
-    inSize -= sizeof(numPageFrames);
-    if (numPageFrames >= 0) {
-        mNumFramesLeftOnPage = numPageFrames;
-    }
-
-    ogg_buffer buf;
-    buf.data = const_cast<unsigned char*>(data);
-    buf.size = inSize;
-    buf.refcount = 1;
-    buf.ptr.owner = nullptr;
-
-    ogg_reference ref;
-    ref.buffer = &buf;
-    ref.begin = 0;
-    ref.length = buf.size;
-    ref.next = nullptr;
-
-    ogg_packet pack;
-    pack.packet = &ref;
-    pack.bytes = ref.length;
-    pack.b_o_s = 0;
-    pack.e_o_s = 0;
-    pack.granulepos = 0;
-    pack.packetno = 0;
-
-    size_t maxSamplesInBuffer = kMaxNumSamplesPerChannel * mVi->channels;
-    size_t outCapacity =  maxSamplesInBuffer * sizeof(int16_t);
-    std::shared_ptr<C2LinearBlock> block;
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
-    if (err != C2_OK) {
-        ALOGE("fetchLinearBlock for Output failed with status %d", err);
-        work->result = C2_NO_MEMORY;
-        return;
-    }
-    C2WriteView wView = block->map().get();
-    if (wView.error()) {
-        ALOGE("write view map failed %d", wView.error());
-        work->result = wView.error();
-        return;
-    }
-
-    int numFrames = 0;
-    int ret = vorbis_dsp_synthesis(mState, &pack, 1);
-    if (0 != ret) {
-        ALOGE("vorbis_dsp_synthesis returned %d", ret);
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
-    } else {
-        numFrames = vorbis_dsp_pcmout(
-                mState,  reinterpret_cast<int16_t *> (wView.data()),
-                kMaxNumSamplesPerChannel);
-        if (numFrames < 0) {
-            ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
-            numFrames = 0;
-        }
-    }
-
-    if (mNumFramesLeftOnPage >= 0) {
-        if (numFrames > mNumFramesLeftOnPage) {
-            ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage);
-            numFrames = mNumFramesLeftOnPage;
-        }
-        mNumFramesLeftOnPage -= numFrames;
-    }
-
-    if (numFrames) {
-        int outSize = numFrames * sizeof(int16_t) * mVi->channels;
-
-        work->worklets.front()->output.flags = work->input.flags;
-        work->worklets.front()->output.buffers.clear();
-        work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
-        work->worklets.front()->output.ordinal = work->input.ordinal;
-        work->workletsProcessed = 1u;
-    } else {
-        fillEmptyWork(work);
-        block.reset();
-    }
-    if (eos) {
-        mSignalledOutputEos = true;
-        ALOGV("signalled EOS");
-    }
-}
-
-class C2SoftVorbisDecFactory : public C2ComponentFactory {
-public:
-    virtual c2_status_t createComponent(
-            c2_node_id_t id,
-            std::shared_ptr<C2Component>* const component,
-            std::function<void(C2Component*)> deleter) override {
-        *component = std::shared_ptr<C2Component>(new C2SoftVorbis(kComponentName, id), deleter);
-        return C2_OK;
-    }
-
-    virtual c2_status_t createInterface(
-            c2_node_id_t id,
-            std::shared_ptr<C2ComponentInterface>* const interface,
-            std::function<void(C2ComponentInterface*)> deleter) override {
-        *interface = BuildIntf(kComponentName, id, deleter);
-        return C2_OK;
-    }
-
-    virtual ~C2SoftVorbisDecFactory() override = default;
-};
-
-}  // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
-    ALOGV("in %s", __func__);
-    return new ::android::C2SoftVorbisDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
-    ALOGV("in %s", __func__);
-    delete factory;
-}
diff --git a/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.h
deleted file mode 100644
index 340c235..0000000
--- a/media/libstagefright/codecs/vorbis/dec/C2SoftVorbis.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 C2_SOFT_VORBIS_H_
-#define C2_SOFT_VORBIS_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ABase.h>
-
-struct vorbis_dsp_state;
-struct vorbis_info;
-
-namespace android {
-
-struct C2SoftVorbis : public SimpleC2Component {
-    C2SoftVorbis(const char *name, c2_node_id_t id);
-    virtual ~C2SoftVorbis();
-
-    // From SimpleC2Component
-    c2_status_t onInit() override;
-    c2_status_t onStop() override;
-    void onReset() override;
-    void onRelease() override;
-    c2_status_t onFlush_sm() override;
-    void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-    c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) override;
-
- private:
-    enum {
-        kMaxNumSamplesPerChannel = 8192,
-    };
-
-    vorbis_dsp_state *mState;
-    vorbis_info *mVi;
-
-    int32_t mNumFramesLeftOnPage;
-    int32_t mNumChannels;
-    int32_t mSamplingRate;
-    size_t mInputBufferCount;
-    bool mSignalledError;
-    bool mSignalledOutputEos;
-
-    status_t initDecoder();
-
-    DISALLOW_EVIL_CONSTRUCTORS(C2SoftVorbis);
-};
-
-}  // namespace android
-
-#endif  // C2_SOFT_VORBIS_H_
-
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 581e51b..8d486cf 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -9,6 +9,8 @@
         "FLACDecoder.cpp",
     ],
 
+    export_include_dirs: [ "." ],
+
     include_dirs: [
         "external/flac/include",
         "frameworks/av/media/libstagefright/include",
diff --git a/media/libstagefright/include/C2OMXNode.h b/media/libstagefright/include/C2OMXNode.h
deleted file mode 100644
index 3c007c4..0000000
--- a/media/libstagefright/include/C2OMXNode.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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>
-
-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 {
-    // TODO: this should take android::hardware::media::c2::V1_0::IComponent
-    explicit C2OMXNode(const std::shared_ptr<C2Component> &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();
-
-private:
-    std::weak_ptr<C2Component> mComp;
-    sp<IOMXBufferSource> mBufferSource;
-    std::shared_ptr<C2Allocator> mAllocator;
-    std::atomic_uint64_t mFrameIndex;
-};
-
-}  // namespace android
-
-#endif  // C2_OMX_NODE_H_
diff --git a/media/libstagefright/include/CCodecBufferChannel.h b/media/libstagefright/include/CCodecBufferChannel.h
deleted file mode 100644
index c8618db..0000000
--- a/media/libstagefright/include/CCodecBufferChannel.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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 <mutex>
-#include <vector>
-
-#include <C2Buffer.h>
-#include <C2Component.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 {
-
-using ::android::hardware::media::c2::V1_0::implementation::InputSurface;
-using ::android::hardware::media::c2::V1_0::implementation::InputSurfaceConnection;
-
-/**
- * BufferChannelBase implementation for CCodec.
- */
-class CCodecBufferChannel
-    : public BufferChannelBase, public std::enable_shared_from_this<CCodecBufferChannel> {
-public:
-    CCodecBufferChannel(const std::function<void(status_t, enum ActionCode)> &onError);
-    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<C2Component> &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);
-
-    /**
-     * Start queueing buffers to the component. This object should never queue
-     * buffers before this call.
-     */
-    status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
-
-    /**
-     * 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.
-     */
-    void onWorkDone(const std::unique_ptr<C2Work> &work);
-
-    // 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() : mCount(-1) {}
-        ~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:
-        std::mutex mMutex;
-        std::atomic_int32_t mCount;
-
-        friend class CCodecBufferChannel::QueueGuard;
-    };
-
-    class QueueGuard {
-    public:
-        QueueGuard(QueueSync &sync);
-        ~QueueGuard();
-        inline bool isRunning() { return mRunning; }
-
-    private:
-        QueueSync &mSync;
-        bool mRunning;
-    };
-
-    void feedInputBufferIfAvailable();
-    status_t queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer);
-
-    QueueSync mSync;
-    sp<MemoryDealer> mDealer;
-    sp<IMemory> mDecryptDestination;
-    int32_t mHeapSeqNum;
-
-    std::shared_ptr<C2Component> mComponent;
-    std::function<void(status_t, enum ActionCode)> mOnError;
-    std::shared_ptr<C2BlockPool> mInputAllocator;
-    QueueSync mQueueSync;
-
-    Mutexed<std::unique_ptr<InputBuffers>> mInputBuffers;
-    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;
-        std::list<std::shared_ptr<C2Buffer>> bufferRefs;
-        size_t maxBufferCount;
-    };
-    Mutexed<OutputSurface> mOutputSurface;
-
-    std::shared_ptr<InputSurfaceWrapper> mInputSurface;
-
-    inline bool hasCryptoOrDescrambler() {
-        return mCrypto != NULL || mDescrambler != NULL;
-    }
-};
-
-}  // namespace android
-
-#endif  // CCODEC_BUFFER_CHANNEL_H_
diff --git a/media/libstagefright/include/Codec2Buffer.h b/media/libstagefright/include/Codec2Buffer.h
deleted file mode 100644
index b2e3b1b..0000000
--- a/media/libstagefright/include/Codec2Buffer.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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 {
-
-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 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 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/libstagefright/include/InputSurfaceWrapper.h b/media/libstagefright/include/InputSurfaceWrapper.h
deleted file mode 100644
index a4d8f29..0000000
--- a/media/libstagefright/include/InputSurfaceWrapper.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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_
-
-namespace android {
-
-/**
- * Wrapper interface around InputSurface.
- */
-class InputSurfaceWrapper {
-public:
-    virtual ~InputSurfaceWrapper() = default;
-
-    /**
-     * Connect the surface with |comp| and start pushing buffers. 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<C2Component> &comp) = 0;
-
-    /**
-     * Disconnect the surface from the component if any.
-     */
-    virtual void disconnect() = 0;
-
-    // TODO: intf()
-};
-
-}  // namespace android
-
-#endif  // INPUT_SURFACE_WRAPPER_H_
diff --git a/media/libstagefright/include/media/stagefright/CCodec.h b/media/libstagefright/include/media/stagefright/CCodec.h
deleted file mode 100644
index 86fbd3a..0000000
--- a/media/libstagefright/include/media/stagefright/CCodec.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 <C2Component.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>
-
-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> &msg) override;
-    virtual void signalEndOfInputStream() override;
-    virtual void signalRequestIDRFrame() override;
-
-    void initiateReleaseIfStuck();
-    void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems);
-
-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 setDeadline(const TimePoint &deadline, const char *name);
-
-    enum {
-        kWhatAllocate,
-        kWhatConfigure,
-        kWhatStart,
-        kWhatFlush,
-        kWhatStop,
-        kWhatRelease,
-        kWhatCreateInputSurface,
-        kWhatSetInputSurface,
-        kWhatWorkDone,
-    };
-
-    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<C2Component> comp;
-    private:
-        int mState;
-    };
-
-    struct Formats {
-        sp<AMessage> inputFormat;
-        sp<AMessage> outputFormat;
-    };
-
-    struct NamedTimePoint {
-        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<C2Component::Listener> mListener;
-    Mutexed<NamedTimePoint> mDeadline;
-    Mutexed<Formats> mFormats;
-    Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
-
-    DISALLOW_EVIL_CONSTRUCTORS(CCodec);
-};
-
-}  // namespace android
-
-#endif  // C_CODEC_H_
diff --git a/media/libstagefright/include/media/stagefright/Codec2InfoBuilder.h b/media/libstagefright/include/media/stagefright/Codec2InfoBuilder.h
deleted file mode 100644
index 30c189e..0000000
--- a/media/libstagefright/include/media/stagefright/Codec2InfoBuilder.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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_
