diff --git a/include/media/TimeCheck.h b/include/media/TimeCheck.h
new file mode 120000
index 0000000..e3ef134
--- /dev/null
+++ b/include/media/TimeCheck.h
@@ -0,0 +1 @@
+../../media/libmedia/include/media/TimeCheck.h
\ No newline at end of file
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/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 3358e35..873d836 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -24,6 +24,7 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
+#include <media/TimeCheck.h>
 #include <private/android_filesystem_config.h>
 
 #include "IAudioFlinger.h"
@@ -933,6 +934,8 @@
             break;
     }
 
+    TimeCheck check("IAudioFlinger");
+
     switch (code) {
         case CREATE_TRACK: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 8f5ff30..0b98502 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -27,6 +27,7 @@
 
 #include <media/AudioEffect.h>
 #include <media/IAudioPolicyService.h>
+#include <media/TimeCheck.h>
 #include <private/android_filesystem_config.h>
 #include <system/audio.h>
 
@@ -882,6 +883,8 @@
             break;
     }
 
+    TimeCheck check("IAudioPolicyService");
+
     switch (code) {
         case SET_DEVICE_CONNECTION_STATE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 34b15a8..3990e69 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -18,7 +18,7 @@
     vndk: {
         enabled: true,
     },
-    srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
+    srcs: ["AudioParameter.cpp", "TypeConverter.cpp", "TimeCheck.cpp"],
     cflags: [
         "-Werror",
         "-Wno-error=deprecated-declarations",
diff --git a/media/libmedia/TimeCheck.cpp b/media/libmedia/TimeCheck.cpp
new file mode 100644
index 0000000..dab5d4f
--- /dev/null
+++ b/media/libmedia/TimeCheck.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+#include <media/TimeCheck.h>
+
+namespace android {
+
+/* static */
+sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
+{
+    static sp<TimeCheck::TimeCheckThread> sTimeCheckThread = new TimeCheck::TimeCheckThread();
+    return sTimeCheckThread;
+}
+
+TimeCheck::TimeCheck(const char *tag, uint32_t timeoutMs)
+    : mEndTimeNs(getTimeCheckThread()->startMonitoring(tag, timeoutMs))
+{
+}
+
+TimeCheck::~TimeCheck() {
+    getTimeCheckThread()->stopMonitoring(mEndTimeNs);
+}
+
+TimeCheck::TimeCheckThread::~TimeCheckThread()
+{
+    AutoMutex _l(mMutex);
+    requestExit();
+    mMonitorRequests.clear();
+    mCond.signal();
+}
+
+nsecs_t TimeCheck::TimeCheckThread::startMonitoring(const char *tag, uint32_t timeoutMs) {
+    Mutex::Autolock _l(mMutex);
+    nsecs_t endTimeNs = systemTime() + milliseconds(timeoutMs);
+    for (; mMonitorRequests.indexOfKey(endTimeNs) >= 0; ++endTimeNs);
+    mMonitorRequests.add(endTimeNs, tag);
+    mCond.signal();
+    return endTimeNs;
+}
+
+void TimeCheck::TimeCheckThread::stopMonitoring(nsecs_t endTimeNs) {
+    Mutex::Autolock _l(mMutex);
+    mMonitorRequests.removeItem(endTimeNs);
+    mCond.signal();
+}
+
+bool TimeCheck::TimeCheckThread::threadLoop()
+{
+    status_t status = TIMED_OUT;
+    const char *tag;
+    {
+        AutoMutex _l(mMutex);
+
+        if (exitPending()) {
+            return false;
+        }
+
+        nsecs_t endTimeNs = INT64_MAX;
+        // KeyedVector mMonitorRequests is ordered so take first entry as next timeout
+        if (mMonitorRequests.size() != 0) {
+            endTimeNs = mMonitorRequests.keyAt(0);
+            tag = mMonitorRequests.valueAt(0);
+        }
+
+        const nsecs_t waitTimeNs = endTimeNs - systemTime();
+        if (waitTimeNs > 0) {
+            status = mCond.waitRelative(mMutex, waitTimeNs);
+        }
+    }
+    LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "TimeCheck timeout for %s", tag);
+    return true;
+}
+
+}; // namespace android
diff --git a/media/libmedia/include/media/TimeCheck.h b/media/libmedia/include/media/TimeCheck.h
new file mode 100644
index 0000000..6c5f656
--- /dev/null
+++ b/media/libmedia/include/media/TimeCheck.h
@@ -0,0 +1,72 @@
+/*
+ * 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 ANDROID_TIME_CHECK_H
+#define ANDROID_TIME_CHECK_H
+
+#include <utils/KeyedVector.h>
+#include <utils/Thread.h>
+
+
+namespace android {
+
+// A class monitoring execution time for a code block (scoped variable) and causing an assert
+// if it exceeds a certain time
+
+class TimeCheck {
+public:
+
+    // The default timeout is chosen to be less than system server watchdog timeout
+    static constexpr uint32_t kDefaultTimeOutMs = 5000;
+
+            TimeCheck(const char *tag, uint32_t timeoutMs = kDefaultTimeOutMs);
+            ~TimeCheck();
+
+private:
+
+    class TimeCheckThread : public Thread {
+    public:
+
+                            TimeCheckThread() {}
+        virtual             ~TimeCheckThread() override;
+
+                nsecs_t     startMonitoring(const char *tag, uint32_t timeoutMs);
+                void        stopMonitoring(nsecs_t endTimeNs);
+
+    private:
+
+                // RefBase
+        virtual void        onFirstRef() override { run("TimeCheckThread", PRIORITY_URGENT_AUDIO); }
+
+                // Thread
+        virtual bool        threadLoop() override;
+
+                Condition           mCond;
+                Mutex               mMutex;
+                // using the end time in ns as key is OK given the risk is low that two entries
+                // are added in such a way that <add time> + <timeout> are the same for both.
+                KeyedVector< nsecs_t, const char*>  mMonitorRequests;
+    };
+
+    static sp<TimeCheckThread> getTimeCheckThread();
+
+    const           nsecs_t mEndTimeNs;
+};
+
+}; // namespace android
+
+#endif  // ANDROID_TIME_CHECK_H
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 e2d5d0d..22b1e59 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -87,66 +87,6 @@
 }
 
 cc_library_shared {
-    name: "libstagefright_ccodec",
-
-    local_include_dirs: ["include"],
-
-    srcs: [
-        "C2OMXNode.cpp",
-        "CCodec.cpp",
-        "CCodecBufferChannel.cpp",
-        "Codec2Buffer.cpp",
-        "Codec2InfoBuilder.cpp",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    header_libs: [
-        "libstagefright_codec2_internal",
-    ],
-
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libgui",
-        "libhidlallocatorutils",
-        "libhidlbase",
-        "liblog",
-        "libmedia",
-        "libmedia_omx",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_codecbase",
-        "libstagefright_foundation",
-        "libstagefright_omx_utils",
-        "libstagefright_xmlparser",
-        "libui",
-        "libutils",
-        // TODO: Remove libv4l2_c2_componentstore.
-        "libv4l2_c2componentstore",
-        "android.hardware.cas.native@1.0",
-
-        // TODO: do not link directly with impl
-        "libstagefright_bufferqueue_helper",
-        "android.hardware.media.c2@1.0-service-impl",
-    ],
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        diag: {
-            cfi: true,
-        },
-    },
-}
-
-cc_library_shared {
     name: "libstagefright",
 
     srcs: [
@@ -220,7 +160,6 @@
         "libui",
         "libutils",
         "libmedia_helper",
-        "libstagefright_ccodec",
         "libstagefright_codecbase",
         "libstagefright_foundation",
         "libstagefright_omx",
diff --git a/media/libstagefright/C2OMXNode.cpp b/media/libstagefright/C2OMXNode.cpp
deleted file mode 100644
index 04faa28..0000000
--- a/media/libstagefright/C2OMXNode.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef __LP64__
-#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
-#endif
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2OMXNode"
-#include <log/log.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2BlockInternal.h>
-#include <C2Component.h>
-#include <C2PlatformSupport.h>
-
-#include <OMX_Component.h>
-#include <OMX_Index.h>
-#include <OMX_IndexExt.h>
-
-#include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/MediaErrors.h>
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include "include/C2OMXNode.h"
-
-namespace android {
-
-namespace {
-
-class Buffer2D : public C2Buffer {
-public:
-    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
-};
-
-}  // namespace
-
-C2OMXNode::C2OMXNode(const std::shared_ptr<C2Component> &comp) : mComp(comp) {}
-
-status_t C2OMXNode::freeNode() {
-    mComp.reset();
-    return OK;
-}
-
-status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    (void)cmd;
-    (void)param;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) {
-    status_t err = ERROR_UNSUPPORTED;
-    switch ((uint32_t)index) {
-        case OMX_IndexParamConsumerUsageBits: {
-            // TODO: read from intf()
-            OMX_U32 *usage = (OMX_U32 *)params;
-            *usage = GRALLOC_USAGE_SW_READ_OFTEN;
-            err = OK;
-            break;
-        }
-        case OMX_IndexParamPortDefinition: {
-            if (size < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
-                return BAD_VALUE;
-            }
-            OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
-            // TODO: read these from intf()
-            pDef->nBufferCountActual = 16;
-            pDef->eDomain = OMX_PortDomainVideo;
-            pDef->format.video.nFrameWidth = 1080;
-            pDef->format.video.nFrameHeight = 1920;
-            err = OK;
-            break;
-        }
-        default:
-            break;
-    }
-    return err;
-}
-
-status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
-    (void)index;
-    (void)params;
-    (void)size;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getConfig(OMX_INDEXTYPE index, void *config, size_t size) {
-    (void)index;
-    (void)config;
-    (void)size;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setConfig(OMX_INDEXTYPE index, const void *config, size_t size) {
-    (void)index;
-    (void)config;
-    (void)size;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
-    (void)portIndex;
-    (void)mode;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::prepareForAdaptivePlayback(
-        OMX_U32 portIndex, OMX_BOOL enable,
-        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
-    (void)portIndex;
-    (void)enable;
-    (void)maxFrameWidth;
-    (void)maxFrameHeight;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::configureVideoTunnelMode(
-        OMX_U32 portIndex, OMX_BOOL tunneled,
-        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
-    (void)portIndex;
-    (void)tunneled;
-    (void)audioHwSync;
-    *sidebandHandle = nullptr;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage) {
-    (void)portIndex;
-    *usage = 0;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
-    c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
-            C2PlatformAllocatorStore::GRALLOC,
-            &mAllocator);
-    if (err != OK) {
-        return UNKNOWN_ERROR;
-    }
-    mBufferSource = bufferSource;
-    return OK;
-}
-
-status_t C2OMXNode::allocateSecureBuffer(
-        OMX_U32 portIndex, size_t size, buffer_id *buffer,
-        void **bufferData, sp<NativeHandle> *nativeHandle) {
-    (void)portIndex;
-    (void)size;
-    (void)nativeHandle;
-    *buffer = 0;
-    *bufferData = nullptr;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::useBuffer(
-        OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer) {
-    (void)portIndex;
-    (void)omxBuf;
-    *buffer = 0;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::freeBuffer(OMX_U32 portIndex, buffer_id buffer) {
-    (void)portIndex;
-    (void)buffer;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::fillBuffer(
-        buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
-    (void)buffer;
-    (void)omxBuf;
-    (void)fenceFd;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::emptyBuffer(
-        buffer_id buffer, const OMXBuffer &omxBuf,
-        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
-    // TODO: better fence handling
-    if (fenceFd >= 0) {
-        sp<Fence> fence = new Fence(fenceFd);
-        fence->waitForever(LOG_TAG);
-    }
-    std::shared_ptr<C2Component> comp = mComp.lock();
-    if (!comp) {
-        return NO_INIT;
-    }
-
-    uint32_t c2Flags = 0;
-    std::shared_ptr<C2GraphicBlock> block;
-
-    C2Handle *handle = nullptr;
-    if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
-        std::shared_ptr<C2GraphicAllocation> alloc;
-        handle = WrapNativeCodec2GrallocHandle(
-                native_handle_clone(omxBuf.mGraphicBuffer->handle),
-                omxBuf.mGraphicBuffer->width,
-                omxBuf.mGraphicBuffer->height,
-                omxBuf.mGraphicBuffer->format,
-                omxBuf.mGraphicBuffer->usage,
-                omxBuf.mGraphicBuffer->stride);
-        c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
-        if (err != OK) {
-            return UNKNOWN_ERROR;
-        }
-        block = _C2BlockFactory::CreateGraphicBlock(alloc);
-    } else if (flags & OMX_BUFFERFLAG_EOS) {
-        c2Flags = C2FrameData::FLAG_END_OF_STREAM;
-    } else {
-        return BAD_VALUE;
-    }
-
-    std::unique_ptr<C2Work> work(new C2Work);
-    work->input.flags = (C2FrameData::flags_t)c2Flags;
-    work->input.ordinal.timestamp = timestamp;
-    work->input.ordinal.frameIndex = mFrameIndex++;
-    work->input.buffers.clear();
-    if (block) {
-        std::shared_ptr<C2Buffer> c2Buffer(
-                // TODO: fence
-                new Buffer2D(block->share(
-                        C2Rect(block->width(), block->height()), ::C2Fence())),
-                [handle, buffer, source = getSource()](C2Buffer *ptr) {
-                    delete ptr;
-                    native_handle_delete(handle);
-                    // TODO: fence
-                    (void)source->onInputBufferEmptied(buffer, -1);
-                });
-        work->input.buffers.push_back(c2Buffer);
-    }
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-
-    c2_status_t err = comp->queue_nb(&items);
-    if (err != C2_OK) {
-        return UNKNOWN_ERROR;
-    }
-
-    return OK;
-}
-
-status_t C2OMXNode::getExtensionIndex(
-        const char *parameterName, OMX_INDEXTYPE *index) {
-    (void)parameterName;
-    *index = OMX_IndexMax;
-    return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
-    if (msg.type != omx_message::EVENT) {
-        return ERROR_UNSUPPORTED;
-    }
-    if (msg.u.event_data.event != OMX_EventDataSpaceChanged) {
-        return ERROR_UNSUPPORTED;
-    }
-    // TODO: fill intf() with info inside |msg|.
-    return OK;
-}
-
-sp<IOMXBufferSource> C2OMXNode::getSource() {
-    return mBufferSource;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/CCodec.cpp b/media/libstagefright/CCodec.cpp
deleted file mode 100644
index 322f9fd..0000000
--- a/media/libstagefright/CCodec.cpp
+++ /dev/null
@@ -1,916 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "CCodec"
-#include <cutils/properties.h>
-#include <utils/Log.h>
-
-#include <thread>
-
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-
-#include <android/IOMXBufferSource.h>
-#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-#include <gui/Surface.h>
-#include <media/stagefright/codec2/1.0/InputSurface.h>
-#include <media/stagefright/BufferProducerWrapper.h>
-#include <media/stagefright/CCodec.h>
-#include <media/stagefright/PersistentSurface.h>
-
-#include "include/C2OMXNode.h"
-#include "include/CCodecBufferChannel.h"
-#include "include/InputSurfaceWrapper.h"
-
-namespace android {
-
-using namespace std::chrono_literals;
-using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
-
-namespace {
-
-class CCodecWatchdog : public AHandler {
-private:
-    enum {
-        kWhatRegister,
-        kWhatWatch,
-    };
-    constexpr static int64_t kWatchIntervalUs = 3000000;  // 3 secs
-
-public:
-    static sp<CCodecWatchdog> getInstance() {
-        Mutexed<sp<CCodecWatchdog>>::Locked instance(sInstance);
-        if (*instance == nullptr) {
-            *instance = new CCodecWatchdog;
-            (*instance)->init();
-        }
-        return *instance;
-    }
-
-    ~CCodecWatchdog() = default;
-
-    void registerCodec(CCodec *codec) {
-        sp<AMessage> msg = new AMessage(kWhatRegister, this);
-        msg->setPointer("codec", codec);
-        msg->post();
-    }
-
-protected:
-    void onMessageReceived(const sp<AMessage> &msg) {
-        switch (msg->what()) {
-            case kWhatRegister: {
-                void *ptr = nullptr;
-                CHECK(msg->findPointer("codec", &ptr));
-                Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs);
-                codecs->emplace_back((CCodec *)ptr);
-                break;
-            }
-
-            case kWhatWatch: {
-                Mutexed<std::list<wp<CCodec>>>::Locked codecs(mCodecs);
-                for (auto it = codecs->begin(); it != codecs->end(); ) {
-                    sp<CCodec> codec = it->promote();
-                    if (codec == nullptr) {
-                        it = codecs->erase(it);
-                        continue;
-                    }
-                    codec->initiateReleaseIfStuck();
-                    ++it;
-                }
-                msg->post(kWatchIntervalUs);
-                break;
-            }
-
-            default: {
-                TRESPASS("CCodecWatchdog: unrecognized message");
-            }
-        }
-    }
-
-private:
-    CCodecWatchdog() : mLooper(new ALooper) {}
-
-    void init() {
-        mLooper->setName("CCodecWatchdog");
-        mLooper->registerHandler(this);
-        mLooper->start();
-        (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs);
-    }
-
-    static Mutexed<sp<CCodecWatchdog>> sInstance;
-
-    sp<ALooper> mLooper;
-    Mutexed<std::list<wp<CCodec>>> mCodecs;
-};
-
-Mutexed<sp<CCodecWatchdog>> CCodecWatchdog::sInstance;
-
-class CCodecListener : public C2Component::Listener {
-public:
-    explicit CCodecListener(const wp<CCodec> &codec) : mCodec(codec) {}
-
-    virtual void onWorkDone_nb(
-            std::weak_ptr<C2Component> component,
-            std::list<std::unique_ptr<C2Work>> workItems) override {
-        (void)component;
-        sp<CCodec> codec(mCodec.promote());
-        if (!codec) {
-            return;
-        }
-        codec->onWorkDone(workItems);
-    }
-
-    virtual void onTripped_nb(
-            std::weak_ptr<C2Component> component,
-            std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
-        // TODO
-        (void)component;
-        (void)settingResult;
-    }
-
-    virtual void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override {
-        // TODO
-        (void)component;
-        (void)errorCode;
-    }
-
-private:
-    wp<CCodec> mCodec;
-};
-
-class C2InputSurfaceWrapper : public InputSurfaceWrapper {
-public:
-    explicit C2InputSurfaceWrapper(const sp<InputSurface> &surface) : mSurface(surface) {}
-    ~C2InputSurfaceWrapper() override = default;
-
-    status_t connect(const std::shared_ptr<C2Component> &comp) override {
-        if (mConnection != nullptr) {
-            return ALREADY_EXISTS;
-        }
-        mConnection = mSurface->connectToComponent(comp);
-        return OK;
-    }
-
-    void disconnect() override {
-        if (mConnection != nullptr) {
-            mConnection->disconnect();
-            mConnection.clear();
-        }
-    }
-
-private:
-    sp<InputSurface> mSurface;
-    sp<InputSurfaceConnection> mConnection;
-};
-
-class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
-public:
-    explicit GraphicBufferSourceWrapper(const sp<IGraphicBufferSource> &source) : mSource(source) {}
-    ~GraphicBufferSourceWrapper() override = default;
-
-    status_t connect(const std::shared_ptr<C2Component> &comp) override {
-        // TODO: proper color aspect & dataspace
-        android_dataspace dataSpace = HAL_DATASPACE_BT709;
-
-        mNode = new C2OMXNode(comp);
-        mSource->configure(mNode, dataSpace);
-
-        // TODO: configure according to intf().
-
-        sp<IOMXBufferSource> source = mNode->getSource();
-        if (source == nullptr) {
-            return NO_INIT;
-        }
-        constexpr size_t kNumSlots = 16;
-        for (size_t i = 0; i < kNumSlots; ++i) {
-            source->onInputBufferAdded(i);
-        }
-        source->onOmxExecuting();
-        return OK;
-    }
-
-    void disconnect() override {
-        if (mNode == nullptr) {
-            return;
-        }
-        sp<IOMXBufferSource> source = mNode->getSource();
-        if (source == nullptr) {
-            ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
-            return;
-        }
-        source->onOmxIdle();
-        source->onOmxLoaded();
-        mNode.clear();
-    }
-
-private:
-    sp<IGraphicBufferSource> mSource;
-    sp<C2OMXNode> mNode;
-};
-
-}  // namespace
-
-CCodec::CCodec()
-    : mChannel(new CCodecBufferChannel([this] (status_t err, enum ActionCode actionCode) {
-          mCallback->onError(err, actionCode);
-      })) {
-    CCodecWatchdog::getInstance()->registerCodec(this);
-}
-
-CCodec::~CCodec() {
-}
-
-std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
-    return mChannel;
-}
-
-status_t CCodec::tryAndReportOnError(std::function<status_t()> job) {
-    status_t err = job();
-    if (err != C2_OK) {
-        mCallback->onError(err, ACTION_CODE_FATAL);
-    }
-    return err;
-}
-
-void CCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
-    auto setAllocating = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != RELEASED) {
-            return INVALID_OPERATION;
-        }
-        state->set(ALLOCATING);
-        return OK;
-    };
-    if (tryAndReportOnError(setAllocating) != OK) {
-        return;
-    }
-
-    sp<RefBase> codecInfo;
-    CHECK(msg->findObject("codecInfo", &codecInfo));
-    // For Codec 2.0 components, componentName == codecInfo->getCodecName().
-
-    sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this));
-    allocMsg->setObject("codecInfo", codecInfo);
-    allocMsg->post();
-}
-
-void CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) {
-    if (codecInfo == nullptr) {
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    }
-    ALOGV("allocate(%s)", codecInfo->getCodecName());
-    mListener.reset(new CCodecListener(this));
-
-    AString componentName = codecInfo->getCodecName();
-    // TODO: use codecInfo->getOwnerName() for connecting to remote process.
-
-    std::shared_ptr<C2Component> comp;
-    c2_status_t err = GetCodec2PlatformComponentStore()->createComponent(
-            componentName.c_str(), &comp);
-    static bool v4l2Enabled =
-            property_get_bool("debug.stagefright.ccodec_v4l2", false);
-    if (err != C2_OK && v4l2Enabled) {
-        err = GetCodec2VDAComponentStore()->createComponent(
-                componentName.c_str(), &comp);
-    }
-    if (err != C2_OK) {
-        ALOGE("Failed Create component: %s", componentName.c_str());
-        Mutexed<State>::Locked state(mState);
-        state->set(RELEASED);
-        state.unlock();
-        mCallback->onError(err, ACTION_CODE_FATAL);
-        state.lock();
-        return;
-    }
-    ALOGV("Success Create component: %s", componentName.c_str());
-    comp->setListener_vb(mListener, C2_MAY_BLOCK);
-    mChannel->setComponent(comp);
-    auto setAllocated = [this, comp] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATING) {
-            state->set(RELEASED);
-            return UNKNOWN_ERROR;
-        }
-        state->set(ALLOCATED);
-        state->comp = comp;
-        return OK;
-    };
-    if (tryAndReportOnError(setAllocated) != OK) {
-        return;
-    }
-    mCallback->onComponentAllocated(comp->intf()->getName().c_str());
-}
-
-void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
-    auto checkAllocated = [this] {
-        Mutexed<State>::Locked state(mState);
-        return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK;
-    };
-    if (tryAndReportOnError(checkAllocated) != OK) {
-        return;
-    }
-
-    sp<AMessage> msg(new AMessage(kWhatConfigure, this));
-    msg->setMessage("format", format);
-    msg->post();
-}
-
-void CCodec::configure(const sp<AMessage> &msg) {
-    std::shared_ptr<C2ComponentInterface> intf;
-    auto checkAllocated = [this, &intf] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATED) {
-            state->set(RELEASED);
-            return UNKNOWN_ERROR;
-        }
-        intf = state->comp->intf();
-        return OK;
-    };
-    if (tryAndReportOnError(checkAllocated) != OK) {
-        return;
-    }
-
-    sp<AMessage> inputFormat(new AMessage);
-    sp<AMessage> outputFormat(new AMessage);
-    auto doConfig = [=] {
-        AString mime;
-        if (!msg->findString("mime", &mime)) {
-            return BAD_VALUE;
-        }
-
-        int32_t encoder;
-        if (!msg->findInt32("encoder", &encoder)) {
-            encoder = false;
-        }
-
-        // TODO: read from intf()
-        if ((!encoder) != (intf->getName().find("encoder") == std::string::npos)) {
-            return UNKNOWN_ERROR;
-        }
-
-        sp<RefBase> obj;
-        if (msg->findObject("native-window", &obj)) {
-            sp<Surface> surface = static_cast<Surface *>(obj.get());
-            setSurface(surface);
-        }
-
-        std::vector<std::unique_ptr<C2Param>> params;
-        std::initializer_list<C2Param::Index> indices {
-            C2PortMimeConfig::input::PARAM_TYPE,
-            C2PortMimeConfig::output::PARAM_TYPE,
-        };
-        c2_status_t c2err = intf->query_vb(
-                {},
-                indices,
-                C2_DONT_BLOCK,
-                &params);
-        if (c2err != C2_OK) {
-            ALOGE("Failed to query component interface: %d", c2err);
-            return UNKNOWN_ERROR;
-        }
-        if (params.size() != indices.size()) {
-            ALOGE("Component returns wrong number of params");
-            return UNKNOWN_ERROR;
-        }
-        if (!params[0] || !params[1]) {
-            ALOGE("Component returns null params");
-            return UNKNOWN_ERROR;
-        }
-        inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value);
-        outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value);
-
-        // XXX: hack
-        bool audio = mime.startsWithIgnoreCase("audio/");
-        if (encoder) {
-            if (audio) {
-                inputFormat->setInt32("channel-count", 1);
-                inputFormat->setInt32("sample-rate", 44100);
-                outputFormat->setInt32("channel-count", 1);
-                outputFormat->setInt32("sample-rate", 44100);
-            } else {
-                outputFormat->setInt32("width", 1080);
-                outputFormat->setInt32("height", 1920);
-            }
-        } else {
-            if (audio) {
-                outputFormat->setInt32("channel-count", 2);
-                outputFormat->setInt32("sample-rate", 44100);
-            } else {
-                int32_t tmp;
-                if (msg->findInt32("width", &tmp)) {
-                    outputFormat->setInt32("width", tmp);
-                }
-                if (msg->findInt32("height", &tmp)) {
-                    outputFormat->setInt32("height", tmp);
-                }
-            }
-        }
-
-        // TODO
-
-        return OK;
-    };
-    if (tryAndReportOnError(doConfig) != OK) {
-        return;
-    }
-
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        formats->inputFormat = inputFormat;
-        formats->outputFormat = outputFormat;
-    }
-    mCallback->onComponentConfigured(inputFormat, outputFormat);
-}
-
-void CCodec::initiateCreateInputSurface() {
-    status_t err = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATED) {
-            return UNKNOWN_ERROR;
-        }
-        // TODO: read it from intf() properly.
-        if (state->comp->intf()->getName().find("encoder") == std::string::npos) {
-            return INVALID_OPERATION;
-        }
-        return OK;
-    }();
-    if (err != OK) {
-        mCallback->onInputSurfaceCreationFailed(err);
-        return;
-    }
-
-    (new AMessage(kWhatCreateInputSurface, this))->post();
-}
-
-void CCodec::createInputSurface() {
-    // TODO: get this from codec process
-    sp<InputSurface> surface(InputSurface::Create());
-
-    // TODO: get proper error code.
-    status_t err = (surface == nullptr) ? UNKNOWN_ERROR : OK;
-    if (err != OK) {
-        ALOGE("Failed to initialize input surface: %d", err);
-        mCallback->onInputSurfaceCreationFailed(err);
-        return;
-    }
-
-    err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(surface));
-    if (err != OK) {
-        ALOGE("Failed to set up input surface: %d", err);
-        mCallback->onInputSurfaceCreationFailed(err);
-        return;
-    }
-
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    mCallback->onInputSurfaceCreated(
-            inputFormat,
-            outputFormat,
-            new BufferProducerWrapper(new H2BGraphicBufferProducer(surface)));
-}
-
-status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
-    status_t err = mChannel->setInputSurface(surface);
-    if (err != OK) {
-        return err;
-    }
-
-    // TODO: configure |surface| with other settings.
-    return OK;
-}
-
-void CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) {
-    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
-    msg->setObject("surface", surface);
-    msg->post();
-}
-
-void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
-    status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-            surface->getBufferSource()));
-    if (err != OK) {
-        ALOGE("Failed to set up input surface: %d", err);
-        mCallback->onInputSurfaceDeclined(err);
-        return;
-    }
-
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
-}
-
-void CCodec::initiateStart() {
-    auto setStarting = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATED) {
-            return UNKNOWN_ERROR;
-        }
-        state->set(STARTING);
-        return OK;
-    };
-    if (tryAndReportOnError(setStarting) != OK) {
-        return;
-    }
-
-    (new AMessage(kWhatStart, this))->post();
-}
-
-void CCodec::start() {
-    std::shared_ptr<C2Component> comp;
-    auto checkStarting = [this, &comp] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != STARTING) {
-            return UNKNOWN_ERROR;
-        }
-        comp = state->comp;
-        return OK;
-    };
-    if (tryAndReportOnError(checkStarting) != OK) {
-        return;
-    }
-
-    c2_status_t err = comp->start();
-    if (err != C2_OK) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    }
-    sp<AMessage> inputFormat;
-    sp<AMessage> outputFormat;
-    {
-        Mutexed<Formats>::Locked formats(mFormats);
-        inputFormat = formats->inputFormat;
-        outputFormat = formats->outputFormat;
-    }
-    status_t err2 = mChannel->start(inputFormat, outputFormat);
-    if (err2 != OK) {
-        mCallback->onError(err2, ACTION_CODE_FATAL);
-        return;
-    }
-
-    auto setRunning = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != STARTING) {
-            return UNKNOWN_ERROR;
-        }
-        state->set(RUNNING);
-        return OK;
-    };
-    if (tryAndReportOnError(setRunning) != OK) {
-        return;
-    }
-    mCallback->onStartCompleted();
-}
-
-void CCodec::initiateShutdown(bool keepComponentAllocated) {
-    if (keepComponentAllocated) {
-        initiateStop();
-    } else {
-        initiateRelease();
-    }
-}
-
-void CCodec::initiateStop() {
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == ALLOCATED
-                || state->get()  == RELEASED
-                || state->get() == STOPPING
-                || state->get() == RELEASING) {
-            // We're already stopped, released, or doing it right now.
-            state.unlock();
-            mCallback->onStopCompleted();
-            state.lock();
-            return;
-        }
-        state->set(STOPPING);
-    }
-
-    (new AMessage(kWhatStop, this))->post();
-}
-
-void CCodec::stop() {
-    std::shared_ptr<C2Component> comp;
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == RELEASING) {
-            state.unlock();
-            // We're already stopped or release is in progress.
-            mCallback->onStopCompleted();
-            state.lock();
-            return;
-        } else if (state->get() != STOPPING) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
-        }
-        comp = state->comp;
-    }
-    mChannel->stop();
-    status_t err = comp->stop();
-    if (err != C2_OK) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-    }
-
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == STOPPING) {
-            state->set(ALLOCATED);
-        }
-    }
-    mCallback->onStopCompleted();
-}
-
-void CCodec::initiateRelease(bool sendCallback /* = true */) {
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == RELEASED || state->get() == RELEASING) {
-            // We're already released or doing it right now.
-            if (sendCallback) {
-                state.unlock();
-                mCallback->onReleaseCompleted();
-                state.lock();
-            }
-            return;
-        }
-        if (state->get() == ALLOCATING) {
-            state->set(RELEASING);
-            // With the altered state allocate() would fail and clean up.
-            if (sendCallback) {
-                state.unlock();
-                mCallback->onReleaseCompleted();
-                state.lock();
-            }
-            return;
-        }
-        state->set(RELEASING);
-    }
-
-    std::thread([this, sendCallback] { release(sendCallback); }).detach();
-}
-
-void CCodec::release(bool sendCallback) {
-    std::shared_ptr<C2Component> comp;
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == RELEASED) {
-            if (sendCallback) {
-                state.unlock();
-                mCallback->onReleaseCompleted();
-                state.lock();
-            }
-            return;
-        }
-        comp = state->comp;
-    }
-    mChannel->stop();
-    comp->release();
-
-    {
-        Mutexed<State>::Locked state(mState);
-        state->set(RELEASED);
-        state->comp.reset();
-    }
-    if (sendCallback) {
-        mCallback->onReleaseCompleted();
-    }
-}
-
-status_t CCodec::setSurface(const sp<Surface> &surface) {
-    return mChannel->setSurface(surface);
-}
-
-void CCodec::signalFlush() {
-    status_t err = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() == FLUSHED) {
-            return ALREADY_EXISTS;
-        }
-        if (state->get() != RUNNING) {
-            return UNKNOWN_ERROR;
-        }
-        state->set(FLUSHING);
-        return OK;
-    }();
-    switch (err) {
-        case ALREADY_EXISTS:
-            mCallback->onFlushCompleted();
-            return;
-        case OK:
-            break;
-        default:
-            mCallback->onError(err, ACTION_CODE_FATAL);
-            return;
-    }
-
-    (new AMessage(kWhatFlush, this))->post();
-}
-
-void CCodec::flush() {
-    std::shared_ptr<C2Component> comp;
-    auto checkFlushing = [this, &comp] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != FLUSHING) {
-            return UNKNOWN_ERROR;
-        }
-        comp = state->comp;
-        return OK;
-    };
-    if (tryAndReportOnError(checkFlushing) != OK) {
-        return;
-    }
-
-    mChannel->stop();
-
-    std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err = comp->flush_sm(C2Component::FLUSH_COMPONENT, &flushedWork);
-    if (err != C2_OK) {
-        // TODO: convert err into status_t
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-    }
-
-    mChannel->flush(flushedWork);
-
-    {
-        Mutexed<State>::Locked state(mState);
-        state->set(FLUSHED);
-    }
-    mCallback->onFlushCompleted();
-}
-
-void CCodec::signalResume() {
-    auto setResuming = [this] {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != FLUSHED) {
-            return UNKNOWN_ERROR;
-        }
-        state->set(RESUMING);
-        return OK;
-    };
-    if (tryAndReportOnError(setResuming) != OK) {
-        return;
-    }
-
-    (void)mChannel->start(nullptr, nullptr);
-
-    {
-        Mutexed<State>::Locked state(mState);
-        if (state->get() != RESUMING) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
-        }
-        state->set(RUNNING);
-    }
-}
-
-void CCodec::signalSetParameters(const sp<AMessage> &msg) {
-    // TODO
-    (void) msg;
-}
-
-void CCodec::signalEndOfInputStream() {
-    // TODO
-    mCallback->onSignaledInputEOS(INVALID_OPERATION);
-}
-
-void CCodec::signalRequestIDRFrame() {
-    // TODO
-}
-
-void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
-    Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
-    queue->splice(queue->end(), workItems);
-    (new AMessage(kWhatWorkDone, this))->post();
-}
-
-void CCodec::onMessageReceived(const sp<AMessage> &msg) {
-    TimePoint now = std::chrono::steady_clock::now();
-    switch (msg->what()) {
-        case kWhatAllocate: {
-            // C2ComponentStore::createComponent() should return within 100ms.
-            setDeadline(now + 150ms, "allocate");
-            sp<RefBase> obj;
-            CHECK(msg->findObject("codecInfo", &obj));
-            allocate((MediaCodecInfo *)obj.get());
-            break;
-        }
-        case kWhatConfigure: {
-            // C2Component::commit_sm() should return within 5ms.
-            setDeadline(now + 50ms, "configure");
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-            configure(format);
-            break;
-        }
-        case kWhatStart: {
-            // C2Component::start() should return within 500ms.
-            setDeadline(now + 550ms, "start");
-            start();
-            break;
-        }
-        case kWhatStop: {
-            // C2Component::stop() should return within 500ms.
-            setDeadline(now + 550ms, "stop");
-            stop();
-            break;
-        }
-        case kWhatFlush: {
-            // C2Component::flush_sm() should return within 5ms.
-            setDeadline(now + 50ms, "flush");
-            flush();
-            break;
-        }
-        case kWhatCreateInputSurface: {
-            // Surface operations may be briefly blocking.
-            setDeadline(now + 100ms, "createInputSurface");
-            createInputSurface();
-            break;
-        }
-        case kWhatSetInputSurface: {
-            // Surface operations may be briefly blocking.
-            setDeadline(now + 100ms, "setInputSurface");
-            sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
-            sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get()));
-            setInputSurface(surface);
-            break;
-        }
-        case kWhatWorkDone: {
-            std::unique_ptr<C2Work> work;
-            {
-                Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
-                if (queue->empty()) {
-                    break;
-                }
-                work.swap(queue->front());
-                queue->pop_front();
-                if (!queue->empty()) {
-                    (new AMessage(kWhatWorkDone, this))->post();
-                }
-            }
-            mChannel->onWorkDone(work);
-            break;
-        }
-        default: {
-            ALOGE("unrecognized message");
-            break;
-        }
-    }
-    setDeadline(TimePoint::max(), "none");
-}
-
-void CCodec::setDeadline(const TimePoint &newDeadline, const char *name) {
-    Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
-    deadline->set(newDeadline, name);
-}
-
-void CCodec::initiateReleaseIfStuck() {
-    std::string name;
-    {
-        Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
-        if (deadline->get() >= std::chrono::steady_clock::now()) {
-            // We're not stuck.
-            return;
-        }
-        name = deadline->getName();
-    }
-
-    ALOGW("previous call to %s exceeded timeout", name.c_str());
-    initiateRelease(false);
-    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-}
-
-}  // namespace android
-
-extern "C" android::CodecBase *CreateCodec() {
-    return new android::CCodec;
-}
diff --git a/media/libstagefright/CCodecBufferChannel.cpp b/media/libstagefright/CCodecBufferChannel.cpp
deleted file mode 100644
index cbe4f16..0000000
--- a/media/libstagefright/CCodecBufferChannel.cpp
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "CCodecBufferChannel"
-#include <utils/Log.h>
-
-#include <numeric>
-#include <thread>
-
-#include <C2AllocatorGralloc.h>
-#include <C2PlatformSupport.h>
-#include <C2BlockInternal.h>
-
-#include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <binder/MemoryDealer.h>
-#include <gui/Surface.h>
-#include <media/openmax/OMX_Core.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/MediaCodecBuffer.h>
-#include <system/window.h>
-
-#include "include/CCodecBufferChannel.h"
-#include "include/Codec2Buffer.h"
-#include "include/SecureBuffer.h"
-#include "include/SharedMemoryBuffer.h"
-
-namespace android {
-
-using hardware::hidl_handle;
-using hardware::hidl_string;
-using hardware::hidl_vec;
-using namespace hardware::cas::V1_0;
-using namespace hardware::cas::native::V1_0;
-
-using CasStatus = hardware::cas::V1_0::Status;
-
-/**
- * Base class for representation of buffers at one port.
- */
-class CCodecBufferChannel::Buffers {
-public:
-    Buffers() = default;
-    virtual ~Buffers() = default;
-
-    /**
-     * Set format for MediaCodec-facing buffers.
-     */
-    void setFormat(const sp<AMessage> &format) {
-        CHECK(format != nullptr);
-        mFormat = format;
-    }
-
-    /**
-     * Returns true if the buffers are operating under array mode.
-     */
-    virtual bool isArrayMode() const { return false; }
-
-    /**
-     * Fills the vector with MediaCodecBuffer's if in array mode; otherwise,
-     * no-op.
-     */
-    virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {}
-
-protected:
-    // Format to be used for creating MediaCodec-facing buffers.
-    sp<AMessage> mFormat;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(Buffers);
-};
-
-class CCodecBufferChannel::InputBuffers : public CCodecBufferChannel::Buffers {
-public:
-    InputBuffers() = default;
-    virtual ~InputBuffers() = default;
-
-    /**
-     * Set a block pool to obtain input memory blocks.
-     */
-    void setPool(const std::shared_ptr<C2BlockPool> &pool) { mPool = pool; }
-
-    /**
-     * Get a new MediaCodecBuffer for input and its corresponding index.
-     * Returns false if no new buffer can be obtained at the moment.
-     */
-    virtual bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) = 0;
-
-    /**
-     * Release the buffer obtained from requestNewBuffer() and get the
-     * associated C2Buffer object back. Returns empty shared_ptr if the
-     * buffer is not on file.
-     */
-    virtual std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
-
-    /**
-     * Flush internal state. After this call, no index or buffer previously
-     * returned from requestNewBuffer() is valid.
-     */
-    virtual void flush() = 0;
-
-    /**
-     * Return array-backed version of input buffers. The returned object
-     * shall retain the internal state so that it will honor index and
-     * buffer from previous calls of requestNewBuffer().
-     */
-    virtual std::unique_ptr<InputBuffers> toArrayMode() = 0;
-
-protected:
-    // Pool to obtain blocks for input buffers.
-    std::shared_ptr<C2BlockPool> mPool;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(InputBuffers);
-};
-
-class CCodecBufferChannel::OutputBuffers : public CCodecBufferChannel::Buffers {
-public:
-    OutputBuffers() = default;
-    virtual ~OutputBuffers() = default;
-
-    /**
-     * Register output C2Buffer from the component and obtain corresponding
-     * index and MediaCodecBuffer object. Returns false if registration
-     * fails.
-     */
-    virtual bool registerBuffer(
-            const std::shared_ptr<C2Buffer> &buffer,
-            size_t *index,
-            sp<MediaCodecBuffer> *clientBuffer) = 0;
-
-    /**
-     * Register codec specific data as a buffer to be consistent with
-     * MediaCodec behavior.
-     */
-    virtual bool registerCsd(
-            const C2StreamCsdInfo::output * /* csd */,
-            size_t * /* index */,
-            sp<MediaCodecBuffer> * /* clientBuffer */) = 0;
-
-    /**
-     * Release the buffer obtained from registerBuffer() and get the
-     * associated C2Buffer object back. Returns empty shared_ptr if the
-     * buffer is not on file.
-     */
-    virtual std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
-
-    /**
-     * Flush internal state. After this call, no index or buffer previously
-     * returned from registerBuffer() is valid.
-     */
-    virtual void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) = 0;
-
-    /**
-     * Return array-backed version of output buffers. The returned object
-     * shall retain the internal state so that it will honor index and
-     * buffer from previous calls of registerBuffer().
-     */
-    virtual std::unique_ptr<OutputBuffers> toArrayMode() = 0;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
-};
-
-namespace {
-
-// TODO: get this info from component
-const static size_t kMinBufferArraySize = 16;
-const static size_t kLinearBufferSize = 524288;
-const static size_t kMaxGraphicBufferRefCount = 4;
-
-/**
- * Simple local buffer pool backed by std::vector.
- */
-class LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> {
-public:
-    /**
-     * Create a new LocalBufferPool object.
-     *
-     * \param poolCapacity  max total size of buffers managed by this pool.
-     *
-     * \return  a newly created pool object.
-     */
-    static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity) {
-        return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity));
-    }
-
-    /**
-     * Return an ABuffer object whose size is at least |capacity|.
-     *
-     * \param   capacity  requested capacity
-     * \return  nullptr if the pool capacity is reached
-     *          an ABuffer object otherwise.
-     */
-    sp<ABuffer> newBuffer(size_t capacity) {
-        Mutex::Autolock lock(mMutex);
-        auto it = std::find_if(
-                mPool.begin(), mPool.end(),
-                [capacity](const std::vector<uint8_t> &vec) {
-                    return vec.capacity() >= capacity;
-                });
-        if (it != mPool.end()) {
-            sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
-            mPool.erase(it);
-            return buffer;
-        }
-        if (mUsedSize + capacity > mPoolCapacity) {
-            while (!mPool.empty()) {
-                mUsedSize -= mPool.back().capacity();
-                mPool.pop_back();
-            }
-            if (mUsedSize + capacity > mPoolCapacity) {
-                ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
-                        mUsedSize, capacity, mPoolCapacity);
-                return nullptr;
-            }
-        }
-        std::vector<uint8_t> vec(capacity);
-        mUsedSize += vec.capacity();
-        return new VectorBuffer(std::move(vec), shared_from_this());
-    }
-
-private:
-    /**
-     * ABuffer backed by std::vector.
-     */
-    class VectorBuffer : public ::android::ABuffer {
-    public:
-        /**
-         * Construct a VectorBuffer by taking the ownership of supplied vector.
-         *
-         * \param vec   backing vector of the buffer. this object takes
-         *              ownership at construction.
-         * \param pool  a LocalBufferPool object to return the vector at
-         *              destruction.
-         */
-        VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
-            : ABuffer(vec.data(), vec.capacity()),
-              mVec(std::move(vec)),
-              mPool(pool) {
-        }
-
-        ~VectorBuffer() override {
-            std::shared_ptr<LocalBufferPool> pool = mPool.lock();
-            if (pool) {
-                // If pool is alive, return the vector back to the pool so that
-                // it can be recycled.
-                pool->returnVector(std::move(mVec));
-            }
-        }
-
-    private:
-        std::vector<uint8_t> mVec;
-        std::weak_ptr<LocalBufferPool> mPool;
-    };
-
-    Mutex mMutex;
-    size_t mPoolCapacity;
-    size_t mUsedSize;
-    std::list<std::vector<uint8_t>> mPool;
-
-    /**
-     * Private constructor to prevent constructing non-managed LocalBufferPool.
-     */
-    explicit LocalBufferPool(size_t poolCapacity)
-        : mPoolCapacity(poolCapacity), mUsedSize(0) {
-    }
-
-    /**
-     * Take back the ownership of vec from the destructed VectorBuffer and put
-     * it in front of the pool.
-     */
-    void returnVector(std::vector<uint8_t> &&vec) {
-        Mutex::Autolock lock(mMutex);
-        mPool.push_front(std::move(vec));
-    }
-
-    DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool);
-};
-
-sp<GraphicBlockBuffer> AllocateGraphicBuffer(
-        const std::shared_ptr<C2BlockPool> &pool,
-        const sp<AMessage> &format,
-        uint32_t pixelFormat,
-        const C2MemoryUsage &usage,
-        const std::shared_ptr<LocalBufferPool> &localBufferPool) {
-    int32_t width, height;
-    if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
-        ALOGD("format lacks width or height");
-        return nullptr;
-    }
-
-    std::shared_ptr<C2GraphicBlock> block;
-    c2_status_t err = pool->fetchGraphicBlock(
-            width, height, pixelFormat, usage, &block);
-    if (err != C2_OK) {
-        ALOGD("fetch graphic block failed: %d", err);
-        return nullptr;
-    }
-
-    return GraphicBlockBuffer::Allocate(
-            format,
-            block,
-            [localBufferPool](size_t capacity) {
-                return localBufferPool->newBuffer(capacity);
-            });
-}
-
-class BuffersArrayImpl;
-
-/**
- * Flexible buffer slots implementation.
- */
-class FlexBuffersImpl {
-public:
-    FlexBuffersImpl() = default;
-
-    /**
-     * Assign an empty slot for a buffer and return the index. If there's no
-     * empty slot, just add one at the end and return it.
-     *
-     * \param buffer[in]  a new buffer to assign a slot.
-     * \return            index of the assigned slot.
-     */
-    size_t assignSlot(const sp<Codec2Buffer> &buffer) {
-        for (size_t i = 0; i < mBuffers.size(); ++i) {
-            if (mBuffers[i].clientBuffer.promote() == nullptr
-                    && mBuffers[i].compBuffer.expired()) {
-                mBuffers[i].clientBuffer = buffer;
-                return i;
-            }
-        }
-        mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() });
-        return mBuffers.size() - 1;
-    }
-
-    /**
-     * Release the slot from the client, and get the C2Buffer object back from
-     * the previously assigned buffer. Note that the slot is not completely free
-     * until the returned C2Buffer object is freed.
-     *
-     * \param buffer[in]  the buffer previously assigned a slot.
-     * \return            C2Buffer object from |buffer|.
-     */
-    std::shared_ptr<C2Buffer> releaseSlot(const sp<MediaCodecBuffer> &buffer) {
-        sp<Codec2Buffer> c2Buffer;
-        size_t index = mBuffers.size();
-        for (size_t i = 0; i < mBuffers.size(); ++i) {
-            if (mBuffers[i].clientBuffer.promote() == buffer) {
-                c2Buffer = mBuffers[i].clientBuffer.promote();
-                index = i;
-                break;
-            }
-        }
-        if (c2Buffer == nullptr) {
-            ALOGD("No matching buffer found");
-            return nullptr;
-        }
-        std::shared_ptr<C2Buffer> result = c2Buffer->asC2Buffer();
-        mBuffers[index].compBuffer = result;
-        return result;
-    }
-
-private:
-    friend class BuffersArrayImpl;
-
-    struct Entry {
-        wp<Codec2Buffer> clientBuffer;
-        std::weak_ptr<C2Buffer> compBuffer;
-    };
-    std::vector<Entry> mBuffers;
-};
-
-/**
- * Static buffer slots implementation based on a fixed-size array.
- */
-class BuffersArrayImpl {
-public:
-    /**
-     * Initialize buffer array from the original |impl|. The buffers known by
-     * the client is preserved, and the empty slots are populated so that the
-     * array size is at least |minSize|.
-     *
-     * \param impl[in]      FlexBuffersImpl object used so far.
-     * \param minSize[in]   minimum size of the buffer array.
-     * \param allocate[in]  function to allocate a client buffer for an empty slot.
-     */
-    void initialize(
-            const FlexBuffersImpl &impl,
-            size_t minSize,
-            std::function<sp<Codec2Buffer>()> allocate) {
-        for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
-            sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer.promote();
-            bool ownedByClient = (clientBuffer != nullptr);
-            if (!ownedByClient) {
-                clientBuffer = allocate();
-            }
-            mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
-        }
-        for (size_t i = impl.mBuffers.size(); i < minSize; ++i) {
-            mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false });
-        }
-    }
-
-    /**
-     * Grab a buffer from the underlying array which matches the criteria.
-     *
-     * \param index[out]    index of the slot.
-     * \param buffer[out]   the matching buffer.
-     * \param match[in]     a function to test whether the buffer matches the
-     *                      criteria or not.
-     * \return OK           if successful,
-     *         NO_MEMORY    if there's no available slot meets the criteria.
-     */
-    status_t grabBuffer(
-            size_t *index,
-            sp<Codec2Buffer> *buffer,
-            std::function<bool(const sp<Codec2Buffer> &)> match =
-                [](const sp<Codec2Buffer> &) { return true; }) {
-        for (size_t i = 0; i < mBuffers.size(); ++i) {
-            if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()
-                    && match(mBuffers[i].clientBuffer)) {
-                mBuffers[i].ownedByClient = true;
-                *buffer = mBuffers[i].clientBuffer;
-                (*buffer)->meta()->clear();
-                (*buffer)->setRange(0, (*buffer)->capacity());
-                *index = i;
-                return OK;
-            }
-        }
-        return NO_MEMORY;
-    }
-
-    /**
-     * Return the buffer from the client, and get the C2Buffer object back from
-     * the buffer. Note that the slot is not completely free until the returned
-     * C2Buffer object is freed.
-     *
-     * \param buffer[in]  the buffer previously grabbed.
-     * \return            C2Buffer object from |buffer|.
-     */
-    std::shared_ptr<C2Buffer> returnBuffer(const sp<MediaCodecBuffer> &buffer) {
-        sp<Codec2Buffer> c2Buffer;
-        size_t index = mBuffers.size();
-        for (size_t i = 0; i < mBuffers.size(); ++i) {
-            if (mBuffers[i].clientBuffer == buffer) {
-                if (!mBuffers[i].ownedByClient) {
-                    ALOGD("Client returned a buffer it does not own according to our record: %zu", i);
-                }
-                c2Buffer = mBuffers[i].clientBuffer;
-                mBuffers[i].ownedByClient = false;
-                index = i;
-                break;
-            }
-        }
-        if (c2Buffer == nullptr) {
-            ALOGD("No matching buffer found");
-            return nullptr;
-        }
-        std::shared_ptr<C2Buffer> result = c2Buffer->asC2Buffer();
-        mBuffers[index].compBuffer = result;
-        return result;
-    }
-
-    /**
-     * Populate |array| with the underlying buffer array.
-     *
-     * \param array[out]  an array to be filled with the underlying buffer array.
-     */
-    void getArray(Vector<sp<MediaCodecBuffer>> *array) const {
-        array->clear();
-        for (const Entry &entry : mBuffers) {
-            array->push(entry.clientBuffer);
-        }
-    }
-
-    /**
-     * The client abandoned all known buffers, so reclaim the ownership.
-     */
-    void flush() {
-        for (Entry &entry : mBuffers) {
-            entry.ownedByClient = false;
-        }
-    }
-
-private:
-    struct Entry {
-        const sp<Codec2Buffer> clientBuffer;
-        std::weak_ptr<C2Buffer> compBuffer;
-        bool ownedByClient;
-    };
-    std::vector<Entry> mBuffers;
-};
-
-class InputBuffersArray : public CCodecBufferChannel::InputBuffers {
-public:
-    InputBuffersArray() = default;
-    ~InputBuffersArray() override = default;
-
-    void initialize(
-            const FlexBuffersImpl &impl,
-            size_t minSize,
-            std::function<sp<Codec2Buffer>()> allocate) {
-        mImpl.initialize(impl, minSize, allocate);
-    }
-
-    bool isArrayMode() const final { return true; }
-
-    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final {
-        return nullptr;
-    }
-
-    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        mImpl.getArray(array);
-    }
-
-    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        sp<Codec2Buffer> c2Buffer;
-        status_t err = mImpl.grabBuffer(index, &c2Buffer);
-        if (err == OK) {
-            c2Buffer->setFormat(mFormat);
-            *buffer = c2Buffer;
-            return true;
-        }
-        return false;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.returnBuffer(buffer);
-    }
-
-    void flush() override {
-        mImpl.flush();
-    }
-
-private:
-    BuffersArrayImpl mImpl;
-};
-
-class LinearInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
-    using CCodecBufferChannel::InputBuffers::InputBuffers;
-
-    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        // TODO: proper max input size
-        // TODO: read usage from intf
-        sp<Codec2Buffer> newBuffer = alloc(kLinearBufferSize);
-        if (newBuffer == nullptr) {
-            return false;
-        }
-        *index = mImpl.assignSlot(newBuffer);
-        *buffer = newBuffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.releaseSlot(buffer);
-    }
-
-    void flush() override {
-        // This is no-op by default unless we're in array mode where we need to keep
-        // track of the flushed work.
-    }
-
-    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final {
-        std::unique_ptr<InputBuffersArray> array(new InputBuffersArray);
-        array->setFormat(mFormat);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [this] () -> sp<Codec2Buffer> { return alloc(kLinearBufferSize); });
-        return std::move(array);
-    }
-
-    virtual sp<Codec2Buffer> alloc(size_t size) const {
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        std::shared_ptr<C2LinearBlock> block;
-
-        c2_status_t err = mPool->fetchLinearBlock(size, usage, &block);
-        if (err != C2_OK) {
-            return nullptr;
-        }
-
-        return LinearBlockBuffer::Allocate(mFormat, block);
-    }
-
-private:
-    FlexBuffersImpl mImpl;
-};
-
-class EncryptedLinearInputBuffers : public LinearInputBuffers {
-public:
-    EncryptedLinearInputBuffers(
-            bool secure,
-            const sp<MemoryDealer> &dealer,
-            const sp<ICrypto> &crypto,
-            int32_t heapSeqNum)
-        : mUsage({0, 0}),
-          mDealer(dealer),
-          mCrypto(crypto),
-          mHeapSeqNum(heapSeqNum) {
-        if (secure) {
-            mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
-        } else {
-            mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        }
-        for (size_t i = 0; i < kMinBufferArraySize; ++i) {
-            sp<IMemory> memory = mDealer->allocate(kLinearBufferSize);
-            if (memory == nullptr) {
-                ALOGD("Failed to allocate memory from dealer: only %zu slots allocated", i);
-                break;
-            }
-            mMemoryVector.push_back({std::weak_ptr<C2LinearBlock>(), memory});
-        }
-    }
-
-    ~EncryptedLinearInputBuffers() override {
-    }
-
-    sp<Codec2Buffer> alloc(size_t size) const override {
-        sp<IMemory> memory;
-        for (const Entry &entry : mMemoryVector) {
-            if (entry.block.expired()) {
-                memory = entry.memory;
-                break;
-            }
-        }
-        if (memory == nullptr) {
-            return nullptr;
-        }
-
-        std::shared_ptr<C2LinearBlock> block;
-        c2_status_t err = mPool->fetchLinearBlock(size, mUsage, &block);
-        if (err != C2_OK) {
-            return nullptr;
-        }
-
-        return new EncryptedLinearBlockBuffer(mFormat, block, memory, mHeapSeqNum);
-    }
-
-private:
-    C2MemoryUsage mUsage;
-    sp<MemoryDealer> mDealer;
-    sp<ICrypto> mCrypto;
-    int32_t mHeapSeqNum;
-    struct Entry {
-        std::weak_ptr<C2LinearBlock> block;
-        sp<IMemory> memory;
-    };
-    std::vector<Entry> mMemoryVector;
-};
-
-class GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
-    GraphicInputBuffers() : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {}
-    ~GraphicInputBuffers() override = default;
-
-    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
-        // TODO: proper max input size
-        // TODO: read usage from intf
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer(
-                mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
-        if (newBuffer == nullptr) {
-            return false;
-        }
-        *index = mImpl.assignSlot(newBuffer);
-        *buffer = newBuffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.releaseSlot(buffer);
-    }
-
-    void flush() override {
-        // This is no-op by default unless we're in array mode where we need to keep
-        // track of the flushed work.
-    }
-
-    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final {
-        std::unique_ptr<InputBuffersArray> array(new InputBuffersArray);
-        array->setFormat(mFormat);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> {
-                    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-                    return AllocateGraphicBuffer(
-                            pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp);
-                });
-        return std::move(array);
-    }
-
-private:
-    FlexBuffersImpl mImpl;
-    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
-};
-
-class DummyInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
-    DummyInputBuffers() = default;
-
-    bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
-        return false;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &) override {
-        return nullptr;
-    }
-
-    void flush() override {
-    }
-
-    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final {
-        return nullptr;
-    }
-
-    bool isArrayMode() const final { return true; }
-
-    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        array->clear();
-    }
-};
-
-class OutputBuffersArray : public CCodecBufferChannel::OutputBuffers {
-public:
-    OutputBuffersArray() = default;
-    ~OutputBuffersArray() override = default;
-
-    void initialize(
-            const FlexBuffersImpl &impl,
-            size_t minSize,
-            std::function<sp<Codec2Buffer>()> allocate) {
-        mImpl.initialize(impl, minSize, allocate);
-    }
-
-    bool isArrayMode() const final { return true; }
-
-    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() final {
-        return nullptr;
-    }
-
-    bool registerBuffer(
-            const std::shared_ptr<C2Buffer> &buffer,
-            size_t *index,
-            sp<MediaCodecBuffer> *clientBuffer) final {
-        sp<Codec2Buffer> c2Buffer;
-        status_t err = mImpl.grabBuffer(
-                index,
-                &c2Buffer,
-                [buffer](const sp<Codec2Buffer> &clientBuffer) {
-                    return clientBuffer->canCopy(buffer);
-                });
-        if (err != OK) {
-            ALOGD("grabBuffer failed: %d", err);
-            return false;
-        }
-        c2Buffer->setFormat(mFormat);
-        if (!c2Buffer->copy(buffer)) {
-            ALOGD("copy buffer failed");
-            return false;
-        }
-        *clientBuffer = c2Buffer;
-        return true;
-    }
-
-    bool registerCsd(
-            const C2StreamCsdInfo::output *csd,
-            size_t *index,
-            sp<MediaCodecBuffer> *clientBuffer) final {
-        sp<Codec2Buffer> c2Buffer;
-        status_t err = mImpl.grabBuffer(
-                index,
-                &c2Buffer,
-                [csd](const sp<Codec2Buffer> &clientBuffer) {
-                    return clientBuffer->base() != nullptr
-                            && clientBuffer->capacity() >= csd->flexCount();
-                });
-        if (err != OK) {
-            return false;
-        }
-        // TODO: proper format update
-        sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy(csd->m.value, csd->flexCount());
-        mFormat = mFormat->dup();
-        mFormat->setBuffer("csd-0", csdBuffer);
-
-        memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
-        c2Buffer->setRange(0, csd->flexCount());
-        c2Buffer->setFormat(mFormat);
-        *clientBuffer = c2Buffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) final {
-        return mImpl.returnBuffer(buffer);
-    }
-
-    void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
-        (void) flushedWork;
-        mImpl.flush();
-    }
-
-    void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
-        mImpl.getArray(array);
-    }
-
-private:
-    BuffersArrayImpl mImpl;
-};
-
-class FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers {
-public:
-    using CCodecBufferChannel::OutputBuffers::OutputBuffers;
-
-    bool registerBuffer(
-            const std::shared_ptr<C2Buffer> &buffer,
-            size_t *index,
-            sp<MediaCodecBuffer> *clientBuffer) override {
-        sp<Codec2Buffer> newBuffer = wrap(buffer);
-        newBuffer->setFormat(mFormat);
-        *index = mImpl.assignSlot(newBuffer);
-        *clientBuffer = newBuffer;
-        return true;
-    }
-
-    bool registerCsd(
-            const C2StreamCsdInfo::output *csd,
-            size_t *index,
-            sp<MediaCodecBuffer> *clientBuffer) final {
-        // TODO: proper format update
-        sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy(csd->m.value, csd->flexCount());
-        mFormat = mFormat->dup();
-        mFormat->setBuffer("csd-0", csdBuffer);
-
-        sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(mFormat, csdBuffer);
-        *index = mImpl.assignSlot(newBuffer);
-        *clientBuffer = newBuffer;
-        return true;
-    }
-
-    std::shared_ptr<C2Buffer> releaseBuffer(
-            const sp<MediaCodecBuffer> &buffer) override {
-        return mImpl.releaseSlot(buffer);
-    }
-
-    void flush(
-            const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
-        (void) flushedWork;
-        // This is no-op by default unless we're in array mode where we need to keep
-        // track of the flushed work.
-    }
-
-    std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode() override {
-        std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray);
-        array->setFormat(mFormat);
-        array->initialize(
-                mImpl,
-                kMinBufferArraySize,
-                [this]() { return allocateArrayBuffer(); });
-        return std::move(array);
-    }
-
-    /**
-     * Return an appropriate Codec2Buffer object for the type of buffers.
-     *
-     * \param buffer  C2Buffer object to wrap.
-     *
-     * \return  appropriate Codec2Buffer object to wrap |buffer|.
-     */
-    virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
-
-    /**
-     * Return an appropriate Codec2Buffer object for the type of buffers, to be
-     * used as an empty array buffer.
-     *
-     * \return  appropriate Codec2Buffer object which can copy() from C2Buffers.
-     */
-    virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
-
-private:
-    FlexBuffersImpl mImpl;
-};
-
-class LinearOutputBuffers : public FlexOutputBuffers {
-public:
-    using FlexOutputBuffers::FlexOutputBuffers;
-
-    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
-        if (buffer == nullptr) {
-            return new DummyContainerBuffer(mFormat, buffer);
-        }
-        if (buffer->data().type() != C2BufferData::LINEAR) {
-            // We expect linear output buffers from the component.
-            return nullptr;
-        }
-        if (buffer->data().linearBlocks().size() != 1u) {
-            // We expect one and only one linear block from the component.
-            return nullptr;
-        }
-        return ConstLinearBlockBuffer::Allocate(mFormat, buffer);
-    }
-
-    sp<Codec2Buffer> allocateArrayBuffer() override {
-        // TODO: proper max output size
-        return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
-    }
-};
-
-class GraphicOutputBuffers : public FlexOutputBuffers {
-public:
-    using FlexOutputBuffers::FlexOutputBuffers;
-
-    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
-        return new DummyContainerBuffer(mFormat, buffer);
-    }
-
-    sp<Codec2Buffer> allocateArrayBuffer() override {
-        return new DummyContainerBuffer(mFormat);
-    }
-};
-
-class RawGraphicOutputBuffers : public FlexOutputBuffers {
-public:
-    RawGraphicOutputBuffers()
-        : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {
-    }
-    ~RawGraphicOutputBuffers() override = default;
-
-    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
-        return ConstGraphicBlockBuffer::Allocate(
-                mFormat,
-                buffer,
-                [lbp = mLocalBufferPool](size_t capacity) {
-                    return lbp->newBuffer(capacity);
-                });
-    }
-
-    sp<Codec2Buffer> allocateArrayBuffer() override {
-        return ConstGraphicBlockBuffer::AllocateEmpty(
-                mFormat,
-                [lbp = mLocalBufferPool](size_t capacity) {
-                    return lbp->newBuffer(capacity);
-                });
-    }
-
-private:
-    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
-};
-
-}  // namespace
-
-CCodecBufferChannel::QueueGuard::QueueGuard(
-        CCodecBufferChannel::QueueSync &sync) : mSync(sync) {
-    std::unique_lock<std::mutex> l(mSync.mMutex);
-    // At this point it's guaranteed that mSync is not under state transition,
-    // as we are holding its mutex.
-    if (mSync.mCount == -1) {
-        mRunning = false;
-    } else {
-        ++mSync.mCount;
-        mRunning = true;
-    }
-}
-
-CCodecBufferChannel::QueueGuard::~QueueGuard() {
-    if (mRunning) {
-        // We are not holding mutex at this point so that QueueSync::stop() can
-        // keep holding the lock until mCount reaches zero.
-        --mSync.mCount;
-    }
-}
-
-void CCodecBufferChannel::QueueSync::start() {
-    std::unique_lock<std::mutex> l(mMutex);
-    // If stopped, it goes to running state; otherwise no-op.
-    int32_t expected = -1;
-    (void)mCount.compare_exchange_strong(expected, 0);
-}
-
-void CCodecBufferChannel::QueueSync::stop() {
-    std::unique_lock<std::mutex> l(mMutex);
-    if (mCount == -1) {
-        // no-op
-        return;
-    }
-    // Holding mutex here blocks creation of additional QueueGuard objects, so
-    // mCount can only decrement. In other words, threads that acquired the lock
-    // are allowed to finish execution but additional threads trying to acquire
-    // the lock at this point will block, and then get QueueGuard at STOPPED
-    // state.
-    int32_t expected = 0;
-    while (!mCount.compare_exchange_weak(expected, -1)) {
-        std::this_thread::yield();
-    }
-}
-
-CCodecBufferChannel::CCodecBufferChannel(
-        const std::function<void(status_t, enum ActionCode)> &onError)
-    : mHeapSeqNum(-1),
-      mOnError(onError),
-      mFrameIndex(0u),
-      mFirstValidFrameIndex(0u) {
-}
-
-CCodecBufferChannel::~CCodecBufferChannel() {
-    if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
-        mCrypto->unsetHeap(mHeapSeqNum);
-    }
-}
-
-void CCodecBufferChannel::setComponent(const std::shared_ptr<C2Component> &component) {
-    mComponent = component;
-}
-
-status_t CCodecBufferChannel::setInputSurface(
-        const std::shared_ptr<InputSurfaceWrapper> &surface) {
-    ALOGV("setInputSurface");
-    mInputSurface = surface;
-    return OK;
-}
-
-status_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) {
-    int64_t timeUs;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-    int32_t flags = 0;
-    int32_t tmp = 0;
-    if (buffer->meta()->findInt32("eos", &tmp) && tmp) {
-        flags |= C2FrameData::FLAG_END_OF_STREAM;
-        ALOGV("input EOS");
-    }
-    if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
-        flags |= C2FrameData::FLAG_CODEC_CONFIG;
-    }
-    ALOGV("queueInputBuffer: buffer->size() = %zu", buffer->size());
-    std::unique_ptr<C2Work> work(new C2Work);
-    work->input.flags = (C2FrameData::flags_t)flags;
-    work->input.ordinal.timestamp = timeUs;
-    work->input.ordinal.frameIndex = mFrameIndex++;
-    work->input.buffers.clear();
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        std::shared_ptr<C2Buffer> c2buffer = (*buffers)->releaseBuffer(buffer);
-        if (!c2buffer) {
-            return -ENOENT;
-        }
-        work->input.buffers.push_back(c2buffer);
-    }
-    // TODO: fill info's
-
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    return mComponent->queue_nb(&items);
-}
-
-status_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
-    QueueGuard guard(mSync);
-    if (!guard.isRunning()) {
-        ALOGW("No more buffers should be queued at current state.");
-        return -ENOSYS;
-    }
-    return queueInputBufferInternal(buffer);
-}
-
-status_t CCodecBufferChannel::queueSecureInputBuffer(
-        const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
-        const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
-        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
-        AString *errorDetailMsg) {
-    QueueGuard guard(mSync);
-    if (!guard.isRunning()) {
-        ALOGW("No more buffers should be queued at current state.");
-        return -ENOSYS;
-    }
-
-    if (!hasCryptoOrDescrambler()) {
-        return -ENOSYS;
-    }
-    sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
-
-    ssize_t result = -1;
-    if (mCrypto != nullptr) {
-        ICrypto::DestinationBuffer destination;
-        if (secure) {
-            destination.mType = ICrypto::kDestinationTypeNativeHandle;
-            destination.mHandle = encryptedBuffer->handle();
-        } else {
-            destination.mType = ICrypto::kDestinationTypeSharedMemory;
-            destination.mSharedMemory = mDecryptDestination;
-        }
-        ICrypto::SourceBuffer source;
-        encryptedBuffer->fillSourceBuffer(&source);
-        result = mCrypto->decrypt(
-                key, iv, mode, pattern, source, buffer->offset(),
-                subSamples, numSubSamples, destination, errorDetailMsg);
-        if (result < 0) {
-            return result;
-        }
-        if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
-            encryptedBuffer->copyDecryptedContent(mDecryptDestination, result);
-        }
-    } else {
-        // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
-        // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
-        hidl_vec<SubSample> hidlSubSamples;
-        hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
-
-        hardware::cas::native::V1_0::SharedBuffer srcBuffer;
-        encryptedBuffer->fillSourceBuffer(&srcBuffer);
-
-        DestinationBuffer dstBuffer;
-        if (secure) {
-            dstBuffer.type = BufferType::NATIVE_HANDLE;
-            dstBuffer.secureMemory = hidl_handle(encryptedBuffer->handle());
-        } else {
-            dstBuffer.type = BufferType::SHARED_MEMORY;
-            dstBuffer.nonsecureMemory = srcBuffer;
-        }
-
-        CasStatus status = CasStatus::OK;
-        hidl_string detailedError;
-
-        auto returnVoid = mDescrambler->descramble(
-                key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
-                hidlSubSamples,
-                srcBuffer,
-                0,
-                dstBuffer,
-                0,
-                [&status, &result, &detailedError] (
-                        CasStatus _status, uint32_t _bytesWritten,
-                        const hidl_string& _detailedError) {
-                    status = _status;
-                    result = (ssize_t)_bytesWritten;
-                    detailedError = _detailedError;
-                });
-
-        if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) {
-            ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
-                    returnVoid.description().c_str(), status, result);
-            return UNKNOWN_ERROR;
-        }
-
-        ALOGV("descramble succeeded, %zd bytes", result);
-
-        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
-            encryptedBuffer->copyDecryptedContentFromMemory(result);
-        }
-    }
-
-    buffer->setRange(0, result);
-    return queueInputBufferInternal(buffer);
-}
-
-void CCodecBufferChannel::feedInputBufferIfAvailable() {
-    sp<MediaCodecBuffer> inBuffer;
-    size_t index;
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) {
-            ALOGV("no new buffer available");
-            inBuffer = nullptr;
-            return;
-        }
-    }
-    ALOGV("new input index = %zu", index);
-    mCallback->onInputBufferAvailable(index, inBuffer);
-}
-
-status_t CCodecBufferChannel::renderOutputBuffer(
-        const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
-    ALOGV("renderOutputBuffer");
-    feedInputBufferIfAvailable();
-
-    std::shared_ptr<C2Buffer> c2Buffer;
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        c2Buffer = (*buffers)->releaseBuffer(buffer);
-    }
-
-    Mutexed<OutputSurface>::Locked output(mOutputSurface);
-    if (output->surface == nullptr) {
-        ALOGE("no surface");
-        return OK;
-    }
-
-    std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
-    if (blocks.size() != 1u) {
-        ALOGE("# of graphic blocks expected to be 1, but %zu", blocks.size());
-        return UNKNOWN_ERROR;
-    }
-
-    native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(blocks.front().handle());
-    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
-            grallocHandle,
-            GraphicBuffer::CLONE_HANDLE,
-            blocks.front().width(),
-            blocks.front().height(),
-            HAL_PIXEL_FORMAT_YCbCr_420_888,
-            // TODO
-            1,
-            (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-            // TODO
-            blocks.front().width()));
-    native_handle_delete(grallocHandle);
-
-    status_t result = output->surface->attachBuffer(graphicBuffer.get());
-    if (result != OK) {
-        ALOGE("attachBuffer failed: %d", result);
-        return result;
-    }
-
-    // TODO: read and set crop
-
-    result = native_window_set_buffers_timestamp(output->surface.get(), timestampNs);
-    ALOGW_IF(result != OK, "failed to set buffer timestamp: %d", result);
-
-    // TODO: fix after C2Fence implementation
-#if 0
-    const C2Fence &fence = blocks.front().fence();
-    result = ((ANativeWindow *)output->surface.get())->queueBuffer(
-            output->surface.get(), graphicBuffer.get(), fence.valid() ? fence.fd() : -1);
-#else
-    result = ((ANativeWindow *)output->surface.get())->queueBuffer(
-            output->surface.get(), graphicBuffer.get(), -1);
-#endif
-    if (result != OK) {
-        ALOGE("queueBuffer failed: %d", result);
-        return result;
-    }
-
-    // XXX: Hack to keep C2Buffers unreleased until the consumer is done
-    //      reading the content. Eventually IGBP-based C2BlockPool should handle
-    //      the lifecycle.
-    output->bufferRefs.push_back(c2Buffer);
-    if (output->bufferRefs.size() > output->maxBufferCount + 1) {
-        output->bufferRefs.pop_front();
-        ALOGV("%zu buffer refs remaining", output->bufferRefs.size());
-    }
-
-    return OK;
-}
-
-status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
-    ALOGV("discardBuffer: %p", buffer.get());
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        (void)(*buffers)->releaseBuffer(buffer);
-    }
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if((*buffers)->releaseBuffer(buffer)) {
-            buffers.unlock();
-            feedInputBufferIfAvailable();
-            buffers.lock();
-        }
-    }
-    return OK;
-}
-
-void CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
-    array->clear();
-    Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-
-    if (!(*buffers)->isArrayMode()) {
-        *buffers = (*buffers)->toArrayMode();
-    }
-
-    (*buffers)->getArray(array);
-}
-
-void CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
-    array->clear();
-    Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
-    if (!(*buffers)->isArrayMode()) {
-        *buffers = (*buffers)->toArrayMode();
-    }
-
-    (*buffers)->getArray(array);
-}
-
-status_t CCodecBufferChannel::start(
-        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
-    C2StreamFormatConfig::input iStreamFormat(0u);
-    C2StreamFormatConfig::output oStreamFormat(0u);
-    c2_status_t err = mComponent->intf()->query_vb(
-            { &iStreamFormat, &oStreamFormat },
-            {},
-            C2_DONT_BLOCK,
-            nullptr);
-    if (err != C2_OK) {
-        return UNKNOWN_ERROR;
-    }
-    bool secure = mComponent->intf()->getName().find(".secure") != std::string::npos;
-
-    if (inputFormat != nullptr) {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-
-        bool graphic = (iStreamFormat.value == C2FormatVideo);
-        if (graphic) {
-            if (mInputSurface) {
-                buffers->reset(new DummyInputBuffers);
-            } else {
-                buffers->reset(new GraphicInputBuffers);
-            }
-        } else {
-            if (hasCryptoOrDescrambler()) {
-                if (mDealer == nullptr) {
-                    mDealer = new MemoryDealer(
-                            align(kLinearBufferSize, MemoryDealer::getAllocationAlignment())
-                                * (kMinBufferArraySize + 1),
-                            "EncryptedLinearInputBuffers");
-                    mDecryptDestination = mDealer->allocate(kLinearBufferSize);
-                }
-                if (mCrypto != nullptr && mHeapSeqNum < 0) {
-                    mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
-                } else {
-                    mHeapSeqNum = -1;
-                }
-                buffers->reset(new EncryptedLinearInputBuffers(
-                        secure, mDealer, mCrypto, mHeapSeqNum));
-            } else {
-                buffers->reset(new LinearInputBuffers);
-            }
-        }
-        (*buffers)->setFormat(inputFormat);
-
-        ALOGV("graphic = %s", graphic ? "true" : "false");
-        std::shared_ptr<C2BlockPool> pool;
-        if (graphic) {
-            err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, mComponent, &pool);
-        } else {
-            err = CreateCodec2BlockPool(C2PlatformAllocatorStore::ION,
-                                        mComponent, &pool);
-        }
-        if (err == C2_OK) {
-            (*buffers)->setPool(pool);
-        } else {
-            // TODO: error
-        }
-    }
-
-    if (outputFormat != nullptr) {
-        bool hasOutputSurface = false;
-        {
-            Mutexed<OutputSurface>::Locked output(mOutputSurface);
-            hasOutputSurface = (output->surface != nullptr);
-        }
-
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
-        bool graphic = (oStreamFormat.value == C2FormatVideo);
-        if (graphic) {
-            if (hasOutputSurface) {
-                buffers->reset(new GraphicOutputBuffers);
-            } else {
-                buffers->reset(new RawGraphicOutputBuffers);
-            }
-        } else {
-            buffers->reset(new LinearOutputBuffers);
-        }
-        (*buffers)->setFormat(outputFormat);
-    }
-
-    mSync.start();
-    if (mInputSurface == nullptr) {
-        // TODO: use proper buffer depth instead of this random value
-        for (size_t i = 0; i < kMinBufferArraySize; ++i) {
-            size_t index;
-            sp<MediaCodecBuffer> buffer;
-            {
-                Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-                if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
-                    if (i == 0) {
-                        ALOGE("start: cannot allocate memory at all");
-                        return NO_MEMORY;
-                    } else {
-                        ALOGV("start: cannot allocate memory, only %zu buffers allocated", i);
-                    }
-                    break;
-                }
-            }
-            mCallback->onInputBufferAvailable(index, buffer);
-        }
-    } else {
-        (void)mInputSurface->connect(mComponent);
-    }
-    return OK;
-}
-
-void CCodecBufferChannel::stop() {
-    mSync.stop();
-    mFirstValidFrameIndex = mFrameIndex.load();
-    if (mInputSurface != nullptr) {
-        mInputSurface->disconnect();
-        mInputSurface.reset();
-    }
-}
-
-void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-        (*buffers)->flush();
-    }
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        (*buffers)->flush(flushedWork);
-    }
-}
-
-void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
-    if (work->result != C2_OK) {
-        if (work->result == C2_NOT_FOUND) {
-            // TODO: Define what flushed work's result is.
-            ALOGD("flushed work; ignored.");
-            return;
-        }
-        ALOGD("work failed to complete: %d", work->result);
-        mOnError(work->result, ACTION_CODE_FATAL);
-        return;
-    }
-
-    // NOTE: MediaCodec usage supposedly have only one worklet
-    if (work->worklets.size() != 1u) {
-        ALOGE("onWorkDone: incorrect number of worklets: %zu",
-                work->worklets.size());
-        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    }
-
-    const std::unique_ptr<C2Worklet> &worklet = work->worklets.front();
-    if ((worklet->output.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
-        // Discard frames from previous generation.
-        return;
-    }
-    std::shared_ptr<C2Buffer> buffer;
-    // NOTE: MediaCodec usage supposedly have only one output stream.
-    if (worklet->output.buffers.size() > 1u) {
-        ALOGE("onWorkDone: incorrect number of output buffers: %zu",
-                worklet->output.buffers.size());
-        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-        return;
-    } else if (worklet->output.buffers.size() == 1u) {
-        buffer = worklet->output.buffers[0];
-        if (!buffer) {
-            ALOGW("onWorkDone: nullptr found in buffers; ignored.");
-        }
-    }
-
-    const C2StreamCsdInfo::output *csdInfo = nullptr;
-    for (const std::unique_ptr<C2Param> &info : worklet->output.configUpdate) {
-        if (info->coreIndex() == C2StreamCsdInfo::output::CORE_INDEX) {
-            ALOGV("onWorkDone: csd found");
-            csdInfo = static_cast<const C2StreamCsdInfo::output *>(info.get());
-        }
-    }
-
-    int32_t flags = 0;
-    if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
-        flags |= MediaCodec::BUFFER_FLAG_EOS;
-        ALOGV("onWorkDone: output EOS");
-    }
-
-    sp<MediaCodecBuffer> outBuffer;
-    size_t index;
-    if (csdInfo != nullptr) {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if ((*buffers)->registerCsd(csdInfo, &index, &outBuffer)) {
-            outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
-            outBuffer->meta()->setInt32("flags", flags | MediaCodec::BUFFER_FLAG_CODECCONFIG);
-            ALOGV("onWorkDone: csd index = %zu", index);
-
-            buffers.unlock();
-            mCallback->onOutputBufferAvailable(index, outBuffer);
-            buffers.lock();
-        } else {
-            ALOGE("onWorkDone: unable to register csd");
-            buffers.unlock();
-            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            buffers.lock();
-            return;
-        }
-    }
-
-    if (!buffer && !flags) {
-        ALOGV("onWorkDone: Not reporting output buffer");
-        return;
-    }
-
-    if (buffer) {
-        for (const std::shared_ptr<const C2Info> &info : buffer->info()) {
-            // TODO: properly translate these to metadata
-            switch (info->coreIndex().coreIndex()) {
-                case C2StreamPictureTypeMaskInfo::CORE_INDEX:
-                    if (((C2StreamPictureTypeMaskInfo *)info.get())->value & C2PictureTypeKeyFrame) {
-                        flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME;
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-        if (!(*buffers)->registerBuffer(buffer, &index, &outBuffer)) {
-            ALOGE("onWorkDone: unable to register output buffer");
-            buffers.unlock();
-            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            buffers.lock();
-            return;
-        }
-    }
-
-    outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
-    outBuffer->meta()->setInt32("flags", flags);
-    ALOGV("onWorkDone: out buffer index = %zu", index);
-    mCallback->onOutputBufferAvailable(index, outBuffer);
-}
-
-status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
-    if (newSurface != nullptr) {
-        newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
-    }
-
-    Mutexed<OutputSurface>::Locked output(mOutputSurface);
-//    if (newSurface == nullptr) {
-//        if (*surface != nullptr) {
-//            ALOGW("cannot unset a surface");
-//            return INVALID_OPERATION;
-//        }
-//        return OK;
-//    }
-//
-//    if (*surface == nullptr) {
-//        ALOGW("component was not configured with a surface");
-//        return INVALID_OPERATION;
-//    }
-
-    output->surface = newSurface;
-    output->bufferRefs.clear();
-    // XXX: hack
-    output->maxBufferCount = kMaxGraphicBufferRefCount;
-
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/Codec2Buffer.cpp b/media/libstagefright/Codec2Buffer.cpp
deleted file mode 100644
index d2ef229..0000000
--- a/media/libstagefright/Codec2Buffer.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * Copyright 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Codec2Buffer"
-#include <utils/Log.h>
-
-#include <hidlmemory/FrameworkUtils.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include "include/Codec2Buffer.h"
-
-namespace android {
-
-// Codec2Buffer
-
-bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
-    if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
-        return false;
-    }
-    if (!buffer) {
-        // Nothing to copy, so we can copy by doing nothing.
-        return true;
-    }
-    if (buffer->data().type() != C2BufferData::LINEAR) {
-        return false;
-    }
-    if (buffer->data().linearBlocks().size() == 0u) {
-        // Nothing to copy, so we can copy by doing nothing.
-        return true;
-    } else if (buffer->data().linearBlocks().size() > 1u) {
-        // We don't know how to copy more than one blocks.
-        return false;
-    }
-    if (buffer->data().linearBlocks()[0].size() > capacity()) {
-        // It won't fit.
-        return false;
-    }
-    return true;
-}
-
-bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
-    // We assume that all canCopyLinear() checks passed.
-    if (!buffer || buffer->data().linearBlocks().size() == 0u) {
-        setRange(0, 0);
-        return true;
-    }
-    C2ReadView view = buffer->data().linearBlocks()[0].map().get();
-    if (view.error() != C2_OK) {
-        ALOGD("Error while mapping: %d", view.error());
-        return false;
-    }
-    if (view.capacity() > capacity()) {
-        ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)",
-                view.capacity(), capacity());
-        return false;
-    }
-    memcpy(base(), view.data(), view.capacity());
-    setRange(0, view.capacity());
-    return true;
-}
-
-// LocalLinearBuffer
-
-bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
-    return canCopyLinear(buffer);
-}
-
-bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
-    return copyLinear(buffer);
-}
-
-// DummyContainerBuffer
-
-DummyContainerBuffer::DummyContainerBuffer(
-        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer)
-    : Codec2Buffer(format, new ABuffer(nullptr, 1)),
-      mBufferRef(buffer) {
-    setRange(0, buffer ? 1 : 0);
-}
-
-std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
-    return std::move(mBufferRef);
-}
-
-bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
-    return !mBufferRef;
-}
-
-bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
-    mBufferRef = buffer;
-    setRange(0, mBufferRef ? 1 : 0);
-    return true;
-}
-
-// LinearBlockBuffer
-
-// static
-sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
-        const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
-    C2WriteView writeView(block->map().get());
-    if (writeView.error() != C2_OK) {
-        return nullptr;
-    }
-    return new LinearBlockBuffer(format, std::move(writeView), block);
-}
-
-std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() {
-    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
-}
-
-bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
-    return canCopyLinear(buffer);
-}
-
-bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
-    return copyLinear(buffer);
-}
-
-LinearBlockBuffer::LinearBlockBuffer(
-        const sp<AMessage> &format,
-        C2WriteView&& writeView,
-        const std::shared_ptr<C2LinearBlock> &block)
-    : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
-      mWriteView(writeView),
-      mBlock(block) {
-}
-
-// ConstLinearBlockBuffer
-
-// static
-sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate(
-        const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) {
-    if (!buffer
-            || buffer->data().type() != C2BufferData::LINEAR
-            || buffer->data().linearBlocks().size() != 1u) {
-        return nullptr;
-    }
-    C2ReadView readView(buffer->data().linearBlocks()[0].map().get());
-    if (readView.error() != C2_OK) {
-        return nullptr;
-    }
-    return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
-}
-
-ConstLinearBlockBuffer::ConstLinearBlockBuffer(
-        const sp<AMessage> &format,
-        C2ReadView&& readView,
-        const std::shared_ptr<C2Buffer> &buffer)
-    : Codec2Buffer(format, new ABuffer(
-            // NOTE: ABuffer only takes non-const pointer but this data is
-            //       supposed to be read-only.
-            const_cast<uint8_t *>(readView.data()), readView.capacity())),
-      mReadView(readView),
-      mBufferRef(buffer) {
-}
-
-std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
-    return std::move(mBufferRef);
-}
-
-// GraphicView2MediaImageConverter
-
-namespace {
-
-class GraphicView2MediaImageConverter {
-public:
-    explicit GraphicView2MediaImageConverter(const C2GraphicView &view)
-        : mInitCheck(NO_INIT),
-          mView(view),
-          mWidth(view.width()),
-          mHeight(view.height()),
-          mAllocatedDepth(0),
-          mBackBufferSize(0),
-          mMediaImage(new ABuffer(sizeof(MediaImage2))) {
-        if (view.error() != C2_OK) {
-            ALOGD("Converter: view.error() = %d", view.error());
-            mInitCheck = BAD_VALUE;
-            return;
-        }
-        MediaImage2 *mediaImage = (MediaImage2 *)mMediaImage->base();
-        const C2PlanarLayout &layout = view.layout();
-        if (layout.numPlanes == 0) {
-            ALOGD("Converter: 0 planes");
-            mInitCheck = BAD_VALUE;
-            return;
-        }
-        mAllocatedDepth = layout.planes[0].allocatedDepth;
-        uint32_t bitDepth = layout.planes[0].bitDepth;
-
-        switch (layout.type) {
-            case C2PlanarLayout::TYPE_YUV:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV; break;
-            case C2PlanarLayout::TYPE_YUVA:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA; break;
-            case C2PlanarLayout::TYPE_RGB:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB; break;
-            case C2PlanarLayout::TYPE_RGBA:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA; break;
-            default:
-                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN; break;
-        }
-        mediaImage->mNumPlanes = layout.numPlanes;
-        mediaImage->mWidth = mWidth;
-        mediaImage->mHeight = mHeight;
-        mediaImage->mBitDepth = bitDepth;
-        mediaImage->mBitDepthAllocated = mAllocatedDepth;
-
-        uint32_t bufferSize = 0;
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            if (plane.rightShift != 0) {
-                ALOGV("rightShift value of %u unsupported", plane.rightShift);
-                mInitCheck = BAD_VALUE;
-                return;
-            }
-            if (plane.endianness != C2PlaneInfo::NATIVE) {
-                ALOGV("endianness value of %u unsupported", plane.endianness);
-                mInitCheck = BAD_VALUE;
-                return;
-            }
-            if (plane.allocatedDepth != mAllocatedDepth || plane.bitDepth != bitDepth) {
-                ALOGV("different allocatedDepth/bitDepth per plane unsupported");
-                mInitCheck = BAD_VALUE;
-                return;
-            }
-            bufferSize += mWidth * mHeight
-                    / plane.rowSampling / plane.colSampling * (plane.allocatedDepth / 8);
-        }
-
-        mBackBufferSize = bufferSize;
-        mInitCheck = OK;
-    }
-
-    status_t initCheck() const { return mInitCheck; }
-
-    uint32_t backBufferSize() const { return mBackBufferSize; }
-
-    /**
-     * Convert C2GraphicView to MediaImage2. Note that if not wrapped, the content
-     * is not copied over in this function --- the caller should use
-     * CopyGraphicView2MediaImage() function to do that explicitly.
-     *
-     * \param   view[in]          source C2GraphicView object.
-     * \param   alloc[in]         allocator function for ABuffer.
-     * \param   mediaImage[out]   destination MediaImage2 object.
-     * \param   buffer[out]       new buffer object.
-     * \param   wrapped[out]      whether we wrapped around existing map or
-     *                            allocated a new buffer
-     *
-     * \return  true              if conversion succeeds,
-     *          false             otherwise; all output params should be ignored.
-     */
-    sp<ABuffer> wrap() {
-        MediaImage2 *mediaImage = getMediaImage();
-        const C2PlanarLayout &layout = mView.layout();
-        if (layout.numPlanes == 1) {
-            const C2PlaneInfo &plane = layout.planes[0];
-            ssize_t offset = plane.minOffset(mWidth, mHeight);
-            mediaImage->mPlane[0].mOffset = -offset;
-            mediaImage->mPlane[0].mColInc = plane.colInc;
-            mediaImage->mPlane[0].mRowInc = plane.rowInc;
-            mediaImage->mPlane[0].mHorizSubsampling = plane.colSampling;
-            mediaImage->mPlane[0].mVertSubsampling = plane.rowSampling;
-            return new ABuffer(
-                    const_cast<uint8_t *>(mView.data()[0] + offset),
-                    plane.maxOffset(mWidth, mHeight) - offset + 1);
-        }
-        const uint8_t *minPtr = mView.data()[0];
-        const uint8_t *maxPtr = mView.data()[0];
-        int32_t planeSize = 0;
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            ssize_t minOffset = plane.minOffset(mWidth, mHeight);
-            ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
-            if (minPtr > mView.data()[i] + minOffset) {
-                minPtr = mView.data()[i] + minOffset;
-            }
-            if (maxPtr < mView.data()[i] + maxOffset) {
-                maxPtr = mView.data()[i] + maxOffset;
-            }
-            planeSize += std::abs(plane.rowInc) * mHeight
-                    / plane.rowSampling / plane.colSampling * (mAllocatedDepth / 8);
-        }
-
-        if ((maxPtr - minPtr + 1) <= planeSize) {
-            // FIXME: this is risky as reading/writing data out of bound results in
-            //        an undefined behavior.
-            for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-                const C2PlaneInfo &plane = layout.planes[i];
-                mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
-                mediaImage->mPlane[i].mColInc = plane.colInc;
-                mediaImage->mPlane[i].mRowInc = plane.rowInc;
-                mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
-                mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
-            }
-            return new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
-        }
-
-        return nullptr;
-    }
-
-    bool setBackBuffer(const sp<ABuffer> &backBuffer) {
-        if (backBuffer->capacity() < mBackBufferSize) {
-            return false;
-        }
-        backBuffer->setRange(0, mBackBufferSize);
-
-        const C2PlanarLayout &layout = mView.layout();
-        MediaImage2 *mediaImage = getMediaImage();
-        uint32_t offset = 0;
-        // TODO: keep interleaved planes together
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            mediaImage->mPlane[i].mOffset = offset;
-            mediaImage->mPlane[i].mColInc = mAllocatedDepth / 8;
-            mediaImage->mPlane[i].mRowInc =
-                mediaImage->mPlane[i].mColInc * mWidth / plane.colSampling;
-            mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
-            mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
-            offset += mediaImage->mPlane[i].mRowInc * mHeight / plane.rowSampling;
-        }
-        mBackBuffer = backBuffer;
-        return true;
-    }
-
-    /**
-     * Copy C2GraphicView to MediaImage2. This function assumes that |mediaImage| is
-     * an output from GraphicView2MediaImage(), so it mostly skips sanity check.
-     *
-     * \param   view[in]          source C2GraphicView object.
-     * \param   mediaImage[in]    destination MediaImage2 object.
-     * \param   buffer[out]       new buffer object.
-     */
-    void copy() {
-        // TODO: more efficient copying --- e.g. one row at a time, copying
-        //       interleaved planes together, etc.
-        const C2PlanarLayout &layout = mView.layout();
-        MediaImage2 *mediaImage = getMediaImage();
-        uint8_t *dst = mBackBuffer->base();
-        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            const uint8_t *src = mView.data()[i];
-            int32_t planeW = mWidth / plane.colSampling;
-            int32_t planeH = mHeight / plane.rowSampling;
-            for (int32_t row = 0; row < planeH; ++row) {
-                for(int32_t col = 0; col < planeW; ++col) {
-                    memcpy(dst, src, mAllocatedDepth / 8);
-                    dst += mediaImage->mPlane[i].mColInc;
-                    src += plane.colInc;
-                }
-                dst -= mediaImage->mPlane[i].mColInc * planeW;
-                dst += mediaImage->mPlane[i].mRowInc;
-                src -= plane.colInc * planeW;
-                src += plane.rowInc;
-            }
-        }
-    }
-
-    const sp<ABuffer> &imageData() const { return mMediaImage; }
-
-private:
-    status_t mInitCheck;
-
-    const C2GraphicView mView;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mAllocatedDepth;
-    uint32_t mBackBufferSize;
-    sp<ABuffer> mMediaImage;
-    std::function<sp<ABuffer>(size_t)> mAlloc;
-
-    sp<ABuffer> mBackBuffer;
-
-    MediaImage2 *getMediaImage() {
-        return (MediaImage2 *)mMediaImage->base();
-    }
-};
-
-}  // namespace
-
-// GraphicBlockBuffer
-
-// static
-sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
-        const sp<AMessage> &format,
-        const std::shared_ptr<C2GraphicBlock> &block,
-        std::function<sp<ABuffer>(size_t)> alloc) {
-    C2GraphicView view(block->map().get());
-    if (view.error() != C2_OK) {
-        ALOGD("C2GraphicBlock::map failed: %d", view.error());
-        return nullptr;
-    }
-    GraphicView2MediaImageConverter converter(view);
-    if (converter.initCheck() != OK) {
-        ALOGD("Converter init failed: %d", converter.initCheck());
-        return nullptr;
-    }
-    bool wrapped = true;
-    sp<ABuffer> buffer = converter.wrap();
-    if (buffer == nullptr) {
-        buffer = alloc(converter.backBufferSize());
-        if (!converter.setBackBuffer(buffer)) {
-            ALOGD("Converter failed to set back buffer");
-            return nullptr;
-        }
-        wrapped = false;
-    }
-    return new GraphicBlockBuffer(
-            format,
-            buffer,
-            std::move(view),
-            block,
-            converter.imageData(),
-            wrapped);
-}
-
-GraphicBlockBuffer::GraphicBlockBuffer(
-        const sp<AMessage> &format,
-        const sp<ABuffer> &buffer,
-        C2GraphicView &&view,
-        const std::shared_ptr<C2GraphicBlock> &block,
-        const sp<ABuffer> &imageData,
-        bool wrapped)
-    : Codec2Buffer(format, buffer),
-      mView(view),
-      mBlock(block),
-      mImageData(imageData),
-      mWrapped(wrapped) {
-    meta()->setBuffer("image-data", imageData);
-}
-
-std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
-    uint32_t width = mView.width();
-    uint32_t height = mView.height();
-    if (!mWrapped) {
-        MediaImage2 *mediaImage = imageData();
-        const C2PlanarLayout &layout = mView.layout();
-        for (uint32_t i = 0; i < mediaImage->mNumPlanes; ++i) {
-            const C2PlaneInfo &plane = layout.planes[i];
-            int32_t planeW = width / plane.colSampling;
-            int32_t planeH = height / plane.rowSampling;
-            const uint8_t *src = base() + mediaImage->mPlane[i].mOffset;
-            uint8_t *dst = mView.data()[i];
-            for (int32_t row = 0; row < planeH; ++row) {
-                for (int32_t col = 0; col < planeW; ++col) {
-                    memcpy(dst, src, mediaImage->mBitDepthAllocated / 8);
-                    src += mediaImage->mPlane[i].mColInc;
-                    dst += plane.colInc;
-                }
-                src -= mediaImage->mPlane[i].mColInc * planeW;
-                dst -= plane.colInc * planeW;
-                src += mediaImage->mPlane[i].mRowInc;
-                dst += plane.rowInc;
-            }
-        }
-    }
-    return C2Buffer::CreateGraphicBuffer(
-            mBlock->share(C2Rect(width, height), C2Fence()));
-}
-
-// ConstGraphicBlockBuffer
-
-// static
-sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
-        const sp<AMessage> &format,
-        const std::shared_ptr<C2Buffer> &buffer,
-        std::function<sp<ABuffer>(size_t)> alloc) {
-    if (!buffer
-            || buffer->data().type() != C2BufferData::GRAPHIC
-            || buffer->data().graphicBlocks().size() != 1u) {
-        ALOGD("C2Buffer precond fail");
-        return nullptr;
-    }
-    std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
-            buffer->data().graphicBlocks()[0].map().get()));
-    std::unique_ptr<const C2GraphicView> holder;
-
-    GraphicView2MediaImageConverter converter(*view);
-    if (converter.initCheck() != OK) {
-        ALOGD("Converter init failed: %d", converter.initCheck());
-        return nullptr;
-    }
-    bool wrapped = true;
-    sp<ABuffer> aBuffer = converter.wrap();
-    if (aBuffer == nullptr) {
-        aBuffer = alloc(converter.backBufferSize());
-        if (!converter.setBackBuffer(aBuffer)) {
-            ALOGD("Converter failed to set back buffer");
-            return nullptr;
-        }
-        wrapped = false;
-        converter.copy();
-        // We don't need the view.
-        holder = std::move(view);
-    }
-    return new ConstGraphicBlockBuffer(
-            format,
-            aBuffer,
-            std::move(view),
-            buffer,
-            converter.imageData(),
-            wrapped);
-}
-
-// static
-sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
-        const sp<AMessage> &format,
-        std::function<sp<ABuffer>(size_t)> alloc) {
-    int32_t width, height;
-    if (!format->findInt32("width", &width)
-            || !format->findInt32("height", &height)) {
-        ALOGD("format had no width / height");
-        return nullptr;
-    }
-    sp<ABuffer> aBuffer(alloc(width * height * 4));
-    return new ConstGraphicBlockBuffer(
-            format,
-            aBuffer,
-            nullptr,
-            nullptr,
-            nullptr,
-            false);
-}
-
-ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
-        const sp<AMessage> &format,
-        const sp<ABuffer> &aBuffer,
-        std::unique_ptr<const C2GraphicView> &&view,
-        const std::shared_ptr<C2Buffer> &buffer,
-        const sp<ABuffer> &imageData,
-        bool wrapped)
-    : Codec2Buffer(format, aBuffer),
-      mView(std::move(view)),
-      mBufferRef(buffer),
-      mWrapped(wrapped) {
-    if (imageData != nullptr) {
-        meta()->setBuffer("image-data", imageData);
-    }
-}
-
-std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
-    mView.reset();
-    return std::move(mBufferRef);
-}
-
-bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
-    if (mWrapped || mBufferRef) {
-        ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
-                mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
-        return false;
-    }
-    if (!buffer) {
-        // Nothing to copy, so we can copy by doing nothing.
-        return true;
-    }
-    if (buffer->data().type() != C2BufferData::GRAPHIC) {
-        ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
-        return false;
-    }
-    if (buffer->data().graphicBlocks().size() == 0) {
-        return true;
-    } else if (buffer->data().graphicBlocks().size() != 1u) {
-        ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
-        return false;
-    }
-    GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get());
-    if (converter.initCheck() != OK) {
-        ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
-        return false;
-    }
-    if (converter.backBufferSize() > capacity()) {
-        ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
-                converter.backBufferSize(), capacity());
-        return false;
-    }
-    return true;
-}
-
-bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
-    if (!buffer || buffer->data().graphicBlocks().size() == 0) {
-        setRange(0, 0);
-        return true;
-    }
-    GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get());
-    if (converter.initCheck() != OK) {
-        ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
-        return false;
-    }
-    sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
-    if (!converter.setBackBuffer(aBuffer)) {
-        ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
-        return false;
-    }
-    converter.copy();
-    meta()->setBuffer("image-data", converter.imageData());
-    mBufferRef = buffer;
-    return true;
-}
-
-// EncryptedLinearBlockBuffer
-
-EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
-        const sp<AMessage> &format,
-        const std::shared_ptr<C2LinearBlock> &block,
-        const sp<IMemory> &memory,
-        int32_t heapSeqNum)
-    : Codec2Buffer(format, new ABuffer(memory->pointer(), memory->size())),
-      mBlock(block),
-      mMemory(memory),
-      mHeapSeqNum(heapSeqNum) {
-}
-
-std::shared_ptr<C2Buffer> EncryptedLinearBlockBuffer::asC2Buffer() {
-    return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
-}
-
-void EncryptedLinearBlockBuffer::fillSourceBuffer(
-        ICrypto::SourceBuffer *source) {
-    source->mSharedMemory = mMemory;
-    source->mHeapSeqNum = mHeapSeqNum;
-}
-
-void EncryptedLinearBlockBuffer::fillSourceBuffer(
-        hardware::cas::native::V1_0::SharedBuffer *source) {
-    ssize_t offset;
-    size_t size;
-
-    mHidlMemory = hardware::fromHeap(mMemory->getMemory(&offset, &size));
-    source->heapBase = *mHidlMemory;
-    source->offset = offset;
-    source->size = size;
-}
-
-bool EncryptedLinearBlockBuffer::copyDecryptedContent(
-        const sp<IMemory> &decrypted, size_t length) {
-    C2WriteView view = mBlock->map().get();
-    if (view.error() != C2_OK) {
-        return false;
-    }
-    if (view.size() < length) {
-        return false;
-    }
-    memcpy(view.data(), decrypted->pointer(), length);
-    return true;
-}
-
-bool EncryptedLinearBlockBuffer::copyDecryptedContentFromMemory(size_t length) {
-    return copyDecryptedContent(mMemory, length);
-}
-
-native_handle_t *EncryptedLinearBlockBuffer::handle() const {
-    return const_cast<native_handle_t *>(mBlock->handle());
-}
-
-}  // namespace android
diff --git a/media/libstagefright/Codec2InfoBuilder.cpp b/media/libstagefright/Codec2InfoBuilder.cpp
deleted file mode 100644
index bd749c4..0000000
--- a/media/libstagefright/Codec2InfoBuilder.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Codec2InfoBuilder"
-#include <log/log.h>
-
-#include <C2Component.h>
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
-#include <media/stagefright/Codec2InfoBuilder.h>
-
-namespace android {
-
-using ConstTraitsPtr = std::shared_ptr<const C2Component::Traits>;
-
-struct ProfileLevel {
-    uint32_t profile;
-    uint32_t level;
-};
-static const ProfileLevel kAvcProfileLevels[] = {
-    { 0x01, 0x0001 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
-    { 0x01, 0x0002 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
-    { 0x01, 0x0004 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
-    { 0x01, 0x0008 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
-    { 0x01, 0x0010 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
-    { 0x01, 0x0020 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
-    { 0x01, 0x0040 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
-    { 0x01, 0x0080 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
-    { 0x01, 0x0100 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
-    { 0x01, 0x0200 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
-    { 0x01, 0x0400 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
-    { 0x01, 0x0800 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
-    { 0x01, 0x1000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
-    { 0x01, 0x2000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
-    { 0x01, 0x4000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5  },
-    { 0x01, 0x8000 },  // { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
-
-    { 0x02, 0x0001 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1  },
-    { 0x02, 0x0002 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1b },
-    { 0x02, 0x0004 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel11 },
-    { 0x02, 0x0008 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel12 },
-    { 0x02, 0x0010 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel13 },
-    { 0x02, 0x0020 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel2  },
-    { 0x02, 0x0040 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel21 },
-    { 0x02, 0x0080 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel22 },
-    { 0x02, 0x0100 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel3  },
-    { 0x02, 0x0200 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel31 },
-    { 0x02, 0x0400 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel32 },
-    { 0x02, 0x0800 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel4  },
-    { 0x02, 0x1000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel41 },
-    { 0x02, 0x2000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel42 },
-    { 0x02, 0x4000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel5  },
-    { 0x02, 0x8000 },  // { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel51 },
-
-    { 0x04, 0x0001 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1  },
-    { 0x04, 0x0002 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1b },
-    { 0x04, 0x0004 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel11 },
-    { 0x04, 0x0008 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel12 },
-    { 0x04, 0x0010 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel13 },
-    { 0x04, 0x0020 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel2  },
-    { 0x04, 0x0040 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel21 },
-    { 0x04, 0x0080 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel22 },
-    { 0x04, 0x0100 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel3  },
-    { 0x04, 0x0200 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel31 },
-    { 0x04, 0x0400 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel32 },
-    { 0x04, 0x0800 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel4  },
-    { 0x04, 0x1000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel41 },
-    { 0x04, 0x2000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel42 },
-    { 0x04, 0x4000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel5  },
-    { 0x04, 0x8000 },  // { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel51 },
-};
-
-status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
-    // Obtain C2ComponentStore
-    std::shared_ptr<C2ComponentStore> store = GetCodec2PlatformComponentStore();
-    if (store == nullptr) {
-        ALOGE("Cannot find a component store.");
-        return NO_INIT;
-    }
-
-    std::vector<ConstTraitsPtr> traits = store->listComponents();
-
-    if (property_get_bool("debug.stagefright.ccodec_v4l2", false)) {
-        std::shared_ptr<C2ComponentStore> v4l2Store = GetCodec2VDAComponentStore();
-        if (v4l2Store == nullptr) {
-            ALOGD("Cannot find a V4L2 component store.");
-            // non-fatal.
-        } else {
-            std::vector<ConstTraitsPtr> v4l2Traits = v4l2Store->listComponents();
-            traits.insert(traits.end(), v4l2Traits.begin(), v4l2Traits.end());
-        }
-    }
-
-    MediaCodecsXmlParser parser(
-            MediaCodecsXmlParser::defaultSearchDirs,
-            "media_codecs_c2.xml");
-    if (parser.getParsingStatus() != OK) {
-        ALOGD("XML parser no good");
-        return OK;
-    }
-    for (const ConstTraitsPtr &trait : traits) {
-        if (parser.getCodecMap().count(trait->name.c_str()) == 0) {
-            ALOGD("%s not found in xml", trait->name.c_str());
-            continue;
-        }
-        const MediaCodecsXmlParser::CodecProperties &codec = parser.getCodecMap().at(trait->name);
-        std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
-        codecInfo->setName(trait->name.c_str());
-        codecInfo->setOwner("dummy");
-        // TODO: get this from trait->kind
-        bool encoder = (trait->name.find("encoder") != std::string::npos);
-        codecInfo->setEncoder(encoder);
-        codecInfo->setRank(trait->rank);
-        for (auto typeIt = codec.typeMap.begin(); typeIt != codec.typeMap.end(); ++typeIt) {
-            const std::string &mediaType = typeIt->first;
-            const MediaCodecsXmlParser::AttributeMap &attrMap = typeIt->second;
-            std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
-                codecInfo->addMime(mediaType.c_str());
-            for (auto attrIt = attrMap.begin(); attrIt != attrMap.end(); ++attrIt) {
-                std::string key, value;
-                std::tie(key, value) = *attrIt;
-                if (key.find("feature-") == 0 && key.find("feature-bitrate-modes") != 0) {
-                    caps->addDetail(key.c_str(), std::stoi(value));
-                } else {
-                    caps->addDetail(key.c_str(), value.c_str());
-                }
-            }
-            // TODO: get this from intf(), and apply to other codecs as well.
-            if (mediaType.find("video/avc") != std::string::npos && !encoder) {
-                for (const auto& pl : kAvcProfileLevels) {
-                    caps->addProfileLevel(pl.profile, pl.level);
-                }
-            }
-            // TODO: get this from intf().
-            if (mediaType.find("video") != std::string::npos && !encoder) {
-                caps->addColorFormat(0x7F420888);  // COLOR_FormatYUV420Flexible
-            }
-        }
-    }
-    return OK;
-}
-
-}  // namespace android
-
-extern "C" android::MediaCodecListBuilderBase *CreateBuilder() {
-    return new android::Codec2InfoBuilder;
-}
diff --git a/media/libstagefright/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/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 388ed6b..4f46be7 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -6,6 +6,7 @@
     },
 
     srcs: [
+        "Conversion.cpp",
         "FrameDropper.cpp",
         "GraphicBufferSource.cpp",
         "WProducerListener.cpp",
@@ -42,8 +43,9 @@
     ],
 
     export_shared_lib_headers: [
-        "libstagefright_foundation",
+        "libgui",
         "libhidlmemory",
+        "libstagefright_foundation",
     ],
 
     cflags: [
diff --git a/media/libstagefright/bqhelper/Conversion.cpp b/media/libstagefright/bqhelper/Conversion.cpp
new file mode 100644
index 0000000..ffed005
--- /dev/null
+++ b/media/libstagefright/bqhelper/Conversion.cpp
@@ -0,0 +1,1542 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/stagefright/bqhelper/Conversion.h>
+
+namespace android {
+namespace conversion {
+
+// native_handle_t helper functions.
+
+/**
+ * \brief Take an fd and create a native handle containing only the given fd.
+ * The created handle will need to be deleted manually with
+ * `native_handle_delete()`.
+ *
+ * \param[in] fd The source file descriptor (of type `int`).
+ * \return The create `native_handle_t*` that contains the given \p fd. If the
+ * supplied \p fd is negative, the created native handle will contain no file
+ * descriptors.
+ *
+ * If the native handle cannot be created, the return value will be
+ * `nullptr`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+native_handle_t* native_handle_create_from_fd(int fd) {
+    if (fd < 2) {
+        return native_handle_create(0, 0);
+    }
+    native_handle_t* nh = native_handle_create(1, 0);
+    if (nh == nullptr) {
+        return nullptr;
+    }
+    nh->data[0] = fd;
+    return nh;
+}
+
+/**
+ * \brief Extract a file descriptor from a native handle.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \param[in] index The index of the file descriptor in \p nh to read from. This
+ * input has the default value of `0`.
+ * \return The `index`-th file descriptor in \p nh. If \p nh does not have
+ * enough file descriptors, the returned value will be `-1`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+int native_handle_read_fd(native_handle_t const* nh, int index) {
+    return ((nh == nullptr) || (nh->numFds == 0) ||
+            (nh->numFds <= index) || (index < 0)) ?
+            -1 : nh->data[index];
+}
+
+/**
+ * Conversion functions
+ * ====================
+ *
+ * There are two main directions of conversion:
+ * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
+ *   input. The wrapper has type `TargetType`.
+ * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
+ *   corresponds to the input. The lifetime of the output does not depend on the
+ *   lifetime of the input.
+ * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
+ *   that cannot be copied and/or moved efficiently, or when there are multiple
+ *   output arguments.
+ * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
+ *   `TargetType` that cannot be copied and/or moved efficiently, or when there
+ *   are multiple output arguments.
+ *
+ * `wrapIn()` and `convertTo()` functions will take output arguments before
+ * input arguments. Some of these functions might return a value to indicate
+ * success or error.
+ *
+ * In converting or wrapping something as a Treble type that contains a
+ * `hidl_handle`, `native_handle_t*` will need to be created and returned as
+ * an additional output argument, hence only `wrapIn()` or `convertTo()` would
+ * be available. The caller must call `native_handle_delete()` to deallocate the
+ * returned native handle when it is no longer needed.
+ *
+ * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
+ * not perform duplication of file descriptors, while `toTargetType()` and
+ * `convertTo()` do.
+ */
+
+/**
+ * \brief Convert `Return<void>` to `binder::Status`.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `binder::Status`.
+ */
+// convert: Return<void> -> ::android::binder::Status
+::android::binder::Status toBinderStatus(
+        Return<void> const& t) {
+    return ::android::binder::Status::fromExceptionCode(
+            t.isOk() ? OK : UNKNOWN_ERROR,
+            t.description().c_str());
+}
+
+/**
+ * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `status_t`.
+ */
+// convert: Return<void> -> status_t
+status_t toStatusT(Return<void> const& t) {
+    return t.isOk() ? OK : UNKNOWN_ERROR;
+}
+
+/**
+ * \brief Wrap `native_handle_t*` in `hidl_handle`.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \return The `hidl_handle` that points to \p nh.
+ */
+// wrap: native_handle_t* -> hidl_handle
+hidl_handle inHidlHandle(native_handle_t const* nh) {
+    return hidl_handle(nh);
+}
+
+/**
+ * \brief Convert `int32_t` to `Dataspace`.
+ *
+ * \param[in] l The source `int32_t`.
+ * \result The corresponding `Dataspace`.
+ */
+// convert: int32_t -> Dataspace
+Dataspace toHardwareDataspace(int32_t l) {
+    return static_cast<Dataspace>(l);
+}
+
+/**
+ * \brief Convert `Dataspace` to `int32_t`.
+ *
+ * \param[in] t The source `Dataspace`.
+ * \result The corresponding `int32_t`.
+ */
+// convert: Dataspace -> int32_t
+int32_t toRawDataspace(Dataspace const& t) {
+    return static_cast<int32_t>(t);
+}
+
+/**
+ * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that points to the buffer.
+ */
+// wrap: void*, size_t -> hidl_vec<uint8_t>
+hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
+    hidl_vec<uint8_t> t;
+    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
+    return t;
+}
+
+/**
+ * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
+ */
+// convert: void*, size_t -> hidl_vec<uint8_t>
+hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
+    hidl_vec<uint8_t> t;
+    t.resize(size);
+    uint8_t const* src = static_cast<uint8_t const*>(l);
+    std::copy(src, src + size, t.data());
+    return t;
+}
+
+/**
+ * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
+ *
+ * \param[out] t The wrapper of type `AnwBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: GraphicBuffer -> AnwBuffer
+void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
+    t->attr.width = l.getWidth();
+    t->attr.height = l.getHeight();
+    t->attr.stride = l.getStride();
+    t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
+    t->attr.layerCount = l.getLayerCount();
+    t->attr.usage = l.getUsage();
+    t->attr.id = l.getId();
+    t->attr.generationNumber = l.getGenerationNumber();
+    t->nativeHandle = hidl_handle(l.handle);
+}
+
+/**
+ * \brief Convert `AnwBuffer` to `GraphicBuffer`.
+ *
+ * \param[out] l The destination `GraphicBuffer`.
+ * \param[in] t The source `AnwBuffer`.
+ *
+ * This function will duplicate all file descriptors in \p t.
+ */
+// convert: AnwBuffer -> GraphicBuffer
+// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
+bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
+    native_handle_t* handle = t.nativeHandle == nullptr ?
+            nullptr : native_handle_clone(t.nativeHandle);
+
+    size_t const numInts = 12 + (handle ? handle->numInts : 0);
+    int32_t* ints = new int32_t[numInts];
+
+    size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
+    int* fds = new int[numFds];
+
+    ints[0] = 'GBFR';
+    ints[1] = static_cast<int32_t>(t.attr.width);
+    ints[2] = static_cast<int32_t>(t.attr.height);
+    ints[3] = static_cast<int32_t>(t.attr.stride);
+    ints[4] = static_cast<int32_t>(t.attr.format);
+    ints[5] = static_cast<int32_t>(t.attr.layerCount);
+    ints[6] = static_cast<int32_t>(t.attr.usage);
+    ints[7] = static_cast<int32_t>(t.attr.id >> 32);
+    ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
+    ints[9] = static_cast<int32_t>(t.attr.generationNumber);
+    ints[10] = 0;
+    ints[11] = 0;
+    if (handle) {
+        ints[10] = static_cast<int32_t>(handle->numFds);
+        ints[11] = static_cast<int32_t>(handle->numInts);
+        int* intsStart = handle->data + handle->numFds;
+        std::copy(handle->data, intsStart, fds);
+        std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
+    }
+
+    void const* constBuffer = static_cast<void const*>(ints);
+    size_t size = numInts * sizeof(int32_t);
+    int const* constFds = static_cast<int const*>(fds);
+    status_t status = l->unflatten(constBuffer, size, constFds, numFds);
+
+    delete [] fds;
+    delete [] ints;
+    native_handle_delete(handle);
+    return status == NO_ERROR;
+}
+
+/**
+ * Conversion functions for types outside media
+ * ============================================
+ *
+ * Some objects in libui and libgui that were made to go through binder calls do
+ * not expose ways to read or write their fields to the public. To pass an
+ * object of this kind through the HIDL boundary, translation functions need to
+ * work around the access restriction by using the publicly available
+ * `flatten()` and `unflatten()` functions.
+ *
+ * All `flatten()` and `unflatten()` overloads follow the same convention as
+ * follows:
+ *
+ *     status_t flatten(ObjectType const& object,
+ *                      [OtherType const& other, ...]
+ *                      void*& buffer, size_t& size,
+ *                      int*& fds, size_t& numFds)
+ *
+ *     status_t unflatten(ObjectType* object,
+ *                        [OtherType* other, ...,]
+ *                        void*& buffer, size_t& size,
+ *                        int*& fds, size_t& numFds)
+ *
+ * The number of `other` parameters varies depending on the `ObjectType`. For
+ * example, in the process of unflattening an object that contains
+ * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
+ * be created.
+ *
+ * The last four parameters always work the same way in all overloads of
+ * `flatten()` and `unflatten()`:
+ * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
+ *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
+ *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
+ *   size (in ints) of the fd buffer pointed to by `fds`.
+ * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
+ *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
+ *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
+ *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
+ * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
+ *   will be advanced, while `size` and `numFds` will be decreased to reflect
+ *   how much storage/data of the two buffers (fd and non-fd) have been used.
+ * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
+ *   `numFds` are invalid.
+ *
+ * The return value of a successful `flatten()` or `unflatten()` call will be
+ * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
+ *
+ * For each object type that supports flattening, there will be two accompanying
+ * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
+ * return the size of the non-fd buffer that the object will need for
+ * flattening. `getFdCount()` will return the size of the fd buffer that the
+ * object will need for flattening.
+ *
+ * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
+ * `flatten()` and `unflatten()`, are similar to functions of the same name in
+ * the abstract class `Flattenable`. The only difference is that functions in
+ * this file are not member functions of the object type. For example, we write
+ *
+ *     flatten(x, buffer, size, fds, numFds)
+ *
+ * instead of
+ *
+ *     x.flatten(buffer, size, fds, numFds)
+ *
+ * because we cannot modify the type of `x`.
+ *
+ * There is one exception to the naming convention: `hidl_handle` that
+ * represents a fence. The four functions for this "Fence" type have the word
+ * "Fence" attched to their names because the object type, which is
+ * `hidl_handle`, does not carry the special meaning that the object itself can
+ * only contain zero or one file descriptor.
+ */
+
+// Ref: frameworks/native/libs/ui/Fence.cpp
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return The required size of the flat buffer.
+ *
+ * The current version of this function always returns 4, which is the number of
+ * bytes required to store the number of file descriptors contained in the fd
+ * part of the flat buffer.
+ */
+size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
+    return 4;
+};
+
+/**
+ * \brief Return the number of file descriptors contained in a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return `0` if \p fence does not contain a valid file descriptor, or `1`
+ * otherwise.
+ */
+size_t getFenceFdCount(hidl_handle const& fence) {
+    return native_handle_read_fd(fence) == -1 ? 0 : 1;
+}
+
+/**
+ * \brief Unflatten `Fence` to `hidl_handle`.
+ *
+ * \param[out] fence The destination `hidl_handle`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will point to a newly created
+ * native handle, which needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+    if (size < 4) {
+        return NO_MEMORY;
+    }
+
+    uint32_t numFdsInHandle;
+    FlattenableUtils::read(buffer, size, numFdsInHandle);
+
+    if (numFdsInHandle > 1) {
+        return BAD_VALUE;
+    }
+
+    if (numFds < numFdsInHandle) {
+        return NO_MEMORY;
+    }
+
+    if (numFdsInHandle) {
+        *nh = native_handle_create_from_fd(*fds);
+        if (*nh == nullptr) {
+            return NO_MEMORY;
+        }
+        *fence = *nh;
+        ++fds;
+        --numFds;
+    } else {
+        *nh = nullptr;
+        *fence = hidl_handle();
+    }
+
+    return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `hidl_handle` as `Fence`.
+ *
+ * \param[in] t The source `hidl_handle`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t flattenFence(hidl_handle const& fence,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+    if (size < getFenceFlattenedSize(fence) ||
+            numFds < getFenceFdCount(fence)) {
+        return NO_MEMORY;
+    }
+    // Cast to uint32_t since the size of a size_t can vary between 32- and
+    // 64-bit processes
+    FlattenableUtils::write(buffer, size,
+            static_cast<uint32_t>(getFenceFdCount(fence)));
+    int fd = native_handle_read_fd(fence);
+    if (fd != -1) {
+        *fds = fd;
+        ++fds;
+        --numFds;
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `Fence` in `hidl_handle`.
+ *
+ * \param[out] t The wrapper of type `hidl_handle`.
+ * \param[out] nh The native handle pointed to by \p t.
+ * \param[in] l The source `Fence`.
+ *
+ * On success, \p nh will hold a newly created native handle, which must be
+ * deleted manually with `native_handle_delete()` afterwards.
+ */
+// wrap: Fence -> hidl_handle
+bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
+    size_t const baseSize = l.getFlattenedSize();
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    size_t const baseNumFds = l.getFdCount();
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = static_cast<int*>(baseFds.get());
+    size_t numFds = baseNumFds;
+    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
+            != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * \brief Convert `hidl_handle` to `Fence`.
+ *
+ * \param[out] l The destination `Fence`. `l` must not have been used
+ * (`l->isValid()` must return `false`) before this function is called.
+ * \param[in] t The source `hidl_handle`.
+ *
+ * If \p t contains a valid file descriptor, it will be duplicated.
+ */
+// convert: hidl_handle -> Fence
+bool convertTo(Fence* l, hidl_handle const& t) {
+    int fd = native_handle_read_fd(t);
+    if (fd != -1) {
+        fd = dup(fd);
+        if (fd == -1) {
+            return false;
+        }
+    }
+    native_handle_t* nh = native_handle_create_from_fd(fd);
+    if (nh == nullptr) {
+        if (fd != -1) {
+            close(fd);
+        }
+        return false;
+    }
+
+    size_t const baseSize = getFenceFlattenedSize(t);
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        native_handle_delete(nh);
+        return false;
+    }
+
+    size_t const baseNumFds = getFenceFdCount(t);
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        native_handle_delete(nh);
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = static_cast<int*>(baseFds.get());
+    size_t numFds = baseNumFds;
+    if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
+        native_handle_delete(nh);
+        return false;
+    }
+    native_handle_delete(nh);
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
+    constexpr size_t min = sizeof(t.state);
+    switch (t.state) {
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
+            return min;
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
+            return min + getFenceFlattenedSize(t.fence);
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+            return min + sizeof(
+                    ::android::FenceTime::Snapshot::signalTime);
+    }
+    return 0;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The number of file descriptors contained in \p snapshot.
+ */
+size_t getFdCount(
+        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
+    return t.state ==
+            HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
+            getFenceFdCount(t.fence) : 0;
+}
+
+/**
+ * \brief Flatten `FenceTimeSnapshot`.
+ *
+ * \param[in] t The source `FenceTimeSnapshot`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence` if `t.state ==
+ * FENCE`.
+ */
+status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+    if (size < getFlattenedSize(t)) {
+        return NO_MEMORY;
+    }
+
+    switch (t.state) {
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
+            FlattenableUtils::write(buffer, size,
+                    ::android::FenceTime::Snapshot::State::EMPTY);
+            return NO_ERROR;
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
+            FlattenableUtils::write(buffer, size,
+                    ::android::FenceTime::Snapshot::State::FENCE);
+            return flattenFence(t.fence, buffer, size, fds, numFds);
+        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+            FlattenableUtils::write(buffer, size,
+                    ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
+            FlattenableUtils::write(buffer, size, t.signalTimeNs);
+            return NO_ERROR;
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Unflatten `FenceTimeSnapshot`.
+ *
+ * \param[out] t The destination `FenceTimeSnapshot`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and the constructed snapshot contains a
+ * file descriptor, \p nh will be created to hold that file descriptor. In this
+ * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
+ */
+status_t unflatten(
+        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+    if (size < sizeof(t->state)) {
+        return NO_MEMORY;
+    }
+
+    *nh = nullptr;
+    ::android::FenceTime::Snapshot::State state;
+    FlattenableUtils::read(buffer, size, state);
+    switch (state) {
+        case ::android::FenceTime::Snapshot::State::EMPTY:
+            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
+            return NO_ERROR;
+        case ::android::FenceTime::Snapshot::State::FENCE:
+            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
+            return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
+        case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
+            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
+            if (size < sizeof(t->signalTimeNs)) {
+                return NO_MEMORY;
+            }
+            FlattenableUtils::read(buffer, size, t->signalTimeNs);
+            return NO_ERROR;
+    }
+    return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
+
+/**
+ * \brief Return a lower bound on the size of the non-fd buffer required to
+ * flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+        HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
+    return sizeof(uint64_t) + // mFrameNumber
+            sizeof(uint8_t) + // mIndex
+            sizeof(uint8_t) + // mAddPostCompositeCalled
+            sizeof(uint8_t) + // mAddRetireCalled
+            sizeof(uint8_t) + // mAddReleaseCalled
+            sizeof(nsecs_t) + // mPostedTime
+            sizeof(nsecs_t) + // mRequestedPresentTime
+            sizeof(nsecs_t) + // mLatchTime
+            sizeof(nsecs_t) + // mFirstRefreshStartTime
+            sizeof(nsecs_t); // mLastRefreshStartTime
+}
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+        HGraphicBufferProducer::FrameEventsDelta const& t) {
+    return minFlattenedSize(t) +
+            getFlattenedSize(t.gpuCompositionDoneFence) +
+            getFlattenedSize(t.displayPresentFence) +
+            getFlattenedSize(t.displayRetireFence) +
+            getFlattenedSize(t.releaseFence);
+};
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+        HGraphicBufferProducer::FrameEventsDelta const& t) {
+    return getFdCount(t.gpuCompositionDoneFence) +
+            getFdCount(t.displayPresentFence) +
+            getFdCount(t.displayRetireFence) +
+            getFdCount(t.releaseFence);
+};
+
+/**
+ * \brief Unflatten `FrameEventsDelta`.
+ *
+ * \param[out] t The destination `FrameEventsDelta`.
+ * \param[out] nh The underlying array of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
+ * populated with `nullptr` or newly created handles. Each non-null slot in \p
+ * nh will need to be deleted manually with `native_handle_delete()`.
+ */
+status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
+        std::vector<native_handle_t*>* nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+    if (size < minFlattenedSize(*t)) {
+        return NO_MEMORY;
+    }
+    FlattenableUtils::read(buffer, size, t->frameNumber);
+
+    // These were written as uint8_t for alignment.
+    uint8_t temp = 0;
+    FlattenableUtils::read(buffer, size, temp);
+    size_t index = static_cast<size_t>(temp);
+    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+        return BAD_VALUE;
+    }
+    t->index = static_cast<uint32_t>(index);
+
+    FlattenableUtils::read(buffer, size, temp);
+    t->addPostCompositeCalled = static_cast<bool>(temp);
+    FlattenableUtils::read(buffer, size, temp);
+    t->addRetireCalled = static_cast<bool>(temp);
+    FlattenableUtils::read(buffer, size, temp);
+    t->addReleaseCalled = static_cast<bool>(temp);
+
+    FlattenableUtils::read(buffer, size, t->postedTimeNs);
+    FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
+    FlattenableUtils::read(buffer, size, t->latchTimeNs);
+    FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
+    FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
+    FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
+
+    // Fences
+    HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
+    tSnapshot[0] = &t->gpuCompositionDoneFence;
+    tSnapshot[1] = &t->displayPresentFence;
+    tSnapshot[2] = &t->displayRetireFence;
+    tSnapshot[3] = &t->releaseFence;
+    nh->resize(4);
+    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+        status_t status = unflatten(
+                tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
+                buffer, size, fds, numFds);
+        if (status != NO_ERROR) {
+            while (snapshotIndex > 0) {
+                --snapshotIndex;
+                if ((*nh)[snapshotIndex] != nullptr) {
+                    native_handle_delete((*nh)[snapshotIndex]);
+                }
+            }
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The source `FrameEventsDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
+//      FrameEventsDelta::flatten
+status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
+        void*& buffer, size_t& size, int*& fds, size_t numFds) {
+    // Check that t.index is within a valid range.
+    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
+            || t.index > std::numeric_limits<uint8_t>::max()) {
+        return BAD_VALUE;
+    }
+
+    FlattenableUtils::write(buffer, size, t.frameNumber);
+
+    // These are static_cast to uint8_t for alignment.
+    FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
+    FlattenableUtils::write(
+            buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
+    FlattenableUtils::write(
+            buffer, size, static_cast<uint8_t>(t.addRetireCalled));
+    FlattenableUtils::write(
+            buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
+
+    FlattenableUtils::write(buffer, size, t.postedTimeNs);
+    FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
+    FlattenableUtils::write(buffer, size, t.latchTimeNs);
+    FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
+    FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
+    FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
+
+    // Fences
+    HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
+    tSnapshot[0] = &t.gpuCompositionDoneFence;
+    tSnapshot[1] = &t.displayPresentFence;
+    tSnapshot[2] = &t.displayRetireFence;
+    tSnapshot[3] = &t.releaseFence;
+    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+        status_t status = flatten(
+                *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
+        if (status != NO_ERROR) {
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+    size_t size = 4 + // mDeltas.size()
+            sizeof(t.compositorTiming);
+    for (size_t i = 0; i < t.deltas.size(); ++i) {
+        size += getFlattenedSize(t.deltas[i]);
+    }
+    return size;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+    size_t numFds = 0;
+    for (size_t i = 0; i < t.deltas.size(); ++i) {
+        numFds += getFdCount(t.deltas[i]);
+    }
+    return numFds;
+}
+
+/**
+ * \brief Unflatten `FrameEventHistoryDelta`.
+ *
+ * \param[out] t The destination `FrameEventHistoryDelta`.
+ * \param[out] nh The underlying array of arrays of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
+ * newly created handles. The second dimension of \p nh will be 4. Each non-null
+ * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
+ */
+status_t unflatten(
+        HGraphicBufferProducer::FrameEventHistoryDelta* t,
+        std::vector<std::vector<native_handle_t*> >* nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+    if (size < 4) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::read(buffer, size, t->compositorTiming);
+
+    uint32_t deltaCount = 0;
+    FlattenableUtils::read(buffer, size, deltaCount);
+    if (static_cast<size_t>(deltaCount) >
+            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+        return BAD_VALUE;
+    }
+    t->deltas.resize(deltaCount);
+    nh->resize(deltaCount);
+    for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
+        status_t status = unflatten(
+                &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
+                buffer, size, fds, numFds);
+        if (status != NO_ERROR) {
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventHistoryDelta`.
+ *
+ * \param[in] t The source `FrameEventHistoryDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+status_t flatten(
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+        return BAD_VALUE;
+    }
+    if (size < getFlattenedSize(t)) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::write(buffer, size, t.compositorTiming);
+
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
+    for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
+        status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
+        if (status != NO_ERROR) {
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `::android::FrameEventHistoryData` in
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `::android::FrameEventHistoryDelta`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
+        std::vector<std::vector<native_handle_t*> >* nh,
+        ::android::FrameEventHistoryDelta const& l) {
+
+    size_t const baseSize = l.getFlattenedSize();
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    size_t const baseNumFds = l.getFdCount();
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = baseFds.get();
+    size_t numFds = baseNumFds;
+    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
+ * `::android::FrameEventHistoryDelta`.
+ *
+ * \param[out] l The destination `::android::FrameEventHistoryDelta`.
+ * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+bool convertTo(
+        ::android::FrameEventHistoryDelta* l,
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+
+    size_t const baseSize = getFlattenedSize(t);
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    size_t const baseNumFds = getFdCount(t);
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = static_cast<int*>(baseFds.get());
+    size_t numFds = baseNumFds;
+    if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+// Ref: frameworks/native/libs/ui/Region.cpp
+
+/**
+ * \brief Return the size of the buffer required to flatten `Region`.
+ *
+ * \param[in] t The input `Region`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(Region const& t) {
+    return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
+}
+
+/**
+ * \brief Unflatten `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t unflatten(Region* t, void const*& buffer, size_t& size) {
+    if (size < sizeof(uint32_t)) {
+        return NO_MEMORY;
+    }
+
+    uint32_t numRects = 0;
+    FlattenableUtils::read(buffer, size, numRects);
+    if (size < numRects * sizeof(Rect)) {
+        return NO_MEMORY;
+    }
+    if (numRects > (UINT32_MAX / sizeof(Rect))) {
+        return NO_MEMORY;
+    }
+
+    t->resize(numRects);
+    for (size_t r = 0; r < numRects; ++r) {
+        ::android::Rect rect(::android::Rect::EMPTY_RECT);
+        status_t status = rect.unflatten(buffer, size);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        FlattenableUtils::advance(buffer, size, sizeof(rect));
+        (*t)[r] = Rect{
+                static_cast<int32_t>(rect.left),
+                static_cast<int32_t>(rect.top),
+                static_cast<int32_t>(rect.right),
+                static_cast<int32_t>(rect.bottom)};
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `Region`.
+ *
+ * \param[in] t The source `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t flatten(Region const& t, void*& buffer, size_t& size) {
+    if (size < getFlattenedSize(t)) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
+    for (size_t r = 0; r < t.size(); ++r) {
+        ::android::Rect rect(
+                static_cast<int32_t>(t[r].left),
+                static_cast<int32_t>(t[r].top),
+                static_cast<int32_t>(t[r].right),
+                static_cast<int32_t>(t[r].bottom));
+        status_t status = rect.flatten(buffer, size);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        FlattenableUtils::advance(buffer, size, sizeof(rect));
+    }
+    return NO_ERROR;
+}
+
+/**
+ * \brief Convert `::android::Region` to `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in] l The source `::android::Region`.
+ */
+// convert: ::android::Region -> Region
+bool convertTo(Region* t, ::android::Region const& l) {
+    size_t const baseSize = l.getFlattenedSize();
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    if (l.flatten(buffer, size) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    if (unflatten(t, constBuffer, size) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * \brief Convert `Region` to `::android::Region`.
+ *
+ * \param[out] l The destination `::android::Region`.
+ * \param[in] t The source `Region`.
+ */
+// convert: Region -> ::android::Region
+bool convertTo(::android::Region* l, Region const& t) {
+    size_t const baseSize = getFlattenedSize(t);
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    if (flatten(t, buffer, size) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    if (l->unflatten(constBuffer, size) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
+//      BGraphicBufferProducer::QueueBufferInput
+
+/**
+ * \brief Return a lower bound on the size of the buffer required to flatten
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+        HGraphicBufferProducer::QueueBufferInput const& /* t */) {
+    return sizeof(int64_t) + // timestamp
+            sizeof(int) + // isAutoTimestamp
+            sizeof(android_dataspace) + // dataSpace
+            sizeof(::android::Rect) + // crop
+            sizeof(int) + // scalingMode
+            sizeof(uint32_t) + // transform
+            sizeof(uint32_t) + // stickyTransform
+            sizeof(bool); // getFrameTimestamps
+}
+
+/**
+ * \brief Return the size of the buffer required to flatten
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
+    return minFlattenedSize(t) +
+            getFenceFlattenedSize(t.fence) +
+            getFlattenedSize(t.surfaceDamage) +
+            sizeof(HdrMetadata::validTypes);
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+        HGraphicBufferProducer::QueueBufferInput const& t) {
+    return getFenceFdCount(t.fence);
+}
+
+/**
+ * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The native handle cloned from `t.fence`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence`. */
+status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
+        native_handle_t** nh,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+    if (size < getFlattenedSize(t)) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::write(buffer, size, t.timestamp);
+    FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
+    FlattenableUtils::write(buffer, size,
+            static_cast<android_dataspace_t>(t.dataSpace));
+    FlattenableUtils::write(buffer, size, ::android::Rect(
+            static_cast<int32_t>(t.crop.left),
+            static_cast<int32_t>(t.crop.top),
+            static_cast<int32_t>(t.crop.right),
+            static_cast<int32_t>(t.crop.bottom)));
+    FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
+    FlattenableUtils::write(buffer, size, t.transform);
+    FlattenableUtils::write(buffer, size, t.stickyTransform);
+    FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
+
+    *nh = t.fence.getNativeHandle() == nullptr ?
+            nullptr : native_handle_clone(t.fence);
+    status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = flatten(t.surfaceDamage, buffer, size);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
+    return NO_ERROR;
+}
+
+/**
+ * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+status_t unflatten(
+        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+    if (size < minFlattenedSize(*t)) {
+        return NO_MEMORY;
+    }
+
+    FlattenableUtils::read(buffer, size, t->timestamp);
+    int lIsAutoTimestamp;
+    FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
+    t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
+    android_dataspace_t lDataSpace;
+    FlattenableUtils::read(buffer, size, lDataSpace);
+    t->dataSpace = static_cast<Dataspace>(lDataSpace);
+    Rect lCrop;
+    FlattenableUtils::read(buffer, size, lCrop);
+    t->crop = Rect{
+            static_cast<int32_t>(lCrop.left),
+            static_cast<int32_t>(lCrop.top),
+            static_cast<int32_t>(lCrop.right),
+            static_cast<int32_t>(lCrop.bottom)};
+    int lScalingMode;
+    FlattenableUtils::read(buffer, size, lScalingMode);
+    t->scalingMode = static_cast<int32_t>(lScalingMode);
+    FlattenableUtils::read(buffer, size, t->transform);
+    FlattenableUtils::read(buffer, size, t->stickyTransform);
+    FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
+
+    status_t status = unflattenFence(&(t->fence), nh,
+            buffer, size, fds, numFds);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    // HdrMetadata ignored
+    return unflatten(&(t->surfaceDamage), buffer, size);
+}
+
+/**
+ * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
+ *
+ * If the return value is `true` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+bool wrapAs(
+        HGraphicBufferProducer::QueueBufferInput* t,
+        native_handle_t** nh,
+        BGraphicBufferProducer::QueueBufferInput const& l) {
+
+    size_t const baseSize = l.getFlattenedSize();
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    size_t const baseNumFds = l.getFdCount();
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = baseFds.get();
+    size_t numFds = baseNumFds;
+    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
+ * `BGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * If `t.fence` has a valid file descriptor, it will be duplicated.
+ */
+bool convertTo(
+        BGraphicBufferProducer::QueueBufferInput* l,
+        HGraphicBufferProducer::QueueBufferInput const& t) {
+
+    size_t const baseSize = getFlattenedSize(t);
+    std::unique_ptr<uint8_t[]> baseBuffer(
+            new (std::nothrow) uint8_t[baseSize]);
+    if (!baseBuffer) {
+        return false;
+    }
+
+    size_t const baseNumFds = getFdCount(t);
+    std::unique_ptr<int[]> baseFds(
+            new (std::nothrow) int[baseNumFds]);
+    if (!baseFds) {
+        return false;
+    }
+
+    void* buffer = static_cast<void*>(baseBuffer.get());
+    size_t size = baseSize;
+    int* fds = baseFds.get();
+    size_t numFds = baseNumFds;
+    native_handle_t* nh;
+    if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
+        return false;
+    }
+
+    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+    size = baseSize;
+    int const* constFds = static_cast<int const*>(baseFds.get());
+    numFds = baseNumFds;
+    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+        if (nh != nullptr) {
+            native_handle_close(nh);
+            native_handle_delete(nh);
+        }
+        return false;
+    }
+
+    native_handle_delete(nh);
+    return true;
+}
+
+// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
+//      BGraphicBufferProducer::QueueBufferOutput
+
+/**
+ * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
+ * `HGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::QueueBufferOutput`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+// wrap: BGraphicBufferProducer::QueueBufferOutput ->
+// HGraphicBufferProducer::QueueBufferOutput
+bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
+        std::vector<std::vector<native_handle_t*> >* nh,
+        BGraphicBufferProducer::QueueBufferOutput const& l) {
+    if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
+        return false;
+    }
+    t->width = l.width;
+    t->height = l.height;
+    t->transformHint = l.transformHint;
+    t->numPendingBuffers = l.numPendingBuffers;
+    t->nextFrameNumber = l.nextFrameNumber;
+    t->bufferReplaced = l.bufferReplaced;
+    return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
+ * `BGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+// convert: HGraphicBufferProducer::QueueBufferOutput ->
+// BGraphicBufferProducer::QueueBufferOutput
+bool convertTo(
+        BGraphicBufferProducer::QueueBufferOutput* l,
+        HGraphicBufferProducer::QueueBufferOutput const& t) {
+    if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
+        return false;
+    }
+    l->width = t.width;
+    l->height = t.height;
+    l->transformHint = t.transformHint;
+    l->numPendingBuffers = t.numPendingBuffers;
+    l->nextFrameNumber = t.nextFrameNumber;
+    l->bufferReplaced = t.bufferReplaced;
+    return true;
+}
+
+/**
+ * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
+ * `HGraphicBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
+ * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
+ */
+HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
+        BGraphicBufferProducer::DisconnectMode l) {
+    switch (l) {
+        case BGraphicBufferProducer::DisconnectMode::Api:
+            return HGraphicBufferProducer::DisconnectMode::API;
+        case BGraphicBufferProducer::DisconnectMode::AllLocal:
+            return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
+    }
+    return HGraphicBufferProducer::DisconnectMode::API;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
+ * `BGraphicBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
+ * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
+ */
+BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
+        HGraphicBufferProducer::DisconnectMode t) {
+    switch (t) {
+        case HGraphicBufferProducer::DisconnectMode::API:
+            return BGraphicBufferProducer::DisconnectMode::Api;
+        case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
+            return BGraphicBufferProducer::DisconnectMode::AllLocal;
+    }
+    return BGraphicBufferProducer::DisconnectMode::Api;
+}
+
+}  // namespace conversion
+}  // namespace android
+
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
index c15fafa..60d8c1e 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef MEDIA_STAGEFRIGHT_CONVERSION_H_
-#define MEDIA_STAGEFRIGHT_CONVERSION_H_
+#ifndef MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
+#define MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
 
 #include <vector>
 #include <list>
@@ -83,17 +83,7 @@
  *
  * This function does not duplicate the file descriptor.
  */
-inline native_handle_t* native_handle_create_from_fd(int fd) {
-    if (fd < 2) {
-        return native_handle_create(0, 0);
-    }
-    native_handle_t* nh = native_handle_create(1, 0);
-    if (nh == nullptr) {
-        return nullptr;
-    }
-    nh->data[0] = fd;
-    return nh;
-}
+native_handle_t* native_handle_create_from_fd(int fd);
 
 /**
  * \brief Extract a file descriptor from a native handle.
@@ -106,11 +96,7 @@
  *
  * This function does not duplicate the file descriptor.
  */
-inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
-    return ((nh == nullptr) || (nh->numFds == 0) ||
-            (nh->numFds <= index) || (index < 0)) ?
-            -1 : nh->data[index];
-}
+int native_handle_read_fd(native_handle_t const* nh, int index = 0);
 
 /**
  * Conversion functions
@@ -151,12 +137,7 @@
  * \return The corresponding `binder::Status`.
  */
 // convert: Return<void> -> ::android::binder::Status
-inline ::android::binder::Status toBinderStatus(
-        Return<void> const& t) {
-    return ::android::binder::Status::fromExceptionCode(
-            t.isOk() ? OK : UNKNOWN_ERROR,
-            t.description().c_str());
-}
+::android::binder::Status toBinderStatus(Return<void> const& t);
 
 /**
  * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
@@ -165,9 +146,7 @@
  * \return The corresponding `status_t`.
  */
 // convert: Return<void> -> status_t
-inline status_t toStatusT(Return<void> const& t) {
-    return t.isOk() ? OK : UNKNOWN_ERROR;
-}
+status_t toStatusT(Return<void> const& t);
 
 /**
  * \brief Wrap `native_handle_t*` in `hidl_handle`.
@@ -176,9 +155,7 @@
  * \return The `hidl_handle` that points to \p nh.
  */
 // wrap: native_handle_t* -> hidl_handle
-inline hidl_handle inHidlHandle(native_handle_t const* nh) {
-    return hidl_handle(nh);
-}
+hidl_handle inHidlHandle(native_handle_t const* nh);
 
 /**
  * \brief Convert `int32_t` to `Dataspace`.
@@ -187,9 +164,7 @@
  * \result The corresponding `Dataspace`.
  */
 // convert: int32_t -> Dataspace
-inline Dataspace toHardwareDataspace(int32_t l) {
-    return static_cast<Dataspace>(l);
-}
+Dataspace toHardwareDataspace(int32_t l);
 
 /**
  * \brief Convert `Dataspace` to `int32_t`.
@@ -198,9 +173,7 @@
  * \result The corresponding `int32_t`.
  */
 // convert: Dataspace -> int32_t
-inline int32_t toRawDataspace(Dataspace const& t) {
-    return static_cast<int32_t>(t);
-}
+int32_t toRawDataspace(Dataspace const& t);
 
 /**
  * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
@@ -210,11 +183,7 @@
  * \return A `hidl_vec<uint8_t>` that points to the buffer.
  */
 // wrap: void*, size_t -> hidl_vec<uint8_t>
-inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
-    return t;
-}
+hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size);
 
 /**
  * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
@@ -224,13 +193,7 @@
  * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
  */
 // convert: void*, size_t -> hidl_vec<uint8_t>
-inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.resize(size);
-    uint8_t const* src = static_cast<uint8_t const*>(l);
-    std::copy(src, src + size, t.data());
-    return t;
-}
+hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size);
 
 /**
  * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
@@ -239,17 +202,7 @@
  * \param[in] l The source `GraphicBuffer`.
  */
 // wrap: GraphicBuffer -> AnwBuffer
-inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
-    t->attr.width = l.getWidth();
-    t->attr.height = l.getHeight();
-    t->attr.stride = l.getStride();
-    t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
-    t->attr.layerCount = l.getLayerCount();
-    t->attr.usage = l.getUsage();
-    t->attr.id = l.getId();
-    t->attr.generationNumber = l.getGenerationNumber();
-    t->nativeHandle = hidl_handle(l.handle);
-}
+void wrapAs(AnwBuffer* t, GraphicBuffer const& l);
 
 /**
  * \brief Convert `AnwBuffer` to `GraphicBuffer`.
@@ -261,46 +214,7 @@
  */
 // convert: AnwBuffer -> GraphicBuffer
 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
-    native_handle_t* handle = t.nativeHandle == nullptr ?
-            nullptr : native_handle_clone(t.nativeHandle);
-
-    size_t const numInts = 12 + (handle ? handle->numInts : 0);
-    int32_t* ints = new int32_t[numInts];
-
-    size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
-    int* fds = new int[numFds];
-
-    ints[0] = 'GBFR';
-    ints[1] = static_cast<int32_t>(t.attr.width);
-    ints[2] = static_cast<int32_t>(t.attr.height);
-    ints[3] = static_cast<int32_t>(t.attr.stride);
-    ints[4] = static_cast<int32_t>(t.attr.format);
-    ints[5] = static_cast<int32_t>(t.attr.layerCount);
-    ints[6] = static_cast<int32_t>(t.attr.usage);
-    ints[7] = static_cast<int32_t>(t.attr.id >> 32);
-    ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
-    ints[9] = static_cast<int32_t>(t.attr.generationNumber);
-    ints[10] = 0;
-    ints[11] = 0;
-    if (handle) {
-        ints[10] = static_cast<int32_t>(handle->numFds);
-        ints[11] = static_cast<int32_t>(handle->numInts);
-        int* intsStart = handle->data + handle->numFds;
-        std::copy(handle->data, intsStart, fds);
-        std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
-    }
-
-    void const* constBuffer = static_cast<void const*>(ints);
-    size_t size = numInts * sizeof(int32_t);
-    int const* constFds = static_cast<int const*>(fds);
-    status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
-    delete [] fds;
-    delete [] ints;
-    native_handle_delete(handle);
-    return status == NO_ERROR;
-}
+bool convertTo(GraphicBuffer* l, AnwBuffer const& t);
 
 /**
  * Conversion functions for types outside media
@@ -387,9 +301,7 @@
  * bytes required to store the number of file descriptors contained in the fd
  * part of the flat buffer.
  */
-inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
-    return 4;
-};
+size_t getFenceFlattenedSize(hidl_handle const& fence);
 
 /**
  * \brief Return the number of file descriptors contained in a fence.
@@ -398,9 +310,7 @@
  * \return `0` if \p fence does not contain a valid file descriptor, or `1`
  * otherwise.
  */
-inline size_t getFenceFdCount(hidl_handle const& fence) {
-    return native_handle_read_fd(fence) == -1 ? 0 : 1;
-}
+size_t getFenceFdCount(hidl_handle const& fence);
 
 /**
  * \brief Unflatten `Fence` to `hidl_handle`.
@@ -417,38 +327,8 @@
  * native handle, which needs to be deleted with `native_handle_delete()`
  * afterwards.
  */
-inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numFdsInHandle;
-    FlattenableUtils::read(buffer, size, numFdsInHandle);
-
-    if (numFdsInHandle > 1) {
-        return BAD_VALUE;
-    }
-
-    if (numFds < numFdsInHandle) {
-        return NO_MEMORY;
-    }
-
-    if (numFdsInHandle) {
-        *nh = native_handle_create_from_fd(*fds);
-        if (*nh == nullptr) {
-            return NO_MEMORY;
-        }
-        *fence = *nh;
-        ++fds;
-        --numFds;
-    } else {
-        *nh = nullptr;
-        *fence = hidl_handle();
-    }
-
-    return NO_ERROR;
-}
+status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
 
 /**
  * \brief Flatten `hidl_handle` as `Fence`.
@@ -460,24 +340,8 @@
  * \param[in,out] numFds The size of the flat fd buffer.
  * \return `NO_ERROR` on success; other value on failure.
  */
-inline status_t flattenFence(hidl_handle const& fence,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFenceFlattenedSize(fence) ||
-            numFds < getFenceFdCount(fence)) {
-        return NO_MEMORY;
-    }
-    // Cast to uint32_t since the size of a size_t can vary between 32- and
-    // 64-bit processes
-    FlattenableUtils::write(buffer, size,
-            static_cast<uint32_t>(getFenceFdCount(fence)));
-    int fd = native_handle_read_fd(fence);
-    if (fd != -1) {
-        *fds = fd;
-        ++fds;
-        --numFds;
-    }
-    return NO_ERROR;
-}
+status_t flattenFence(hidl_handle const& fence,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds);
 
 /**
  * \brief Wrap `Fence` in `hidl_handle`.
@@ -490,40 +354,7 @@
  * deleted manually with `native_handle_delete()` afterwards.
  */
 // wrap: Fence -> hidl_handle
-inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
-            != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l);
 
 /**
  * \brief Convert `hidl_handle` to `Fence`.
@@ -535,58 +366,7 @@
  * If \p t contains a valid file descriptor, it will be duplicated.
  */
 // convert: hidl_handle -> Fence
-inline bool convertTo(Fence* l, hidl_handle const& t) {
-    int fd = native_handle_read_fd(t);
-    if (fd != -1) {
-        fd = dup(fd);
-        if (fd == -1) {
-            return false;
-        }
-    }
-    native_handle_t* nh = native_handle_create_from_fd(fd);
-    if (nh == nullptr) {
-        if (fd != -1) {
-            close(fd);
-        }
-        return false;
-    }
-
-    size_t const baseSize = getFenceFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    size_t const baseNumFds = getFenceFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
-        native_handle_delete(nh);
-        return false;
-    }
-    native_handle_delete(nh);
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+bool convertTo(Fence* l, hidl_handle const& t);
 
 // Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
 
@@ -597,20 +377,7 @@
  * \param[in] t The input `FenceTimeSnapshot`.
  * \return The required size of the flat buffer.
  */
-inline size_t getFlattenedSize(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    constexpr size_t min = sizeof(t.state);
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            return min;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            return min + getFenceFlattenedSize(t.fence);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            return min + sizeof(
-                    ::android::FenceTime::Snapshot::signalTime);
-    }
-    return 0;
-}
+size_t getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const& t);
 
 /**
  * \brief Return the number of file descriptors contained in
@@ -619,12 +386,7 @@
  * \param[in] t The input `FenceTimeSnapshot`.
  * \return The number of file descriptors contained in \p snapshot.
  */
-inline size_t getFdCount(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    return t.state ==
-            HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
-            getFenceFdCount(t.fence) : 0;
-}
+size_t getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const& t);
 
 /**
  * \brief Flatten `FenceTimeSnapshot`.
@@ -639,29 +401,8 @@
  * This function will duplicate the file descriptor in `t.fence` if `t.state ==
  * FENCE`.
  */
-inline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::EMPTY);
-            return NO_ERROR;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::FENCE);
-            return flattenFence(t.fence, buffer, size, fds, numFds);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
-            FlattenableUtils::write(buffer, size, t.signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
+status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
+        void*& buffer, size_t& size, int*& fds, size_t& numFds);
 
 /**
  * \brief Unflatten `FenceTimeSnapshot`.
@@ -678,72 +419,20 @@
  * file descriptor, \p nh will be created to hold that file descriptor. In this
  * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
  */
-inline status_t unflatten(
+status_t unflatten(
         HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < sizeof(t->state)) {
-        return NO_MEMORY;
-    }
-
-    *nh = nullptr;
-    ::android::FenceTime::Snapshot::State state;
-    FlattenableUtils::read(buffer, size, state);
-    switch (state) {
-        case ::android::FenceTime::Snapshot::State::EMPTY:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
-            return NO_ERROR;
-        case ::android::FenceTime::Snapshot::State::FENCE:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
-            return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
-        case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
-            if (size < sizeof(t->signalTimeNs)) {
-                return NO_MEMORY;
-            }
-            FlattenableUtils::read(buffer, size, t->signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
 
 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
 
 /**
- * \brief Return a lower bound on the size of the non-fd buffer required to
- * flatten `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
-    return sizeof(uint64_t) + // mFrameNumber
-            sizeof(uint8_t) + // mIndex
-            sizeof(uint8_t) + // mAddPostCompositeCalled
-            sizeof(uint8_t) + // mAddRetireCalled
-            sizeof(uint8_t) + // mAddReleaseCalled
-            sizeof(nsecs_t) + // mPostedTime
-            sizeof(nsecs_t) + // mRequestedPresentTime
-            sizeof(nsecs_t) + // mLatchTime
-            sizeof(nsecs_t) + // mFirstRefreshStartTime
-            sizeof(nsecs_t); // mLastRefreshStartTime
-}
-
-/**
  * \brief Return the size of the non-fd buffer required to flatten
  * `FrameEventsDelta`.
  *
  * \param[in] t The input `FrameEventsDelta`.
  * \return The required size of the flat buffer.
  */
-inline size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return minFlattenedSize(t) +
-            getFlattenedSize(t.gpuCompositionDoneFence) +
-            getFlattenedSize(t.displayPresentFence) +
-            getFlattenedSize(t.displayRetireFence) +
-            getFlattenedSize(t.releaseFence);
-};
+size_t getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const& t);
 
 /**
  * \brief Return the number of file descriptors contained in
@@ -752,13 +441,7 @@
  * \param[in] t The input `FrameEventsDelta`.
  * \return The number of file descriptors contained in \p t.
  */
-inline size_t getFdCount(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return getFdCount(t.gpuCompositionDoneFence) +
-            getFdCount(t.displayPresentFence) +
-            getFdCount(t.displayRetireFence) +
-            getFdCount(t.releaseFence);
-};
+size_t getFdCount(HGraphicBufferProducer::FrameEventsDelta const& t);
 
 /**
  * \brief Unflatten `FrameEventsDelta`.
@@ -775,60 +458,9 @@
  * populated with `nullptr` or newly created handles. Each non-null slot in \p
  * nh will need to be deleted manually with `native_handle_delete()`.
  */
-inline status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
+status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
         std::vector<native_handle_t*>* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-    FlattenableUtils::read(buffer, size, t->frameNumber);
-
-    // These were written as uint8_t for alignment.
-    uint8_t temp = 0;
-    FlattenableUtils::read(buffer, size, temp);
-    size_t index = static_cast<size_t>(temp);
-    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->index = static_cast<uint32_t>(index);
-
-    FlattenableUtils::read(buffer, size, temp);
-    t->addPostCompositeCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addRetireCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addReleaseCalled = static_cast<bool>(temp);
-
-    FlattenableUtils::read(buffer, size, t->postedTimeNs);
-    FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
-    FlattenableUtils::read(buffer, size, t->latchTimeNs);
-    FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
-    tSnapshot[0] = &t->gpuCompositionDoneFence;
-    tSnapshot[1] = &t->displayPresentFence;
-    tSnapshot[2] = &t->displayRetireFence;
-    tSnapshot[3] = &t->releaseFence;
-    nh->resize(4);
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = unflatten(
-                tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            while (snapshotIndex > 0) {
-                --snapshotIndex;
-                if ((*nh)[snapshotIndex] != nullptr) {
-                    native_handle_delete((*nh)[snapshotIndex]);
-                }
-            }
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
 
 /**
  * \brief Flatten `FrameEventsDelta`.
@@ -844,47 +476,8 @@
  */
 // Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
 //      FrameEventsDelta::flatten
-inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t numFds) {
-    // Check that t.index is within a valid range.
-    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
-            || t.index > std::numeric_limits<uint8_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    FlattenableUtils::write(buffer, size, t.frameNumber);
-
-    // These are static_cast to uint8_t for alignment.
-    FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addRetireCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
-
-    FlattenableUtils::write(buffer, size, t.postedTimeNs);
-    FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
-    FlattenableUtils::write(buffer, size, t.latchTimeNs);
-    FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
-    tSnapshot[0] = &t.gpuCompositionDoneFence;
-    tSnapshot[1] = &t.displayPresentFence;
-    tSnapshot[2] = &t.displayRetireFence;
-    tSnapshot[3] = &t.releaseFence;
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = flatten(
-                *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
+status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
+        void*& buffer, size_t& size, int*& fds, size_t numFds);
 
 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
 
@@ -895,15 +488,8 @@
  * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
  * \return The required size of the flat buffer.
  */
-inline size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t size = 4 + // mDeltas.size()
-            sizeof(t.compositorTiming);
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        size += getFlattenedSize(t.deltas[i]);
-    }
-    return size;
-}
+size_t getFlattenedSize(
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
 
 /**
  * \brief Return the number of file descriptors contained in
@@ -912,14 +498,8 @@
  * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
  * \return The number of file descriptors contained in \p t.
  */
-inline size_t getFdCount(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t numFds = 0;
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        numFds += getFdCount(t.deltas[i]);
-    }
-    return numFds;
-}
+size_t getFdCount(
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
 
 /**
  * \brief Unflatten `FrameEventHistoryDelta`.
@@ -936,34 +516,10 @@
  * newly created handles. The second dimension of \p nh will be 4. Each non-null
  * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
  */
-inline status_t unflatten(
+status_t unflatten(
         HGraphicBufferProducer::FrameEventHistoryDelta* t,
         std::vector<std::vector<native_handle_t*> >* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->compositorTiming);
-
-    uint32_t deltaCount = 0;
-    FlattenableUtils::read(buffer, size, deltaCount);
-    if (static_cast<size_t>(deltaCount) >
-            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->deltas.resize(deltaCount);
-    nh->resize(deltaCount);
-    for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
-        status_t status = unflatten(
-                &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
 
 /**
  * \brief Flatten `FrameEventHistoryDelta`.
@@ -977,27 +533,9 @@
  *
  * This function will duplicate file descriptors contained in \p t.
  */
-inline status_t flatten(
+status_t flatten(
         HGraphicBufferProducer::FrameEventHistoryDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.compositorTiming);
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
-    for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
-        status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
+        void*& buffer, size_t& size, int*& fds, size_t& numFds);
 
 /**
  * \brief Wrap `::android::FrameEventHistoryData` in
@@ -1013,42 +551,9 @@
  * native handle. All the non-`nullptr` elements must be deleted individually
  * with `native_handle_delete()`.
  */
-inline bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
+bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
         std::vector<std::vector<native_handle_t*> >* nh,
-        ::android::FrameEventHistoryDelta const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+        ::android::FrameEventHistoryDelta const& l);
 
 /**
  * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
@@ -1059,42 +564,9 @@
  *
  * This function will duplicate all file descriptors contained in \p t.
  */
-inline bool convertTo(
+bool convertTo(
         ::android::FrameEventHistoryDelta* l,
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
 
 // Ref: frameworks/native/libs/ui/Region.cpp
 
@@ -1104,9 +576,7 @@
  * \param[in] t The input `Region`.
  * \return The required size of the flat buffer.
  */
-inline size_t getFlattenedSize(Region const& t) {
-    return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
-}
+size_t getFlattenedSize(Region const& t);
 
 /**
  * \brief Unflatten `Region`.
@@ -1116,36 +586,7 @@
  * \param[in,out] size The size of the flat buffer.
  * \return `NO_ERROR` on success; other value on failure.
  */
-inline status_t unflatten(Region* t, void const*& buffer, size_t& size) {
-    if (size < sizeof(uint32_t)) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numRects = 0;
-    FlattenableUtils::read(buffer, size, numRects);
-    if (size < numRects * sizeof(Rect)) {
-        return NO_MEMORY;
-    }
-    if (numRects > (UINT32_MAX / sizeof(Rect))) {
-        return NO_MEMORY;
-    }
-
-    t->resize(numRects);
-    for (size_t r = 0; r < numRects; ++r) {
-        ::android::Rect rect(::android::Rect::EMPTY_RECT);
-        status_t status = rect.unflatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-        (*t)[r] = Rect{
-                static_cast<int32_t>(rect.left),
-                static_cast<int32_t>(rect.top),
-                static_cast<int32_t>(rect.right),
-                static_cast<int32_t>(rect.bottom)};
-    }
-    return NO_ERROR;
-}
+status_t unflatten(Region* t, void const*& buffer, size_t& size);
 
 /**
  * \brief Flatten `Region`.
@@ -1155,26 +596,7 @@
  * \param[in,out] size The size of the flat buffer.
  * \return `NO_ERROR` on success; other value on failure.
  */
-inline status_t flatten(Region const& t, void*& buffer, size_t& size) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
-    for (size_t r = 0; r < t.size(); ++r) {
-        ::android::Rect rect(
-                static_cast<int32_t>(t[r].left),
-                static_cast<int32_t>(t[r].top),
-                static_cast<int32_t>(t[r].right),
-                static_cast<int32_t>(t[r].bottom));
-        status_t status = rect.flatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-    }
-    return NO_ERROR;
-}
+status_t flatten(Region const& t, void*& buffer, size_t& size);
 
 /**
  * \brief Convert `::android::Region` to `Region`.
@@ -1183,28 +605,7 @@
  * \param[in] l The source `::android::Region`.
  */
 // convert: ::android::Region -> Region
-inline bool convertTo(Region* t, ::android::Region const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (l.flatten(buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (unflatten(t, constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+bool convertTo(Region* t, ::android::Region const& l);
 
 /**
  * \brief Convert `Region` to `::android::Region`.
@@ -1213,64 +614,19 @@
  * \param[in] t The source `Region`.
  */
 // convert: Region -> ::android::Region
-inline bool convertTo(::android::Region* l, Region const& t) {
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (flatten(t, buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (l->unflatten(constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+bool convertTo(::android::Region* l, Region const& t);
 
 // Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
 //      BGraphicBufferProducer::QueueBufferInput
 
 /**
- * \brief Return a lower bound on the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::QueueBufferInput const& /* t */) {
-    return sizeof(int64_t) + // timestamp
-            sizeof(int) + // isAutoTimestamp
-            sizeof(android_dataspace) + // dataSpace
-            sizeof(::android::Rect) + // crop
-            sizeof(int) + // scalingMode
-            sizeof(uint32_t) + // transform
-            sizeof(uint32_t) + // stickyTransform
-            sizeof(bool); // getFrameTimestamps
-}
-
-/**
  * \brief Return the size of the buffer required to flatten
  * `HGraphicBufferProducer::QueueBufferInput`.
  *
  * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
  * \return The required size of the flat buffer.
  */
-inline size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
-    return minFlattenedSize(t) +
-            getFenceFlattenedSize(t.fence) +
-            getFlattenedSize(t.surfaceDamage) +
-            sizeof(HdrMetadata::validTypes);
-}
+size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t);
 
 /**
  * \brief Return the number of file descriptors contained in
@@ -1279,11 +635,8 @@
  * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
  * \return The number of file descriptors contained in \p t.
  */
-inline size_t getFdCount(
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-    return getFenceFdCount(t.fence);
-}
-
+size_t getFdCount(
+        HGraphicBufferProducer::QueueBufferInput const& t);
 /**
  * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
  *
@@ -1296,40 +649,9 @@
  * \return `NO_ERROR` on success; other value on failure.
  *
  * This function will duplicate the file descriptor in `t.fence`. */
-inline status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
+status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
         native_handle_t** nh,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.timestamp);
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
-    FlattenableUtils::write(buffer, size,
-            static_cast<android_dataspace_t>(t.dataSpace));
-    FlattenableUtils::write(buffer, size, ::android::Rect(
-            static_cast<int32_t>(t.crop.left),
-            static_cast<int32_t>(t.crop.top),
-            static_cast<int32_t>(t.crop.right),
-            static_cast<int32_t>(t.crop.bottom)));
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
-    FlattenableUtils::write(buffer, size, t.transform);
-    FlattenableUtils::write(buffer, size, t.stickyTransform);
-    FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
-
-    *nh = t.fence.getNativeHandle() == nullptr ?
-            nullptr : native_handle_clone(t.fence);
-    status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    status = flatten(t.surfaceDamage, buffer, size);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
-    return NO_ERROR;
-}
+        void*& buffer, size_t& size, int*& fds, size_t& numFds);
 
 /**
  * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
@@ -1347,42 +669,9 @@
  * descriptor. \p nh needs to be deleted with `native_handle_delete()`
  * afterwards.
  */
-inline status_t unflatten(
+status_t unflatten(
         HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->timestamp);
-    int lIsAutoTimestamp;
-    FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
-    t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
-    android_dataspace_t lDataSpace;
-    FlattenableUtils::read(buffer, size, lDataSpace);
-    t->dataSpace = static_cast<Dataspace>(lDataSpace);
-    Rect lCrop;
-    FlattenableUtils::read(buffer, size, lCrop);
-    t->crop = Rect{
-            static_cast<int32_t>(lCrop.left),
-            static_cast<int32_t>(lCrop.top),
-            static_cast<int32_t>(lCrop.right),
-            static_cast<int32_t>(lCrop.bottom)};
-    int lScalingMode;
-    FlattenableUtils::read(buffer, size, lScalingMode);
-    t->scalingMode = static_cast<int32_t>(lScalingMode);
-    FlattenableUtils::read(buffer, size, t->transform);
-    FlattenableUtils::read(buffer, size, t->stickyTransform);
-    FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
-
-    status_t status = unflattenFence(&(t->fence), nh,
-            buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    // HdrMetadata ignored
-    return unflatten(&(t->surfaceDamage), buffer, size);
-}
+        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
 
 /**
  * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
@@ -1398,43 +687,10 @@
  * descriptor. \p nh needs to be deleted with `native_handle_delete()`
  * afterwards.
  */
-inline bool wrapAs(
+bool wrapAs(
         HGraphicBufferProducer::QueueBufferInput* t,
         native_handle_t** nh,
-        BGraphicBufferProducer::QueueBufferInput const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
+        BGraphicBufferProducer::QueueBufferInput const& l);
 
 /**
  * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
@@ -1445,48 +701,9 @@
  *
  * If `t.fence` has a valid file descriptor, it will be duplicated.
  */
-inline bool convertTo(
+bool convertTo(
         BGraphicBufferProducer::QueueBufferInput* l,
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    native_handle_t* nh;
-    if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        if (nh != nullptr) {
-            native_handle_close(nh);
-            native_handle_delete(nh);
-        }
-        return false;
-    }
-
-    native_handle_delete(nh);
-    return true;
-}
+        HGraphicBufferProducer::QueueBufferInput const& t);
 
 // Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
 //      BGraphicBufferProducer::QueueBufferOutput
@@ -1507,20 +724,9 @@
  */
 // wrap: BGraphicBufferProducer::QueueBufferOutput ->
 // HGraphicBufferProducer::QueueBufferOutput
-inline bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
+bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
         std::vector<std::vector<native_handle_t*> >* nh,
-        BGraphicBufferProducer::QueueBufferOutput const& l) {
-    if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
-        return false;
-    }
-    t->width = l.width;
-    t->height = l.height;
-    t->transformHint = l.transformHint;
-    t->numPendingBuffers = l.numPendingBuffers;
-    t->nextFrameNumber = l.nextFrameNumber;
-    t->bufferReplaced = l.bufferReplaced;
-    return true;
-}
+        BGraphicBufferProducer::QueueBufferOutput const& l);
 
 /**
  * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
@@ -1533,20 +739,9 @@
  */
 // convert: HGraphicBufferProducer::QueueBufferOutput ->
 // BGraphicBufferProducer::QueueBufferOutput
-inline bool convertTo(
+bool convertTo(
         BGraphicBufferProducer::QueueBufferOutput* l,
-        HGraphicBufferProducer::QueueBufferOutput const& t) {
-    if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
-        return false;
-    }
-    l->width = t.width;
-    l->height = t.height;
-    l->transformHint = t.transformHint;
-    l->numPendingBuffers = t.numPendingBuffers;
-    l->nextFrameNumber = t.nextFrameNumber;
-    l->bufferReplaced = t.bufferReplaced;
-    return true;
-}
+        HGraphicBufferProducer::QueueBufferOutput const& t);
 
 /**
  * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
@@ -1555,16 +750,8 @@
  * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
  * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
  */
-inline HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
-        BGraphicBufferProducer::DisconnectMode l) {
-    switch (l) {
-        case BGraphicBufferProducer::DisconnectMode::Api:
-            return HGraphicBufferProducer::DisconnectMode::API;
-        case BGraphicBufferProducer::DisconnectMode::AllLocal:
-            return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
-    }
-    return HGraphicBufferProducer::DisconnectMode::API;
-}
+HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
+        BGraphicBufferProducer::DisconnectMode l);
 
 /**
  * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
@@ -1573,18 +760,10 @@
  * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
  * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
  */
-inline BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
-        HGraphicBufferProducer::DisconnectMode t) {
-    switch (t) {
-        case HGraphicBufferProducer::DisconnectMode::API:
-            return BGraphicBufferProducer::DisconnectMode::Api;
-        case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
-            return BGraphicBufferProducer::DisconnectMode::AllLocal;
-    }
-    return BGraphicBufferProducer::DisconnectMode::Api;
-}
+BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
+        HGraphicBufferProducer::DisconnectMode t);
 
 }  // namespace conversion
 }  // namespace android
 
-#endif  // MEDIA_STAGEFRIGHT_CONVERSION_H_
+#endif  // MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
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 30c189e..0000000
--- a/media/libstagefright/include/media/stagefright/Codec2InfoBuilder.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CODEC2_INFO_BUILDER_H_
-#define CODEC2_INFO_BUILDER_H_
-
-#include <media/stagefright/MediaCodecList.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class Codec2InfoBuilder : public MediaCodecListBuilderBase {
-public:
-    Codec2InfoBuilder() = default;
-    ~Codec2InfoBuilder() override = default;
-    status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
-};
-
-}  // namespace android
-
-#endif  // CODEC2_INFO_BUILDER_H_
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/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index b6480a2..b0d8e7d 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -40,9 +40,6 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
 
-# TODO: Enable proguard (b/74090741)
-LOCAL_PROGUARD_ENABLED := disabled
-
 LOCAL_MULTILIB := first
 
 LOCAL_JAVA_LIBRARIES += android-support-annotations
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 2b7c72a..89c29e6 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -48,6 +48,7 @@
 import android.media.MediaSession2.CommandButton;
 import android.media.MediaSession2.CommandGroup;
 import android.media.MediaSession2.ControllerInfo;
+import android.media.MediaSession2.OnDataSourceMissingHelper;
 import android.media.MediaSession2.SessionCallback;
 import android.media.MediaSessionService2;
 import android.media.SessionToken2;
@@ -61,7 +62,6 @@
 import android.os.ResultReceiver;
 import android.support.annotation.GuardedBy;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.util.Log;
 
 import java.lang.ref.WeakReference;
@@ -111,9 +111,13 @@
     @GuardedBy("mLock")
     private MediaPlaylistAgent mPlaylistAgent;
     @GuardedBy("mLock")
+    private SessionPlaylistAgent mSessionPlaylistAgent;
+    @GuardedBy("mLock")
     private VolumeProvider2 mVolumeProvider;
     @GuardedBy("mLock")
     private PlaybackInfo mPlaybackInfo;
+    @GuardedBy("mLock")
+    private OnDataSourceMissingHelper mDsmHelper;
 
     /**
      * Can be only called by the {@link Builder#build()}.
@@ -207,7 +211,7 @@
     }
 
     @Override
-    public void updatePlayer_impl(MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
+    public void updatePlayer_impl(@NonNull MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
             VolumeProvider2 volumeProvider) throws IllegalArgumentException {
         ensureCallingThread();
         if (player == null) {
@@ -225,9 +229,12 @@
             oldPlayer = mPlayer;
             oldAgent = mPlaylistAgent;
             mPlayer = player;
-            // TODO(jaewan): Replace this with the proper default agent (b/74090741)
             if (agent == null) {
-                agent = new MediaPlaylistAgent(mContext) {};
+                mSessionPlaylistAgent = new SessionPlaylistAgent(mContext, this, mPlayer);
+                if (mDsmHelper != null) {
+                    mSessionPlaylistAgent.setOnDataSourceMissingHelper(mDsmHelper);
+                }
+                agent = mSessionPlaylistAgent;
             }
             mPlaylistAgent = agent;
             mVolumeProvider = volumeProvider;
@@ -312,6 +319,7 @@
             mPlayer = null;
             agent = mPlaylistAgent;
             mPlaylistAgent = null;
+            mSessionPlaylistAgent = null;
         }
         if (player != null) {
             player.unregisterPlayerEventCallback(mPlayerEventCallback);
@@ -385,7 +393,7 @@
     }
 
     @Override
-    public void skipToPlaylistItem_impl(MediaItem2 item) {
+    public void skipToPlaylistItem_impl(@NonNull MediaItem2 item) {
         if (item == null) {
             throw new IllegalArgumentException("item shouldn't be null");
         }
@@ -418,7 +426,8 @@
     }
 
     @Override
-    public void setCustomLayout_impl(ControllerInfo controller, List<CommandButton> layout) {
+    public void setCustomLayout_impl(@NonNull ControllerInfo controller,
+            @NonNull List<CommandButton> layout) {
         ensureCallingThread();
         if (controller == null) {
             throw new IllegalArgumentException("controller shouldn't be null");
@@ -434,7 +443,8 @@
     //////////////////////////////////////////////////////////////////////////////////////
 
     @Override
-    public void setAllowedCommands_impl(ControllerInfo controller, CommandGroup commands) {
+    public void setAllowedCommands_impl(@NonNull ControllerInfo controller,
+            @NonNull CommandGroup commands) {
         if (controller == null) {
             throw new IllegalArgumentException("controller shouldn't be null");
         }
@@ -445,8 +455,8 @@
     }
 
     @Override
-    public void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
-            ResultReceiver receiver) {
+    public void sendCustomCommand_impl(@NonNull ControllerInfo controller, @NonNull Command command,
+            Bundle args, ResultReceiver receiver) {
         if (controller == null) {
             throw new IllegalArgumentException("controller shouldn't be null");
         }
@@ -457,7 +467,7 @@
     }
 
     @Override
-    public void sendCustomCommand_impl(Command command, Bundle args) {
+    public void sendCustomCommand_impl(@NonNull Command command, Bundle args) {
         if (command == null) {
             throw new IllegalArgumentException("command shouldn't be null");
         }
@@ -465,7 +475,7 @@
     }
 
     @Override
-    public void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata) {
+    public void setPlaylist_impl(@NonNull List<MediaItem2> list, MediaMetadata2 metadata) {
         if (list == null) {
             throw new IllegalArgumentException("list shouldn't be null");
         }
@@ -489,7 +499,7 @@
     }
 
     @Override
-    public void addPlaylistItem_impl(int index, MediaItem2 item) {
+    public void addPlaylistItem_impl(int index, @NonNull MediaItem2 item) {
         if (index < 0) {
             throw new IllegalArgumentException("index shouldn't be negative");
         }
@@ -505,7 +515,7 @@
     }
 
     @Override
-    public void removePlaylistItem_impl(MediaItem2 item) {
+    public void removePlaylistItem_impl(@NonNull MediaItem2 item) {
         if (item == null) {
             throw new IllegalArgumentException("item shouldn't be null");
         }
@@ -518,7 +528,7 @@
     }
 
     @Override
-    public void replacePlaylistItem_impl(int index, MediaItem2 item) {
+    public void replacePlaylistItem_impl(int index, @NonNull MediaItem2 item) {
         if (index < 0) {
             throw new IllegalArgumentException("index shouldn't be negative");
         }
@@ -685,6 +695,29 @@
         mSessionStub.notifyError(errorCode, extras);
     }
 
+    @Override
+    public void setOnDataSourceMissingHelper_impl(@NonNull OnDataSourceMissingHelper helper) {
+        if (helper == null) {
+            throw new IllegalArgumentException("helper shouldn't be null");
+        }
+        synchronized (mLock) {
+            mDsmHelper = helper;
+            if (mSessionPlaylistAgent != null) {
+                mSessionPlaylistAgent.setOnDataSourceMissingHelper(helper);
+            }
+        }
+    }
+
+    @Override
+    public void clearOnDataSourceMissingHelper_impl() {
+        synchronized (mLock) {
+            mDsmHelper = null;
+            if (mSessionPlaylistAgent != null) {
+                mSessionPlaylistAgent.clearOnDataSourceMissingHelper();
+            }
+        }
+    }
+
     ///////////////////////////////////////////////////
     // Protected or private methods
     ///////////////////////////////////////////////////
@@ -1022,7 +1055,7 @@
         /**
          * @return a new Command instance from the Bundle
          */
-        public static Command fromBundle_impl(Context context, Bundle command) {
+        public static Command fromBundle_impl(Context context, @NonNull Bundle command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1092,7 +1125,7 @@
         }
 
         @Override
-        public void addCommand_impl(Command command) {
+        public void addCommand_impl(@NonNull Command command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1129,7 +1162,7 @@
         }
 
         @Override
-        public void removeCommand_impl(Command command) {
+        public void removeCommand_impl(@NonNull Command command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1137,7 +1170,7 @@
         }
 
         @Override
-        public boolean hasCommand_impl(Command command) {
+        public boolean hasCommand_impl(@NonNull Command command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1217,7 +1250,7 @@
         private final IMediaController2 mControllerBinder;
 
         public ControllerInfoImpl(Context context, ControllerInfo instance, int uid,
-                int pid, String packageName, IMediaController2 callback) {
+                int pid, @NonNull String packageName, @NonNull IMediaController2 callback) {
             if (TextUtils.isEmpty(packageName)) {
                 throw new IllegalArgumentException("packageName shouldn't be empty");
             }
@@ -1234,7 +1267,7 @@
             // Ask server whether the controller is trusted.
             // App cannot know this because apps cannot query enabled notification listener for
             // another package, but system server can do.
-            mIsTrusted = manager.isTrusted(uid, packageName);
+            mIsTrusted = manager.isTrusted(packageName, pid, uid);
         }
 
         @Override
@@ -1468,7 +1501,7 @@
          *      {@link MediaSession2} or {@link MediaController2}.
          */
         // TODO(jaewan): Also need executor
-        public BuilderBaseImpl(Context context) {
+        public BuilderBaseImpl(@NonNull Context context) {
             if (context == null) {
                 throw new IllegalArgumentException("context shouldn't be null");
             }
@@ -1478,7 +1511,7 @@
         }
 
         @Override
-        public void setPlayer_impl(MediaPlayerBase player) {
+        public void setPlayer_impl(@NonNull MediaPlayerBase player) {
             if (player == null) {
                 throw new IllegalArgumentException("player shouldn't be null");
             }
@@ -1486,7 +1519,7 @@
         }
 
         @Override
-        public void setPlaylistAgent_impl(MediaPlaylistAgent playlistAgent) {
+        public void setPlaylistAgent_impl(@NonNull MediaPlaylistAgent playlistAgent) {
             if (playlistAgent == null) {
                 throw new IllegalArgumentException("playlistAgent shouldn't be null");
             }
@@ -1504,7 +1537,7 @@
         }
 
         @Override
-        public void setId_impl(String id) {
+        public void setId_impl(@NonNull String id) {
             if (id == null) {
                 throw new IllegalArgumentException("id shouldn't be null");
             }
@@ -1512,7 +1545,7 @@
         }
 
         @Override
-        public void setSessionCallback_impl(Executor executor, C callback) {
+        public void setSessionCallback_impl(@NonNull Executor executor, @NonNull C callback) {
             if (executor == null) {
                 throw new IllegalArgumentException("executor shouldn't be null");
             }
diff --git a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
index 6805dad..693e137 100644
--- a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
+++ b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
@@ -24,7 +24,6 @@
 import android.media.MediaMetadata2;
 import android.media.MediaPlayerBase;
 import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2;
 import android.media.MediaSession2.OnDataSourceMissingHelper;
 import android.util.ArrayMap;
 
@@ -47,14 +46,13 @@
     private final PlayItem mEopPlayItem = new PlayItem(END_OF_PLAYLIST, null);
 
     private final Object mLock = new Object();
-    private final MediaSession2 mSession;
+    private final MediaSession2Impl mSessionImpl;
 
     // TODO: Set data sources properly into mPlayer (b/74090741)
     @GuardedBy("mLock")
     private MediaPlayerBase mPlayer;
     @GuardedBy("mLock")
-    private OnDataSourceMissingHelper mDsdHelper;
-
+    private OnDataSourceMissingHelper mDsmHelper;
     // TODO: Check if having the same item is okay (b/74090741)
     @GuardedBy("mLock")
     private ArrayList<MediaItem2> mPlaylist = new ArrayList<>();
@@ -118,16 +116,16 @@
         }
     }
 
-    public SessionPlaylistAgent(@NonNull Context context, @NonNull MediaSession2 session,
+    public SessionPlaylistAgent(@NonNull Context context, @NonNull MediaSession2Impl sessionImpl,
             @NonNull MediaPlayerBase player) {
         super(context);
-        if (session == null) {
-            throw new IllegalArgumentException("session shouldn't be null");
+        if (sessionImpl == null) {
+            throw new IllegalArgumentException("sessionImpl shouldn't be null");
         }
         if (player == null) {
             throw new IllegalArgumentException("player shouldn't be null");
         }
-        mSession = session;
+        mSessionImpl = sessionImpl;
         mPlayer = player;
     }
 
@@ -142,7 +140,13 @@
 
     public void setOnDataSourceMissingHelper(OnDataSourceMissingHelper helper) {
         synchronized (mLock) {
-            mDsdHelper = helper;
+            mDsmHelper = helper;
+        }
+    }
+
+    public void clearOnDataSourceMissingHelper() {
+        synchronized (mLock) {
+            mDsmHelper = null;
         }
     }
 
@@ -154,8 +158,7 @@
     }
 
     @Override
-    public void setPlaylist(@NonNull List<MediaItem2> list,
-            @Nullable MediaMetadata2 metadata) {
+    public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
         if (list == null) {
             throw new IllegalArgumentException("list shouldn't be null");
         }
@@ -359,10 +362,10 @@
         if (dsd != null) {
             return dsd;
         }
-        OnDataSourceMissingHelper helper = mDsdHelper;
+        OnDataSourceMissingHelper helper = mDsmHelper;
         if (helper != null) {
             // TODO: Do not call onDataSourceMissing with the lock (b/74090741).
-            dsd = helper.onDataSourceMissing(mSession, item);
+            dsd = helper.onDataSourceMissing(mSessionImpl.getInstance(), item);
             if (dsd != null) {
                 mItemDsdMap.put(item, dsd);
             }
diff --git a/packages/MediaComponents/tests/Android.mk b/packages/MediaComponents/tests/Android.mk
index bf81efb..dddfd2a 100644
--- a/packages/MediaComponents/tests/Android.mk
+++ b/packages/MediaComponents/tests/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android.test.runner.stubs \
     android.test.base.stubs \
+    mockito-target-minus-junit4 \
     junit
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
index 80370ec..ca941ab 100644
--- a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
+++ b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
@@ -16,19 +16,21 @@
 
 package com.android.media;
 
+import static org.mockito.Mockito.*;
+
 import android.content.Context;
+import android.media.AudioAttributes;
 import android.media.DataSourceDesc;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
-import android.media.MediaPlayer2;
 import android.media.MediaPlayerBase;
 import android.media.MediaPlaylistAgent;
 import android.media.MediaSession2;
+import android.media.MediaSession2.OnDataSourceMissingHelper;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.test.AndroidTestCase;
-import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
@@ -52,10 +54,10 @@
 
     private Object mWaitLock = new Object();
     private Context mContext;
-    private MediaSession2 mSession;
+    private MediaSession2Impl mSessionImpl;
     private MediaPlayerBase mPlayer;
     private SessionPlaylistAgent mAgent;
-    private MyDataSourceHelper mDataSourceHelper;
+    private OnDataSourceMissingHelper mDataSourceHelper;
     private MyPlaylistEventCallback mEventCallback;
 
     public class MyPlaylistEventCallback extends MediaPlaylistAgent.PlaylistEventCallback {
@@ -108,7 +110,7 @@
         }
     }
 
-    public class MyDataSourceHelper implements MediaSession2.OnDataSourceMissingHelper {
+    public class MyDataSourceHelper implements OnDataSourceMissingHelper {
         @Override
         public DataSourceDesc onDataSourceMissing(MediaSession2 session, MediaItem2 item) {
             if (item.getMediaId().contains("WITHOUT_DSD")) {
@@ -121,8 +123,104 @@
         }
     }
 
+    public class MockPlayer extends MediaPlayerBase {
+        @Override
+        public void play() {
+        }
+
+        @Override
+        public void prepare() {
+        }
+
+        @Override
+        public void pause() {
+        }
+
+        @Override
+        public void reset() {
+        }
+
+        @Override
+        public void skipToNext() {
+        }
+
+        @Override
+        public void seekTo(long pos) {
+        }
+
+        @Override
+        public int getPlayerState() {
+            return 0;
+        }
+
+        @Override
+        public int getBufferingState() {
+            return 0;
+        }
+
+        @Override
+        public void setAudioAttributes(AudioAttributes attributes) {
+        }
+
+        @Override
+        public AudioAttributes getAudioAttributes() {
+            return null;
+        }
+
+        @Override
+        public void setDataSource(DataSourceDesc dsd) {
+        }
+
+        @Override
+        public void setNextDataSource(DataSourceDesc dsd) {
+        }
+
+        @Override
+        public void setNextDataSources(List<DataSourceDesc> dsds) {
+        }
+
+        @Override
+        public DataSourceDesc getCurrentDataSource() {
+            return null;
+        }
+
+        @Override
+        public void loopCurrent(boolean loop) {
+        }
+
+        @Override
+        public void setPlaybackSpeed(float speed) {
+        }
+
+        @Override
+        public void setPlayerVolume(float volume) {
+        }
+
+        @Override
+        public float getPlayerVolume() {
+            return 0;
+        }
+
+        @Override
+        public void registerPlayerEventCallback(Executor e, PlayerEventCallback cb) {
+        }
+
+        @Override
+        public void unregisterPlayerEventCallback(PlayerEventCallback cb) {
+        }
+
+        @Override
+        public void close() throws Exception {
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
+        mContext = getContext();
+        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
+        // Dexmaker is used by mockito.
+        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
+
         HandlerThread handlerThread = new HandlerThread("SessionPlaylistAgent");
         handlerThread.start();
         mHandler = new Handler(handlerThread.getLooper());
@@ -130,15 +228,10 @@
             mHandler.post(runnable);
         };
 
-        mContext = getContext();
-        mPlayer = MediaPlayer2.create();
-        mSession = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(mHandlerExecutor,
-                        new MediaSession2.SessionCallback(mContext) {})
-                .setId(TAG).build();
+        mPlayer = mock(MockPlayer.class);
+        mSessionImpl = mock(MediaSession2Impl.class);
         mDataSourceHelper = new MyDataSourceHelper();
-        mAgent = new SessionPlaylistAgent(mContext, mSession, mPlayer);
+        mAgent = new SessionPlaylistAgent(mContext, mSessionImpl, mPlayer);
         mAgent.setOnDataSourceMissingHelper(mDataSourceHelper);
         mEventCallback = new MyPlaylistEventCallback(mWaitLock);
         mAgent.registerPlaylistEventCallback(mHandlerExecutor, mEventCallback);
@@ -146,8 +239,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mSession.close();
-        mPlayer.close();
         mHandler.getLooper().quitSafely();
         mHandler = null;
         mHandlerExecutor = null;
diff --git a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
index 31b7e0f..e4fd176 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
@@ -62,7 +62,8 @@
     [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
     [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
     [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
-    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround"
+    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround",
+    [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] =      "ForceUseForVibrateRinging"
 };
 
 
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 977a396..be7f7ec 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -154,6 +154,13 @@
         }
         mForceUse[usage] = config;
         break;
+    case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
+        if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
+            ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
+            return BAD_VALUE;
+        }
+        mForceUse[usage] = config;
+        break;
     default:
         ALOGW("setForceUse() invalid usage %d", usage);
         break; // TODO return BAD_VALUE?
@@ -423,8 +430,7 @@
 
         // if SCO headset is connected and we are told to use it, play ringtone over
         // speaker and BT SCO
-        if (((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO)) {
+        if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
             uint32_t device2 = AUDIO_DEVICE_NONE;
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
             if (device2 == AUDIO_DEVICE_NONE) {
@@ -433,10 +439,23 @@
             if (device2 == AUDIO_DEVICE_NONE) {
                 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
             }
-
-            if (device2 != AUDIO_DEVICE_NONE) {
-                device |= device2;
-                break;
+            // Use ONLY Bluetooth SCO output when ringing in vibration mode
+            if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+                    && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
+                if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
+                        == AUDIO_POLICY_FORCE_BT_SCO) {
+                    if (device2 != AUDIO_DEVICE_NONE) {
+                        device = device2;
+                        break;
+                    }
+                }
+            }
+            // Use both Bluetooth SCO and phone default output when ringing in normal mode
+            if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
+                if (device2 != AUDIO_DEVICE_NONE) {
+                    device |= device2;
+                    break;
+                }
             }
         }
         // The second device used for sonification is the same as the device used by media strategy
