diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 666d68a..26b8251 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -76,9 +76,14 @@
 
     Vector<uint32_t> thumbnails;
     Vector<uint32_t> dimgRefs;
+    Vector<uint32_t> cdscRefs;
     size_t nextTileIndex;
 };
 
+struct ExifItem {
+    off64_t offset;
+    size_t size;
+};
 
 /////////////////////////////////////////////////////////////////////
 //
@@ -473,7 +478,9 @@
 
     uint32_t itemId() { return mItemId; }
 
-    void apply(KeyedVector<uint32_t, ImageItem> &itemIdToItemMap) const;
+    void apply(
+            KeyedVector<uint32_t, ImageItem> &itemIdToItemMap,
+            KeyedVector<uint32_t, ExifItem> &itemIdToExifMap) const;
 
 private:
     uint32_t mItemId;
@@ -483,17 +490,20 @@
     DISALLOW_EVIL_CONSTRUCTORS(ItemReference);
 };
 
-void ItemReference::apply(KeyedVector<uint32_t, ImageItem> &itemIdToItemMap) const {
-    ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
-
-    // ignore non-image items
-    if (itemIndex < 0) {
-        return;
-    }
-
+void ItemReference::apply(
+        KeyedVector<uint32_t, ImageItem> &itemIdToItemMap,
+        KeyedVector<uint32_t, ExifItem> &itemIdToExifMap) const {
     ALOGV("attach reference type 0x%x to item id %d)", type(), mItemId);
 
-    if (type() == FOURCC('d', 'i', 'm', 'g')) {
+    switch(type()) {
+    case FOURCC('d', 'i', 'm', 'g'): {
+        ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
+
+        // ignore non-image items
+        if (itemIndex < 0) {
+            return;
+        }
+
         ImageItem &derivedImage = itemIdToItemMap.editValueAt(itemIndex);
         if (!derivedImage.dimgRefs.empty()) {
             ALOGW("dimgRefs if not clean!");
@@ -512,7 +522,16 @@
             // mark the source image of the derivation as hidden
             sourceImage.hidden = true;
         }
-    } else if (type() == FOURCC('t', 'h', 'm', 'b')) {
+        break;
+    }
+    case FOURCC('t', 'h', 'm', 'b'): {
+        ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
+
+        // ignore non-image items
+        if (itemIndex < 0) {
+            return;
+        }
+
         // mark thumbnail image as hidden, these can be retrieved if the client
         // request thumbnail explicitly, but won't be exposed as displayables.
         ImageItem &thumbImage = itemIdToItemMap.editValueAt(itemIndex);
@@ -532,11 +551,43 @@
             }
             masterImage.thumbnails.push_back(mItemId);
         }
-    } else if (type() == FOURCC('a', 'u', 'x', 'l')) {
+        break;
+    }
+    case FOURCC('c', 'd', 's', 'c'): {
+        ssize_t itemIndex = itemIdToExifMap.indexOfKey(mItemId);
+
+        // ignore non-exif block items
+        if (itemIndex < 0) {
+            return;
+        }
+
+        for (size_t i = 0; i < mRefs.size(); i++) {
+            itemIndex = itemIdToItemMap.indexOfKey(mRefs[i]);
+
+            // ignore non-image items
+            if (itemIndex < 0) {
+                continue;
+            }
+            ALOGV("Image item id %d uses metadata item id %d", mRefs[i], mItemId);
+            ImageItem &image = itemIdToItemMap.editValueAt(itemIndex);
+            image.cdscRefs.push_back(mItemId);
+        }
+        break;
+    }
+    case FOURCC('a', 'u', 'x', 'l'): {
+        ssize_t itemIndex = itemIdToItemMap.indexOfKey(mItemId);
+
+        // ignore non-image items
+        if (itemIndex < 0) {
+            return;
+        }
+
         // mark auxiliary image as hidden
         ImageItem &auxImage = itemIdToItemMap.editValueAt(itemIndex);
         auxImage.hidden = true;
-    } else {
+        break;
+    }
+    default:
         ALOGW("ignoring unsupported ref type 0x%x", type());
     }
 }
@@ -1299,10 +1350,13 @@
     for (size_t i = 0; i < mItemInfos.size(); i++) {
         const ItemInfo &info = mItemInfos[i];
 
-
-        // ignore non-image items
+        // Only handle 3 types of items, all others are ignored:
+        //   'grid': derived image from tiles
+        //   'hvc1': coded image (or tile)
+        //   'Exif': EXIF metadata
         if (info.itemType != FOURCC('g', 'r', 'i', 'd') &&
-            info.itemType != FOURCC('h', 'v', 'c', '1')) {
+            info.itemType != FOURCC('h', 'v', 'c', '1') &&
+            info.itemType != FOURCC('E', 'x', 'i', 'f')) {
             continue;
         }
 
@@ -1325,6 +1379,19 @@
             return ERROR_MALFORMED;
         }
 
+        if (info.itemType == FOURCC('E', 'x', 'i', 'f')) {
+            // Only add if the Exif data is non-empty. The first 4 bytes contain
+            // the offset to TIFF header, which the Exif parser doesn't use.
+            if (size > 4) {
+                ExifItem exifItem = {
+                        .offset = offset,
+                        .size = size,
+                };
+                mItemIdToExifMap.add(info.itemId, exifItem);
+            }
+            continue;
+        }
+
         ImageItem image(info.itemType, info.itemId, info.hidden);
 
         ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
@@ -1354,7 +1421,7 @@
     }
 
     for (size_t i = 0; i < mItemReferences.size(); i++) {
-        mItemReferences[i]->apply(mItemIdToItemMap);
+        mItemReferences[i]->apply(mItemIdToItemMap, mItemIdToExifMap);
     }
 
     bool foundPrimary = false;
@@ -1574,6 +1641,34 @@
     return OK;
 }
 
+status_t ItemTable::getExifOffsetAndSize(off64_t *offset, size_t *size) {
+    if (!mImageItemsValid) {
+        return INVALID_OPERATION;
+    }
+
+    ssize_t itemIndex = mItemIdToItemMap.indexOfKey(mPrimaryItemId);
+
+    // this should not happen, something's seriously wrong.
+    if (itemIndex < 0) {
+        return INVALID_OPERATION;
+    }
+
+    const ImageItem &image = mItemIdToItemMap[itemIndex];
+    if (image.cdscRefs.size() == 0) {
+        return NAME_NOT_FOUND;
+    }
+
+    ssize_t exifIndex = mItemIdToExifMap.indexOfKey(image.cdscRefs[0]);
+    if (exifIndex < 0) {
+        return NAME_NOT_FOUND;
+    }
+
+    // skip the first 4-byte of the offset to TIFF header
+    *offset = mItemIdToExifMap[exifIndex].offset + 4;
+    *size = mItemIdToExifMap[exifIndex].size - 4;
+    return OK;
+}
+
 } // namespace heif
 
 }  // namespace android
diff --git a/media/extractors/mp4/ItemTable.h b/media/extractors/mp4/ItemTable.h
index f4a69cc..536dcb0 100644
--- a/media/extractors/mp4/ItemTable.h
+++ b/media/extractors/mp4/ItemTable.h
@@ -32,6 +32,7 @@
 
 struct AssociationEntry;
 struct ImageItem;
+struct ExifItem;
 struct ItemLoc;
 struct ItemInfo;
 struct ItemProperty;
@@ -55,6 +56,7 @@
     status_t findThumbnailItem(const uint32_t imageIndex, uint32_t *itemIndex);
     status_t getImageOffsetAndSize(
             uint32_t *itemIndex, off64_t *offset, size_t *size);
+    status_t getExifOffsetAndSize(off64_t *offset, size_t *size);
 
 protected:
     ~ItemTable();
@@ -78,6 +80,7 @@
     bool mImageItemsValid;
     uint32_t mCurrentItemIndex;
     KeyedVector<uint32_t, ImageItem> mItemIdToItemMap;
+    KeyedVector<uint32_t, ExifItem> mItemIdToExifMap;
     Vector<uint32_t> mDisplayables;
 
     status_t parseIlocBox(off64_t offset, size_t size);
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index a9f66fa..07ef0e3 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -586,6 +586,12 @@
     }
 
     if (mIsHeif && (mItemTable != NULL) && (mItemTable->countImages() > 0)) {
+        off64_t exifOffset;
+        size_t exifSize;
+        if (mItemTable->getExifOffsetAndSize(&exifOffset, &exifSize) == OK) {
+            mFileMetaData.setInt64(kKeyExifOffset, (int64_t)exifOffset);
+            mFileMetaData.setInt64(kKeyExifSize, (int64_t)exifSize);
+        }
         for (uint32_t imageIndex = 0;
                 imageIndex < mItemTable->countImages(); imageIndex++) {
             sp<MetaData> meta = mItemTable->getImageMeta(imageIndex);
@@ -601,6 +607,7 @@
                 ALOGW("Extracting still images only");
                 err = OK;
             }
+            mInitCheck = OK;
 
             ALOGV("adding HEIF image track %u", imageIndex);
             Track *track = new Track;
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
index 18e63f2..f1b7806 100644
--- a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
@@ -218,6 +218,8 @@
     kKeyIccProfile       = 'prof', // raw data, ICC profile data
     kKeyIsPrimaryImage   = 'prim', // bool (int32_t), image track is the primary image
     kKeyFrameCount       = 'nfrm', // int32_t, total number of frame in video track
+    kKeyExifOffset       = 'exof', // int64_t, Exif data offset
+    kKeyExifSize         = 'exsz', // int64_t, Exif data size
 };
 
 enum {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 71bff84..22b1e59 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -56,6 +56,7 @@
     srcs: [
         "CodecBase.cpp",
         "FrameRenderTracker.cpp",
+        "MediaCodecListWriter.cpp",
     ],
 
     cflags: [
@@ -66,68 +67,11 @@
     shared_libs: [
         "libgui",
         "liblog",
-        "libmedia",
-        "libstagefright_foundation",
-        "libui",
-        "libutils",
-        "android.hardware.cas.native@1.0",
-    ],
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        diag: {
-            cfi: true,
-        },
-    },
-}
-
-cc_library_shared {
-    name: "libstagefright_ccodec",
-
-    local_include_dirs: ["include"],
-
-    srcs: [
-        "C2OMXNode.cpp",
-        "CCodec.cpp",
-        "CCodecBufferChannel.cpp",
-        "Codec2Buffer.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",
         "libui",
         "libutils",
-        "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: {
@@ -154,7 +98,6 @@
         "AudioPresentationInfo.cpp",
         "AudioSource.cpp",
         "BufferImpl.cpp",
-        "Codec2InfoBuilder.cpp",
         "CallbackDataSource.cpp",
         "CallbackMediaSource.cpp",
         "CameraSource.cpp",
@@ -190,6 +133,7 @@
         "SkipCutBuffer.cpp",
         "StagefrightMediaScanner.cpp",
         "StagefrightMetadataRetriever.cpp",
+        "StagefrightPluginLoader.cpp",
         "SurfaceUtils.cpp",
         "Utils.cpp",
         "ThrottledSource.cpp",
@@ -216,9 +160,6 @@
         "libui",
         "libutils",
         "libmedia_helper",
-        "libstagefright_ccodec",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
         "libstagefright_codecbase",
         "libstagefright_foundation",
         "libstagefright_omx",
@@ -228,8 +169,6 @@
         "libhidlallocatorutils",
         "libhidlbase",
         "libhidlmemory",
-        // TODO: Remove libv4l2_c2_componentstore.
-        "libv4l2_c2componentstore",
         "libziparchive",
         "android.hidl.allocator@1.0",
         "android.hardware.cas.native@1.0",
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 0a20d34..0000000
--- a/media/libstagefright/CCodec.cpp
+++ /dev/null
@@ -1,912 +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
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 78c4e38..0000000
--- a/media/libstagefright/Codec2InfoBuilder.cpp
+++ /dev/null
@@ -1,161 +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
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index edcb8c7..5ad4c01 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -16,11 +16,14 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaCodec"
+#include <utils/Log.h>
+
 #include <inttypes.h>
 
 #include "include/SecureBuffer.h"
 #include "include/SharedMemoryBuffer.h"
 #include "include/SoftwareRenderer.h"
+#include "StagefrightPluginLoader.h"
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
 
@@ -45,7 +48,6 @@
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/ACodec.h>
 #include <media/stagefright/BufferProducerWrapper.h>
-#include <media/stagefright/CCodec.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaDefs.h>
@@ -56,7 +58,6 @@
 #include <media/stagefright/SurfaceUtils.h>
 #include <mediautils/BatteryNotifier.h>
 #include <private/android_filesystem_config.h>
-#include <utils/Log.h>
 #include <utils/Singleton.h>
 
 namespace android {
@@ -570,11 +571,15 @@
     response->postReply(replyID);
 }
 
+static CodecBase *CreateCCodec() {
+    return StagefrightPluginLoader::GetCCodecInstance()->createCodec();
+}
+
 //static
 sp<CodecBase> MediaCodec::GetCodecBase(const AString &name) {
     static bool ccodecEnabled = property_get_bool("debug.stagefright.ccodec", false);
     if (ccodecEnabled && name.startsWithIgnoreCase("c2.")) {
-        return new CCodec;
+        return CreateCCodec();
     } else if (name.startsWithIgnoreCase("omx.")) {
         // at this time only ACodec specifies a mime type.
         return new ACodec;
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 9244886..cd091a6 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include "MediaCodecListOverrides.h"
+#include "StagefrightPluginLoader.h"
 
 #include <binder/IServiceManager.h>
 
@@ -29,7 +30,6 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/Codec2InfoBuilder.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/OmxInfoBuilder.h>
@@ -78,14 +78,25 @@
 }
 
 OmxInfoBuilder sOmxInfoBuilder;
-Codec2InfoBuilder sCodec2InfoBuilder;
 
-std::initializer_list<MediaCodecListBuilderBase *> GetBuilders() {
-    if (property_get_bool("debug.stagefright.ccodec", false)) {
-        return {&sOmxInfoBuilder, &sCodec2InfoBuilder};
-    } else {
-        return {&sOmxInfoBuilder};
+Mutex sCodec2InfoBuilderMutex;
+std::unique_ptr<MediaCodecListBuilderBase> sCodec2InfoBuilder;
+
+MediaCodecListBuilderBase *GetCodec2InfoBuilder() {
+    Mutex::Autolock _l(sCodec2InfoBuilderMutex);
+    if (!sCodec2InfoBuilder) {
+        sCodec2InfoBuilder.reset(
+                StagefrightPluginLoader::GetCCodecInstance()->createBuilder());
     }
+    return sCodec2InfoBuilder.get();
+}
+
+std::vector<MediaCodecListBuilderBase *> GetBuilders() {
+    std::vector<MediaCodecListBuilderBase *> builders {&sOmxInfoBuilder};
+    if (property_get_bool("debug.stagefright.ccodec", false)) {
+        builders.push_back(GetCodec2InfoBuilder());
+    }
+    return builders;
 }
 
 }  // unnamed namespace
@@ -179,16 +190,22 @@
     return sRemoteList;
 }
 
-MediaCodecList::MediaCodecList(std::initializer_list<MediaCodecListBuilderBase*> builders) {
+MediaCodecList::MediaCodecList(std::vector<MediaCodecListBuilderBase*> builders) {
     mGlobalSettings = new AMessage();
     mCodecInfos.clear();
-    MediaCodecListWriter writer(this);
+    MediaCodecListWriter writer;
     for (MediaCodecListBuilderBase *builder : builders) {
+        if (builder == nullptr) {
+            ALOGD("ignored a null builder");
+            continue;
+        }
         mInitCheck = builder->buildMediaCodecList(&writer);
         if (mInitCheck != OK) {
             break;
         }
     }
+    writer.writeGlobalSettings(mGlobalSettings);
+    writer.writeCodecInfos(&mCodecInfos);
     std::stable_sort(
             mCodecInfos.begin(),
             mCodecInfos.end(),
@@ -210,23 +227,6 @@
     return mInitCheck;
 }
 
-MediaCodecListWriter::MediaCodecListWriter(MediaCodecList* list) :
-    mList(list) {
-}
-
-void MediaCodecListWriter::addGlobalSetting(
-        const char* key, const char* value) {
-    mList->mGlobalSettings->setString(key, value);
-}
-
-std::unique_ptr<MediaCodecInfoWriter>
-        MediaCodecListWriter::addMediaCodecInfo() {
-    sp<MediaCodecInfo> info = new MediaCodecInfo();
-    mList->mCodecInfos.push_back(info);
-    return std::unique_ptr<MediaCodecInfoWriter>(
-            new MediaCodecInfoWriter(info.get()));
-}
-
 // legacy method for non-advanced codecs
 ssize_t MediaCodecList::findCodecByType(
         const char *type, bool encoder, size_t startIndex) const {
@@ -344,7 +344,4 @@
     }
 }
 
-MediaCodecListBuilderBase::~MediaCodecListBuilderBase() {
-}
-
 }  // namespace android
diff --git a/media/libstagefright/MediaCodecListWriter.cpp b/media/libstagefright/MediaCodecListWriter.cpp
new file mode 100644
index 0000000..b32e470
--- /dev/null
+++ b/media/libstagefright/MediaCodecListWriter.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 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 "MediaCodecListWriter"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaCodecListWriter.h>
+#include <media/MediaCodecInfo.h>
+
+namespace android {
+
+void MediaCodecListWriter::addGlobalSetting(
+        const char* key, const char* value) {
+    mGlobalSettings.emplace_back(key, value);
+}
+
+std::unique_ptr<MediaCodecInfoWriter>
+        MediaCodecListWriter::addMediaCodecInfo() {
+    sp<MediaCodecInfo> info = new MediaCodecInfo();
+    mCodecInfos.push_back(info);
+    return std::unique_ptr<MediaCodecInfoWriter>(
+            new MediaCodecInfoWriter(info.get()));
+}
+
+void MediaCodecListWriter::writeGlobalSettings(
+        const sp<AMessage> &globalSettings) const {
+    for (const std::pair<std::string, std::string> &kv : mGlobalSettings) {
+        globalSettings->setString(kv.first.c_str(), kv.second.c_str());
+    }
+}
+
+void MediaCodecListWriter::writeCodecInfos(
+        std::vector<sp<MediaCodecInfo>> *codecInfos) const {
+    for (const sp<MediaCodecInfo> &info : mCodecInfos) {
+        codecInfos->push_back(info);
+    }
+}
+
+}  // namespace android
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 27b9a5d..4a7d6ca 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -307,6 +307,26 @@
     return OK;
 }
 
+status_t NuMediaExtractor::getExifOffsetSize(off64_t *offset, size_t *size) const {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mImpl == NULL) {
+        return -EINVAL;
+    }
+
+    sp<MetaData> meta = mImpl->getMetaData();
+
+    int64_t exifOffset, exifSize;
+    if (meta->findInt64(kKeyExifOffset, &exifOffset)
+     && meta->findInt64(kKeyExifSize, &exifSize)) {
+        *offset = (off64_t) exifOffset;
+        *size = (size_t) exifSize;
+
+        return OK;
+    }
+    return ERROR_UNSUPPORTED;
+}
+
 status_t NuMediaExtractor::selectTrack(size_t index,
         int64_t startTimeUs, MediaSource::ReadOptions::SeekMode mode) {
     Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/StagefrightPluginLoader.cpp b/media/libstagefright/StagefrightPluginLoader.cpp
new file mode 100644
index 0000000..7f13f87
--- /dev/null
+++ b/media/libstagefright/StagefrightPluginLoader.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 "StagefrightPluginLoader"
+#include <utils/Log.h>
+
+#include <dlfcn.h>
+
+#include "StagefrightPluginLoader.h"
+
+namespace android {
+
+/* static */ Mutex StagefrightPluginLoader::sMutex;
+/* static */ std::unique_ptr<StagefrightPluginLoader> StagefrightPluginLoader::sInstance;
+
+StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath)
+    : mCreateCodec(nullptr),
+      mCreateBuilder(nullptr) {
+    mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
+    if (mLibHandle == nullptr) {
+        ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
+        return;
+    }
+    mCreateCodec = (CodecBase::CreateCodecFunc)dlsym(mLibHandle, "CreateCodec");
+    if (mCreateCodec == nullptr) {
+        ALOGD("Failed to find symbol: CreateCodec (%s)", dlerror());
+    }
+    mCreateBuilder = (MediaCodecListBuilderBase::CreateBuilderFunc)dlsym(
+            mLibHandle, "CreateBuilder");
+    if (mCreateBuilder == nullptr) {
+        ALOGD("Failed to find symbol: CreateBuilder (%s)", dlerror());
+    }
+}
+
+StagefrightPluginLoader::~StagefrightPluginLoader() {
+    if (mLibHandle != nullptr) {
+        ALOGV("Closing handle");
+        dlclose(mLibHandle);
+    }
+}
+
+CodecBase *StagefrightPluginLoader::createCodec() {
+    if (mLibHandle == nullptr || mCreateCodec == nullptr) {
+        ALOGD("Handle or CreateCodec symbol is null");
+        return nullptr;
+    }
+    return mCreateCodec();
+}
+
+MediaCodecListBuilderBase *StagefrightPluginLoader::createBuilder() {
+    if (mLibHandle == nullptr || mCreateBuilder == nullptr) {
+        ALOGD("Handle or CreateBuilder symbol is null");
+        return nullptr;
+    }
+    return mCreateBuilder();
+}
+
+//static
+const std::unique_ptr<StagefrightPluginLoader> &StagefrightPluginLoader::GetCCodecInstance() {
+    Mutex::Autolock _l(sMutex);
+    if (!sInstance) {
+        ALOGV("Loading library");
+        sInstance.reset(new StagefrightPluginLoader("libstagefright_ccodec.so"));
+    }
+    return sInstance;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/StagefrightPluginLoader.h b/media/libstagefright/StagefrightPluginLoader.h
new file mode 100644
index 0000000..2746756
--- /dev/null
+++ b/media/libstagefright/StagefrightPluginLoader.h
@@ -0,0 +1,47 @@
+/*
+ * 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 STAGEFRIGHT_PLUGIN_LOADER_H_
+
+#define STAGEFRIGHT_PLUGIN_LOADER_H_
+
+#include <media/stagefright/CodecBase.h>
+#include <media/stagefright/MediaCodecListWriter.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+class StagefrightPluginLoader {
+public:
+    static const std::unique_ptr<StagefrightPluginLoader> &GetCCodecInstance();
+    ~StagefrightPluginLoader();
+
+    CodecBase *createCodec();
+    MediaCodecListBuilderBase *createBuilder();
+private:
+    explicit StagefrightPluginLoader(const char *libPath);
+
+    static Mutex sMutex;
+    static std::unique_ptr<StagefrightPluginLoader> sInstance;
+
+    void *mLibHandle;
+    CodecBase::CreateCodecFunc mCreateCodec;
+    MediaCodecListBuilderBase::CreateBuilderFunc mCreateBuilder;
+};
+
+}  // namespace android
+
+#endif  // STAGEFRIGHT_PLUGIN_LOADER_H_
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 388ed6b..9febe12 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -42,8 +42,9 @@
     ],
 
     export_shared_lib_headers: [
-        "libstagefright_foundation",
+        "libgui",
         "libhidlmemory",
+        "libstagefright_foundation",
     ],
 
     cflags: [
diff --git a/media/libstagefright/codec2/vndk/Android.bp b/media/libstagefright/codec2/vndk/Android.bp
index 95e7c39..8966933 100644
--- a/media/libstagefright/codec2/vndk/Android.bp
+++ b/media/libstagefright/codec2/vndk/Android.bp
@@ -5,10 +5,12 @@
         "internal",
     ],
 
-    vendor_available: false,
     vndk: {
         enabled: true,
     },
+
+    // TODO: Remove this when this module is moved back to frameworks/av.
+    vendor_available: true,
 }
 
 cc_library_shared {
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 ea0b5c4..0000000
--- a/media/libstagefright/include/media/stagefright/Codec2InfoBuilder.h
+++ /dev/null
@@ -1,33 +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;
-    status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
-};
-
-}  // namespace android
-
-#endif  // CODEC2_INFO_BUILDER_H_
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 268662f..1cbf865 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -222,9 +222,7 @@
     virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
     virtual void signalEndOfInputStream() = 0;
 
-    /*
-     * Codec-related defines
-     */
+    typedef CodecBase *(*CreateCodecFunc)(void);
 
 protected:
     CodecBase() = default;
@@ -324,4 +322,3 @@
 }  // namespace android
 
 #endif  // CODEC_BASE_H_
-
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecList.h b/media/libstagefright/include/media/stagefright/MediaCodecList.h
index bb4da09..e44b0a4 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecList.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecList.h
@@ -18,10 +18,11 @@
 
 #define MEDIA_CODEC_LIST_H_
 
-#include <initializer_list>
+#include <vector>
 
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/MediaCodecListWriter.h>
 #include <media/IMediaCodecList.h>
 #include <media/MediaCodecInfo.h>
 
@@ -37,8 +38,6 @@
 
 struct AMessage;
 
-struct MediaCodecListBuilderBase;
-
 struct MediaCodecList : public BnMediaCodecList {
     static sp<IMediaCodecList> getInstance();
 
@@ -97,7 +96,7 @@
      * This constructor will call `buildMediaCodecList()` from the given
      * `MediaCodecListBuilderBase` objects.
      */
-    MediaCodecList(std::initializer_list<MediaCodecListBuilderBase*> builders);
+    MediaCodecList(std::vector<MediaCodecListBuilderBase*> builders);
 
     ~MediaCodecList();
 
@@ -105,66 +104,6 @@
 
     MediaCodecList(const MediaCodecList&) = delete;
     MediaCodecList& operator=(const MediaCodecList&) = delete;
-
-    friend MediaCodecListWriter;
-};
-
-/**
- * This class is to be used by a `MediaCodecListBuilderBase` instance to add
- * information to the associated `MediaCodecList` object.
- */
-struct MediaCodecListWriter {
-    /**
-     * Add a key-value pair to a `MediaCodecList`'s global settings.
-     *
-     * @param key Key.
-     * @param value Value.
-     */
-    void addGlobalSetting(const char* key, const char* value);
-    /**
-     * Create an add a new `MediaCodecInfo` object to a `MediaCodecList`, and
-     * return a `MediaCodecInfoWriter` object associated with the newly added
-     * `MediaCodecInfo`.
-     *
-     * @return The `MediaCodecInfoWriter` object associated with the newly
-     * added `MediaCodecInfo` object.
-     */
-    std::unique_ptr<MediaCodecInfoWriter> addMediaCodecInfo();
-private:
-    /**
-     * The associated `MediaCodecList` object.
-     */
-    MediaCodecList* mList;
-
-    /**
-     * Construct this writer object associated with the given `MediaCodecList`
-     * object.
-     *
-     * @param list The "base" `MediaCodecList` object.
-     */
-    MediaCodecListWriter(MediaCodecList* list);
-
-    friend MediaCodecList;
-};
-
-/**
- * This interface is to be used by `MediaCodecList` to fill its members with
- * appropriate information. `buildMediaCodecList()` will be called from a
- * `MediaCodecList` object during its construction.
- */
-struct MediaCodecListBuilderBase {
-    /**
-     * Build the `MediaCodecList` via the given `MediaCodecListWriter` interface.
-     *
-     * @param writer The writer interface.
-     * @return The status of the construction. `NO_ERROR` means success.
-     */
-    virtual status_t buildMediaCodecList(MediaCodecListWriter* writer) = 0;
-
-    /**
-     * The default destructor does nothing.
-     */
-    virtual ~MediaCodecListBuilderBase();
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h b/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h
new file mode 100644
index 0000000..59f57c7
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/MediaCodecListWriter.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_CODEC_LIST_WRITER_H_
+
+#define MEDIA_CODEC_LIST_WRITER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaCodecListWriter.h>
+#include <media/MediaCodecInfo.h>
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+/**
+ * This class is to be used by a `MediaCodecListBuilderBase` instance to add
+ * information to the destination `MediaCodecList` object.
+ */
+struct MediaCodecListWriter {
+    /**
+     * Add a key-value pair to a `MediaCodecList`'s global settings.
+     *
+     * @param key Key.
+     * @param value Value.
+     */
+    void addGlobalSetting(const char* key, const char* value);
+    /**
+     * Create an add a new `MediaCodecInfo` object for a `MediaCodecList`, and
+     * return a `MediaCodecInfoWriter` object associated with the newly added
+     * `MediaCodecInfo`.
+     *
+     * @return The `MediaCodecInfoWriter` object associated with the newly
+     * added `MediaCodecInfo` object.
+     */
+    std::unique_ptr<MediaCodecInfoWriter> addMediaCodecInfo();
+private:
+    MediaCodecListWriter() = default;
+
+    void writeGlobalSettings(const sp<AMessage> &globalSettings) const;
+    void writeCodecInfos(std::vector<sp<MediaCodecInfo>> *codecInfos) const;
+
+    std::vector<std::pair<std::string, std::string>> mGlobalSettings;
+    std::vector<sp<MediaCodecInfo>> mCodecInfos;
+
+    friend struct MediaCodecList;
+};
+
+/**
+ * This interface is to be used by `MediaCodecList` to fill its members with
+ * appropriate information. `buildMediaCodecList()` will be called from a
+ * `MediaCodecList` object during its construction.
+ */
+struct MediaCodecListBuilderBase {
+    /**
+     * Build the `MediaCodecList` via the given `MediaCodecListWriter` interface.
+     *
+     * @param writer The writer interface.
+     * @return The status of the construction. `NO_ERROR` means success.
+     */
+    virtual status_t buildMediaCodecList(MediaCodecListWriter* writer) = 0;
+
+    /**
+     * The default destructor does nothing.
+     */
+    virtual ~MediaCodecListBuilderBase() = default;
+
+    typedef MediaCodecListBuilderBase *(*CreateBuilderFunc)(void);
+};
+
+}  // namespace android
+
+#endif  // MEDIA_CODEC_LIST_WRITER_H_
+
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 675c932..54a7095 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -71,6 +71,8 @@
 
     status_t getFileFormat(sp<AMessage> *format) const;
 
+    status_t getExifOffsetSize(off64_t *offset, size_t *size) const;
+
     status_t selectTrack(size_t index, int64_t startTimeUs = -1ll,
             MediaSource::ReadOptions::SeekMode mode =
                 MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
diff --git a/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h b/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
index 1b4d873..28f6094 100644
--- a/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
+++ b/media/libstagefright/include/media/stagefright/OmxInfoBuilder.h
@@ -25,6 +25,7 @@
 class OmxInfoBuilder : public MediaCodecListBuilderBase {
 public:
     OmxInfoBuilder();
+    ~OmxInfoBuilder() override = default;
     status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
 };
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index ad63899..fb9b0ba 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1550,6 +1550,9 @@
 
     switch(eventId) {
         case ICameraService::EVENT_USER_SWITCHED: {
+            // Try to register for UID policy updates, in case we're recovering
+            // from a system server crash
+            mUidPolicy->registerSelf();
             doUserSwitch(/*newUserIds*/ args);
             break;
         }
@@ -2365,17 +2368,31 @@
 // ----------------------------------------------------------------------------
 
 void CameraService::UidPolicy::registerSelf() {
+    Mutex::Autolock _l(mUidLock);
+
     ActivityManager am;
+    if (mRegistered) return;
     am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
             | ActivityManager::UID_OBSERVER_ACTIVE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("cameraserver"));
+    status_t res = am.linkToDeath(this);
+    if (res == OK) {
+        mRegistered = true;
+        ALOGV("UidPolicy: Registered with ActivityManager");
+    }
 }
 
 void CameraService::UidPolicy::unregisterSelf() {
+    Mutex::Autolock _l(mUidLock);
+
     ActivityManager am;
     am.unregisterUidObserver(this);
+    am.unlinkToDeath(this);
+    mRegistered = false;
+    mActiveUids.clear();
+    ALOGV("UidPolicy: Unregistered with ActivityManager");
 }
 
 void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
@@ -2404,17 +2421,14 @@
 }
 
 bool CameraService::UidPolicy::isUidActive(uid_t uid) {
-    // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
-        return true;
-    }
     Mutex::Autolock _l(mUidLock);
     return isUidActiveLocked(uid);
 }
 
 bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
     // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
+    // If activity manager is unreachable, assume everything is active
+    if (uid < FIRST_APPLICATION_UID || !mRegistered) {
         return true;
     }
     auto it = mOverrideUids.find(uid);
@@ -2432,6 +2446,13 @@
     updateOverrideUid(uid, false, false);
 }
 
+void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
+    Mutex::Autolock _l(mUidLock);
+    ALOGV("UidPolicy: ActivityManager has died");
+    mRegistered = false;
+    mActiveUids.clear();
+}
+
 void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
     bool wasActive = false;
     bool isActive = false;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3812925..86a2b81 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -518,10 +518,10 @@
 
     // Observer for UID lifecycle enforcing that UIDs in idle
     // state cannot use the camera to protect user privacy.
-    class UidPolicy : public BnUidObserver {
+    class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(sp<CameraService> service)
-                : mService(service) {}
+                : mRegistered(false), mService(service) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -535,11 +535,14 @@
         void addOverrideUid(uid_t uid, bool active);
         void removeOverrideUid(uid_t uid);
 
+        // IBinder::DeathRecipient implementation
+        virtual void binderDied(const wp<IBinder> &who);
     private:
         bool isUidActiveLocked(uid_t uid);
         void updateOverrideUid(uid_t uid, bool active, bool insert);
 
         Mutex mUidLock;
+        bool mRegistered;
         wp<CameraService> mService;
         std::unordered_set<uid_t> mActiveUids;
         std::unordered_map<uid_t, bool> mOverrideUids;
