Merge "Release AudioTrackCallback when the track is removed." into rvc-qpr-dev am: c7d12948fb

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/12629238

Change-Id: I1b635405c05c5a6690ec3da86412b0cd37003e05
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/apex/Android.bp b/apex/Android.bp
index c1ef3d8..ef296d6 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -59,6 +59,16 @@
     name: "com.android.media",
     manifest: "manifest.json",
     defaults: ["com.android.media-defaults"],
+    prebuilts: [
+        "media-linker-config",
+    ],
+}
+
+prebuilt_etc {
+    name: "media-linker-config",
+    src: "linker.config.txt",
+    filename: "linker.config.txt",
+    installable: false,
 }
 
 filegroup {
diff --git a/apex/linker.config.txt b/apex/linker.config.txt
new file mode 100644
index 0000000..d1c815b
--- /dev/null
+++ b/apex/linker.config.txt
@@ -0,0 +1,7 @@
+# Extra linker configurations for media APEX
+# See https://android.googlesource.com/platform/system/linkerconfig/+/master/README.md#apex_etc_linker_config_txt
+
+[properties]
+
+# Set media APEX as force visible so media APEX namespace is accessible via android_get_exported_namespace
+visible = true
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 2320fd7..1f05d2e 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,7 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 300000000
+  "version": 300000000,
+  "requireNativeLibs": [
+    ":sphal"
+  ]
 }
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 68969cf..e95c91c 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -20,6 +20,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <camera/CameraParameters.h>
 #include <system/graphics.h>
 
diff --git a/camera/CameraParameters2.cpp b/camera/CameraParameters2.cpp
index c29233c..a1cf355 100644
--- a/camera/CameraParameters2.cpp
+++ b/camera/CameraParameters2.cpp
@@ -21,6 +21,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <camera/CameraParameters2.h>
 
 namespace android {
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index dc7f88a..09a333b 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -37,7 +37,7 @@
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
     ],
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
     cflags: [
         "-Wall",
         "-Wextra",
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index b58ebe2..419250c 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -743,7 +743,7 @@
     // No way to get package name from native.
     // Send a zero length package name and let camera service figure it out from UID
     binder::Status serviceRet = cs->connectDevice(
-            callbacks, String16(cameraId), String16(""), std::unique_ptr<String16>(),
+            callbacks, String16(cameraId), String16(""), {},
             hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
 
     if (!serviceRet.isOk()) {
diff --git a/camera/ndk/include/camera/NdkCameraMetadata.h b/camera/ndk/include/camera/NdkCameraMetadata.h
index 072bb02..a840bd1 100644
--- a/camera/ndk/include/camera/NdkCameraMetadata.h
+++ b/camera/ndk/include/camera/NdkCameraMetadata.h
@@ -36,6 +36,7 @@
 #ifndef _NDK_CAMERA_METADATA_H
 #define _NDK_CAMERA_METADATA_H
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <sys/cdefs.h>
 
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 8ccded2..eee05ff 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -378,7 +378,7 @@
         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
         sp<hardware::camera2::ICameraDeviceUser> device;
         res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
-                std::unique_ptr<String16>(), hardware::ICameraService::USE_CALLING_UID,
+                {}, hardware::ICameraService::USE_CALLING_UID,
                 /*out*/&device);
         EXPECT_TRUE(res.isOk()) << res;
         ASSERT_NE(nullptr, device.get());
@@ -421,7 +421,7 @@
         {
             SCOPED_TRACE("openNewDevice");
             binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
-                    std::unique_ptr<String16>(), hardware::ICameraService::USE_CALLING_UID,
+                    {}, hardware::ICameraService::USE_CALLING_UID,
                     /*out*/&device);
             EXPECT_TRUE(res.isOk()) << res;
         }
diff --git a/drm/common/include/DrmEngineBase.h b/drm/common/include/DrmEngineBase.h
index 73f11a4..c0a5e3b 100644
--- a/drm/common/include/DrmEngineBase.h
+++ b/drm/common/include/DrmEngineBase.h
@@ -309,7 +309,7 @@
 
     /**
      * Removes all the rights information of each plug-in associated with
-     * DRM framework. Will be used in master reset
+     * DRM framework.
      *
      * @param[in] uniqueId Unique identifier for a session
      * @return status_t
diff --git a/drm/common/include/IDrmEngine.h b/drm/common/include/IDrmEngine.h
index 1837a11..a545941 100644
--- a/drm/common/include/IDrmEngine.h
+++ b/drm/common/include/IDrmEngine.h
@@ -250,7 +250,7 @@
 
     /**
      * Removes all the rights information of each plug-in associated with
-     * DRM framework. Will be used in master reset
+     * DRM framework.
      *
      * @param[in] uniqueId Unique identifier for a session
      * @return status_t
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index b68e6c2..fcd291f 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -43,7 +43,7 @@
         "-Werror",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     init_rc: ["drmserver.rc"],
 }
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 9a32cc5..74e3223 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -99,13 +99,13 @@
         }
         default:
         {
-            ALOGW("Unrecognized message type: %zd", msg->what());
+            ALOGW("Unrecognized message type: %u", msg->what());
         }
     }
 }
 
 int64_t DrmManager::getMetricsFlushPeriodUs() {
-    return 1000 * 1000 * std::max(1ll, property_get_int64("drmmanager.metrics.period", 86400));
+    return 1000 * 1000 * std::max(1ll, (long long)property_get_int64("drmmanager.metrics.period", 86400));
 }
 
 void DrmManager::recordEngineMetrics(
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 3858675..8c8783b 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -230,7 +230,7 @@
 
     /**
      * Removes all the rights information of each plug-in associated with
-     * DRM framework. Will be used in master reset
+     * DRM framework.
      *
      * @param[in] uniqueId Unique identifier for a session
      * @return status_t
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
index b62ddb9..eb5b0f6 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
@@ -252,8 +252,7 @@
 
 /**
  * Removes all the rights information of each plug-in associated with
- * DRM framework. Will be used in master reset but does nothing for
- * Forward Lock Engine.
+ * DRM framework. Does nothing for Forward Lock Engine.
  *
  * @param uniqueId Unique identifier for a session
  * @return status_t
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/doc/FwdLock.html b/drm/libdrmframework/plugins/forward-lock/internal-format/doc/FwdLock.html
index 8f95cd2..c1d5b3d 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/doc/FwdLock.html
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/doc/FwdLock.html
@@ -488,7 +488,7 @@
 <p class=MsoBodyText><b>Note:</b> The key-encryption key must be unique to each
 device; this is what makes the files forward lock–protected. Ideally, it should
 be derived from secret hardware parameters, but at the very least it should be
-persistent from one master reset to the next.</p>
+persistent from one factory reset to the next.</p>
 
 <div style='margin-bottom:24.0pt;border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
 background:#F2F2F2'>
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 5292705..e31395d 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -66,7 +66,7 @@
     std::vector<MediaResourceParcel> resources;
     MediaResourceParcel resource{
             Type::kDrmSession, SubType::kUnspecifiedSubType,
-            toStdVec<int8_t>(sessionId), value};
+            toStdVec<>(sessionId), value};
     resources.push_back(resource);
     return resources;
 }
diff --git a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
index 9e43504..c56bf01 100644
--- a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
+++ b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
@@ -62,7 +62,7 @@
     void removeSession(const Vector<uint8_t>& sessionId);
     bool reclaimSession(int callingPid);
 
-    // sanity check APIs
+    // inspection APIs
     size_t getSessionCount() const;
     bool containsSession(const Vector<uint8_t>& sessionId) const;
 
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
index cb69f91..466e571 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
@@ -62,8 +62,8 @@
     }
     ALOGV("descriptor_size=%zu", container.descriptor_size());
 
-    // Sanity check to verify that the BroadcastEncryptor is sending a properly
-    // formed EcmContainer. If it contains two Ecms, the ids should have different
+    // Validate that the BroadcastEncryptor is sending a properly formed
+    // EcmContainer. If it contains two Ecms, the ids should have different
     // parity (one odd, one even). This does not necessarily affect decryption
     // but indicates a problem with Ecm generation.
     if (container.descriptor_size() == 2) {
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index 866edac..a38aa9b 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -318,7 +318,7 @@
 
     /**
      * Removes all the rights information of each plug-in associated with
-     * DRM framework. Will be used in master reset
+     * DRM framework.
      *
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
diff --git a/media/OWNERS b/media/OWNERS
index 1afc253..bd83ad9 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -8,7 +8,6 @@
 hunga@google.com
 jiabin@google.com
 jmtrivi@google.com
-krocard@google.com
 lajos@google.com
 marcone@google.com
 mnaganov@google.com
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index f9f4f31..17309dd 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -49,7 +49,12 @@
 
     signal(SIGPIPE, SIG_IGN);
 
+#if 1
+    // FIXME See bug 165702394 and bug 168511485
+    const bool doLog = false;
+#else
     bool doLog = (bool) property_get_bool("ro.test_harness", 0);
+#endif
 
     pid_t childPid;
     // FIXME The advantage of making the process containing media.log service the parent process of
diff --git a/media/bufferpool/1.0/vts/multi.cpp b/media/bufferpool/1.0/vts/multi.cpp
index 1796819..d8cc285 100644
--- a/media/bufferpool/1.0/vts/multi.cpp
+++ b/media/bufferpool/1.0/vts/multi.cpp
@@ -215,7 +215,7 @@
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-  setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+  android::hardware::details::setTrebleTestingOverride(true);
   ::testing::InitGoogleTest(&argc, argv);
   int status = RUN_ALL_TESTS();
   LOG(INFO) << "Test result = " << status;
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/bufferpool/2.0/tests/multi.cpp
index 68b6992..b40838e 100644
--- a/media/bufferpool/2.0/tests/multi.cpp
+++ b/media/bufferpool/2.0/tests/multi.cpp
@@ -215,7 +215,7 @@
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-  setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+  android::hardware::details::setTrebleTestingOverride(true);
   ::testing::InitGoogleTest(&argc, argv);
   int status = RUN_ALL_TESTS();
   LOG(INFO) << "Test result = " << status;
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index c7046cb..9ba3b697 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -506,30 +506,28 @@
 }
 
 static void copyOutputBufferToYuvPlanarFrame(
-        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
+        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
         size_t srcYStride, size_t srcUStride, size_t srcVStride,
         size_t dstYStride, size_t dstUVStride,
         uint32_t width, uint32_t height) {
-    uint8_t* dstStart = dst;
 
     for (size_t i = 0; i < height; ++i) {
-        memcpy(dst, srcY, width);
+        memcpy(dstY, srcY, width);
         srcY += srcYStride;
-        dst += dstYStride;
+        dstY += dstYStride;
     }
 
-    dst = dstStart + dstYStride * height;
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcV, width / 2);
+        memcpy(dstV, srcV, width / 2);
         srcV += srcVStride;
-        dst += dstUVStride;
+        dstV += dstUVStride;
     }
 
-    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcU, width / 2);
+        memcpy(dstU, srcU, width / 2);
         srcU += srcUStride;
-        dst += dstUVStride;
+        dstU += dstUVStride;
     }
 }
 
@@ -596,16 +594,12 @@
     return;
 }
 
-static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+static void convertYUV420Planar16ToYUV420Planar(
+        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
         const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
         size_t srcYStride, size_t srcUStride, size_t srcVStride,
-        size_t dstYStride, size_t dstUVStride, size_t width, size_t height) {
-
-    uint8_t *dstY = (uint8_t *)dst;
-    size_t dstYSize = dstYStride * height;
-    size_t dstUVSize = dstUVStride * height / 2;
-    uint8_t *dstV = dstY + dstYSize;
-    uint8_t *dstU = dstV + dstUVSize;
+        size_t dstYStride, size_t dstUVStride,
+        size_t width, size_t height) {
 
     for (size_t y = 0; y < height; ++y) {
         for (size_t x = 0; x < width; ++x) {
@@ -696,7 +690,9 @@
           block->width(), block->height(), mWidth, mHeight,
           (int)*(int64_t*)img->user_priv);
 
-    uint8_t* dst = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t* dstY = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t* dstU = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_U]);
+    uint8_t* dstV = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_V]);
     size_t srcYStride = img->stride[AOM_PLANE_Y];
     size_t srcUStride = img->stride[AOM_PLANE_U];
     size_t srcVStride = img->stride[AOM_PLANE_V];
@@ -710,13 +706,14 @@
         const uint16_t *srcV = (const uint16_t *)img->planes[AOM_PLANE_V];
 
         if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
-            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+            convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
                                     srcUStride / 2, srcVStride / 2,
                                     dstYStride / sizeof(uint32_t),
                                     mWidth, mHeight);
         } else {
-            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
-                                    srcUStride / 2, srcVStride / 2,
+            convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+                                    srcY, srcU, srcV,
+                                    srcYStride / 2, srcUStride / 2, srcVStride / 2,
                                     dstYStride, dstUVStride,
                                     mWidth, mHeight);
         }
@@ -725,7 +722,7 @@
         const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U];
         const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V];
         copyOutputBufferToYuvPlanarFrame(
-                dst, srcY, srcU, srcV,
+                dstY, dstU, dstV, srcY, srcU, srcV,
                 srcYStride, srcUStride, srcVStride,
                 dstYStride, dstUVStride,
                 mWidth, mHeight);
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index d7b9e12..3afd670 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -34,7 +34,11 @@
 constexpr size_t kMinInputBufferSize = 2 * 1024 * 1024;
 constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
 constexpr uint32_t kDefaultOutputDelay = 8;
-constexpr uint32_t kMaxOutputDelay = 16;
+/* avc specification allows for a maximum delay of 16 frames.
+   As soft avc decoder supports interlaced, this delay would be 32 fields.
+   And avc decoder implementation has an additional delay of 2 decode calls.
+   So total maximum output delay is 34 */
+constexpr uint32_t kMaxOutputDelay = 34;
 constexpr uint32_t kMinInputBytes = 4;
 }  // namespace
 
diff --git a/media/codec2/components/cmds/codec2.cpp b/media/codec2/components/cmds/codec2.cpp
index d6025de..a17b04e 100644
--- a/media/codec2/components/cmds/codec2.cpp
+++ b/media/codec2/components/cmds/codec2.cpp
@@ -138,7 +138,7 @@
 
 SimplePlayer::SimplePlayer()
     : mListener(new Listener(this)),
-      mProducerListener(new DummyProducerListener),
+      mProducerListener(new StubProducerListener),
       mLinearPoolId(C2BlockPool::PLATFORM_START),
       mComposerClient(new SurfaceComposerClient) {
     CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
diff --git a/media/codec2/components/g711/Android.bp b/media/codec2/components/g711/Android.bp
index 3ede68c..0101b1a 100644
--- a/media/codec2/components/g711/Android.bp
+++ b/media/codec2/components/g711/Android.bp
@@ -7,6 +7,8 @@
 
     srcs: ["C2SoftG711Dec.cpp"],
 
+    static_libs: ["codecs_g711dec"],
+
     cflags: [
         "-DALAW",
     ],
@@ -20,4 +22,6 @@
     ],
 
     srcs: ["C2SoftG711Dec.cpp"],
+
+    static_libs: ["codecs_g711dec"],
 }
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
index 4ff0793..7f9c34e 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.cpp
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -22,7 +22,7 @@
 
 #include <C2PlatformSupport.h>
 #include <SimpleC2Interface.h>
-
+#include <g711Dec.h>
 #include "C2SoftG711Dec.h"
 
 namespace android {
@@ -224,53 +224,6 @@
     return C2_OK;
 }
 
-#ifdef ALAW
-void C2SoftG711Dec::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 C2SoftG711Dec::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:
     C2SoftG711DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
diff --git a/media/codec2/components/g711/C2SoftG711Dec.h b/media/codec2/components/g711/C2SoftG711Dec.h
index 23e8ffc..f93840b 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.h
+++ b/media/codec2/components/g711/C2SoftG711Dec.h
@@ -45,12 +45,6 @@
     std::shared_ptr<IntfImpl> mIntf;
     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
-
     C2_DO_NOT_COPY(C2SoftG711Dec);
 };
 
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 120ba7a..a1929e7 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -458,32 +458,28 @@
   }
 }
 
-static void copyOutputBufferToYuvPlanarFrame(uint8_t *dst, const uint8_t *srcY,
-                                             const uint8_t *srcU,
-                                             const uint8_t *srcV, size_t srcYStride,
-                                             size_t srcUStride, size_t srcVStride,
-                                             size_t dstYStride, size_t dstUVStride,
-                                             uint32_t width, uint32_t height) {
-  uint8_t *const dstStart = dst;
+static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
+                                        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+                                        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+                                        size_t dstYStride, size_t dstUVStride,
+                                        uint32_t width, uint32_t height) {
 
   for (size_t i = 0; i < height; ++i) {
-    memcpy(dst, srcY, width);
+    memcpy(dstY, srcY, width);
     srcY += srcYStride;
-    dst += dstYStride;
+    dstY += dstYStride;
   }
 
-  dst = dstStart + dstYStride * height;
   for (size_t i = 0; i < height / 2; ++i) {
-    memcpy(dst, srcV, width / 2);
+    memcpy(dstV, srcV, width / 2);
     srcV += srcVStride;
-    dst += dstUVStride;
+    dstV += dstUVStride;
   }
 
-  dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
   for (size_t i = 0; i < height / 2; ++i) {
-    memcpy(dst, srcU, width / 2);
+    memcpy(dstU, srcU, width / 2);
     srcU += srcUStride;
-    dst += dstUVStride;
+    dstU += dstUVStride;
   }
 }
 
@@ -555,15 +551,11 @@
 }
 
 static void convertYUV420Planar16ToYUV420Planar(
-    uint8_t *dst, const uint16_t *srcY, const uint16_t *srcU,
-    const uint16_t *srcV, size_t srcYStride, size_t srcUStride,
-    size_t srcVStride, size_t dstYStride, size_t dstUVStride,
+    uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
+    const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+    size_t srcYStride, size_t srcUStride, size_t srcVStride,
+    size_t dstYStride, size_t dstUVStride,
     size_t width, size_t height) {
-  uint8_t *dstY = (uint8_t *)dst;
-  size_t dstYSize = dstYStride * height;
-  size_t dstUVSize = dstUVStride * height / 2;
-  uint8_t *dstV = dstY + dstYSize;
-  uint8_t *dstU = dstV + dstUVSize;
 
   for (size_t y = 0; y < height; ++y) {
     for (size_t x = 0; x < width; ++x) {
@@ -667,10 +659,13 @@
   ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d", block->width(),
         block->height(), mWidth, mHeight, (int)buffer->user_private_data);
 
-  uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+  uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+  uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
+  uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
   size_t srcYStride = buffer->stride[0];
   size_t srcUStride = buffer->stride[1];
   size_t srcVStride = buffer->stride[2];
+
   C2PlanarLayout layout = wView.layout();
   size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
   size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
@@ -682,20 +677,24 @@
 
     if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
       convertYUV420Planar16ToY410(
-          (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
+          (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
           srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
     } else {
-      convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
-                                          srcUStride / 2, srcVStride / 2,
-                                          dstYStride, dstUVStride, mWidth, mHeight);
+      convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+                                          srcY, srcU, srcV,
+                                          srcYStride / 2, srcUStride / 2, srcVStride / 2,
+                                          dstYStride, dstUVStride,
+                                          mWidth, mHeight);
     }
   } else {
     const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
     const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
     const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
-    copyOutputBufferToYuvPlanarFrame(dst, srcY, srcU, srcV, srcYStride, srcUStride,
-                                     srcVStride, dstYStride, dstUVStride,
-                                     mWidth, mHeight);
+    copyOutputBufferToYV12Frame(dstY, dstU, dstV,
+                                srcY, srcU, srcV,
+                                srcYStride, srcUStride, srcVStride,
+                                dstYStride, dstUVStride,
+                                mWidth, mHeight);
   }
   finishWork(buffer->user_private_data, work, std::move(block));
   block = nullptr;
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.h b/media/codec2/components/gsm/C2SoftGsmDec.h
index 2b209fe..edd273b 100644
--- a/media/codec2/components/gsm/C2SoftGsmDec.h
+++ b/media/codec2/components/gsm/C2SoftGsmDec.h
@@ -19,10 +19,7 @@
 
 #include <SimpleC2Component.h>
 
-
-extern "C" {
-    #include "gsm.h"
-}
+#include "gsm.h"
 
 namespace android {
 
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 61b286c..13cc0ec 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -464,34 +464,34 @@
 /* TODO: can remove temporary copy after library supports writing to display
  * buffer Y, U and V plane pointers using stride info. */
 static void copyOutputBufferToYuvPlanarFrame(
-        uint8_t *dst, uint8_t *src,
+        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, uint8_t *src,
         size_t dstYStride, size_t dstUVStride,
         size_t srcYStride, uint32_t width,
         uint32_t height) {
     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);
+         memcpy(dstY, src, width);
          src += srcYStride;
-         dst += dstYStride;
+         dstY += 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);
+         memcpy(dstU, src, width / 2);
          src += srcUVStride;
-         dst += dstUVStride;
+         dstU += 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);
+         memcpy(dstV, src, width / 2);
          src += srcUVStride;
-         dst += dstUVStride;
+         dstV += dstUVStride;
     }
 }
 
@@ -672,11 +672,14 @@
         }
 
         uint8_t *outputBufferY = wView.data()[C2PlanarLayout::PLANE_Y];
+        uint8_t *outputBufferU = wView.data()[C2PlanarLayout::PLANE_U];
+        uint8_t *outputBufferV = wView.data()[C2PlanarLayout::PLANE_V];
+
         C2PlanarLayout layout = wView.layout();
         size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
         size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
         (void)copyOutputBufferToYuvPlanarFrame(
-                outputBufferY,
+                outputBufferY, outputBufferU, outputBufferV,
                 mOutputBuffer[mNumSamplesOutput & 1],
                 dstYStride, dstUVStride,
                 align(mWidth, 16), mWidth, mHeight);
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 3eef1e3..91238e8 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -631,31 +631,30 @@
 }
 
 static void copyOutputBufferToYuvPlanarFrame(
-        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
+        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
         size_t srcYStride, size_t srcUStride, size_t srcVStride,
         size_t dstYStride, size_t dstUVStride,
         uint32_t width, uint32_t height) {
-    uint8_t *dstStart = dst;
 
     for (size_t i = 0; i < height; ++i) {
-         memcpy(dst, srcY, width);
+         memcpy(dstY, srcY, width);
          srcY += srcYStride;
-         dst += dstYStride;
+         dstY += dstYStride;
     }
 
-    dst = dstStart + dstYStride * height;
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcV, width / 2);
+         memcpy(dstV, srcV, width / 2);
          srcV += srcVStride;
-         dst += dstUVStride;
+         dstV += dstUVStride;
     }
 
-    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcU, width / 2);
+         memcpy(dstU, srcU, width / 2);
          srcU += srcUStride;
-         dst += dstUVStride;
+         dstU += dstUVStride;
     }
+
 }
 
 static void convertYUV420Planar16ToY410(uint32_t *dst,
@@ -721,16 +720,12 @@
     return;
 }
 
-static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+static void convertYUV420Planar16ToYUV420Planar(
+        uint8_t *dstY, uint8_t *dstU, uint8_t *dstV,
         const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
         size_t srcYStride, size_t srcUStride, size_t srcVStride,
-        size_t dstYStride, size_t dstUVStride, size_t width, size_t height) {
-
-    uint8_t *dstY = (uint8_t *)dst;
-    size_t dstYSize = dstYStride * height;
-    size_t dstUVSize = dstUVStride * height / 2;
-    uint8_t *dstV = dstY + dstYSize;
-    uint8_t *dstU = dstV + dstUVSize;
+        size_t dstYStride, size_t dstUVStride,
+        size_t width, size_t height) {
 
     for (size_t y = 0; y < height; ++y) {
         for (size_t x = 0; x < width; ++x) {
@@ -823,7 +818,10 @@
            block->width(), block->height(), mWidth, mHeight,
            ((c2_cntr64_t *)img->user_priv)->peekll());
 
-    uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
+    uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
+
     size_t srcYStride = img->stride[VPX_PLANE_Y];
     size_t srcUStride = img->stride[VPX_PLANE_U];
     size_t srcVStride = img->stride[VPX_PLANE_V];
@@ -842,18 +840,18 @@
             constexpr size_t kHeight = 64;
             for (; i < mHeight; i += kHeight) {
                 queue->entries.push_back(
-                        [dst, srcY, srcU, srcV,
+                        [dstY, srcY, srcU, srcV,
                          srcYStride, srcUStride, srcVStride, dstYStride,
                          width = mWidth, height = std::min(mHeight - i, kHeight)] {
                             convertYUV420Planar16ToY410(
-                                    (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+                                    (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
                                     srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
                                     width, height);
                         });
                 srcY += srcYStride / 2 * kHeight;
                 srcU += srcUStride / 2 * (kHeight / 2);
                 srcV += srcVStride / 2 * (kHeight / 2);
-                dst += dstYStride * kHeight;
+                dstY += dstYStride * kHeight;
             }
             CHECK_EQ(0u, queue->numPending);
             queue->numPending = queue->entries.size();
@@ -862,8 +860,9 @@
                 queue.waitForCondition(queue->cond);
             }
         } else {
-            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
-                                                srcUStride / 2, srcVStride / 2,
+            convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+                                                srcY, srcU, srcV,
+                                                srcYStride / 2, srcUStride / 2, srcVStride / 2,
                                                 dstYStride, dstUVStride,
                                                 mWidth, mHeight);
         }
@@ -871,8 +870,10 @@
         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];
+
         copyOutputBufferToYuvPlanarFrame(
-                dst, srcY, srcU, srcV,
+                dstY, dstU, dstV,
+                srcY, srcU, srcV,
                 srcYStride, srcUStride, srcVStride,
                 dstYStride, dstUVStride,
                 mWidth, mHeight);
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
index ce1c9ac..33fafa7 100644
--- a/media/codec2/core/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -21,6 +21,10 @@
         "-Werror",
     ],
 
+    header_abi_checker: {
+        check_all_apis: true,
+    },
+
     header_libs: [
         "libcodec2_headers",
         "libhardware_headers",
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index a16b106..3780a5a 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -52,6 +52,9 @@
     // directly in the main device manifest.xml file or via vintf_fragments.
     // (Remove the line below if the entry is already in the main manifest.)
     vintf_fragments: ["manifest_media_c2_V1_1_default.xml"],
+
+    // Remove this line to enable this module.
+    enabled: false,
 }
 
 // seccomp policy file.
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 1972d3f..73b3857 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1816,15 +1816,18 @@
                         // move all info into output-stream #0 domain
                         updates.emplace_back(C2Param::CopyAsStream(*info, true /* output */, stream));
                     }
-                    for (const C2ConstGraphicBlock &block : buf->data().graphicBlocks()) {
+
+                    const std::vector<C2ConstGraphicBlock> blocks = buf->data().graphicBlocks();
+                    // for now only do the first block
+                    if (!blocks.empty()) {
                         // ALOGV("got output buffer with crop %u,%u+%u,%u and size %u,%u",
                         //      block.crop().left, block.crop().top,
                         //      block.crop().width, block.crop().height,
                         //      block.width(), block.height());
+                        const C2ConstGraphicBlock &block = blocks[0];
                         updates.emplace_back(new C2StreamCropRectInfo::output(stream, block.crop()));
                         updates.emplace_back(new C2StreamPictureSizeInfo::output(
                                 stream, block.crop().width, block.crop().height));
-                        break; // for now only do the first block
                     }
                     ++stream;
                 }
@@ -1836,7 +1839,7 @@
                 // copy standard infos to graphic buffers if not already present (otherwise, we
                 // may overwrite the actual intermediate value with a final value)
                 stream = 0;
-                const static std::vector<C2Param::Index> stdGfxInfos = {
+                const static C2Param::Index stdGfxInfos[] = {
                     C2StreamRotationInfo::output::PARAM_TYPE,
                     C2StreamColorAspectsInfo::output::PARAM_TYPE,
                     C2StreamDataSpaceInfo::output::PARAM_TYPE,
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index c49a16c..3c99bf6 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -91,7 +91,9 @@
             newFormat->setInt32(KEY_STRIDE, stride);
             ALOGD("[%s] updating stride = %d", mName, stride);
             if (img->mNumPlanes > 1 && stride > 0) {
-                int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride;
+                int64_t offsetDelta =
+                    (int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset;
+                int32_t vstride = int32_t(offsetDelta / stride);
                 newFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
                 ALOGD("[%s] updating vstride = %d", mName, vstride);
             }
diff --git a/media/codec2/tests/C2UtilTest.cpp b/media/codec2/tests/C2UtilTest.cpp
index 59cd313..2d66df1 100644
--- a/media/codec2/tests/C2UtilTest.cpp
+++ b/media/codec2/tests/C2UtilTest.cpp
@@ -78,7 +78,7 @@
       { "value2", Enum3Value2 },
       { "value4", Enum3Value4 },
       { "invalid", Invalid } });
-    Enum3 e3;
+    Enum3 e3(Invalid);
     C2FieldDescriptor::namedValuesFor(e3);
 
     // upper case
diff --git a/media/codecs/g711/decoder/Android.bp b/media/codecs/g711/decoder/Android.bp
new file mode 100644
index 0000000..efff60b
--- /dev/null
+++ b/media/codecs/g711/decoder/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_library_static {
+    name: "codecs_g711dec",
+    vendor_available: true,
+    host_supported: true,
+
+    srcs: [
+        "g711DecAlaw.cpp",
+        "g711DecMlaw.cpp",
+    ],
+
+    export_include_dirs: ["."],
+
+    cflags: ["-Werror"],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+            "unsigned-integer-overflow",
+        ],
+        cfi: true,
+    },
+    apex_available: ["com.android.media.swcodec"],
+    min_sdk_version: "29",
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
diff --git a/media/codecs/g711/decoder/g711Dec.h b/media/codecs/g711/decoder/g711Dec.h
new file mode 100644
index 0000000..ca357a5
--- /dev/null
+++ b/media/codecs/g711/decoder/g711Dec.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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 G711_DEC_H_
+#define G711_DEC_H_
+
+/**
+ * @file g711Dec.h
+ * @brief g711 Decoder API: DecodeALaw and DecodeMLaw
+ */
+
+/** Decodes input bytes of size inSize according to ALAW
+ *
+ * @param [in] out <tt>int16_t*</tt>: output buffer to be filled with decoded bytes.
+ * @param [in] in <tt>const uint8_t*</tt>: input buffer containing bytes to be decoded.
+ * @param [in] inSize <tt>size_t</tt>: size of the input buffer.
+ */
+void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
+
+/** Decodes input bytes of size inSize according to MLAW
+ *
+ * @param [in] out <tt>int16_t*</tt>: output buffer to be filled with decoded bytes.
+ * @param [in] in <tt>const uint8_t*</tt>: input buffer containing bytes to be decoded.
+ * @param [in] inSize <tt>size_t</tt>: size of the input buffer.
+ */
+void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
+
+#endif  // G711_DECODER_H_
diff --git a/media/codecs/g711/decoder/g711DecAlaw.cpp b/media/codecs/g711/decoder/g711DecAlaw.cpp
new file mode 100644
index 0000000..e41a7b4
--- /dev/null
+++ b/media/codecs/g711/decoder/g711DecAlaw.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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 <stddef.h>
+#include <stdint.h>
+
+void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize) {
+  if (out != nullptr && in != nullptr) {
+    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;
+    }
+  }
+}
diff --git a/media/codecs/g711/decoder/g711DecMlaw.cpp b/media/codecs/g711/decoder/g711DecMlaw.cpp
new file mode 100644
index 0000000..bb2caea
--- /dev/null
+++ b/media/codecs/g711/decoder/g711DecMlaw.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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 <stddef.h>
+#include <stdint.h>
+
+void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize) {
+  if (out != nullptr && in != nullptr) {
+    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;
+    }
+  }
+}
diff --git a/media/codecs/g711/fuzzer/Android.bp b/media/codecs/g711/fuzzer/Android.bp
new file mode 100644
index 0000000..ff5efa9
--- /dev/null
+++ b/media/codecs/g711/fuzzer/Android.bp
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "g711alaw_dec_fuzzer",
+    host_supported: true,
+    srcs: [
+        "g711_dec_fuzzer.cpp",
+    ],
+    static_libs: [
+        "codecs_g711dec",
+    ],
+    cflags: [
+        "-DALAW",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
+
+cc_fuzz {
+    name: "g711mlaw_dec_fuzzer",
+    host_supported: true,
+    srcs: [
+        "g711_dec_fuzzer.cpp",
+    ],
+    static_libs: [
+        "codecs_g711dec",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/media/codecs/g711/fuzzer/README.md b/media/codecs/g711/fuzzer/README.md
new file mode 100644
index 0000000..0c1c36b
--- /dev/null
+++ b/media/codecs/g711/fuzzer/README.md
@@ -0,0 +1,49 @@
+# Fuzzer for libstagefright_g711dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for G711 is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+G711 supports two types of decoding:
+1. DecodeALaw
+2. DecodeMLaw
+
+These two decoder API's are fuzzed separately using g711alaw_dec_fuzzer and
+g711mlaw_dec_fuzzer respectively.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec as expected by decoder API.
+
+## Build
+
+This describes steps to build g711alaw_dec_fuzzer and g711mlaw_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) g711alaw_dec_fuzzer
+  $ mm -j$(nproc) g711mlaw_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some g711 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/g711alaw_dec_fuzzer/g711alaw_dec_fuzzer CORPUS_DIR
+  $ adb shell /data/fuzz/arm64/g711mlaw_dec_fuzzer/g711mlaw_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/g711alaw_dec_fuzzer/g711alaw_dec_fuzzer CORPUS_DIR
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/g711mlaw_dec_fuzzer/g711mlaw_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp b/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
new file mode 100644
index 0000000..adfbcf5
--- /dev/null
+++ b/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g711Dec.h"
+
+class Codec {
+ public:
+  Codec() = default;
+  ~Codec() = default;
+  void decodeFrames(const uint8_t *data, size_t size);
+};
+
+void Codec::decodeFrames(const uint8_t *data, size_t size) {
+  size_t outputBufferSize = sizeof(int16_t) * size;
+  int16_t *out = new int16_t[outputBufferSize];
+  if (!out) {
+    return;
+  }
+#ifdef ALAW
+  DecodeALaw(out, data, size);
+#else
+  DecodeMLaw(out, data, size);
+#endif
+  delete[] out;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (size < 1) {
+    return 0;
+  }
+  Codec *codec = new Codec();
+  if (!codec) {
+    return 0;
+  }
+  codec->decodeFrames(data, size);
+  delete codec;
+  return 0;
+}
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
index 7c4e62f..f9abfe3 100644
--- a/media/extractors/Android.bp
+++ b/media/extractors/Android.bp
@@ -21,7 +21,6 @@
 
     shared_libs: [
         "liblog",
-        "libmediandk#29",
     ],
 
     // extractors are supposed to work on Q(29)
@@ -39,6 +38,21 @@
 
     version_script: "exports.lds",
 
+    target: {
+        android: {
+            shared_libs: [
+                "libmediandk#29",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libutils",
+                "libmediandk_format",
+                "libmedia_ndkformatpriv",
+            ],
+        },
+    },
+
     sanitize: {
         cfi: true,
         misc_undefined: [
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index 60d3ae1..c036bb5 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -10,4 +10,11 @@
         "libutils",
     ],
 
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index 49c9567..440065f 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -8,4 +8,10 @@
         "libstagefright_foundation",
     ],
 
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    }
 }
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 826c1a0..2593000 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -21,4 +21,12 @@
         "libutils",
     ],
 
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
 }
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
new file mode 100644
index 0000000..31d6f83
--- /dev/null
+++ b/media/extractors/fuzzers/Android.bp
@@ -0,0 +1,312 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+cc_defaults {
+    name: "extractor-fuzzerbase-defaults",
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    static_libs: [
+        "liblog",
+        "libstagefright_foundation",
+        "libmediandk_format",
+        "libmedia_ndkformatpriv",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "libbinder",
+        "libbase",
+        "libcutils",
+    ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+cc_defaults {
+    name: "extractor-fuzzer-defaults",
+    defaults: ["extractor-fuzzerbase-defaults"],
+
+    static_libs: [
+        "libextractorfuzzerbase",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
+
+cc_defaults {
+    name: "mpeg2-extractor-fuzzer-defaults",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    include_dirs: [
+        "frameworks/av/media/extractors/mpeg2",
+        "frameworks/av/media/libstagefright",
+    ],
+
+    static_libs: [
+        "libstagefright_foundation_without_imemory",
+        "libstagefright_mpeg2support",
+        "libstagefright_mpeg2extractor",
+        "libstagefright_esds",
+        "libmpeg2extractor",
+        "libmedia_helper",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.token@1.0-utils",
+        "android.hidl.allocator@1.0",
+        "libcrypto",
+        "libhidlmemory",
+        "libhidlbase",
+    ],
+}
+
+cc_library_static {
+    name: "libextractorfuzzerbase",
+    defaults: ["extractor-fuzzerbase-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "ExtractorFuzzerBase.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "mp4_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "mp4_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/mp4",
+    ],
+
+    header_libs: [
+        "libaudioclient_headers",
+    ],
+
+    static_libs: [
+        "libstagefright_id3",
+        "libstagefright_esds",
+        "libmp4extractor",
+    ],
+
+    dictionary: "mp4_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "wav_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "wav_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/wav",
+    ],
+
+    static_libs: [
+        "libfifo",
+        "libwavextractor",
+    ],
+
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "amr_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "amr_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/amr",
+    ],
+
+    static_libs: [
+        "libamrextractor",
+    ],
+
+    dictionary: "amr_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "mkv_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "mkv_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/mkv",
+    ],
+
+    static_libs: [
+        "libwebm",
+        "libstagefright_flacdec",
+        "libstagefright_metadatautils",
+        "libmkvextractor",
+        "libFLAC",
+    ],
+
+    dictionary: "mkv_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "ogg_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "ogg_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/ogg",
+    ],
+
+    static_libs: [
+        "libstagefright_metadatautils",
+        "libvorbisidec",
+        "liboggextractor",
+    ],
+
+    dictionary: "ogg_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "mpeg2ps_extractor_fuzzer",
+    defaults: ["mpeg2-extractor-fuzzer-defaults"],
+
+    srcs: [
+        "mpeg2_extractor_fuzzer.cpp",
+    ],
+
+    cflags: [
+        "-DMPEG2PS",
+    ],
+
+    dictionary: "mpeg2ps_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "mpeg2ts_extractor_fuzzer",
+    defaults: ["mpeg2-extractor-fuzzer-defaults"],
+
+    srcs: [
+        "mpeg2_extractor_fuzzer.cpp",
+    ],
+
+    dictionary: "mpeg2ts_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "mp3_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "mp3_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/mp3",
+    ],
+
+    static_libs: [
+        "libfifo",
+        "libmp3extractor",
+        "libstagefright_id3",
+    ],
+}
+
+cc_fuzz {
+    name: "aac_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "aac_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/aac",
+    ],
+
+    static_libs: [
+        "libaacextractor",
+        "libstagefright_metadatautils",
+    ],
+}
+
+cc_fuzz {
+    name: "flac_extractor_fuzzer",
+    defaults: ["extractor-fuzzer-defaults"],
+    host_supported: true,
+
+    srcs: [
+        "flac_extractor_fuzzer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/flac",
+    ],
+
+    static_libs: [
+        "libstagefright_metadatautils",
+        "libFLAC",
+        "libflacextractor",
+    ],
+
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+
+    dictionary: "flac_extractor_fuzzer.dict",
+}
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
new file mode 100644
index 0000000..1be8466
--- /dev/null
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2020 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 "ExtractorFuzzerBase"
+#include <utils/Log.h>
+
+#include "ExtractorFuzzerBase.h"
+
+using namespace android;
+
+bool ExtractorFuzzerBase::setDataSource(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return false;
+  }
+  mBufferSource = new BufferSource(data, size);
+  mDataSource = reinterpret_cast<DataSource*>(mBufferSource.get());
+  if (!mDataSource) {
+    return false;
+  }
+  return true;
+}
+
+void ExtractorFuzzerBase::getExtractorDef() {
+  float confidence;
+  void* meta = nullptr;
+  FreeMetaFunc freeMeta = nullptr;
+
+  ExtractorDef extractorDef = GETEXTRACTORDEF();
+  if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+    extractorDef.u.v2.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+  } else if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+    extractorDef.u.v3.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+  }
+
+  if (meta != nullptr && freeMeta != nullptr) {
+    freeMeta(meta);
+  }
+}
+
+void ExtractorFuzzerBase::extractTracks() {
+  MediaBufferGroup* bufferGroup = new MediaBufferGroup();
+  if (!bufferGroup) {
+    return;
+  }
+  size_t trackCount = mExtractor->countTracks();
+  for (size_t trackIndex = 0; trackIndex < trackCount; ++trackIndex) {
+    MediaTrackHelper* track = mExtractor->getTrack(trackIndex);
+    if (!track) {
+      continue;
+    }
+    extractTrack(track, bufferGroup);
+    delete track;
+  }
+  delete bufferGroup;
+}
+
+void ExtractorFuzzerBase::extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup) {
+  CMediaTrack* cTrack = wrap(track);
+  if (!cTrack) {
+    return;
+  }
+
+  media_status_t status = cTrack->start(track, bufferGroup->wrap());
+  if (status != AMEDIA_OK) {
+    free(cTrack);
+    return;
+  }
+
+  do {
+    MediaBufferHelper* buffer = nullptr;
+    status = track->read(&buffer);
+    if (buffer) {
+      buffer->release();
+    }
+  } while (status == AMEDIA_OK);
+
+  cTrack->stop(track);
+  free(cTrack);
+}
+
+void ExtractorFuzzerBase::getTracksMetadata() {
+  AMediaFormat* format = AMediaFormat_new();
+  uint32_t flags = MediaExtractorPluginHelper::kIncludeExtensiveMetaData;
+
+  size_t trackCount = mExtractor->countTracks();
+  for (size_t trackIndex = 0; trackIndex < trackCount; ++trackIndex) {
+    mExtractor->getTrackMetaData(format, trackIndex, flags);
+  }
+
+  AMediaFormat_delete(format);
+}
+
+void ExtractorFuzzerBase::getMetadata() {
+  AMediaFormat* format = AMediaFormat_new();
+  mExtractor->getMetaData(format);
+  AMediaFormat_delete(format);
+}
+
+void ExtractorFuzzerBase::setDataSourceFlags(uint32_t flags) {
+  mBufferSource->setFlags(flags);
+}
+
+void ExtractorFuzzerBase::seekAndExtractTracks() {
+  MediaBufferGroup* bufferGroup = new MediaBufferGroup();
+  if (!bufferGroup) {
+    return;
+  }
+  size_t trackCount = mExtractor->countTracks();
+  for (size_t trackIndex = 0; trackIndex < trackCount; ++trackIndex) {
+    MediaTrackHelper* track = mExtractor->getTrack(trackIndex);
+    if (!track) {
+      continue;
+    }
+
+    AMediaFormat* trackMetaData = AMediaFormat_new();
+    int64_t trackDuration = 0;
+    uint32_t flags = MediaExtractorPluginHelper::kIncludeExtensiveMetaData;
+    mExtractor->getTrackMetaData(trackMetaData, trackIndex, flags);
+    AMediaFormat_getInt64(trackMetaData, AMEDIAFORMAT_KEY_DURATION, &trackDuration);
+
+    seekAndExtractTrack(track, bufferGroup, trackDuration);
+    AMediaFormat_delete(trackMetaData);
+    delete track;
+  }
+  delete bufferGroup;
+}
+
+void ExtractorFuzzerBase::seekAndExtractTrack(MediaTrackHelper* track,
+                                              MediaBufferGroup* bufferGroup,
+                                              int64_t trackDuration) {
+  CMediaTrack* cTrack = wrap(track);
+  if (!cTrack) {
+    return;
+  }
+
+  media_status_t status = cTrack->start(track, bufferGroup->wrap());
+  if (status != AMEDIA_OK) {
+    free(cTrack);
+    return;
+  }
+
+  int32_t seekCount = 0;
+  std::vector<int64_t> seekToTimeStamp;
+  while (seekCount <= kFuzzerMaxSeekPointsCount) {
+    /* This ensures kFuzzerMaxSeekPointsCount seek points are within the clipDuration and 1 seek
+     * point is outside of the clipDuration.
+     */
+    int64_t timeStamp = (seekCount * trackDuration) / (kFuzzerMaxSeekPointsCount - 1);
+    seekToTimeStamp.push_back(timeStamp);
+    seekCount++;
+  }
+
+  std::vector<uint32_t> seekOptions;
+  seekOptions.push_back(CMediaTrackReadOptions::SEEK | CMediaTrackReadOptions::SEEK_CLOSEST);
+  seekOptions.push_back(CMediaTrackReadOptions::SEEK | CMediaTrackReadOptions::SEEK_CLOSEST_SYNC);
+  seekOptions.push_back(CMediaTrackReadOptions::SEEK | CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC);
+  seekOptions.push_back(CMediaTrackReadOptions::SEEK | CMediaTrackReadOptions::SEEK_NEXT_SYNC);
+  seekOptions.push_back(CMediaTrackReadOptions::SEEK | CMediaTrackReadOptions::SEEK_FRAME_INDEX);
+
+  for (uint32_t seekOption : seekOptions) {
+    for (int64_t seekPts : seekToTimeStamp) {
+      MediaTrackHelper::ReadOptions* options =
+          new MediaTrackHelper::ReadOptions(seekOption, seekPts);
+      MediaBufferHelper* buffer = nullptr;
+      track->read(&buffer, options);
+      if (buffer) {
+        buffer->release();
+      }
+      delete options;
+    }
+  }
+
+  cTrack->stop(track);
+  free(cTrack);
+}
+
+void ExtractorFuzzerBase::processData(const uint8_t* data, size_t size) {
+  if (setDataSource(data, size)) {
+    if (createExtractor()) {
+      getExtractorDef();
+      getMetadata();
+      extractTracks();
+      getTracksMetadata();
+      seekAndExtractTracks();
+    }
+  }
+}
diff --git a/media/extractors/fuzzers/README.md b/media/extractors/fuzzers/README.md
new file mode 100644
index 0000000..4223b5e
--- /dev/null
+++ b/media/extractors/fuzzers/README.md
@@ -0,0 +1,326 @@
+# Fuzzer for extractors
+
+## Table of contents
++ [libextractorfuzzerbase](#ExtractorFuzzerBase)
++ [libmp4extractor](#mp4ExtractorFuzzer)
++ [libwavextractor](#wavExtractorFuzzer)
++ [libamrextractor](#amrExtractorFuzzer)
++ [libmkvextractor](#mkvExtractorFuzzer)
++ [liboggextractor](#oggExtractorFuzzer)
++ [libmpeg2extractor](#mpeg2ExtractorFuzzer)
++ [libmp3extractor](#mp3ExtractorFuzzer)
++ [libaacextractor](#aacExtractorFuzzer)
++ [libflacextractor](#flacExtractor)
+
+# <a name="ExtractorFuzzerBase"></a> Fuzzer for libextractorfuzzerbase
+All the extractors have a common API - creating a data source, extraction
+of all the tracks, etc. These common APIs have been abstracted in a base class
+called `ExtractorFuzzerBase` to ensure code is reused between fuzzer plugins.
+
+Additionally, `ExtractorFuzzerBase` also has support for memory based buffer
+`BufferSource` since the fuzzing engine feeds data using memory buffers and
+usage of standard data source objects like FileSource, HTTPSource, etc. is
+not feasible.
+
+# <a name="mp4ExtractorFuzzer"></a> Fuzzer for libmp4extractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MP4 extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MP4 extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MP4 to ensure that the required MP4
+atoms are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered as a range of MP4 atoms will be
+present in the input data.
+
+
+## Build
+
+This describes steps to build mp4_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mp4_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MP4 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mp4_extractor_fuzzer/mp4_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="wavExtractorFuzzer"></a> Fuzzer for libwavextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for WAV extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the WAV extractor class.
+
+
+## Build
+
+This describes steps to build wav_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) wav_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some wav files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/wav_extractor_fuzzer/wav_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="amrExtractorFuzzer"></a> Fuzzer for libamrextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the AMR extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for AMR to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build amr_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) amr_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some AMR files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/amr_extractor_fuzzer/amr_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mkvExtractorFuzzer"></a> Fuzzer for libmkvextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MKV extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MKV extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MKV to ensure that the required element
+ID's are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build mkv_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mkv_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mkv files to that folder.
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mkv_extractor_fuzzer/mkv_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="oggExtractorFuzzer"></a> Fuzzer for liboggextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for OGG extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the OGG extractor object.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for OGG to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build ogg_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) ogg_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some ogg files to that folder.
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ogg_extractor_fuzzer/ogg_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mpeg2ExtractorFuzzer"></a> Fuzzer for libmpeg2extractor
+
+## Plugin Design Considerations
+The fuzzer plugins for MPEG2-PS and MPEG2-TS extractor use the `ExtractorFuzzerBase` class and
+implement only the `createExtractor` to create the MPEG2-PS or MPEG2-TS extractor
+object respectively.
+
+##### Maximize code coverage
+Dict files (dictionary files) are created for MPEG2-PS and MPEG2-TS to ensure that the
+required start bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+##### Other considerations
+Two fuzzer binaries - mpeg2ps_extractor_fuzzer and mpeg2ts_extractor_fuzzer are
+generated based on the presence of a flag - `MPEG2PS`
+
+
+## Build
+
+This describes steps to build mpeg2ps_extractor_fuzzer and mpeg2ts_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mpeg2ps_extractor_fuzzer
+  $ mm -j$(nproc) mpeg2ts_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mpeg2 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mpeg2ps_extractor_fuzzer/mpeg2ps_extractor_fuzzer CORPUS_DIR
+  $ adb shell /data/fuzz/arm64/mpeg2ts_extractor_fuzzer/mpeg2ts_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mp3ExtractorFuzzer"></a> Fuzzer for libmp3extractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MP3 extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MP3 extractor class.
+
+
+## Build
+
+This describes steps to build mp3_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mp3_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mp3 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mp3_extractor_fuzzer/mp3_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="aacExtractorFuzzer"></a> Fuzzer for libaacextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for AAC extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the AAC extractor class.
+
+
+## Build
+
+This describes steps to build aac_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) aac_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some aac files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/aac_extractor_fuzzer/aac_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="flacExtractor"></a> Fuzzer for libflacextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for FLAC extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the FLAC extractor object.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for FLAC to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build flac_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) flac_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some flac files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/flac_extractor_fuzzer/flac_extractor_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
new file mode 100644
index 0000000..98a6cc9
--- /dev/null
+++ b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "AACExtractor.h"
+
+#include "ExtractorFuzzerBase.h"
+
+using namespace android;
+
+class AacExtractor : public ExtractorFuzzerBase {
+ public:
+  AacExtractor() = default;
+  ~AacExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool AacExtractor::createExtractor() {
+  mExtractor = new AACExtractor(new DataSourceHelper(mDataSource->wrap()), 0);
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  AacExtractor* extractor = new AacExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
new file mode 100644
index 0000000..6c9e1a5
--- /dev/null
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "AMRExtractor.h"
+
+using namespace android;
+
+class AmrExtractor : public ExtractorFuzzerBase {
+ public:
+  AmrExtractor() = default;
+  ~AmrExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool AmrExtractor::createExtractor() {
+  mExtractor = new AMRExtractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  AmrExtractor* extractor = new AmrExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.dict b/media/extractors/fuzzers/amr_extractor_fuzzer.dict
new file mode 100644
index 0000000..bc5726c
--- /dev/null
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code
+kw1="#!AMR"
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
new file mode 100644
index 0000000..8734d45
--- /dev/null
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "FLACExtractor.h"
+
+using namespace android;
+
+class FlacExtractor : public ExtractorFuzzerBase {
+ public:
+  FlacExtractor() = default;
+  ~FlacExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool FlacExtractor::createExtractor() {
+  mExtractor = new FLACExtractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  FlacExtractor* extractor = new FlacExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.dict b/media/extractors/fuzzers/flac_extractor_fuzzer.dict
new file mode 100644
index 0000000..53ad44f
--- /dev/null
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.dict
@@ -0,0 +1,3 @@
+# Start code (bytes 0-3)
+# The below 4 bytes correspond to "fLaC" in ASCII
+kw1="\x66\x4C\x61\x43"
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
new file mode 100644
index 0000000..6a2a1c1
--- /dev/null
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __EXTRACTOR_FUZZER_BASE_H__
+#define __EXTRACTOR_FUZZER_BASE_H__
+
+#include <media/DataSource.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <vector>
+
+extern "C" {
+android::ExtractorDef GETEXTRACTORDEF();
+}
+
+constexpr int32_t kFuzzerMaxSeekPointsCount = 5;
+
+namespace android {
+
+class ExtractorFuzzerBase {
+ public:
+  ExtractorFuzzerBase() = default;
+  virtual ~ExtractorFuzzerBase() {
+    if (mExtractor) {
+      delete mExtractor;
+      mExtractor = nullptr;
+    }
+    if (mBufferSource) {
+      mBufferSource.clear();
+      mBufferSource = nullptr;
+    }
+  }
+
+  /** Function to create the media extractor component.
+    * To be implemented by the derived class.
+    */
+  virtual bool createExtractor() = 0;
+
+  /** Parent class functions to be reused by derived class.
+    * These are common for all media extractor components.
+    */
+  bool setDataSource(const uint8_t* data, size_t size);
+
+  void getExtractorDef();
+
+  void extractTracks();
+
+  void getMetadata();
+
+  void getTracksMetadata();
+
+  void setDataSourceFlags(uint32_t flags);
+
+  void seekAndExtractTracks();
+
+  void processData(const uint8_t* data, size_t size);
+
+ protected:
+  class BufferSource : public DataSource {
+   public:
+    BufferSource(const uint8_t* data, size_t length) : mData(data), mLength(length) {}
+    virtual ~BufferSource() { mData = nullptr; }
+
+    void setFlags(uint32_t flags) { mFlags = flags; }
+
+    uint32_t flags() { return mFlags; }
+
+    status_t initCheck() const { return mData != nullptr ? OK : NO_INIT; }
+
+    ssize_t readAt(off64_t offset, void* data, size_t size) {
+      if (!mData) {
+        return NO_INIT;
+      }
+
+      Mutex::Autolock autoLock(mLock);
+      if ((offset >= static_cast<off64_t>(mLength)) || (offset < 0)) {
+        return 0;  // read beyond bounds.
+      }
+      size_t numAvailable = mLength - static_cast<size_t>(offset);
+      if (size > numAvailable) {
+        size = numAvailable;
+      }
+      return readAt_l(offset, data, size);
+    }
+
+    status_t getSize(off64_t* size) {
+      if (!mData) {
+        return NO_INIT;
+      }
+
+      Mutex::Autolock autoLock(mLock);
+      *size = static_cast<off64_t>(mLength);
+      return OK;
+    }
+
+   protected:
+    ssize_t readAt_l(off64_t offset, void* data, size_t size) {
+      void* result = memcpy(data, mData + offset, size);
+      return result != nullptr ? size : 0;
+    }
+
+    const uint8_t* mData = nullptr;
+    size_t mLength = 0;
+    Mutex mLock;
+    uint32_t mFlags = 0;
+
+   private:
+    DISALLOW_EVIL_CONSTRUCTORS(BufferSource);
+  };
+
+  sp<BufferSource> mBufferSource;
+  DataSource* mDataSource = nullptr;
+  MediaExtractorPluginHelper* mExtractor = nullptr;
+
+  virtual void extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup);
+  virtual void seekAndExtractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup,
+                                   int64_t trackDuration);
+};
+
+}  // namespace android
+
+#endif  // __EXTRACTOR_FUZZER_BASE_H__
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
new file mode 100644
index 0000000..eceb93f
--- /dev/null
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MatroskaExtractor.h"
+
+using namespace android;
+
+class MKVExtractor : public ExtractorFuzzerBase {
+ public:
+  MKVExtractor() = default;
+  ~MKVExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool MKVExtractor::createExtractor() {
+  mExtractor = new MatroskaExtractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  MKVExtractor* extractor = new MKVExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.dict b/media/extractors/fuzzers/mkv_extractor_fuzzer.dict
new file mode 100644
index 0000000..b3815dc
--- /dev/null
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.dict
@@ -0,0 +1,244 @@
+# Elements ID's
+kw1="\x42\x86"
+kw2="\x42\xF7"
+kw3="\x42\xF2"
+kw4="\x42\xF3"
+kw5="\x42\x87"
+kw6="\x42\x85"
+kw7="\x18\x53\x80\x67"
+kw8="\x11\x4D\x9B\x74"
+kw9="\x4D\xBB"
+kw10="\x53\xAB"
+kw11="\x53\xAC"
+kw12="\x15\x49\xA9\x66"
+kw13="\x73\xA4"
+kw14="\x73\x84"
+kw15="\x3C\xB9\x23"
+kw16="\x3C\x83\xAB"
+kw17="\x3C\xB9\x23"
+kw18="\x3E\x83\xBB"
+kw19="\x44\x44"
+kw20="\x69\x24"
+kw21="\x69\xFC"
+kw22="\x69\xBF"
+kw23="\x69\xA5"
+kw24="\x2A\xD7\xB1"
+kw25="\x44\x89"
+kw26="\x44\x61"
+kw27="\x7B\xA9"
+kw28="\x4D\x80"
+kw29="\x57\x41"
+kw30="\x1F\x43\xB6\x75"
+kw31="\xE7"
+kw32="\x58\x54"
+kw33="\x58\xD7"
+kw34="\xA7"
+kw35="\xAB"
+kw36="\xA3"
+kw37="\xA0"
+kw38="\xA1"
+kw39="\xA2"
+kw40="\x75\xA1"
+kw41="\x2A\xD7\xB1"
+kw42="\xA6"
+kw43="\xEE"
+kw44="\xA5"
+kw45="\x9A"
+kw46="\xFA"
+kw47="\xFB"
+kw48="\xFD"
+kw49="\xA4"
+kw50="\x75\xA2"
+kw51="\x8E"
+kw52="\xE8"
+kw53="\xCC"
+kw54="\xCD"
+kw55="\xCB"
+kw56="\xCE"
+kw57="\xCF"
+kw58="\xC8"
+kw59="\xC9"
+kw60="\xCA"
+kw61="\xAF"
+kw62="\x16\x54\xAE\x6B"
+kw63="\xAE"
+kw64="\xD7"
+kw65="\x73\xC5"
+kw66="\x83"
+kw67="\xB9"
+kw68="\x88"
+kw69="\x55\xAA"
+kw70="\x9C"
+kw71="\x6D\xE7"
+kw72="\x6D\xF8"
+kw73="\x23\xE3\x83"
+kw74="\x23\x4E\x7A"
+kw75="\x23\x31\x4F"
+kw76="\x53\x7F"
+kw77="\x55\xEE"
+kw78="\x53\x6E"
+kw79="\x22\xB5\x9C"
+kw80="\x22\xB5\x9D"
+kw81="\x86"
+kw82="\x63\xA2"
+kw83="\x25\x86\x88"
+kw84="\x26\xB2\x40"
+kw85="\xAA"
+kw86="\x6F\xAB"
+kw87="\x56\xAA"
+kw88="\x56\xBB"
+kw89="\x66\x24"
+kw90="\x66\xFC"
+kw91="\x66\xBF"
+kw92="\xE0"
+kw93="\x9A"
+kw94="\x9D"
+kw95="\x53\xB8"
+kw96="\x53\xC0"
+kw97="\x53\xB9"
+kw98="\xB0"
+kw99="\xBA"
+kw100="\x54\xAA"
+kw101="\x54\xBB"
+kw102="\x54\xCC"
+kw103="\x54\xDD"
+kw104="\x54\xB0"
+kw105="\x54\xBA"
+kw106="\x54\xB2"
+kw107="\x54\xB3"
+kw108="\x2E\xB5\x24"
+kw109="\x2F\xB5\x23"
+kw110="\x23\x83\xE3"
+kw111="\x55\xB0"
+kw112="\x55\xB1"
+kw113="\x55\xB2"
+kw114="\x55\xB3"
+kw115="\x55\xB4"
+kw116="\x55\xB5"
+kw117="\x55\xB6"
+kw118="\x55\xB7"
+kw119="\x55\xB8"
+kw120="\x55\xB9"
+kw121="\x55\xBA"
+kw122="\x55\xBB"
+kw123="\x55\xBC"
+kw124="\x55\xBD"
+kw125="\x55\xD0"
+kw126="\x55\xD1"
+kw127="\x55\xD2"
+kw128="\x55\xD3"
+kw129="\x55\xD4"
+kw130="\x55\xD5"
+kw131="\x55\xD6"
+kw132="\x55\xD7"
+kw133="\x55\xD8"
+kw134="\x55\xD9"
+kw135="\x55\xDA"
+kw136="\x76\x70"
+kw137="\x76\x71"
+kw138="\x76\x72"
+kw139="\x76\x73"
+kw140="\x76\x74"
+kw141="\x76\x75"
+kw142="\xE1"
+kw143="\xB5"
+kw144="\x78\xB5"
+kw145="\x9F"
+kw146="\x7D\x7B"
+kw147="\x62\x64"
+kw148="\xE2"
+kw149="\xE3"
+kw150="\xE4"
+kw151="\xE5"
+kw152="\xE6"
+kw153="\xE9"
+kw154="\xED"
+kw155="\xC0"
+kw156="\xC1"
+kw157="\xC6"
+kw158="\xC7"
+kw159="\xC4"
+kw160="\x6D\x80"
+kw161="\x62\x40"
+kw162="\x50\x31"
+kw163="\x50\x32"
+kw164="\x50\x33"
+kw165="\x50\x34"
+kw166="\x50\x35"
+kw167="\x42\x54"
+kw168="\x42\x55"
+kw169="\x47\xE1"
+kw170="\x47\xE2"
+kw171="\x47\xE7"
+kw172="\x47\xE8"
+kw173="\x47\xE3"
+kw174="\x47\xE4"
+kw175="\x47\xE5"
+kw176="\x47\xE6"
+kw177="\x1C\x53\xBB\x6B"
+kw178="\xBB"
+kw179="\xB3"
+kw180="\xB7"
+kw181="\xF7"
+kw182="\xF1"
+kw183="\xF0"
+kw184="\xB2"
+kw185="\x53\x78"
+kw186="\xEA"
+kw187="\xDB"
+kw188="\x96"
+kw189="\x97"
+kw190="\x53\x5F"
+kw191="\xEB"
+kw192="\x19\x41\xA4\x69"
+kw193="\x46\x7E"
+kw194="\x46\x6E"
+kw195="\x46\x60"
+kw196="\x46\x5C"
+kw197="\x46\xAE"
+kw198="\x46\x75"
+kw199="\x46\x61"
+kw200="\x46\x62"
+kw201="\x10\x43\xA7\x70"
+kw202="\x45\xB9"
+kw203="\x45\xBC"
+kw204="\x45\xBD"
+kw205="\x45\xDB"
+kw206="\x45\xDD"
+kw207="\xB6"
+kw208="\x73\xC4"
+kw209="\x56\x54"
+kw210="\x91"
+kw211="\x92"
+kw212="\x98"
+kw213="\x45\x98"
+kw214="\x6E\x67"
+kw215="\x6E\xBC"
+kw216="\x63\xC3"
+kw217="\x8F"
+kw218="\x89"
+kw219="\x80"
+kw220="\x85"
+kw221="\x43\x7C"
+kw222="\x43\x7D"
+kw223="\x43\x7E"
+kw224="\x69\x44"
+kw225="\x69\x55"
+kw226="\x45\x0D"
+kw227="\x69\x11"
+kw228="\x69\x22"
+kw229="\x69\x33"
+kw230="\x12\x54\xC3\x67"
+kw231="\x73\x73"
+kw232="\x63\xC0"
+kw233="\x68\xCA"
+kw234="\x63\xCA"
+kw235="\x63\xC5"
+kw236="\x63\xC9"
+kw237="\x67\xC8"
+kw238="\x45\xA3"
+kw239="\x44\x7A"
+kw240="\x44\x7B"
+kw241="\x44\x84"
+kw242="\x44\x87"
+kw243="\x44\x85"
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
new file mode 100644
index 0000000..9a47c18
--- /dev/null
+++ b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MP3Extractor.h"
+
+using namespace android;
+
+class Mp3Extractor : public ExtractorFuzzerBase {
+ public:
+  Mp3Extractor() = default;
+  ~Mp3Extractor() = default;
+
+  bool createExtractor();
+};
+
+bool Mp3Extractor::createExtractor() {
+  mExtractor = new MP3Extractor(new DataSourceHelper(mDataSource->wrap()), nullptr);
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  Mp3Extractor* extractor = new Mp3Extractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
new file mode 100644
index 0000000..3903519
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MPEG4Extractor.h"
+#include "SampleTable.h"
+
+using namespace android;
+
+class MP4Extractor : public ExtractorFuzzerBase {
+ public:
+  MP4Extractor() = default;
+  ~MP4Extractor() = default;
+
+  bool createExtractor();
+};
+
+bool MP4Extractor::createExtractor() {
+  mExtractor = new MPEG4Extractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  setDataSourceFlags(DataSourceBase::kWantsPrefetching | DataSourceBase::kIsCachingDataSource);
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  MP4Extractor* extractor = new MP4Extractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.dict b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
new file mode 100644
index 0000000..3683649
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
@@ -0,0 +1,248 @@
+# MP4 Atoms/Boxes
+kw1="ftyp"
+kw2="free"
+kw3="mdat"
+kw4="moov"
+kw5="mvhd"
+kw6="trak"
+kw7="tkhd"
+kw8="edts"
+kw9="elst"
+kw10="mdia"
+kw11="mdhd"
+kw12="hdlr"
+kw13="minf"
+kw14="vmhd"
+kw15="dinf"
+kw16="dref"
+kw17="url "
+kw18="stbl"
+kw19="stsd"
+kw20="avc1"
+kw21="avcC"
+kw22="stts"
+kw23="stss"
+kw24="ctts"
+kw25="stsc"
+kw26="stsz"
+kw27="stco"
+kw28="mp4a"
+kw29="esds"
+kw30="udta"
+kw31="meta"
+kw32="ilst"
+kw33="samr"
+kw34="sawb"
+kw35="ec-3"
+kw36="mp4v"
+kw37="s263"
+kw38="h263"
+kw39="H263"
+kw40="avc1"
+kw41="hvc1"
+kw42="hev1"
+kw43="ac-4"
+kw44="Opus"
+kw45="twos"
+kw46="sowt"
+kw47="alac"
+kw48="fLaC"
+kw49="av01"
+kw50=".mp3"
+kw51="keys"
+kw52="cprt"
+kw53="covr"
+kw54="mvex"
+kw55="moof"
+kw56="traf"
+kw57="mfra"
+kw58="sinf"
+kw59="schi"
+kw60="wave"
+kw61="schm"
+kw62="cbc1"
+kw63="cbcs"
+kw64="cenc"
+kw65="cens"
+kw66="frma"
+kw67="tenc"
+kw68="tref"
+kw69="thmb"
+kw70="pssh"
+kw71="mett"
+kw72="enca"
+kw73="encv"
+kw74="co64"
+kw75="stz2"
+kw76="\xA9xyz"
+kw77="btrt"
+kw78="hvcC"
+kw79="av1C"
+kw80="d263"
+kw81="iloc"
+kw82="iinf"
+kw83="iprp"
+kw84="pitm"
+kw85="idat"
+kw86="iref"
+kw87="ipro"
+kw88="mean"
+kw89="name"
+kw90="data"
+kw91="mehd"
+kw92="text"
+kw93="sbtl"
+kw94="trex"
+kw95="tx3g"
+kw96="colr"
+kw97="titl"
+kw98="perf"
+kw99="auth"
+kw100="gnre"
+kw101="albm"
+kw102="yrrc"
+kw103="ID32"
+kw104="----"
+kw105="sidx"
+kw106="ac-3"
+kw107="qt  "
+kw108="mif1"
+kw109="heic"
+kw110="dac4"
+kw111="dec3"
+kw112="dac3"
+kw113="\xA9alb"
+kw114="\xA9ART"
+kw115="aART"
+kw116="\xA9day"
+kw117="\xA9nam"
+kw118="\xA9wrt"
+kw119="\xA9gen"
+kw120="cpil"
+kw121="trkn"
+kw122="disk"
+kw123="nclx"
+kw124="nclc"
+kw125="tfhd"
+kw126="trun"
+kw127="saiz"
+kw128="saio"
+kw129="senc"
+kw130="isom"
+kw131="iso2"
+kw132="3gp4"
+kw133="mp41"
+kw134="mp42"
+kw135="dash"
+kw136="nvr1"
+kw137="MSNV"
+kw138="wmf "
+kw139="3g2a"
+kw140="3g2b"
+kw141="msf1"
+kw142="hevc"
+kw143="pdin"
+kw144="trgr"
+kw145="smhd"
+kw146="hmhd"
+kw147="nmhd"
+kw148="cslg"
+kw149="stsh"
+kw150="padb"
+kw151="stdp"
+kw152="sdtp"
+kw153="sbgp"
+kw154="sgpd"
+kw155="subs"
+kw156="leva"
+kw157="mfhd"
+kw158="tfdt"
+kw159="tfra"
+kw160="mfro"
+kw161="skip"
+kw162="tsel"
+kw163="strk"
+kw164="stri"
+kw165="strd"
+kw166="xml "
+kw167="bxml"
+kw168="fiin"
+kw169="paen"
+kw170="fire"
+kw171="fpar"
+kw172="fecr"
+kw173="segr"
+kw174="gitn"
+kw175="meco"
+kw176="mere"
+kw177="styp"
+kw178="ssix"
+kw179="prft"
+kw180="hint"
+kw181="cdsc"
+kw182="hind"
+kw183="vdep"
+kw184="vplx"
+kw185="msrc"
+kw186="urn "
+kw187="enct"
+kw188="encs"
+kw189="rinf"
+kw190="srpp"
+kw191="stsg"
+kw192="stvi"
+kw193="tims"
+kw194="tsro"
+kw195="snro"
+kw196="rtp "
+kw197="srtp"
+kw198="rtpo"
+kw199="hnti"
+kw200="sdp "
+kw201="trpy"
+kw202="nump"
+kw203="tpyl"
+kw204="totl"
+kw205="npck"
+kw206="tpay"
+kw207="maxr"
+kw208="dmed"
+kw209="dimm"
+kw210="drep"
+kw211="tmin"
+kw212="tmax"
+kw213="pmax"
+kw214="dmax"
+kw215="payt"
+kw216="fdp "
+kw217="fdsa"
+kw218="fdpa"
+kw219="extr"
+kw220="feci"
+kw221="rm2t"
+kw222="sm2t"
+kw223="tPAT"
+kw224="tPMT"
+kw225="tOD "
+kw226="tsti"
+kw227="istm"
+kw228="pm2t"
+kw229="rrtp"
+kw230="rssr"
+kw231="rscr"
+kw232="rsrp"
+kw233="rssr"
+kw234="ccid"
+kw235="sroc"
+kw236="prtp"
+kw237="roll"
+kw238="rash"
+kw239="alst"
+kw240="rap "
+kw241="tele"
+kw242="mp71"
+kw243="iso3"
+kw244="iso4"
+kw245="iso5"
+kw246="resv"
+kw247="iso6"
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
new file mode 100644
index 0000000..240ef66
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#ifdef MPEG2PS
+#include "MPEG2PSExtractor.h"
+#else
+#include "MPEG2TSExtractor.h"
+#endif
+
+using namespace android;
+
+class MPEG2Extractor : public ExtractorFuzzerBase {
+ public:
+  MPEG2Extractor() = default;
+  ~MPEG2Extractor() = default;
+
+  bool createExtractor();
+};
+
+bool MPEG2Extractor::createExtractor() {
+#ifdef MPEG2PS
+  mExtractor = new MPEG2PSExtractor(new DataSourceHelper(mDataSource->wrap()));
+#else
+  mExtractor = new MPEG2TSExtractor(new DataSourceHelper(mDataSource->wrap()));
+#endif
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  MPEG2Extractor* extractor = new MPEG2Extractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict b/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
new file mode 100644
index 0000000..69d390a
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code (bytes 0-3)
+kw1="\x00\x00\x01\xBA"
diff --git a/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict b/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
new file mode 100644
index 0000000..006a1eb
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start byte
+kw1="\x47"
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
new file mode 100644
index 0000000..bd2fcc5
--- /dev/null
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "OggExtractor.h"
+
+using namespace android;
+
+class OGGExtractor : public ExtractorFuzzerBase {
+ public:
+  OGGExtractor() = default;
+  ~OGGExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool OGGExtractor::createExtractor() {
+  mExtractor = new OggExtractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  OGGExtractor* extractor = new OGGExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.dict b/media/extractors/fuzzers/ogg_extractor_fuzzer.dict
new file mode 100644
index 0000000..df2fc38
--- /dev/null
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.dict
@@ -0,0 +1,3 @@
+# Start code(bytes 0-3)
+# The below 4 bytes correspond to "OggS" in ASCII
+kw1="\x4F\x67\x67\x53"
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
new file mode 100644
index 0000000..cb11ebd
--- /dev/null
+++ b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "WAVExtractor.h"
+
+using namespace android;
+
+class wavExtractor : public ExtractorFuzzerBase {
+ public:
+  wavExtractor() = default;
+  ~wavExtractor() = default;
+
+  bool createExtractor();
+};
+
+bool wavExtractor::createExtractor() {
+  mExtractor = new WAVExtractor(new DataSourceHelper(mDataSource->wrap()));
+  if (!mExtractor) {
+    return false;
+  }
+  mExtractor->name();
+  return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if ((!data) || (size == 0)) {
+    return 0;
+  }
+  wavExtractor* extractor = new wavExtractor();
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
+  }
+  return 0;
+}
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 7ad8cc1..330d4fe 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -21,4 +21,12 @@
         "libutils",
     ],
 
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
 }
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index b88e4e8..fd6a8c6 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -1888,13 +1888,12 @@
 
     for(size_t i = 0; i < track->GetContentEncodingCount(); i++) {
         const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i);
-        for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) {
+        if (encoding->GetEncryptionCount() > 0) {
             const mkvparser::ContentEncoding::ContentEncryption *encryption;
-            encryption = encoding->GetEncryptionByIndex(j);
+            encryption = encoding->GetEncryptionByIndex(0);
             AMediaFormat_setBuffer(trackInfo->mMeta,
                     AMEDIAFORMAT_KEY_CRYPTO_KEY, encryption->key_id, encryption->key_id_len);
             trackInfo->mEncrypted = true;
-            break;
         }
 
         for(size_t j = 0; j < encoding->GetCompressionCount(); j++) {
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index 102ac81..7d70548 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -13,4 +13,11 @@
         "libstagefright_foundation",
     ],
 
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index e48e1b7..afa055f 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -16,4 +16,12 @@
         "libstagefright_id3",
         "libutils",
     ],
+
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 0773387..2599c2c 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -546,11 +546,11 @@
                 continue;
             }
             ALOGV("Image item id %d uses thumbnail item id %d", mRefs[i], mItemId);
-            ImageItem &masterImage = itemIdToItemMap.editValueAt(itemIndex);
-            if (!masterImage.thumbnails.empty()) {
+            ImageItem &imageItem = itemIdToItemMap.editValueAt(itemIndex);
+            if (!imageItem.thumbnails.empty()) {
                 ALOGW("already has thumbnails!");
             }
-            masterImage.thumbnails.push_back(mItemId);
+            imageItem.thumbnails.push_back(mItemId);
         }
         break;
     }
@@ -929,7 +929,7 @@
 
 status_t IpcoBox::parse(off64_t offset, size_t size) {
     ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
-    // push dummy as the index is 1-based
+    // push a placeholder as the index is 1-based
     mItemProperties->push_back(new ItemProperty());
     return parseChunks(offset, size);
 }
@@ -1614,17 +1614,17 @@
         return BAD_VALUE;
     }
 
-    uint32_t masterItemIndex = mDisplayables[imageIndex];
+    uint32_t imageItemIndex = mDisplayables[imageIndex];
 
-    const ImageItem &masterImage = mItemIdToItemMap[masterItemIndex];
-    if (masterImage.thumbnails.empty()) {
-        *itemIndex = masterItemIndex;
+    const ImageItem &imageItem = mItemIdToItemMap[imageItemIndex];
+    if (imageItem.thumbnails.empty()) {
+        *itemIndex = imageItemIndex;
         return OK;
     }
 
-    ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(masterImage.thumbnails[0]);
+    ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(imageItem.thumbnails[0]);
     if (thumbItemIndex < 0) {
-        // Do not return the master image in this case, fail it so that the
+        // Do not return the image item in this case, fail it so that the
         // thumbnail extraction code knows we really don't have it.
         return INVALID_OPERATION;
     }
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
old mode 100755
new mode 100644
index a976a2b..65ba382
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -372,6 +372,8 @@
             return MEDIA_MIMETYPE_AUDIO_FLAC;
         case FOURCC("av01"):
             return MEDIA_MIMETYPE_VIDEO_AV1;
+        case FOURCC("vp09"):
+            return MEDIA_MIMETYPE_VIDEO_VP9;
         case FOURCC(".mp3"):
         case 0x6D730055: // "ms U" mp3 audio
             return MEDIA_MIMETYPE_AUDIO_MPEG;
@@ -1149,7 +1151,7 @@
             } else if (chunk_type == FOURCC("moov")) {
                 mInitCheck = OK;
 
-                return UNKNOWN_ERROR;  // Return a dummy error.
+                return UNKNOWN_ERROR;  // Return a generic error.
             }
             break;
         }
@@ -1787,7 +1789,7 @@
                 return ERROR_IO;
             }
 
-            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
+            // we can get data_ref_index value from U16_AT(&buffer[6])
             uint16_t version = U16_AT(&buffer[8]);
             uint32_t num_channels = U16_AT(&buffer[16]);
 
@@ -1972,6 +1974,7 @@
         case FOURCC("dvh1"):
         case FOURCC("dav1"):
         case FOURCC("av01"):
+        case FOURCC("vp09"):
         {
             uint8_t buffer[78];
             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
@@ -1984,7 +1987,7 @@
                 return ERROR_IO;
             }
 
-            uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
+            // we can get data_ref_index value from U16_AT(&buffer[6])
             uint16_t width = U16_AT(&buffer[6 + 18]);
             uint16_t height = U16_AT(&buffer[6 + 20]);
 
@@ -2434,6 +2437,8 @@
             *offset += chunk_size;
             break;
         }
+
+        case FOURCC("vpcC"):
         case FOURCC("av1C"):
         {
             auto buffer = heapbuffer<uint8_t>(chunk_data_size);
@@ -3407,7 +3412,7 @@
     }
 
     // skip
-    unsigned bsmod __unused = br.getBits(3);
+    br.skipBits(3); // bsmod
 
     unsigned acmod = br.getBits(3);
     unsigned lfeon = br.getBits(1);
@@ -3718,19 +3723,18 @@
         return ERROR_IO;
     }
 
-    uint64_t ctime __unused, mtime __unused, duration __unused;
     int32_t id;
 
     if (version == 1) {
-        ctime = U64_AT(&buffer[4]);
-        mtime = U64_AT(&buffer[12]);
+        // we can get ctime value from U64_AT(&buffer[4])
+        // we can get mtime value from U64_AT(&buffer[12])
         id = U32_AT(&buffer[20]);
-        duration = U64_AT(&buffer[28]);
+        // we can get duration value from U64_AT(&buffer[28])
     } else if (version == 0) {
-        ctime = U32_AT(&buffer[4]);
-        mtime = U32_AT(&buffer[8]);
+        // we can get ctime value from U32_AT(&buffer[4])
+        // we can get mtime value from U32_AT(&buffer[8])
         id = U32_AT(&buffer[12]);
-        duration = U32_AT(&buffer[20]);
+        // we can get duration value from U32_AT(&buffer[20])
     } else {
         return ERROR_UNSUPPORTED;
     }
@@ -4337,6 +4341,18 @@
         if (size < 5 || ptr[0] != 0x81) {  // configurationVersion == 1
             return NULL;
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VP9)) {
+        void *data;
+        size_t size;
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
+            return NULL;
+        }
+
+        const uint8_t *ptr = (const uint8_t *)data;
+
+        if (size < 5 || ptr[0] != 0x01) {  // configurationVersion == 1
+            return NULL;
+        }
     }
 
     ALOGV("track->elst_shift_start_ticks :%" PRIu64, track->elst_shift_start_ticks);
@@ -4391,6 +4407,10 @@
         if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
             return ERROR_MALFORMED;
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VP9)) {
+        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
+            return ERROR_MALFORMED;
+        }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
             || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
@@ -4638,18 +4658,17 @@
     if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 tbl 1.13
         if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
         uint32_t extFreqIndex = br.getBits(4);
-        int32_t extSampleRate __unused;
         if (extFreqIndex == 15) {
             if (csd_size < 8) {
                 return ERROR_MALFORMED;
             }
             if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
-            extSampleRate = br.getBits(24);
+            br.skipBits(24); // extSampleRate
         } else {
             if (extFreqIndex == 13 || extFreqIndex == 14) {
                 return ERROR_MALFORMED;
             }
-            extSampleRate = kSamplingRate[extFreqIndex];
+            //extSampleRate = kSamplingRate[extFreqIndex];
         }
         //TODO: save the extension sampling rate value in meta data =>
         //      AMediaFormat_setInt32(mLastTrack->meta, kKeyExtSampleRate, extSampleRate);
@@ -4692,13 +4711,13 @@
                 objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
                 objectType == AOT_ER_BSAC) {
             if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
-            const int32_t frameLengthFlag __unused = br.getBits(1);
+            br.skipBits(1); // frameLengthFlag
 
             const int32_t dependsOnCoreCoder = br.getBits(1);
 
             if (dependsOnCoreCoder ) {
                 if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
-                const int32_t coreCoderDelay __unused = br.getBits(14);
+                br.skipBits(14); // coreCoderDelay
             }
 
             int32_t extensionFlag = -1;
@@ -4730,64 +4749,64 @@
                 if (br.numBitsLeft() < 32) {
                     return ERROR_MALFORMED;
                 }
-                const int32_t ElementInstanceTag __unused = br.getBits(4);
-                const int32_t Profile __unused = br.getBits(2);
-                const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
+                br.skipBits(4); // ElementInstanceTag
+                br.skipBits(2); // Profile
+                br.skipBits(4); // SamplingFrequencyIndex
                 const int32_t NumFrontChannelElements = br.getBits(4);
                 const int32_t NumSideChannelElements = br.getBits(4);
                 const int32_t NumBackChannelElements = br.getBits(4);
                 const int32_t NumLfeChannelElements = br.getBits(2);
-                const int32_t NumAssocDataElements __unused = br.getBits(3);
-                const int32_t NumValidCcElements __unused = br.getBits(4);
+                br.skipBits(3); // NumAssocDataElements
+                br.skipBits(4); // NumValidCcElements
 
                 const int32_t MonoMixdownPresent = br.getBits(1);
 
                 if (MonoMixdownPresent != 0) {
                     if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
-                    const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
+                    br.skipBits(4); // MonoMixdownElementNumber
                 }
 
                 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
                 const int32_t StereoMixdownPresent = br.getBits(1);
                 if (StereoMixdownPresent != 0) {
                     if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
-                    const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
+                    br.skipBits(4); // StereoMixdownElementNumber
                 }
 
                 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
                 const int32_t MatrixMixdownIndexPresent = br.getBits(1);
                 if (MatrixMixdownIndexPresent != 0) {
                     if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
-                    const int32_t MatrixMixdownIndex __unused = br.getBits(2);
-                    const int32_t PseudoSurroundEnable __unused = br.getBits(1);
+                    br.skipBits(2); // MatrixMixdownIndex
+                    br.skipBits(1); // PseudoSurroundEnable
                 }
 
                 int i;
                 for (i=0; i < NumFrontChannelElements; i++) {
                     if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
                     const int32_t FrontElementIsCpe = br.getBits(1);
-                    const int32_t FrontElementTagSelect __unused = br.getBits(4);
+                    br.skipBits(4); // FrontElementTagSelect
                     channelsNum += FrontElementIsCpe ? 2 : 1;
                 }
 
                 for (i=0; i < NumSideChannelElements; i++) {
                     if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
                     const int32_t SideElementIsCpe = br.getBits(1);
-                    const int32_t SideElementTagSelect __unused = br.getBits(4);
+                    br.skipBits(4); // SideElementTagSelect
                     channelsNum += SideElementIsCpe ? 2 : 1;
                 }
 
                 for (i=0; i < NumBackChannelElements; i++) {
                     if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
                     const int32_t BackElementIsCpe = br.getBits(1);
-                    const int32_t BackElementTagSelect __unused = br.getBits(4);
+                    br.skipBits(4); // BackElementTagSelect
                     channelsNum += BackElementIsCpe ? 2 : 1;
                 }
                 channelsEffectiveNum = channelsNum;
 
                 for (i=0; i < NumLfeChannelElements; i++) {
                     if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
-                    const int32_t LfeElementTagSelect __unused = br.getBits(4);
+                    br.skipBits(4); // LfeElementTagSelect
                     channelsNum += 1;
                 }
                 ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
@@ -5766,7 +5785,7 @@
             return -EINVAL;
         }
 
-        // apply some sanity (vs strict legality) checks
+        // apply some quick (vs strict legality) checks
         //
         static constexpr uint32_t kMaxTrunSampleCount = 10000;
         if (sampleCount > kMaxTrunSampleCount) {
@@ -6713,6 +6732,7 @@
         FOURCC("hvc1"),
         FOURCC("hev1"),
         FOURCC("av01"),
+        FOURCC("vp09"),
         FOURCC("3gp4"),
         FOURCC("mp41"),
         FOURCC("mp42"),
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index bc8632c..4c25314 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -1,6 +1,16 @@
 cc_library {
     name: "libmpeg2extractor",
 
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+        android: {
+            shared_libs: ["libvndksupport#29"],
+        },
+    },
+
     defaults: ["extractor-defaults"],
 
     srcs: [
@@ -12,14 +22,13 @@
     shared_libs: [
         "libbase",
         "libcgrouprc#29",
-        "libvndksupport#29",
     ],
 
     header_libs: [
         "libaudioclient_headers",
         "libbase_headers",
         "libstagefright_headers",
-        "libmedia_headers",
+        "libmedia_datasource_headers",
     ],
 
     static_libs: [
@@ -37,7 +46,7 @@
         "libstagefright_esds",
         "libstagefright_foundation_without_imemory",
         "libstagefright_mpeg2extractor",
-        "libstagefright_mpeg2support",
+        "libstagefright_mpeg2support_nocrypto",
         "libutils",
     ],
 
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index 7aed683..579065e 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -20,4 +20,11 @@
         "libvorbisidec",
     ],
 
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/extractors/tests/AndroidTest.xml b/media/extractors/tests/AndroidTest.xml
index 6bb2c8a..fc8152c 100644
--- a/media/extractors/tests/AndroidTest.xml
+++ b/media/extractors/tests/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="ExtractorUnitTest->/data/local/tmp/ExtractorUnitTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.4.zip?unzip=true"
             value="/data/local/tmp/ExtractorUnitTestRes/" />
     </target_preparer>
 
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/extractors/tests/ExtractorUnitTest.cpp
index 518166e..d91fffa 100644
--- a/media/extractors/tests/ExtractorUnitTest.cpp
+++ b/media/extractors/tests/ExtractorUnitTest.cpp
@@ -20,8 +20,10 @@
 
 #include <datasource/FileSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaDataUtils.h>
+#include <media/stagefright/foundation/OpusHeader.h>
 
 #include "aac/AACExtractor.h"
 #include "amr/AMRExtractor.h"
@@ -43,11 +45,76 @@
 #define OUTPUT_DUMP_FILE "/data/local/tmp/extractorOutput"
 
 constexpr int32_t kMaxCount = 10;
-constexpr int32_t kOpusSeekPreRollUs = 80000;  // 80 ms;
+constexpr int32_t kAudioDefaultSampleDuration = 20000;                       // 20ms
+constexpr int32_t kRandomSeekToleranceUs = 2 * kAudioDefaultSampleDuration;  // 40 ms;
+constexpr int32_t kRandomSeed = 700;
+constexpr int32_t kUndefined = -1;
+
+enum inputID {
+    // audio streams
+    AAC_1,
+    AMR_NB_1,
+    AMR_WB_1,
+    FLAC_1,
+    GSM_1,
+    MIDI_1,
+    MP3_1,
+    OPUS_1,
+    VORBIS_1,
+    // video streams
+    HEVC_1,
+    HEVC_2,
+    MPEG2_PS_1,
+    MPEG2_TS_1,
+    MPEG4_1,
+    VP9_1,
+    UNKNOWN_ID,
+};
+
+// LookUpTable of clips and metadata for component testing
+static const struct InputData {
+    inputID inpId;
+    string mime;
+    string inputFile;
+    int32_t firstParam;
+    int32_t secondParam;
+    int32_t profile;
+    int32_t frameRate;
+} kInputData[] = {
+        {AAC_1, MEDIA_MIMETYPE_AUDIO_AAC, "test_mono_44100Hz_aac.aac", 44100, 1, AACObjectLC,
+         kUndefined},
+        {AMR_NB_1, MEDIA_MIMETYPE_AUDIO_AMR_NB, "bbb_mono_8kHz_amrnb.amr", 8000, 1, kUndefined,
+         kUndefined},
+        {AMR_WB_1, MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_mono_16kHz_amrwb.amr", 16000, 1, kUndefined,
+         kUndefined},
+        {FLAC_1, MEDIA_MIMETYPE_AUDIO_RAW, "bbb_stereo_48kHz_flac.flac", 48000, 2, kUndefined,
+         kUndefined},
+        {GSM_1, MEDIA_MIMETYPE_AUDIO_MSGSM, "test_mono_8kHz_gsm.wav", 8000, 1, kUndefined,
+         kUndefined},
+        {MIDI_1, MEDIA_MIMETYPE_AUDIO_RAW, "midi_a.mid", 22050, 2, kUndefined, kUndefined},
+        {MP3_1, MEDIA_MIMETYPE_AUDIO_MPEG, "bbb_stereo_48kHz_mp3.mp3", 48000, 2, kUndefined,
+         kUndefined},
+        {OPUS_1, MEDIA_MIMETYPE_AUDIO_OPUS, "test_stereo_48kHz_opus.opus", 48000, 2, kUndefined,
+         kUndefined},
+        {VORBIS_1, MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_stereo_48kHz_vorbis.ogg", 48000, 2, kUndefined,
+         kUndefined},
+
+        // Test (b/151677264) for MP4 extractor
+        {HEVC_1, MEDIA_MIMETYPE_VIDEO_HEVC, "crowd_508x240_25fps_hevc.mp4", 508, 240,
+         HEVCProfileMain, 25},
+        {HEVC_2, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, "test3.heic", 820, 460, kUndefined, kUndefined},
+        {MPEG2_PS_1, MEDIA_MIMETYPE_VIDEO_MPEG2, "swirl_144x136_mpeg2.mpg", 144, 136,
+         MPEG2ProfileMain, 12},
+        {MPEG2_TS_1, MEDIA_MIMETYPE_VIDEO_MPEG2, "bbb_cif_768kbps_30fps_mpeg2.ts", 352, 288,
+         MPEG2ProfileMain, 30},
+        {MPEG4_1, MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_cif_768kbps_30fps_mpeg4.mkv", 352, 288,
+         MPEG4ProfileSimple, 30},
+        {VP9_1, MEDIA_MIMETYPE_VIDEO_VP9, "bbb_340x280_30fps_vp9.webm", 340, 280, VP9Profile0, 30},
+};
 
 static ExtractorUnitTestEnvironment *gEnv = nullptr;
 
-class ExtractorUnitTest : public ::testing::TestWithParam<pair<string, string>> {
+class ExtractorUnitTest {
   public:
     ExtractorUnitTest() : mInputFp(nullptr), mDataSource(nullptr), mExtractor(nullptr) {}
 
@@ -66,16 +133,29 @@
         }
     }
 
-    virtual void SetUp() override {
+    void setupExtractor(string writerFormat) {
         mExtractorName = unknown_comp;
         mDisableTest = false;
 
         static const std::map<std::string, standardExtractors> mapExtractor = {
-                {"aac", AAC},     {"amr", AMR},         {"mp3", MP3},        {"ogg", OGG},
-                {"wav", WAV},     {"mkv", MKV},         {"flac", FLAC},      {"midi", MIDI},
-                {"mpeg4", MPEG4}, {"mpeg2ts", MPEG2TS}, {"mpeg2ps", MPEG2PS}};
+                {"aac", AAC},
+                {"amr", AMR},
+                {"flac", FLAC},
+                {"mid", MIDI},
+                {"midi", MIDI},
+                {"mkv", MKV},
+                {"mp3", MP3},
+                {"mp4", MPEG4},
+                {"mpeg2ps", MPEG2PS},
+                {"mpeg2ts", MPEG2TS},
+                {"mpeg4", MPEG4},
+                {"mpg", MPEG2PS},
+                {"ogg", OGG},
+                {"opus", OGG},
+                {"ts", MPEG2TS},
+                {"wav", WAV},
+                {"webm", MKV}};
         // Find the component type
-        string writerFormat = GetParam().first;
         if (mapExtractor.find(writerFormat) != mapExtractor.end()) {
             mExtractorName = mapExtractor.at(writerFormat);
         }
@@ -112,6 +192,39 @@
     MediaExtractorPluginHelper *mExtractor;
 };
 
+class ExtractorFunctionalityTest
+    : public ExtractorUnitTest,
+      public ::testing::TestWithParam<tuple<string /* container */, string /* InputFile */,
+                                            int32_t /* numTracks */, bool /* seekSupported */>> {
+  public:
+    virtual void SetUp() override {
+        tuple<string, string, int32_t, bool> params = GetParam();
+        mContainer = get<0>(params);
+        mNumTracks = get<2>(params);
+        setupExtractor(mContainer);
+    }
+    string mContainer;
+    int32_t mNumTracks;
+};
+
+class ConfigParamTest : public ExtractorUnitTest,
+                        public ::testing::TestWithParam<pair<string, inputID>> {
+  public:
+    virtual void SetUp() override { setupExtractor(GetParam().first); }
+
+    struct configFormat {
+        string mime;
+        int32_t width;
+        int32_t height;
+        int32_t sampleRate;
+        int32_t channelCount;
+        int32_t profile;
+        int32_t frameRate;
+    };
+
+    void getFileProperties(inputID inputId, string &inputFile, configFormat &configParam);
+};
+
 int32_t ExtractorUnitTest::setDataSource(string inputFileName) {
     mInputFp = fopen(inputFileName.c_str(), "rb");
     if (!mInputFp) {
@@ -168,6 +281,75 @@
     return 0;
 }
 
+void ConfigParamTest::getFileProperties(inputID inputId, string &inputFile,
+                                        configFormat &configParam) {
+    int32_t inputDataSize = sizeof(kInputData) / sizeof(kInputData[0]);
+    int32_t inputIdx = 0;
+    for (; inputIdx < inputDataSize; inputIdx++) {
+        if (inputId == kInputData[inputIdx].inpId) {
+            break;
+        }
+    }
+    if (inputIdx == inputDataSize) {
+        return;
+    }
+    inputFile += kInputData[inputIdx].inputFile;
+    configParam.mime = kInputData[inputIdx].mime;
+    size_t found = configParam.mime.find("audio/");
+    // Check if 'audio/' is present in the begininig of the mime type
+    if (found == 0) {
+        configParam.sampleRate = kInputData[inputIdx].firstParam;
+        configParam.channelCount = kInputData[inputIdx].secondParam;
+    } else {
+        configParam.width = kInputData[inputIdx].firstParam;
+        configParam.height = kInputData[inputIdx].secondParam;
+    }
+    configParam.profile = kInputData[inputIdx].profile;
+    configParam.frameRate = kInputData[inputIdx].frameRate;
+    return;
+}
+
+void randomSeekTest(MediaTrackHelper *track, int64_t clipDuration) {
+    int32_t status = 0;
+    int32_t seekCount = 0;
+    bool hasTimestamp = false;
+    vector<int64_t> seekToTimeStamp;
+    string seekPtsString;
+
+    srand(kRandomSeed);
+    while (seekCount < kMaxCount) {
+        int64_t timeStamp = ((double)rand() / RAND_MAX) * clipDuration;
+        seekToTimeStamp.push_back(timeStamp);
+        seekPtsString.append(to_string(timeStamp));
+        seekPtsString.append(", ");
+        seekCount++;
+    }
+
+    for (int64_t seekPts : seekToTimeStamp) {
+        MediaTrackHelper::ReadOptions *options = new MediaTrackHelper::ReadOptions(
+                CMediaTrackReadOptions::SEEK_CLOSEST | CMediaTrackReadOptions::SEEK, seekPts);
+        ASSERT_NE(options, nullptr) << "Cannot create read option";
+
+        MediaBufferHelper *buffer = nullptr;
+        status = track->read(&buffer, options);
+        if (buffer) {
+            AMediaFormat *metaData = buffer->meta_data();
+            int64_t timeStamp = 0;
+            hasTimestamp = AMediaFormat_getInt64(metaData, AMEDIAFORMAT_KEY_TIME_US, &timeStamp);
+            ASSERT_TRUE(hasTimestamp) << "Extractor didn't set timestamp for the given sample";
+
+            buffer->release();
+            EXPECT_LE(abs(timeStamp - seekPts), kRandomSeekToleranceUs)
+                    << "Seek unsuccessful. Expected timestamp range ["
+                    << seekPts - kRandomSeekToleranceUs << ", " << seekPts + kRandomSeekToleranceUs
+                    << "] "
+                    << "received " << timeStamp << ", list of input seek timestamps ["
+                    << seekPtsString << "]";
+        }
+        delete options;
+    }
+}
+
 void getSeekablePoints(vector<int64_t> &seekablePoints, MediaTrackHelper *track) {
     int32_t status = 0;
     if (!seekablePoints.empty()) {
@@ -190,20 +372,21 @@
     }
 }
 
-TEST_P(ExtractorUnitTest, CreateExtractorTest) {
+TEST_P(ExtractorFunctionalityTest, CreateExtractorTest) {
     if (mDisableTest) return;
 
     ALOGV("Checks if a valid extractor is created for a given input file");
-    string inputFileName = gEnv->getRes() + GetParam().second;
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
 
-    ASSERT_EQ(setDataSource(inputFileName), 0)
-            << "SetDataSource failed for" << GetParam().first << "extractor";
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
 
-    ASSERT_EQ(createExtractor(), 0)
-            << "Extractor creation failed for" << GetParam().first << "extractor";
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
 
-    // A valid extractor instace should return success for following calls
-    ASSERT_GT(mExtractor->countTracks(), 0);
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
 
     AMediaFormat *format = AMediaFormat_new();
     ASSERT_NE(format, nullptr) << "AMediaFormat_new returned null AMediaformat";
@@ -212,20 +395,21 @@
     AMediaFormat_delete(format);
 }
 
-TEST_P(ExtractorUnitTest, ExtractorTest) {
+TEST_P(ExtractorFunctionalityTest, ExtractorTest) {
     if (mDisableTest) return;
 
-    ALOGV("Validates %s Extractor for a given input file", GetParam().first.c_str());
-    string inputFileName = gEnv->getRes() + GetParam().second;
+    ALOGV("Validates %s Extractor for a given input file", mContainer.c_str());
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
 
     int32_t status = setDataSource(inputFileName);
-    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
 
     status = createExtractor();
-    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
 
     int32_t numTracks = mExtractor->countTracks();
-    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
 
     for (int32_t idx = 0; idx < numTracks; idx++) {
         MediaTrackHelper *track = mExtractor->getTrack(idx);
@@ -262,20 +446,21 @@
     }
 }
 
-TEST_P(ExtractorUnitTest, MetaDataComparisonTest) {
+TEST_P(ExtractorFunctionalityTest, MetaDataComparisonTest) {
     if (mDisableTest) return;
 
     ALOGV("Validates Extractor's meta data for a given input file");
-    string inputFileName = gEnv->getRes() + GetParam().second;
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
 
     int32_t status = setDataSource(inputFileName);
-    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
 
     status = createExtractor();
-    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
 
     int32_t numTracks = mExtractor->countTracks();
-    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
 
     AMediaFormat *extractorFormat = AMediaFormat_new();
     ASSERT_NE(extractorFormat, nullptr) << "AMediaFormat_new returned null AMediaformat";
@@ -337,20 +522,21 @@
     AMediaFormat_delete(extractorFormat);
 }
 
-TEST_P(ExtractorUnitTest, MultipleStartStopTest) {
+TEST_P(ExtractorFunctionalityTest, MultipleStartStopTest) {
     if (mDisableTest) return;
 
-    ALOGV("Test %s extractor for multiple start and stop calls", GetParam().first.c_str());
-    string inputFileName = gEnv->getRes() + GetParam().second;
+    ALOGV("Test %s extractor for multiple start and stop calls", mContainer.c_str());
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
 
     int32_t status = setDataSource(inputFileName);
-    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
 
     status = createExtractor();
-    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
 
     int32_t numTracks = mExtractor->countTracks();
-    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
 
     // start/stop the tracks multiple times
     for (int32_t count = 0; count < kMaxCount; count++) {
@@ -379,27 +565,28 @@
     }
 }
 
-TEST_P(ExtractorUnitTest, SeekTest) {
-    // Both Flac and Wav extractor can give samples from any pts and mark the given sample as
-    // sync frame. So, this seek test is not applicable to FLAC and WAV extractors
-    if (mDisableTest || mExtractorName == FLAC || mExtractorName == WAV) return;
+TEST_P(ExtractorFunctionalityTest, SeekTest) {
+    if (mDisableTest) return;
 
-    ALOGV("Validates %s Extractor behaviour for different seek modes", GetParam().first.c_str());
-    string inputFileName = gEnv->getRes() + GetParam().second;
+    ALOGV("Validates %s Extractor behaviour for different seek modes", mContainer.c_str());
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
 
     int32_t status = setDataSource(inputFileName);
-    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
 
     status = createExtractor();
-    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
 
     int32_t numTracks = mExtractor->countTracks();
-    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
 
     uint32_t seekFlag = mExtractor->flags();
-    if (!(seekFlag & MediaExtractorPluginHelper::CAN_SEEK)) {
-        cout << "[   WARN   ] Test Skipped. " << GetParam().first
-             << " Extractor doesn't support seek\n";
+    bool seekSupported = get<3>(GetParam());
+    bool seekable = seekFlag & MediaExtractorPluginHelper::CAN_SEEK;
+    if (!seekable) {
+        ASSERT_FALSE(seekSupported) << mContainer << "Extractor is expected to support seek ";
+        cout << "[   WARN   ] Test Skipped. " << mContainer << " Extractor doesn't support seek\n";
         return;
     }
 
@@ -415,19 +602,73 @@
         MediaBufferGroup *bufferGroup = new MediaBufferGroup();
         status = cTrack->start(track, bufferGroup->wrap());
         ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
-        getSeekablePoints(seekablePoints, track);
-        ASSERT_GT(seekablePoints.size(), 0)
-                << "Failed to get seekable points for " << GetParam().first << " extractor";
+
+        // For Flac, Wav and Midi extractor, all samples are seek points.
+        // We cannot create list of all seekable points for these.
+        // This means that if we pass a seekToTimeStamp between two seek points, we may
+        // end up getting the timestamp of next sample as a seekable timestamp.
+        // This timestamp may/may not be a part of the seekable point vector thereby failing the
+        // test. So we test these extractors using random seek test.
+        if (mExtractorName == FLAC || mExtractorName == WAV || mExtractorName == MIDI) {
+            AMediaFormat *trackMeta = AMediaFormat_new();
+            ASSERT_NE(trackMeta, nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+            status = mExtractor->getTrackMetaData(trackMeta, idx, 1);
+            ASSERT_EQ(OK, (media_status_t)status) << "Failed to get trackMetaData";
+
+            int64_t clipDuration = 0;
+            AMediaFormat_getInt64(trackMeta, AMEDIAFORMAT_KEY_DURATION, &clipDuration);
+            ASSERT_GT(clipDuration, 0) << "Invalid clip duration ";
+            randomSeekTest(track, clipDuration);
+            AMediaFormat_delete(trackMeta);
+            continue;
+        }
 
         AMediaFormat *trackFormat = AMediaFormat_new();
         ASSERT_NE(trackFormat, nullptr) << "AMediaFormat_new returned null format";
         status = track->getFormat(trackFormat);
         ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
 
-        bool isOpus = false;
         const char *mime;
-        AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
-        if (!strcmp(mime, "audio/opus")) isOpus = true;
+        ASSERT_TRUE(AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime))
+                << "Failed to get mime";
+
+        // Image formats are not expected to be seekable
+        if (!strncmp(mime, "image/", 6)) continue;
+
+        // Request seekable points for remaining extractors which will be used to validate the seek
+        // accuracy for the extractors. Depending on SEEK Mode, we expect the extractors to return
+        // the expected sync frame. We don't prefer random seek test for these extractors because
+        // they aren't expected to seek to random samples. MP4 for instance can seek to
+        // next/previous sync frames but not to samples between two sync frames.
+        getSeekablePoints(seekablePoints, track);
+        ASSERT_GT(seekablePoints.size(), 0)
+                << "Failed to get seekable points for " << mContainer << " extractor";
+
+        bool isOpus = false;
+        int64_t opusSeekPreRollUs = 0;
+        if (!strcmp(mime, "audio/opus")) {
+            isOpus = true;
+            void *seekPreRollBuf = nullptr;
+            size_t size = 0;
+            if (!AMediaFormat_getBuffer(trackFormat, "csd-2", &seekPreRollBuf, &size)) {
+                size_t opusHeadSize = 0;
+                size_t codecDelayBufSize = 0;
+                size_t seekPreRollBufSize = 0;
+                void *csdBuffer = nullptr;
+                void *opusHeadBuf = nullptr;
+                void *codecDelayBuf = nullptr;
+                AMediaFormat_getBuffer(trackFormat, "csd-0", &csdBuffer, &size);
+                ASSERT_NE(csdBuffer, nullptr);
+
+                GetOpusHeaderBuffers((uint8_t *)csdBuffer, size, &opusHeadBuf, &opusHeadSize,
+                                     &codecDelayBuf, &codecDelayBufSize, &seekPreRollBuf,
+                                     &seekPreRollBufSize);
+            }
+            ASSERT_NE(seekPreRollBuf, nullptr)
+                    << "Invalid track format. SeekPreRoll info missing for Opus file";
+            opusSeekPreRollUs = *((int64_t *)seekPreRollBuf);
+        }
         AMediaFormat_delete(trackFormat);
 
         int32_t seekIdx = 0;
@@ -448,7 +689,7 @@
                 // extractor is calculated based on (seekPts - seekPreRollUs).
                 // So we add the preRoll value to the timeStamp we want to seek to.
                 if (isOpus) {
-                    seekToTimeStamp += kOpusSeekPreRollUs;
+                    seekToTimeStamp += opusSeekPreRollUs;
                 }
 
                 MediaTrackHelper::ReadOptions *options = new MediaTrackHelper::ReadOptions(
@@ -496,24 +737,517 @@
     seekablePoints.clear();
 }
 
-// TODO: (b/145332185)
-// Add MIDI inputs
-INSTANTIATE_TEST_SUITE_P(ExtractorUnitTestAll, ExtractorUnitTest,
-                         ::testing::Values(make_pair("aac", "loudsoftaac.aac"),
-                                           make_pair("amr", "testamr.amr"),
-                                           make_pair("amr", "amrwb.wav"),
-                                           make_pair("ogg", "john_cage.ogg"),
-                                           make_pair("wav", "monotestgsm.wav"),
-                                           make_pair("mpeg2ts", "segment000001.ts"),
-                                           make_pair("flac", "sinesweepflac.flac"),
-                                           make_pair("ogg", "testopus.opus"),
-                                           make_pair("mkv", "sinesweepvorbis.mkv"),
-                                           make_pair("mpeg4", "sinesweepoggmp4.mp4"),
-                                           make_pair("mp3", "sinesweepmp3lame.mp3"),
-                                           make_pair("mkv", "swirl_144x136_vp9.webm"),
-                                           make_pair("mkv", "swirl_144x136_vp8.webm"),
-                                           make_pair("mpeg2ps", "swirl_144x136_mpeg2.mpg"),
-                                           make_pair("mpeg4", "swirl_132x130_mpeg4.mp4")));
+// Tests the extractors for seek beyond range : (0, ClipDuration)
+TEST_P(ExtractorFunctionalityTest, MonkeySeekTest) {
+    if (mDisableTest) return;
+    // TODO(b/155630778): Enable test for wav extractors
+    if (mExtractorName == WAV) return;
+
+    ALOGV("Validates %s Extractor behaviour for invalid seek points", mContainer.c_str());
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
+
+    uint32_t seekFlag = mExtractor->flags();
+    bool seekSupported = get<3>(GetParam());
+    bool seekable = seekFlag & MediaExtractorPluginHelper::CAN_SEEK;
+    if (!seekable) {
+        ASSERT_FALSE(seekSupported) << mContainer << "Extractor is expected to support seek ";
+        cout << "[   WARN   ] Test Skipped. " << mContainer << " Extractor doesn't support seek\n";
+        return;
+    }
+
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        MediaTrackHelper *track = mExtractor->getTrack(idx);
+        ASSERT_NE(track, nullptr) << "Failed to get track for index " << idx;
+
+        CMediaTrack *cTrack = wrap(track);
+        ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << idx;
+
+        MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+        status = cTrack->start(track, bufferGroup->wrap());
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+
+        AMediaFormat *trackMeta = AMediaFormat_new();
+        ASSERT_NE(trackMeta, nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+        status = mExtractor->getTrackMetaData(
+                trackMeta, idx, MediaExtractorPluginHelper::kIncludeExtensiveMetaData);
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to get trackMetaData";
+
+        const char *mime;
+        ASSERT_TRUE(AMediaFormat_getString(trackMeta, AMEDIAFORMAT_KEY_MIME, &mime))
+                << "Failed to get mime";
+
+        int64_t clipDuration = 0;
+        AMediaFormat_getInt64(trackMeta, AMEDIAFORMAT_KEY_DURATION, &clipDuration);
+        // Image formats are not expected to have duration information
+        ASSERT_TRUE(clipDuration > 0 || !strncmp(mime, "image/", 6)) << "Invalid clip duration ";
+        AMediaFormat_delete(trackMeta);
+
+        int64_t seekToTimeStampUs[] = {-clipDuration, clipDuration / 2, clipDuration,
+                                       clipDuration * 2};
+        for (int32_t mode = CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC;
+             mode <= CMediaTrackReadOptions::SEEK_CLOSEST; mode++) {
+            for (int64_t seekTimeUs : seekToTimeStampUs) {
+                MediaTrackHelper::ReadOptions *options = new MediaTrackHelper::ReadOptions(
+                        mode | CMediaTrackReadOptions::SEEK, seekTimeUs);
+                ASSERT_NE(options, nullptr) << "Cannot create read option";
+
+                MediaBufferHelper *buffer = nullptr;
+                status = track->read(&buffer, options);
+                if (status == AMEDIA_ERROR_END_OF_STREAM) {
+                    delete options;
+                    continue;
+                }
+                if (buffer) {
+                    AMediaFormat *metaData = buffer->meta_data();
+                    int64_t timeStamp;
+                    AMediaFormat_getInt64(metaData, AMEDIAFORMAT_KEY_TIME_US, &timeStamp);
+                    ALOGV("Seeked to timestamp : %lld, requested : %lld", (long long)timeStamp,
+                          (long long)seekTimeUs);
+                    buffer->release();
+                }
+                delete options;
+            }
+        }
+        status = cTrack->stop(track);
+        ASSERT_EQ(OK, status) << "Failed to stop the track";
+        delete bufferGroup;
+        delete track;
+    }
+}
+
+// Tests extractors for invalid tracks
+TEST_P(ExtractorFunctionalityTest, SanityTest) {
+    if (mDisableTest) return;
+    // TODO(b/155626946): Enable test for MPEG2 TS/PS extractors
+    if (mExtractorName == MPEG2TS || mExtractorName == MPEG2PS) return;
+
+    ALOGV("Validates %s Extractor behaviour for invalid tracks", mContainer.c_str());
+    string inputFileName = gEnv->getRes() + get<1>(GetParam());
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << mContainer << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_EQ(numTracks, mNumTracks)
+            << "Extractor reported wrong number of track for the given clip";
+
+    int32_t trackIdx[] = {-1, numTracks};
+    for (int32_t idx : trackIdx) {
+        MediaTrackHelper *track = mExtractor->getTrack(idx);
+        ASSERT_EQ(track, nullptr) << "Failed to get track for index " << idx << "\n";
+
+        AMediaFormat *extractorFormat = AMediaFormat_new();
+        ASSERT_NE(extractorFormat, nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+        status = mExtractor->getTrackMetaData(
+                extractorFormat, idx, MediaExtractorPluginHelper::kIncludeExtensiveMetaData);
+        ASSERT_NE(OK, status) << "getTrackMetaData should return error for invalid index " << idx;
+        AMediaFormat_delete(extractorFormat);
+    }
+
+    // Validate Extractor's getTrackMetaData for null format
+    AMediaFormat *mediaFormat = nullptr;
+    status = mExtractor->getTrackMetaData(mediaFormat, 0,
+                                          MediaExtractorPluginHelper::kIncludeExtensiveMetaData);
+    ASSERT_NE(OK, status) << "getTrackMetaData should return error for null Media format";
+}
+
+// This test validates config params for a given input file.
+// For this test we only take single track files since the focus of this test is
+// to validate the file properties reported by Extractor and not multi-track behavior
+TEST_P(ConfigParamTest, ConfigParamValidation) {
+    if (mDisableTest) return;
+
+    string container = GetParam().first;
+    ALOGV("Validates %s Extractor for input's file properties", container.c_str());
+    string inputFileName = gEnv->getRes();
+    inputID inputFileId = GetParam().second;
+    configFormat configParam;
+    getFileProperties(inputFileId, inputFileName, configParam);
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for " << container << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for " << container << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+    MediaTrackHelper *track = mExtractor->getTrack(0);
+    ASSERT_NE(track, nullptr) << "Failed to get track for index 0";
+
+    AMediaFormat *trackFormat = AMediaFormat_new();
+    ASSERT_NE(trackFormat, nullptr) << "AMediaFormat_new returned null format";
+
+    status = track->getFormat(trackFormat);
+    ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
+
+    const char *trackMime;
+    bool valueFound = AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &trackMime);
+    ASSERT_TRUE(valueFound) << "Mime type not set by extractor";
+    ASSERT_STREQ(configParam.mime.c_str(), trackMime) << "Invalid track format";
+
+    if (!strncmp(trackMime, "audio/", 6)) {
+        int32_t trackSampleRate, trackChannelCount;
+        ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                          &trackChannelCount));
+        ASSERT_TRUE(
+                AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, &trackSampleRate));
+        ASSERT_EQ(configParam.sampleRate, trackSampleRate) << "SampleRate not as expected";
+        ASSERT_EQ(configParam.channelCount, trackChannelCount) << "ChannelCount not as expected";
+    } else {
+        int32_t trackWidth, trackHeight;
+        ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_WIDTH, &trackWidth));
+        ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_HEIGHT, &trackHeight));
+        ASSERT_EQ(configParam.width, trackWidth) << "Width not as expected";
+        ASSERT_EQ(configParam.height, trackHeight) << "Height not as expected";
+
+        if (configParam.frameRate != kUndefined) {
+            int32_t frameRate;
+            ASSERT_TRUE(
+                    AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_FRAME_RATE, &frameRate));
+            ASSERT_EQ(configParam.frameRate, frameRate) << "frameRate not as expected";
+        }
+    }
+    // validate the profile for the input clip
+    int32_t profile;
+    if (configParam.profile != kUndefined) {
+        if (AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_PROFILE, &profile)) {
+            ASSERT_EQ(configParam.profile, profile) << "profile not as expected";
+        } else if (mExtractorName == AAC &&
+                   AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_AAC_PROFILE, &profile)) {
+            ASSERT_EQ(configParam.profile, profile) << "profile not as expected";
+        } else {
+            ASSERT_TRUE(false) << "profile not returned in extractor";
+        }
+    }
+
+    delete track;
+    AMediaFormat_delete(trackFormat);
+}
+
+class ExtractorComparison
+    : public ExtractorUnitTest,
+      public ::testing::TestWithParam<pair<string /* InputFile0 */, string /* InputFile1 */>> {
+  public:
+    ~ExtractorComparison() {
+        for (int8_t *extractorOp : mExtractorOutput) {
+            if (extractorOp != nullptr) {
+                free(extractorOp);
+            }
+        }
+    }
+
+    int8_t *mExtractorOutput[2]{};
+    size_t mExtractorOuputSize[2]{};
+};
+
+size_t allocateOutputBuffers(string inputFileName, AMediaFormat *extractorFormat) {
+    size_t bufferSize = 0u;
+    // allocating the buffer size as sampleRate * channelCount * clipDuration since
+    // some extractors like flac, midi and wav decodes the file. These extractors
+    // advertise the mime type as raw.
+    const char *mime;
+    AMediaFormat_getString(extractorFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+    if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
+        int64_t clipDurationUs = -1;
+        int32_t channelCount = -1;
+        int32_t sampleRate = -1;
+        int32_t bitsPerSampple = -1;
+        if (!AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                   &channelCount) || channelCount <= 0) {
+            ALOGE("Invalid channelCount for input file : %s", inputFileName.c_str());
+            return 0;
+        }
+        if (!AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate) ||
+            sampleRate <= 0) {
+            ALOGE("Invalid sampleRate for input file : %s", inputFileName.c_str());
+            return 0;
+        }
+        if (!AMediaFormat_getInt64(extractorFormat, AMEDIAFORMAT_KEY_DURATION, &clipDurationUs) ||
+            clipDurationUs <= 0) {
+            ALOGE("Invalid clip duration for input file : %s", inputFileName.c_str());
+            return 0;
+        }
+        if (!AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                                   &bitsPerSampple) || bitsPerSampple <= 0) {
+            ALOGE("Invalid bits per sample for input file : %s", inputFileName.c_str());
+            return 0;
+        }
+        bufferSize = bitsPerSampple * channelCount * sampleRate * (clipDurationUs / 1000000 + 1);
+    } else {
+        struct stat buf;
+        int32_t status = stat(inputFileName.c_str(), &buf);
+        if (status != 0) {
+            ALOGE("Unable to get file properties for: %s", inputFileName.c_str());
+            return 0;
+        }
+        bufferSize = buf.st_size;
+    }
+    return bufferSize;
+}
+
+// Compare output of two extractors for identical content
+TEST_P(ExtractorComparison, ExtractorComparisonTest) {
+    vector<string> inputFileNames = {GetParam().first, GetParam().second};
+    size_t extractedOutputSize[2]{};
+    AMediaFormat *extractorFormat[2]{};
+    int32_t status = OK;
+
+    for (int32_t idx = 0; idx < inputFileNames.size(); idx++) {
+        string containerFormat = inputFileNames[idx].substr(inputFileNames[idx].find(".") + 1);
+        setupExtractor(containerFormat);
+        if (mDisableTest) {
+            ALOGV("Unknown extractor %s. Skipping the test", containerFormat.c_str());
+            return;
+        }
+
+        ALOGV("Validates %s Extractor for %s", containerFormat.c_str(),
+              inputFileNames[idx].c_str());
+        string inputFileName = gEnv->getRes() + inputFileNames[idx];
+
+        status = setDataSource(inputFileName);
+        ASSERT_EQ(status, 0) << "SetDataSource failed for" << containerFormat << "extractor";
+
+        status = createExtractor();
+        ASSERT_EQ(status, 0) << "Extractor creation failed for " << containerFormat << " extractor";
+
+        int32_t numTracks = mExtractor->countTracks();
+        ASSERT_EQ(numTracks, 1) << "This test expects inputs with one track only";
+
+        int32_t trackIdx = 0;
+        MediaTrackHelper *track = mExtractor->getTrack(trackIdx);
+        ASSERT_NE(track, nullptr) << "Failed to get track for index " << trackIdx;
+
+        extractorFormat[idx] = AMediaFormat_new();
+        ASSERT_NE(extractorFormat[idx], nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+        status = track->getFormat(extractorFormat[idx]);
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
+
+        CMediaTrack *cTrack = wrap(track);
+        ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << trackIdx;
+
+        mExtractorOuputSize[idx] = allocateOutputBuffers(inputFileName, extractorFormat[idx]);
+        ASSERT_GT(mExtractorOuputSize[idx], 0u) << " Invalid size for output buffers";
+
+        mExtractorOutput[idx] = (int8_t *)calloc(1, mExtractorOuputSize[idx]);
+        ASSERT_NE(mExtractorOutput[idx], nullptr)
+                << "Unable to allocate memory for writing extractor's output";
+
+        MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+        status = cTrack->start(track, bufferGroup->wrap());
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+
+        int32_t offset = 0;
+        while (status != AMEDIA_ERROR_END_OF_STREAM) {
+            MediaBufferHelper *buffer = nullptr;
+            status = track->read(&buffer);
+            ALOGV("track->read Status = %d buffer %p", status, buffer);
+            if (buffer) {
+                ASSERT_LE(offset + buffer->range_length(), mExtractorOuputSize[idx])
+                        << "Memory overflow. Extracted output size more than expected";
+
+                memcpy(mExtractorOutput[idx] + offset, buffer->data(), buffer->range_length());
+                extractedOutputSize[idx] += buffer->range_length();
+                offset += buffer->range_length();
+                buffer->release();
+            }
+        }
+        status = cTrack->stop(track);
+        ASSERT_EQ(OK, status) << "Failed to stop the track";
+
+        fclose(mInputFp);
+        delete bufferGroup;
+        delete track;
+        mDataSource.clear();
+        delete mExtractor;
+        mInputFp = nullptr;
+        mExtractor = nullptr;
+    }
+
+    // Compare the meta data from both the extractors
+    const char *mime[2];
+    AMediaFormat_getString(extractorFormat[0], AMEDIAFORMAT_KEY_MIME, &mime[0]);
+    AMediaFormat_getString(extractorFormat[1], AMEDIAFORMAT_KEY_MIME, &mime[1]);
+    ASSERT_STREQ(mime[0], mime[1]) << "Mismatch between extractor's format";
+
+    if (!strncmp(mime[0], "audio/", 6)) {
+        int32_t channelCount0, channelCount1;
+        int32_t sampleRate0, sampleRate1;
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                          &channelCount0));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                          &sampleRate0));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                          &channelCount1));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                          &sampleRate1));
+        ASSERT_EQ(channelCount0, channelCount1) << "Mismatch between extractor's channelCount";
+        ASSERT_EQ(sampleRate0, sampleRate1) << "Mismatch between extractor's sampleRate";
+    } else if (!strncmp(mime[0], "video/", 6)) {
+        int32_t width0, height0;
+        int32_t width1, height1;
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_WIDTH, &width0));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_HEIGHT, &height0));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_WIDTH, &width1));
+        ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_HEIGHT, &height1));
+        ASSERT_EQ(width0, width1) << "Mismatch between extractor's width";
+        ASSERT_EQ(height0, height1) << "Mismatch between extractor's height";
+    } else {
+        ASSERT_TRUE(false) << "Invalid mime type " << mime[0];
+    }
+
+    for (AMediaFormat *exFormat : extractorFormat) {
+        AMediaFormat_delete(exFormat);
+    }
+
+    // Compare the extracted outputs of both extractor
+    ASSERT_EQ(extractedOutputSize[0], extractedOutputSize[1])
+            << "Extractor's output size doesn't match between " << inputFileNames[0] << "and "
+            << inputFileNames[1] << " extractors";
+    status = memcmp(mExtractorOutput[0], mExtractorOutput[1], extractedOutputSize[0]);
+    ASSERT_EQ(status, 0) << "Extracted content mismatch between " << inputFileNames[0] << "and "
+                         << inputFileNames[1] << " extractors";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        ExtractorComparisonAll, ExtractorComparison,
+        ::testing::Values(make_pair("swirl_144x136_vp9.mp4", "swirl_144x136_vp9.webm"),
+                          make_pair("video_480x360_mp4_vp9_333kbps_25fps.mp4",
+                                    "video_480x360_webm_vp9_333kbps_25fps.webm"),
+                          make_pair("video_1280x720_av1_hdr_static_3mbps.mp4",
+                                    "video_1280x720_av1_hdr_static_3mbps.webm"),
+                          make_pair("swirl_132x130_mpeg4.3gp", "swirl_132x130_mpeg4.mkv"),
+                          make_pair("swirl_144x136_avc.mkv", "swirl_144x136_avc.mp4"),
+                          make_pair("swirl_132x130_mpeg4.mp4", "swirl_132x130_mpeg4.mkv"),
+                          make_pair("crowd_508x240_25fps_hevc.mp4","crowd_508x240_25fps_hevc.mkv"),
+                          make_pair("bbb_cif_768kbps_30fps_mpeg2.mp4",
+                                    "bbb_cif_768kbps_30fps_mpeg2.ts"),
+
+                          make_pair("loudsoftaac.aac", "loudsoftaac.mkv"),
+                          make_pair("sinesweepflacmkv.mkv", "sinesweepflacmp4.mp4"),
+                          make_pair("sinesweepmp3lame.mp3", "sinesweepmp3lame.mkv"),
+                          make_pair("sinesweepoggmp4.mp4", "sinesweepogg.ogg"),
+                          make_pair("sinesweepvorbis.mp4", "sinesweepvorbis.ogg"),
+                          make_pair("sinesweepvorbis.mkv", "sinesweepvorbis.ogg"),
+                          make_pair("testopus.mkv", "testopus.mp4"),
+                          make_pair("testopus.mp4", "testopus.opus"),
+
+                          make_pair("loudsoftaac.aac", "loudsoftaac.aac"),
+                          make_pair("testamr.amr", "testamr.amr"),
+                          make_pair("sinesweepflac.flac", "sinesweepflac.flac"),
+                          make_pair("midi_a.mid", "midi_a.mid"),
+                          make_pair("sinesweepvorbis.mkv", "sinesweepvorbis.mkv"),
+                          make_pair("sinesweepmp3lame.mp3", "sinesweepmp3lame.mp3"),
+                          make_pair("sinesweepoggmp4.mp4", "sinesweepoggmp4.mp4"),
+                          make_pair("testopus.opus", "testopus.opus"),
+                          make_pair("john_cage.ogg", "john_cage.ogg"),
+                          make_pair("monotestgsm.wav", "monotestgsm.wav"),
+
+                          make_pair("swirl_144x136_mpeg2.mpg", "swirl_144x136_mpeg2.mpg"),
+                          make_pair("swirl_132x130_mpeg4.mp4", "swirl_132x130_mpeg4.mp4"),
+                          make_pair("swirl_144x136_vp9.webm", "swirl_144x136_vp9.webm"),
+                          make_pair("swirl_144x136_vp8.webm", "swirl_144x136_vp8.webm")));
+
+INSTANTIATE_TEST_SUITE_P(ConfigParamTestAll, ConfigParamTest,
+                         ::testing::Values(make_pair("aac", AAC_1),
+                                           make_pair("amr", AMR_NB_1),
+                                           make_pair("amr", AMR_WB_1),
+                                           make_pair("flac", FLAC_1),
+                                           make_pair("wav", GSM_1),
+                                           make_pair("midi", MIDI_1),
+                                           make_pair("mp3", MP3_1),
+                                           make_pair("ogg", OPUS_1),
+                                           make_pair("ogg", VORBIS_1),
+
+                                           make_pair("mpeg4", HEVC_1),
+                                           make_pair("mpeg4", HEVC_2),
+                                           make_pair("mpeg2ps", MPEG2_PS_1),
+                                           make_pair("mpeg2ts", MPEG2_TS_1),
+                                           make_pair("mkv", MPEG4_1),
+                                           make_pair("mkv", VP9_1)));
+
+// Validate extractors for container format, input file, no. of tracks and supports seek flag
+INSTANTIATE_TEST_SUITE_P(
+        ExtractorUnitTestAll, ExtractorFunctionalityTest,
+        ::testing::Values(
+                make_tuple("aac", "loudsoftaac.aac", 1, true),
+                make_tuple("amr", "testamr.amr", 1, true),
+                make_tuple("amr", "amrwb.wav", 1, true),
+                make_tuple("flac", "sinesweepflac.flac", 1, true),
+                make_tuple("midi", "midi_a.mid", 1, true),
+                make_tuple("mkv", "sinesweepvorbis.mkv", 1, true),
+                make_tuple("mkv", "sinesweepmp3lame.mkv", 1, true),
+                make_tuple("mkv", "loudsoftaac.mkv", 1, true),
+                make_tuple("mp3", "sinesweepmp3lame.mp3", 1, true),
+                make_tuple("mp3", "id3test10.mp3", 1, true),
+                make_tuple("mpeg2ts", "segment000001.ts", 2, false),
+                make_tuple("mpeg2ts", "testac3ts.ts", 1, false),
+                make_tuple("mpeg2ts", "testac4ts.ts", 1, false),
+                make_tuple("mpeg2ts", "testeac3ts.ts", 1, false),
+                make_tuple("mpeg4", "audio_aac_mono_70kbs_44100hz.mp4", 2, true),
+                make_tuple("mpeg4", "multi0_ac4.mp4", 1, true),
+                make_tuple("mpeg4", "noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a", 1, true),
+                make_tuple("mpeg4", "sinesweepalac.mov", 1, true),
+                make_tuple("mpeg4", "sinesweepflacmp4.mp4", 1, true),
+                make_tuple("mpeg4", "sinesweepm4a.m4a", 1, true),
+                make_tuple("mpeg4", "sinesweepoggmp4.mp4", 1, true),
+                make_tuple("mpeg4", "sinesweepopusmp4.mp4", 1, true),
+                make_tuple("mpeg4", "testac3mp4.mp4", 1, true),
+                make_tuple("mpeg4", "testeac3mp4.mp4", 1, true),
+                make_tuple("ogg", "john_cage.ogg", 1, true),
+                make_tuple("ogg", "testopus.opus", 1, true),
+                make_tuple("ogg", "sinesweepoggalbumart.ogg", 1, true),
+                make_tuple("wav", "loudsoftwav.wav", 1, true),
+                make_tuple("wav", "monotestgsm.wav", 1, true),
+                make_tuple("wav", "noise_5ch_44khz_aot2_wave.wav", 1, true),
+                make_tuple("wav", "sine1khzm40db_alaw.wav", 1, true),
+                make_tuple("wav", "sine1khzm40db_f32le.wav", 1, true),
+                make_tuple("wav", "sine1khzm40db_mulaw.wav", 1, true),
+
+                make_tuple("mkv", "swirl_144x136_avc.mkv", 1, true),
+                make_tuple("mkv", "withoutcues.mkv", 2, true),
+                make_tuple("mkv", "swirl_144x136_vp9.webm", 1, true),
+                make_tuple("mkv", "swirl_144x136_vp8.webm", 1, true),
+                make_tuple("mpeg2ps", "swirl_144x136_mpeg2.mpg", 1, false),
+                make_tuple("mpeg2ps", "programstream.mpeg", 2, false),
+                make_tuple("mpeg4", "color_176x144_bt601_525_lr_sdr_h264.mp4", 1, true),
+                make_tuple("mpeg4", "heifwriter_input.heic", 4, false),
+                make_tuple("mpeg4", "psshtest.mp4", 1, true),
+                make_tuple("mpeg4", "swirl_132x130_mpeg4.mp4", 1, true),
+                make_tuple("mpeg4", "testvideo.3gp", 4, true),
+                make_tuple("mpeg4", "testvideo_with_2_timedtext_tracks.3gp", 4, true),
+                make_tuple("mpeg4",
+                           "video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_11025hz_"
+                           "metadata_gyro_compliant.3gp",
+                           3, true),
+                make_tuple(
+                        "mpeg4",
+                        "video_1920x1080_mp4_mpeg2_12000kbps_30fps_aac_stereo_128kbps_48000hz.mp4",
+                        2, true),
+                make_tuple("mpeg4",
+                           "video_480x360_mp4_hevc_650kbps_30fps_aac_stereo_128kbps_48000hz.mp4", 2,
+                           true),
+                make_tuple(
+                        "mpeg4",
+                        "video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz_dash.mp4",
+                        2, true)));
 
 int main(int argc, char **argv) {
     gEnv = new ExtractorUnitTestEnvironment();
diff --git a/media/extractors/tests/README.md b/media/extractors/tests/README.md
index 69538b6..cff09ca 100644
--- a/media/extractors/tests/README.md
+++ b/media/extractors/tests/README.md
@@ -22,7 +22,7 @@
 adb push ${OUT}/data/nativetest/ExtractorUnitTest/ExtractorUnitTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip). Download, unzip and push these files into device for testing.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.4.zip). Download, unzip and push these files into device for testing.
 
 ```
 adb push extractor /data/local/tmp/
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 5d38a81..85d4cce 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -19,4 +19,11 @@
         "libfifo",
         "libstagefright_foundation",
     ],
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/janitors/OWNERS-codecs b/media/janitors/OWNERS-codecs
new file mode 100644
index 0000000..e201399
--- /dev/null
+++ b/media/janitors/OWNERS-codecs
@@ -0,0 +1,5 @@
+# gerrit owner/approvers for the actual software codec libraries
+# differentiated from plugins connecting those codecs to either omx or codec2 infrastructure
+essick@google.com
+lajos@google.com
+marcone@google.com
diff --git a/media/janitors/README b/media/janitors/README
new file mode 100644
index 0000000..9db8e0e
--- /dev/null
+++ b/media/janitors/README
@@ -0,0 +1,4 @@
+A collection of OWNERS files that we reference from other projects,
+such as the software codecs in directories like external/libavc.
+This is to simplify our owner/approver management across the multiple
+projects related to media.
diff --git a/media/libaaudio/examples/utils/dummy.cpp b/media/libaaudio/examples/utils/dummy.cpp
deleted file mode 100644
index 8ef7e36..0000000
--- a/media/libaaudio/examples/utils/dummy.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Dummy file needed to get Android Studio to scan this folder.
- */
-
-int g_DoNotUseThisVariable = 0;
diff --git a/media/libaaudio/examples/utils/unused.cpp b/media/libaaudio/examples/utils/unused.cpp
new file mode 100644
index 0000000..9a5205e
--- /dev/null
+++ b/media/libaaudio/examples/utils/unused.cpp
@@ -0,0 +1,5 @@
+/**
+ * Unused file required to get Android Studio to scan this folder.
+ */
+
+int g_DoNotUseThisVariable = 0;
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index cab8929..e0ac7e5 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -29,6 +29,8 @@
 #ifndef AAUDIO_AAUDIO_H
 #define AAUDIO_AAUDIO_H
 
+#include <stdbool.h>
+#include <stdint.h>
 #include <time.h>
 
 #ifdef __cplusplus
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.h b/media/libaaudio/src/binding/SharedMemoryParcelable.h
index 4ec38c5..3927f58 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.h
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.h
@@ -26,7 +26,7 @@
 
 namespace aaudio {
 
-// Arbitrary limits for sanity checks. TODO remove after debugging.
+// Arbitrary limits for range checks.
 #define MAX_SHARED_MEMORIES (32)
 #define MAX_MMAP_OFFSET_BYTES (32 * 1024 * 8)
 #define MAX_MMAP_SIZE_BYTES (32 * 1024 * 8)
diff --git a/media/libaaudio/src/flowgraph/AudioProcessorBase.h b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
index eda46ae..972932f 100644
--- a/media/libaaudio/src/flowgraph/AudioProcessorBase.h
+++ b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
@@ -267,7 +267,7 @@
     AudioFloatInputPort input;
 
     /**
-     * Dummy processor. The work happens in the read() method.
+     * Do nothing. The work happens in the read() method.
      *
      * @param framePosition index of first frame to be processed
      * @param numFrames
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index d2e4805..82eb77d 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -21,6 +21,7 @@
 #include <functional>
 #include <stdint.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <utils/Errors.h>
 #include <system/audio.h>
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 0c40cbb..e8e1a09 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -12,6 +12,12 @@
     export_header_lib_headers: [
         "libaudiofoundation_headers",
     ],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_shared {
diff --git a/media/libaudioclient/AudioAttributes.cpp b/media/libaudioclient/AudioAttributes.cpp
index 1ee6930..ff4ba06 100644
--- a/media/libaudioclient/AudioAttributes.cpp
+++ b/media/libaudioclient/AudioAttributes.cpp
@@ -57,7 +57,7 @@
         parcel->writeInt32(0);
     } else {
         parcel->writeInt32(1);
-        parcel->writeUtf8AsUtf16(mAttributes.tags);
+        parcel->writeUtf8AsUtf16(std::string(mAttributes.tags));
     }
     parcel->writeInt32(static_cast<int32_t>(mStreamType));
     parcel->writeUint32(static_cast<uint32_t>(mGroupId));
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 3ead6cb..73b96ab 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -36,64 +36,10 @@
 // ---------------------------------------------------------------------------
 
 AudioEffect::AudioEffect(const String16& opPackageName)
-    : mStatus(NO_INIT), mProbe(false), mOpPackageName(opPackageName)
+    : mOpPackageName(opPackageName)
 {
 }
 
-
-AudioEffect::AudioEffect(const effect_uuid_t *type,
-                const String16& opPackageName,
-                const effect_uuid_t *uuid,
-                int32_t priority,
-                effect_callback_t cbf,
-                void* user,
-                audio_session_t sessionId,
-                audio_io_handle_t io,
-                const AudioDeviceTypeAddr& device,
-                bool probe
-                )
-    : mStatus(NO_INIT), mProbe(false), mOpPackageName(opPackageName)
-{
-    AutoMutex lock(mConstructLock);
-    mStatus = set(type, uuid, priority, cbf, user, sessionId, io, device, probe);
-}
-
-AudioEffect::AudioEffect(const char *typeStr,
-                const String16& opPackageName,
-                const char *uuidStr,
-                int32_t priority,
-                effect_callback_t cbf,
-                void* user,
-                audio_session_t sessionId,
-                audio_io_handle_t io,
-                const AudioDeviceTypeAddr& device,
-                bool probe
-                )
-    : mStatus(NO_INIT), mProbe(false), mOpPackageName(opPackageName)
-{
-    effect_uuid_t type;
-    effect_uuid_t *pType = NULL;
-    effect_uuid_t uuid;
-    effect_uuid_t *pUuid = NULL;
-
-    ALOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr);
-
-    if (typeStr != NULL) {
-        if (stringToGuid(typeStr, &type) == NO_ERROR) {
-            pType = &type;
-        }
-    }
-
-    if (uuidStr != NULL) {
-        if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
-            pUuid = &uuid;
-        }
-    }
-
-    AutoMutex lock(mConstructLock);
-    mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io, device, probe);
-}
-
 status_t AudioEffect::set(const effect_uuid_t *type,
                 const effect_uuid_t *uuid,
                 int32_t priority,
@@ -194,6 +140,34 @@
     return mStatus;
 }
 
+status_t AudioEffect::set(const char *typeStr,
+                const char *uuidStr,
+                int32_t priority,
+                effect_callback_t cbf,
+                void* user,
+                audio_session_t sessionId,
+                audio_io_handle_t io,
+                const AudioDeviceTypeAddr& device,
+                bool probe)
+{
+    effect_uuid_t type;
+    effect_uuid_t *pType = nullptr;
+    effect_uuid_t uuid;
+    effect_uuid_t *pUuid = nullptr;
+
+    ALOGV("AudioEffect::set string\n - type: %s\n - uuid: %s",
+            typeStr ? typeStr : "nullptr", uuidStr ? uuidStr : "nullptr");
+
+    if (stringToGuid(typeStr, &type) == NO_ERROR) {
+        pType = &type;
+    }
+    if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
+        pUuid = &uuid;
+    }
+
+    return set(pType, pUuid, priority, cbf, user, sessionId, io, device, probe);
+}
+
 
 AudioEffect::~AudioEffect()
 {
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 9568e83..d6671e3 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -1103,7 +1103,7 @@
     }
 
     if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
-        // sanity-check. user is most-likely passing an error code, and it would
+        // Validation. user is most-likely passing an error code, and it would
         // make the return value ambiguous (actualSize vs error).
         ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
                 __func__, mPortId, buffer, userSize, userSize);
@@ -1330,7 +1330,7 @@
         mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
         size_t readSize = audioBuffer.size;
 
-        // Sanity check on returned size
+        // Validate on returned size
         if (ssize_t(readSize) < 0 || readSize > reqSize) {
             ALOGE("%s(%d):  EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
                     __func__, mPortId, reqSize, ssize_t(readSize));
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 6357da4..f621aa5 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -581,7 +581,8 @@
         case AUDIO_INPUT_CONFIG_CHANGED: {
             sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle);
             if (oldDesc == 0) {
-                ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle);
+                ALOGW("ioConfigChanged() modifying unknown %s! %d",
+                    event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input", ioDesc->mIoHandle);
                 break;
             }
 
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 68d11d4..41af78c 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1946,7 +1946,7 @@
     }
 
     if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
-        // Sanity-check: user is most-likely passing an error code, and it would
+        // Validation: user is most-likely passing an error code, and it would
         // make the return value ambiguous (actualSize vs error).
         ALOGE("%s(%d): AudioTrack::write(buffer=%p, size=%zu (%zd)",
                 __func__, mPortId, buffer, userSize, userSize);
@@ -2336,7 +2336,7 @@
                 mUserData, &audioBuffer);
         size_t writtenSize = audioBuffer.size;
 
-        // Sanity check on returned size
+        // Validate on returned size
         if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) {
             ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
                     __func__, mPortId, reqSize, ssize_t(writtenSize));
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 16d2232..6d79aba 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -1001,7 +1001,7 @@
             break;
     }
 
-    // Whitelist of relevant events to trigger log merging.
+    // List of relevant events that trigger log merging.
     // Log merging should activate during audio activity of any kind. This are considered the
     // most relevant events.
     // TODO should select more wisely the items from the list
diff --git a/media/libaudioclient/OWNERS b/media/libaudioclient/OWNERS
index 482b9fb..034d161 100644
--- a/media/libaudioclient/OWNERS
+++ b/media/libaudioclient/OWNERS
@@ -1,3 +1,4 @@
 gkasten@google.com
+hunga@google.com
 jmtrivi@google.com
 mnaganov@google.com
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index cb76252..3d4bb4e 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -339,16 +339,21 @@
      *
      * opPackageName:      The package name used for app op checks.
      */
-    AudioEffect(const String16& opPackageName);
+    explicit AudioEffect(const String16& opPackageName);
 
+    /* Terminates the AudioEffect and unregisters it from AudioFlinger.
+     * The effect engine is also destroyed if this AudioEffect was the last controlling
+     * the engine.
+     */
+                        ~AudioEffect();
 
-    /* Constructor.
+    /**
+     * Initialize an uninitialized AudioEffect.
      *
      * Parameters:
      *
      * type:  type of effect created: can be null if uuid is specified. This corresponds to
      *        the OpenSL ES interface implemented by this effect.
-     * opPackageName:  The package name used for app op checks.
      * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to
      *        a particular implementation of an effect type.
      * priority:    requested priority for effect control: the priority level corresponds to the
@@ -356,7 +361,7 @@
      *      higher priorities, 0 being the normal priority.
      * cbf:         optional callback function (see effect_callback_t)
      * user:        pointer to context for use by the callback receiver.
-     * sessionID:   audio session this effect is associated to.
+     * sessionId:   audio session this effect is associated to.
      *      If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
      *      the output mix.  Otherwise, the effect will be applied to all players
      *      (AudioTrack or MediaPLayer) within the same audio session.
@@ -369,46 +374,13 @@
      *        In this mode, no IEffect interface to AudioFlinger is created and all actions
      *        besides getters implemented in client AudioEffect object are no ops
      *        after effect creation.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR or ALREADY_EXISTS: successful initialization
+     *  - INVALID_OPERATION: AudioEffect is already initialized
+     *  - BAD_VALUE: invalid parameter
+     *  - NO_INIT: audio flinger or audio hardware not initialized
      */
-
-    AudioEffect(const effect_uuid_t *type,
-                const String16& opPackageName,
-                const effect_uuid_t *uuid = NULL,
-                int32_t priority = 0,
-                effect_callback_t cbf = NULL,
-                void* user = NULL,
-                audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
-                audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
-                const AudioDeviceTypeAddr& device = {},
-                bool probe = false);
-
-    /* Constructor.
-     *      Same as above but with type and uuid specified by character strings
-     */
-    AudioEffect(const char *typeStr,
-                    const String16& opPackageName,
-                    const char *uuidStr = NULL,
-                    int32_t priority = 0,
-                    effect_callback_t cbf = NULL,
-                    void* user = NULL,
-                    audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
-                    audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
-                    const AudioDeviceTypeAddr& device = {},
-                    bool probe = false);
-
-    /* Terminates the AudioEffect and unregisters it from AudioFlinger.
-     * The effect engine is also destroyed if this AudioEffect was the last controlling
-     * the engine.
-     */
-                        ~AudioEffect();
-
-    /* Initialize an uninitialized AudioEffect.
-    * Returned status (from utils/Errors.h) can be:
-    *  - NO_ERROR or ALREADY_EXISTS: successful initialization
-    *  - INVALID_OPERATION: AudioEffect is already initialized
-    *  - BAD_VALUE: invalid parameter
-    *  - NO_INIT: audio flinger or audio hardware not initialized
-    * */
             status_t    set(const effect_uuid_t *type,
                             const effect_uuid_t *uuid = NULL,
                             int32_t priority = 0,
@@ -418,6 +390,18 @@
                             audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
                             const AudioDeviceTypeAddr& device = {},
                             bool probe = false);
+    /*
+     * Same as above but with type and uuid specified by character strings.
+     */
+            status_t    set(const char *typeStr,
+                            const char *uuidStr = NULL,
+                            int32_t priority = 0,
+                            effect_callback_t cbf = NULL,
+                            void* user = NULL,
+                            audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+                            audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
+                            const AudioDeviceTypeAddr& device = {},
+                            bool probe = false);
 
     /* Result of constructing the AudioEffect. This must be checked
      * before using any AudioEffect API.
@@ -547,21 +531,20 @@
      static const uint32_t kMaxPreProcessing = 10;
 
 protected:
-     bool                    mEnabled;           // enable state
-     audio_session_t         mSessionId;         // audio session ID
-     int32_t                 mPriority;          // priority for effect control
-     status_t                mStatus;            // effect status
-     bool                    mProbe;             // effect created in probe mode: all commands
+     const String16          mOpPackageName;     // The package name used for app op checks.
+     bool                    mEnabled = false;   // enable state
+     audio_session_t         mSessionId = AUDIO_SESSION_OUTPUT_MIX; // audio session ID
+     int32_t                 mPriority = 0;      // priority for effect control
+     status_t                mStatus = NO_INIT;  // effect status
+     bool                    mProbe = false;     // effect created in probe mode: all commands
                                                  // are no ops because mIEffect is NULL
-     effect_callback_t       mCbf;               // callback function for status, control and
+     effect_callback_t       mCbf = nullptr;     // callback function for status, control and
                                                  // parameter changes notifications
-     void*                   mUserData;          // client context for callback function
-     effect_descriptor_t     mDescriptor;        // effect descriptor
-     int32_t                 mId;                // system wide unique effect engine instance ID
+     void*                   mUserData = nullptr;// client context for callback function
+     effect_descriptor_t     mDescriptor = {};   // effect descriptor
+     int32_t                 mId = -1;           // system wide unique effect engine instance ID
      Mutex                   mLock;              // Mutex for mEnabled access
-     Mutex                   mConstructLock;     // Mutex for integrality construction
 
-     String16                mOpPackageName;     // The package name used for app op checks.
 
      // IEffectClient
      virtual void controlStatusChanged(bool controlGranted);
@@ -586,22 +569,12 @@
         virtual void controlStatusChanged(bool controlGranted) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
-                {
-                    // Got the mConstructLock means the construction of AudioEffect
-                    // has finished, we should release the mConstructLock immediately.
-                    AutoMutex lock(effect->mConstructLock);
-                }
                 effect->controlStatusChanged(controlGranted);
             }
         }
         virtual void enableStatusChanged(bool enabled) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
-                {
-                    // Got the mConstructLock means the construction of AudioEffect
-                    // has finished, we should release the mConstructLock immediately.
-                    AutoMutex lock(effect->mConstructLock);
-                }
                 effect->enableStatusChanged(enabled);
             }
         }
@@ -612,11 +585,6 @@
                                      void *pReplyData) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
-                {
-                    // Got the mConstructLock means the construction of AudioEffect
-                    // has finished, we should release the mConstructLock immediately.
-                    AutoMutex lock(effect->mConstructLock);
-                }
                 effect->commandExecuted(
                     cmdCode, cmdSize, pCmdData, replySize, pReplyData);
             }
@@ -626,11 +594,6 @@
         virtual void binderDied(const wp<IBinder>& /*who*/) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
-                {
-                    // Got the mConstructLock means the construction of AudioEffect
-                    // has finished, we should release the mConstructLock immediately.
-                    AutoMutex lock(effect->mConstructLock);
-                }
                 effect->binderDied();
             }
         }
@@ -644,7 +607,7 @@
     sp<IEffect>             mIEffect;           // IEffect binder interface
     sp<EffectClient>        mIEffectClient;     // IEffectClient implementation
     sp<IMemory>             mCblkMemory;        // shared memory for deferred parameter setting
-    effect_param_cblk_t*    mCblk;              // control block for deferred parameter setting
+    effect_param_cblk_t*    mCblk = nullptr;    // control block for deferred parameter setting
     pid_t                   mClientPid = (pid_t)-1;
     uid_t                   mClientUid = (uid_t)-1;
 };
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index 548b080..a8e6c31 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -12,6 +12,12 @@
         "libaudio_system_headers",
         "libmedia_helper_headers",
     ],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library {
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 3dbe37d..e9b589d 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -22,6 +22,9 @@
 #include <media/DeviceDescriptorBase.h>
 #include <media/TypeConverter.h>
 
+#include <arpa/inet.h>
+#include <regex>
+
 namespace android {
 
 DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
@@ -34,6 +37,31 @@
 {
 }
 
+namespace {
+
+static const std::string SUPPRESSED = "SUPPRESSED";
+static const std::regex MAC_ADDRESS_REGEX("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
+
+bool isAddressSensitive(const std::string &address) {
+    if (std::regex_match(address, MAC_ADDRESS_REGEX)) {
+        return true;
+    }
+
+    sockaddr_storage ss4;
+    if (inet_pton(AF_INET, address.c_str(), &ss4) > 0) {
+        return true;
+    }
+
+    sockaddr_storage ss6;
+    if (inet_pton(AF_INET6, address.c_str(), &ss6) > 0) {
+        return true;
+    }
+
+    return false;
+}
+
+} // namespace
+
 DeviceDescriptorBase::DeviceDescriptorBase(const AudioDeviceTypeAddr &deviceTypeAddr) :
         AudioPort("", AUDIO_PORT_TYPE_DEVICE,
                   audio_is_output_device(deviceTypeAddr.mType) ? AUDIO_PORT_ROLE_SINK :
@@ -43,6 +71,12 @@
     if (mDeviceTypeAddr.mAddress.empty() && audio_is_remote_submix_device(mDeviceTypeAddr.mType)) {
         mDeviceTypeAddr.mAddress = "0";
     }
+    mIsAddressSensitive = isAddressSensitive(mDeviceTypeAddr.mAddress);
+}
+
+void DeviceDescriptorBase::setAddress(const std::string &address) {
+    mDeviceTypeAddr.mAddress = address;
+    mIsAddressSensitive = isAddressSensitive(address);
 }
 
 void DeviceDescriptorBase::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -130,10 +164,15 @@
     AudioPort::dump(dst, spaces, verbose);
 }
 
-std::string DeviceDescriptorBase::toString() const
+std::string DeviceDescriptorBase::toString(bool includeSensitiveInfo) const
 {
     std::stringstream sstream;
-    sstream << "type:0x" << std::hex << type() << ",@:" << mDeviceTypeAddr.mAddress;
+    sstream << "type:0x" << std::hex << type();
+    // IP and MAC address are sensitive information. The sensitive information will be suppressed
+    // is `includeSensitiveInfo` is false.
+    sstream << ",@:"
+            << (!includeSensitiveInfo && mIsAddressSensitive ? SUPPRESSED
+                                                             : mDeviceTypeAddr.mAddress);
     return sstream.str();
 }
 
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index af04721..c143c7e 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -42,7 +42,7 @@
 
     audio_devices_t type() const { return mDeviceTypeAddr.mType; }
     std::string address() const { return mDeviceTypeAddr.mAddress; }
-    void setAddress(const std::string &address) { mDeviceTypeAddr.mAddress = address; }
+    void setAddress(const std::string &address);
     const AudioDeviceTypeAddr& getDeviceTypeAddr() const { return mDeviceTypeAddr; }
 
     // AudioPortConfig
@@ -61,7 +61,14 @@
     void dump(std::string *dst, int spaces, int index,
               const char* extraInfo = nullptr, bool verbose = true) const;
     void log() const;
-    std::string toString() const;
+
+    /**
+     * Return a string to describe the DeviceDescriptor.
+     *
+     * @param includeSensitiveInfo sensitive information will be added when it is true.
+     * @return a string that can be used to describe the DeviceDescriptor.
+     */
+    std::string toString(bool includeSensitiveInfo = false) const;
 
     bool equals(const sp<DeviceDescriptorBase>& other) const;
 
@@ -70,6 +77,7 @@
 
 protected:
     AudioDeviceTypeAddr mDeviceTypeAddr;
+    bool mIsAddressSensitive;
     uint32_t mEncapsulationModes = 0;
     uint32_t mEncapsulationMetadataTypes = 0;
 };
diff --git a/media/libaudiohal/OWNERS b/media/libaudiohal/OWNERS
index 1456ab6..71b17e6 100644
--- a/media/libaudiohal/OWNERS
+++ b/media/libaudiohal/OWNERS
@@ -1,2 +1 @@
-krocard@google.com
 mnaganov@google.com
diff --git a/media/libaudiohal/impl/StreamPowerLog.h b/media/libaudiohal/impl/StreamPowerLog.h
index 5fd3912..f6a554b 100644
--- a/media/libaudiohal/impl/StreamPowerLog.h
+++ b/media/libaudiohal/impl/StreamPowerLog.h
@@ -19,6 +19,7 @@
 
 #include <audio_utils/clock.h>
 #include <audio_utils/PowerLog.h>
+#include <cutils/bitops.h>
 #include <cutils/properties.h>
 #include <system/audio.h>
 
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index ec56b00..1aacfd1 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -25,7 +25,6 @@
 
 #include <cutils/compiler.h>
 #include <cutils/properties.h>
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <audio_utils/primitives.h>
 
@@ -636,7 +635,7 @@
     const uint32_t phaseWrapLimit = c.mL << c.mShift;
     size_t inFrameCount = (phaseIncrement * (uint64_t)outFrameCount + phaseFraction)
             / phaseWrapLimit;
-    // sanity check that inFrameCount is in signed 32 bit integer range.
+    // validate that inFrameCount is in signed 32 bit integer range.
     ALOG_ASSERT(0 <= inFrameCount && inFrameCount < (1U << 31));
 
     //ALOGV("inFrameCount:%d  outFrameCount:%d"
@@ -646,7 +645,7 @@
     // NOTE: be very careful when modifying the code here. register
     // pressure is very high and a small change might cause the compiler
     // to generate far less efficient code.
-    // Always sanity check the result with objdump or test-resample.
+    // Always validate the result with objdump or test-resample.
 
     // the following logic is a bit convoluted to keep the main processing loop
     // as tight as possible with register allocation.
diff --git a/media/libaudioprocessing/AudioResamplerFirProcess.h b/media/libaudioprocessing/AudioResamplerFirProcess.h
index 9b70a1c..1fcffcc 100644
--- a/media/libaudioprocessing/AudioResamplerFirProcess.h
+++ b/media/libaudioprocessing/AudioResamplerFirProcess.h
@@ -381,7 +381,7 @@
     // NOTE: be very careful when modifying the code here. register
     // pressure is very high and a small change might cause the compiler
     // to generate far less efficient code.
-    // Always sanity check the result with objdump or test-resample.
+    // Always validate the result with objdump or test-resample.
 
     if (LOCKED) {
         // locked polyphase (no interpolation)
diff --git a/media/libaudioprocessing/AudioResamplerSinc.cpp b/media/libaudioprocessing/AudioResamplerSinc.cpp
index 5a03a0d..f2c386d 100644
--- a/media/libaudioprocessing/AudioResamplerSinc.cpp
+++ b/media/libaudioprocessing/AudioResamplerSinc.cpp
@@ -404,7 +404,7 @@
     // NOTE: be very careful when modifying the code here. register
     // pressure is very high and a small change might cause the compiler
     // to generate far less efficient code.
-    // Always sanity check the result with objdump or test-resample.
+    // Always validate the result with objdump or test-resample.
 
     // compute the index of the coefficient on the positive side and
     // negative side
diff --git a/media/libcpustats/ThreadCpuUsage.cpp b/media/libcpustats/ThreadCpuUsage.cpp
index 4b7549f..e71a7db 100644
--- a/media/libcpustats/ThreadCpuUsage.cpp
+++ b/media/libcpustats/ThreadCpuUsage.cpp
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <unistd.h>
 
 #include <utils/Log.h>
 
diff --git a/media/libeffects/OWNERS b/media/libeffects/OWNERS
index 7f9ae81..b7832ea 100644
--- a/media/libeffects/OWNERS
+++ b/media/libeffects/OWNERS
@@ -1,4 +1,3 @@
 hunga@google.com
-krocard@google.com
 mnaganov@google.com
 rago@google.com
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
index fcef36f..e23530e 100644
--- a/media/libeffects/factory/EffectsConfigLoader.c
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -394,7 +394,7 @@
        }
        sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
        effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
-       // Since we return a dummy descriptor for the proxy during
+       // Since we return a stub descriptor for the proxy during
        // get_descriptor call,we replace it with the correspoding
        // sw effect descriptor, but with Proxy UUID
        // check for Sw desc
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
index 505be7c..30a9007 100644
--- a/media/libeffects/factory/EffectsXmlConfigLoader.cpp
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -283,7 +283,7 @@
             }
             listPush(effectLoadResult.effectDesc.get(), subEffectList);
 
-            // Since we return a dummy descriptor for the proxy during
+            // Since we return a stub descriptor for the proxy during
             // get_descriptor call, we replace it with the corresponding
             // sw effect descriptor, but keep the Proxy UUID
             *effectLoadResult.effectDesc = *swEffectLoadResult.effectDesc;
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index 1f2a5e1..ee69cfb 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -30,7 +30,6 @@
         "Bundle/src/LVM_Control.cpp",
         "SpectrumAnalyzer/src/LVPSA_Control.cpp",
         "SpectrumAnalyzer/src/LVPSA_Init.cpp",
-        "SpectrumAnalyzer/src/LVPSA_Memory.cpp",
         "SpectrumAnalyzer/src/LVPSA_Process.cpp",
         "SpectrumAnalyzer/src/LVPSA_QPD_Init.cpp",
         "SpectrumAnalyzer/src/LVPSA_QPD_Process.cpp",
@@ -137,7 +136,6 @@
     ],
     cppflags: [
         "-fvisibility=hidden",
-        "-DSUPPORT_MC",
 
         "-Wall",
         "-Werror",
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index 948d79c..cb69c88 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -69,9 +69,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory table*/
-#define LVDBE_NR_MEMORY_REGIONS        4                            /* Number of memory regions */
-
 /* Bass Enhancement effect level */
 #define LVDBE_EFFECT_03DB            3                              /* Effect defines for backwards compatibility */
 #define LVDBE_EFFECT_06DB            6
@@ -112,25 +109,12 @@
     LVDBE_VOLUME_MAX = LVM_MAXINT_32
 } LVDBE_Volume_en;
 
-/* Memory Types */
-typedef enum
-{
-    LVDBE_PERSISTENT      = 0,
-    LVDBE_PERSISTENT_DATA = 1,
-    LVDBE_PERSISTENT_COEF = 2,
-    LVDBE_SCRATCH         = 3,
-    LVDBE_MEMORY_MAX      = LVM_MAXINT_32
-
-} LVDBE_MemoryTypes_en;
-
 /* Function return status */
 typedef enum
 {
     LVDBE_SUCCESS        = 0,                        /* Successful return from a routine */
-    LVDBE_ALIGNMENTERROR = 1,                        /* Memory alignment error */
-    LVDBE_NULLADDRESS    = 2,                        /* NULL allocation address */
-    LVDBE_TOOMANYSAMPLES = 3,                        /* Maximum block size exceeded */
-    LVDBE_SIZEERROR      = 4,                        /* Incorrect structure size */
+    LVDBE_NULLADDRESS    = 1,                        /* NULL allocation address */
+    LVDBE_TOOMANYSAMPLES = 2,                        /* Maximum block size exceeded */
     LVDBE_STATUS_MAX     = LVM_MAXINT_32
 } LVDBE_ReturnStatus_en;
 
@@ -213,21 +197,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory region definition */
-typedef struct
-{
-    LVM_UINT32                Size;                        /* Region size in bytes */
-    LVM_UINT16                Alignment;                  /* Region alignment in bytes */
-    LVDBE_MemoryTypes_en      Type;                       /* Region type */
-    void                      *pBaseAddress;              /* Pointer to the region base address */
-} LVDBE_MemoryRegion_t;
-
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVDBE_MemoryRegion_t    Region[LVDBE_NR_MEMORY_REGIONS];  /* One definition for each region */
-} LVDBE_MemTab_t;
-
 /* Parameter structure */
 typedef struct
 {
@@ -239,9 +208,7 @@
     LVDBE_Volume_en         VolumeControl;
     LVM_INT16               VolumedB;
     LVM_INT16               HeadroomdB;
-#ifdef SUPPORT_MC
     LVM_INT16               NrChannels;
-#endif
 
 } LVDBE_Params_t;
 
@@ -261,75 +228,40 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                 LVDBE_Memory                                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*    This function is used for memory allocation and free. It can be called in         */
-/*    two ways:                                                                         */
-/*                                                                                      */
-/*        hInstance = NULL                Returns the memory requirements               */
-/*        hInstance = Instance handle        Returns the memory requirements and        */
-/*                                        allocated base addresses for the instance     */
-/*                                                                                      */
-/*    When this function is called for memory allocation (hInstance=NULL) the memory    */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*    When the function is called for free (hInstance = Instance Handle) the memory     */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance                Instance Handle                                            */
-/*  pMemoryTable             Pointer to an empty memory definition table                */
-/*    pCapabilities            Pointer to the default capabilites                       */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVDBE_SUCCESS            Succeeded                                                  */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*    1.    This function may be interrupted by the LVDBE_Process function              */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t           hInstance,
-                                   LVDBE_MemTab_t           *pMemoryTable,
-                                   LVDBE_Capabilities_t     *pCapabilities);
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                 LVDBE_Init                                                 */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
 /*    Create and initialisation function for the Bass Enhancement module                */
 /*                                                                                      */
-/*    This function can be used to create an algorithm instance by calling with         */
-/*    hInstance set to NULL. In this case the algorithm returns the new instance        */
-/*    handle.                                                                           */
-/*                                                                                      */
-/*    This function can be used to force a full re-initialisation of the algorithm      */
-/*    by calling with hInstance = Instance Handle. In this case the memory table        */
-/*    should be correct for the instance, this can be ensured by calling the function   */
-/*    LVDBE_Memory before calling this function.                                        */
-/*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  hInstance                  Instance handle                                          */
-/*  pMemoryTable             Pointer to the memory definition table                     */
+/*  phInstance               Pointer to instance handle                                 */
 /*  pCapabilities            Pointer to the initialisation capabilities                 */
+/*  pScratch                 Pointer to the bundle scratch buffer                       */
 /*                                                                                      */
 /* RETURNS:                                                                             */
-/*  LVDBE_SUCCESS                Initialisation succeeded                               */
-/*  LVDBE_ALIGNMENTERROR        Instance or scratch memory on incorrect alignment       */
-/*    LVDBE_NULLADDRESS            One or more memory has a NULL pointer                */
+/*  LVDBE_SUCCESS            Initialisation succeeded                                   */
+/*  LVDBE_NULLADDRESS        One or more memory has a NULL pointer - malloc failure     */
 /*                                                                                      */
 /* NOTES:                                                                               */
-/*  1.     The instance handle is the pointer to the base address of the first memory   */
-/*        region.                                                                       */
-/*    2.    This function must not be interrupted by the LVDBE_Process function         */
+/*  1.    This function must not be interrupted by the LVDBE_Process function           */
 /*                                                                                      */
 /****************************************************************************************/
+LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t           *phInstance,
+                                 LVDBE_Capabilities_t     *pCapabilities,
+                                 void                     *pScratch);
 
-LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t             *phInstance,
-                                   LVDBE_MemTab_t           *pMemoryTable,
-                                   LVDBE_Capabilities_t     *pCapabilities);
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                 LVDBE_DeInit                                               */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*    Free the memories created during LVDBE_Init including instance handle             */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance               Pointer to instance handle                                 */
+/*                                                                                      */
+/****************************************************************************************/
+void LVDBE_DeInit(LVDBE_Handle_t         *phInstance);
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
index ad77696..bd03dd3 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
@@ -20,176 +20,60 @@
 /*    Includes                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
+#include <stdlib.h>
 
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                 LVDBE_Memory                                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*    This function is used for memory allocation and free. It can be called in         */
-/*    two ways:                                                                         */
-/*                                                                                      */
-/*        hInstance = NULL                Returns the memory requirements               */
-/*        hInstance = Instance handle        Returns the memory requirements and        */
-/*                                        allocated base addresses for the instance     */
-/*                                                                                      */
-/*    When this function is called for memory allocation (hInstance=NULL) the memory    */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*    When the function is called for free (hInstance = Instance Handle) the memory     */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance                Instance Handle                                            */
-/*  pMemoryTable             Pointer to an empty memory definition table                */
-/*    pCapabilities           Pointer to the instance capabilities                      */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVDBE_SUCCESS            Succeeded                                                  */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*    1.    This function may be interrupted by the LVDBE_Process function              */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t            hInstance,
-                                   LVDBE_MemTab_t            *pMemoryTable,
-                                   LVDBE_Capabilities_t      *pCapabilities)
-{
-
-    LVM_UINT32          ScratchSize;
-    LVDBE_Instance_t    *pInstance = (LVDBE_Instance_t *)hInstance;
-
-    /*
-     * Fill in the memory table
-     */
-    if (hInstance == LVM_NULL)
-    {
-        /*
-         * Instance memory
-         */
-        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Size         = sizeof(LVDBE_Instance_t);
-        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Alignment    = LVDBE_INSTANCE_ALIGN;
-        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Type         = LVDBE_PERSISTENT;
-        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
-
-        /*
-         * Data memory
-         */
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size   = sizeof(LVDBE_Data_FLOAT_t);
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment    = LVDBE_PERSISTENT_DATA_ALIGN;
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type         = LVDBE_PERSISTENT_DATA;
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
-
-        /*
-         * Coef memory
-         */
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size   = sizeof(LVDBE_Coef_FLOAT_t);
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment    = LVDBE_PERSISTENT_COEF_ALIGN;
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type         = LVDBE_PERSISTENT_COEF;
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
-
-        /*
-         * Scratch memory
-         */
-        ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT) * \
-                                        pCapabilities->MaxBlockSize);
-        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size         = ScratchSize;
-        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment    = LVDBE_SCRATCH_ALIGN;
-        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type         = LVDBE_SCRATCH;
-        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
-    }
-    else
-    {
-        /* Read back memory allocation table */
-        *pMemoryTable = pInstance->MemoryTable;
-    }
-
-    return(LVDBE_SUCCESS);
-}
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                 LVDBE_Init                                                 */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
-/*    Create and initialisation function for the Dynamic Bass Enhancement module        */
-/*                                                                                      */
-/*    This function can be used to create an algorithm instance by calling with         */
-/*    hInstance set to NULL. In this case the algorithm returns the new instance        */
-/*    handle.                                                                           */
-/*                                                                                      */
-/*    This function can be used to force a full re-initialisation of the algorithm      */
-/*    by calling with hInstance = Instance Handle. In this case the memory table        */
-/*    should be correct for the instance, this can be ensured by calling the function   */
-/*    DBE_Memory before calling this function.                                          */
+/*    Create and initialisation function for the Bass Enhancement module                */
 /*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  hInstance                  Instance handle                                          */
-/*  pMemoryTable             Pointer to the memory definition table                     */
-/*  pCapabilities              Pointer to the instance capabilities                     */
+/*  phInstance               Pointer to instance handle                                 */
+/*  pCapabilities            Pointer to the initialisation capabilities                 */
+/*  pScratch                 Pointer to the bundle scratch buffer                       */
 /*                                                                                      */
 /* RETURNS:                                                                             */
 /*  LVDBE_SUCCESS            Initialisation succeeded                                   */
-/*  LVDBE_ALIGNMENTERROR    Instance or scratch memory on incorrect alignment           */
-/*    LVDBE_NULLADDRESS        Instance or scratch memory has a NULL pointer            */
+/*  LVDBE_NULLADDRESS        One or more memory has a NULL pointer - malloc failure     */
 /*                                                                                      */
 /* NOTES:                                                                               */
-/*  1.     The instance handle is the pointer to the base address of the first memory   */
-/*        region.                                                                       */
-/*    2.    This function must not be interrupted by the LVDBE_Process function         */
+/*  1.    This function must not be interrupted by the LVDBE_Process function           */
 /*                                                                                      */
 /****************************************************************************************/
-
-LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t         *phInstance,
-                                   LVDBE_MemTab_t       *pMemoryTable,
-                                   LVDBE_Capabilities_t *pCapabilities)
+LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t       *phInstance,
+                                 LVDBE_Capabilities_t *pCapabilities,
+                                 void                 *pScratch)
 {
 
     LVDBE_Instance_t      *pInstance;
-    LVMixer3_1St_FLOAT_st       *pMixer_Instance;
-    LVMixer3_2St_FLOAT_st       *pBypassMixer_Instance;
+    LVMixer3_1St_FLOAT_st *pMixer_Instance;
+    LVMixer3_2St_FLOAT_st *pBypassMixer_Instance;
     LVM_FLOAT             MixGain;
-    LVM_INT16             i;
 
     /*
-     * Set the instance handle if not already initialised
+     * Create the instance handle if not already initialised
      */
     if (*phInstance == LVM_NULL)
     {
-        *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress;
+        *phInstance = calloc(1, sizeof(*pInstance));
+    }
+    if (*phInstance == LVM_NULL)
+    {
+        return LVDBE_NULLADDRESS;
     }
     pInstance =(LVDBE_Instance_t  *)*phInstance;
 
     /*
-     * Check the memory table for NULL pointers and incorrectly aligned data
-     */
-    for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++)
-    {
-        if (pMemoryTable->Region[i].Size!=0)
-        {
-            if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
-            {
-                return(LVDBE_NULLADDRESS);
-            }
-            if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
-                return(LVDBE_ALIGNMENTERROR);
-            }
-        }
-    }
-
-    /*
      * Save the memory table in the instance structure
      */
     pInstance->Capabilities = *pCapabilities;
 
-    /*
-     * Save the memory table in the instance structure
-     */
-    pInstance->MemoryTable = *pMemoryTable;
+    pInstance->pScratch = pScratch;
 
     /*
      * Set the default instance parameters
@@ -204,12 +88,18 @@
     pInstance->Params.VolumedB          =    0;
 
     /*
-     * Set pointer to data and coef memory
+     * Create pointer to data and coef memory
      */
-    pInstance->pData =
-         (LVDBE_Data_FLOAT_t *)pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress;
-    pInstance->pCoef =
-         (LVDBE_Coef_FLOAT_t *)pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress;
+    pInstance->pData = (LVDBE_Data_FLOAT_t *)calloc(1, sizeof(*(pInstance->pData)));
+    if (pInstance->pData == NULL)
+    {
+        return LVDBE_NULLADDRESS;
+    }
+    pInstance->pCoef = (LVDBE_Coef_FLOAT_t *)calloc(1, sizeof(*(pInstance->pCoef)));
+    if (pInstance->pCoef == NULL)
+    {
+        return LVDBE_NULLADDRESS;
+    }
 
     /*
      * Initialise the filters
@@ -278,3 +168,32 @@
 
     return(LVDBE_SUCCESS);
 }
+
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                 LVDBE_DeInit                                               */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*    Free the memories created during LVDBE_Init including instance handle             */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance               Pointer to instance handle                                 */
+/*                                                                                      */
+/****************************************************************************************/
+void LVDBE_DeInit(LVDBE_Handle_t *phInstance)
+{
+    LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *)*phInstance;
+    if (pInstance == LVM_NULL) {
+        return;
+    }
+    if (pInstance->pData != LVM_NULL) {
+        free(pInstance->pData);
+        pInstance->pData = LVM_NULL;
+    }
+    if (pInstance->pCoef != LVM_NULL) {
+        free(pInstance->pCoef);
+        pInstance->pCoef = LVM_NULL;
+    }
+    free(pInstance);
+    *phInstance = LVM_NULL;
+}
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index f3faaed..377d20e 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -47,24 +47,6 @@
 /* General */
 #define    LVDBE_INVALID            0xFFFF        /* Invalid init parameter */
 
-/* Memory */
-#define LVDBE_MEMREGION_INSTANCE         0       /* Offset to the instance memory region */
-#define LVDBE_MEMREGION_PERSISTENT_DATA  1       /* Offset to persistent data memory region */
-#define LVDBE_MEMREGION_PERSISTENT_COEF  2       /* Offset to persistent coefficient region */
-#define LVDBE_MEMREGION_SCRATCH          3       /* Offset to data scratch memory region */
-
-#define LVDBE_INSTANCE_ALIGN             4       /* 32-bit alignment for structures */
-#define LVDBE_PERSISTENT_DATA_ALIGN      4       /* 32-bit alignment for data */
-#define LVDBE_PERSISTENT_COEF_ALIGN      4       /* 32-bit alignment for coef */
-#define LVDBE_SCRATCH_ALIGN              4       /* 32-bit alignment for long data */
-
-#ifdef SUPPORT_MC
-/* Number of buffers required for inplace processing */
-#define LVDBE_SCRATCHBUFFERS_INPLACE     (LVM_MAX_CHANNELS * 3)
-#else
-#define LVDBE_SCRATCHBUFFERS_INPLACE     6       /* Number of buffers required for inplace processing */
-#endif
-
 #define LVDBE_MIXER_TC                   5       /* Mixer time  */
 #define LVDBE_BYPASS_MIXER_TC            100     /* Bypass mixer time */
 
@@ -100,13 +82,13 @@
 typedef struct
 {
     /* Public parameters */
-    LVDBE_MemTab_t                MemoryTable;        /* Instance memory allocation table */
     LVDBE_Params_t                Params;             /* Instance parameters */
     LVDBE_Capabilities_t        Capabilities;         /* Instance capabilities */
 
     /* Data and coefficient pointers */
     LVDBE_Data_FLOAT_t                *pData;                /* Instance data */
     LVDBE_Coef_FLOAT_t                *pCoef;                /* Instance coefficients */
+    void                        *pScratch;             /* scratch pointer */
 } LVDBE_Instance_t;
 
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
index b4a71c7..088de9f 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
@@ -81,18 +81,13 @@
   LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
 
   /*Extract number of Channels info*/
-#ifdef SUPPORT_MC
   // Mono passed in as stereo
   const LVM_INT32 NrChannels = pInstance->Params.NrChannels == 1
       ? 2 : pInstance->Params.NrChannels;
-#else
-  const LVM_INT32 NrChannels = 2; // FCC_2
-#endif
   const LVM_INT32 NrSamples = NrChannels * NrFrames;
 
   /* Space to store DBE path computation */
-  LVM_FLOAT * const pScratch =
-          (LVM_FLOAT *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
+  LVM_FLOAT * const pScratch = (LVM_FLOAT *)pInstance->pScratch;
 
   /*
    * Scratch for Mono path starts at offset of
@@ -136,33 +131,20 @@
      */
     if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
     {
-#ifdef SUPPORT_MC
       BQ_MC_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance, /* Filter instance      */
           pScratch, /* Source               */
           pScratch, /* Destination          */
           (LVM_INT16)NrFrames,
           (LVM_INT16)NrChannels);
-#else
-      BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
-          pScratch, /* Source               */
-          pScratch, /* Destination          */
-          (LVM_INT16)NrFrames);
-#endif
     }
 
     /*
      * Create the mono stream
      */
-#ifdef SUPPORT_MC
     FromMcToMono_Float(pScratch, /* Source */
         pMono, /* Mono destination */
         (LVM_INT16)NrFrames,  /* Number of frames */
         (LVM_INT16)NrChannels);
-#else
-    From2iToMono_Float(pScratch, /* Stereo source         */
-        pMono, /* Mono destination      */
-        (LVM_INT16)NrFrames);
-#endif
 
     /*
      * Apply the band pass filter
@@ -175,20 +157,12 @@
     /*
      * Apply the AGC and mix
      */
-#ifdef SUPPORT_MC
     AGC_MIX_VOL_Mc1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
         pScratch, /* Source         */
         pMono, /* Mono band pass source */
         pScratch, /* Destination    */
         NrFrames, /* Number of frames     */
         NrChannels); /* Number of channels     */
-#else
-    AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
-        pScratch, /* Stereo source         */
-        pMono, /* Mono band pass source */
-        pScratch, /* Stereo destination    */
-        NrFrames);
-#endif
 
     for (LVM_INT32 ii = 0; ii < NrSamples; ++ii) {
       //TODO: replace with existing clamping function
@@ -213,18 +187,11 @@
      * The algorithm is disabled but volume management is required to compensate for
      * headroom and volume (if enabled)
      */
-#ifdef SUPPORT_MC
     LVC_MixSoft_Mc_D16C31_SAT(&pInstance->pData->BypassVolume,
         pInData,
         pScratchVol,
         (LVM_INT16)NrFrames,
         (LVM_INT16)NrChannels);
-#else
-    LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
-        pInData,
-        pScratchVol,
-        (LVM_INT16)NrSamples); /* Left and right, really # samples */
-#endif
   } else {
     // clear bypass volume path
     memset(pScratchVol, 0, sizeof(*pScratchVol) * NrSamples);
@@ -233,19 +200,11 @@
   /*
    * Mix DBE processed path and bypass volume path
    */
-#ifdef SUPPORT_MC
   LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->pData->BypassMixer,
       pScratch,
       pScratchVol,
       pOutData,
       (LVM_INT16)NrFrames,
       (LVM_INT16)NrChannels);
-#else
-  LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
-      pScratch,
-      pScratchVol,
-      pOutData,
-      (LVM_INT16)NrSamples);
-#endif
   return LVDBE_SUCCESS;
 }
diff --git a/media/libeffects/lvm/lib/Bundle/lib/LVM.h b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
index e4e8450..783c3a0 100644
--- a/media/libeffects/lvm/lib/Bundle/lib/LVM.h
+++ b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
@@ -67,9 +67,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory table*/
-#define LVM_NR_MEMORY_REGIONS                 4     /* Number of memory regions */
-
 /* Concert Sound effect level presets */
 #define LVM_CS_EFFECT_NONE                    0     /* 0% effect, minimum value */
 #define LVM_CS_EFFECT_LOW                 16384     /* 50% effect */
@@ -225,12 +222,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVM_MemoryRegion_st         Region[LVM_NR_MEMORY_REGIONS];  /* One definition for each region */
-} LVM_MemTab_t;
-
 /* N-Band equaliser band definition */
 typedef struct
 {
@@ -285,10 +276,8 @@
     /* Spectrum Analyzer parameters Control */
     LVM_PSA_Mode_en             PSA_Enable;
     LVM_PSA_DecaySpeed_en       PSA_PeakDecayRate;      /* Peak value decay rate*/
-#ifdef SUPPORT_MC
     LVM_INT32                   NrChannels;
     LVM_INT32                   ChMask;
-#endif
 
 } LVM_ControlParams_t;
 
@@ -343,51 +332,14 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                LVM_GetMemoryTable                                          */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the memory       */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pInstParams             Pointer to the instance parameters                          */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVM_SUCCESS             Succeeded                                                   */
-/*  LVM_NULLADDRESS         When one of pMemoryTable or pInstParams is NULL             */
-/*  LVM_OUTOFRANGE          When any of the Instance parameters are out of range        */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVM_Process function                    */
-/*                                                                                      */
-/****************************************************************************************/
-LVM_ReturnStatus_en LVM_GetMemoryTable(LVM_Handle_t         hInstance,
-                                       LVM_MemTab_t         *pMemoryTable,
-                                       LVM_InstParams_t     *pInstParams);
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                LVM_GetInstanceHandle                                       */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
-/*  This function is used to create a bundle instance. It returns the created instance  */
-/*  handle through phInstance. All parameters are set to their default, inactive state. */
+/*  This function is used to create a bundle instance.                                  */
+/*  All parameters are set to their default, inactive state.                            */
 /*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  phInstance              pointer to the instance handle                              */
-/*  pMemoryTable            Pointer to the memory definition table                      */
+/*  phInstance              Pointer to the instance handle                              */
 /*  pInstParams             Pointer to the instance parameters                          */
 /*                                                                                      */
 /* RETURNS:                                                                             */
@@ -400,11 +352,27 @@
 /*                                                                                      */
 /****************************************************************************************/
 LVM_ReturnStatus_en LVM_GetInstanceHandle(LVM_Handle_t        *phInstance,
-                                          LVM_MemTab_t        *pMemoryTable,
                                           LVM_InstParams_t    *pInstParams);
 
 /****************************************************************************************/
 /*                                                                                      */
+/* FUNCTION:                LVM_DelInstanceHandle                                       */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*  This function is used to create a bundle instance. It returns the created instance  */
+/*  handle through phInstance. All parameters are set to their default, inactive state. */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance              Pointer to the instance handle                              */
+/*                                                                                      */
+/* NOTES:                                                                               */
+/*  1. This function must not be interrupted by the LVM_Process function                */
+/*                                                                                      */
+/****************************************************************************************/
+void LVM_DelInstanceHandle(LVM_Handle_t        *phInstance);
+
+/****************************************************************************************/
+/*                                                                                      */
 /* FUNCTION:                LVM_ClearAudioBuffers                                       */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.cpp
index 3aeddbb..4c25ce0 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.cpp
@@ -62,11 +62,7 @@
     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
     LVM_Buffer_t     *pBuffer;
     LVM_FLOAT        *pDest;
-#ifdef SUPPORT_MC
     LVM_INT16        NumChannels = pInstance->NrChannels;
-#else
-    LVM_INT16        NumChannels = 2;
-#endif
 
     /*
      * Set the processing address pointers
@@ -388,11 +384,9 @@
     LVM_INT16       NumSamples;
     LVM_FLOAT       *pStart;
     LVM_FLOAT       *pDest;
-#ifdef SUPPORT_MC
     LVM_INT32       NrChannels = pInstance->NrChannels;
 #define NrFrames NumSamples  // alias for clarity
 #define FrameCount SampleCount
-#endif
 
     /*
      * Set the pointers
@@ -426,25 +420,15 @@
             /*
              * Copy all output delay samples to the output
              */
-#ifdef SUPPORT_MC
             Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
                        pDest,                                      /* Destination */
                        /* Number of delay samples */
                        (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
-#else
-            Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
-                       pDest,                                      /* Destination */
-                       (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
-#endif
 
             /*
              * Update the pointer and sample counts
              */
-#ifdef SUPPORT_MC
             pDest += NrChannels * pBuffer->OutDelaySamples; /* Output sample pointer */
-#else
-            pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
-#endif
             NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
                                                                                 to send */
             pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
@@ -454,40 +438,24 @@
             /*
              * Copy only some of the ouput delay samples to the output
              */
-#ifdef SUPPORT_MC
             Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
                        pDest,                                          /* Destination */
                        (LVM_INT16)(NrChannels * NrFrames));       /* Number of delay samples */
-#else
-            Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
-                       pDest,                                          /* Destination */
-                       (LVM_INT16)(2 * NumSamples));       /* Number of delay samples */
-#endif
 
             /*
              * Update the pointer and sample counts
              */
-#ifdef SUPPORT_MC
             pDest += NrChannels * NrFrames; /* Output sample pointer */
-#else
-            pDest += 2 * NumSamples; /* Output sample pointer */
-#endif
             /* No samples left in the buffer */
             pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
 
             /*
              * Realign the delay buffer data to avoid using circular buffer management
              */
-#ifdef SUPPORT_MC
             Copy_Float(&pBuffer->OutDelayBuffer[NrChannels * NrFrames],         /* Source */
                        &pBuffer->OutDelayBuffer[0],                    /* Destination */
                        /* Number of samples to move */
                        (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
-#else
-            Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples],         /* Source */
-                       &pBuffer->OutDelayBuffer[0],                    /* Destination */
-                       (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
-#endif
             NumSamples = 0;                                /* Samples left to send */
         }
     }
@@ -503,23 +471,13 @@
             /*
              * Copy all processed samples to the output
              */
-#ifdef SUPPORT_MC
             Copy_Float(pStart,                                      /* Source */
                        pDest,                                       /* Destination */
                        (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
-#else
-            Copy_Float(pStart,                                      /* Source */
-                       pDest,                                       /* Destination */
-                       (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
-#endif
             /*
              * Update the pointer and sample counts
              */
-#ifdef SUPPORT_MC
             pDest      += NrChannels * FrameCount;                 /* Output sample pointer */
-#else
-            pDest      += 2 * SampleCount;                          /* Output sample pointer */
-#endif
             NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
             SampleCount = 0; /* No samples left in the buffer */
         }
@@ -528,25 +486,14 @@
             /*
              * Copy only some processed samples to the output
              */
-#ifdef SUPPORT_MC
             Copy_Float(pStart,                                         /* Source */
                        pDest,                                          /* Destination */
                        (LVM_INT16)(NrChannels * NrFrames));  /* Number of processed samples */
-#else
-            Copy_Float(pStart,                                         /* Source */
-                       pDest,                                          /* Destination */
-                       (LVM_INT16)(2 * NumSamples));     /* Number of processed samples */
-#endif
             /*
              * Update the pointers and sample counts
                */
-#ifdef SUPPORT_MC
             pStart      += NrChannels * NrFrames;               /* Processed sample pointer */
             pDest       += NrChannels * NrFrames;               /* Output sample pointer */
-#else
-            pStart      += 2 * NumSamples;                        /* Processed sample pointer */
-            pDest       += 2 * NumSamples;                        /* Output sample pointer */
-#endif
             SampleCount  = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
             NumSamples   = 0;                                     /* Clear the sample count */
         }
@@ -557,16 +504,10 @@
      */
     if (SampleCount != 0)
     {
-#ifdef SUPPORT_MC
         Copy_Float(pStart,                                                 /* Source */
                    /* Destination */
                    &pBuffer->OutDelayBuffer[NrChannels * pBuffer->OutDelaySamples],
                    (LVM_INT16)(NrChannels * FrameCount));      /* Number of processed samples */
-#else
-        Copy_Float(pStart,                                                 /* Source */
-                   &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
-                   (LVM_INT16)(2 * SampleCount));               /* Number of processed samples */
-#endif
         /* Update the buffer count */
         pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
     }
@@ -606,7 +547,6 @@
 {
 
     LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
-#ifdef SUPPORT_MC
     LVM_INT16           NumChannels = pInstance->NrChannels;
     if (NumChannels == 1)
     {
@@ -615,19 +555,12 @@
     }
 #undef NrFrames
 #define NrFrames (*pNumSamples) // alias for clarity
-#else
-    LVM_INT16           NumChannels = 2;
-#endif
 
     /*
      * Update sample counts
      */
     pInstance->pInputSamples    += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
-#ifdef SUPPORT_MC
     pInstance->pOutputSamples   += (LVM_INT16)(NrFrames * NumChannels);
-#else
-    pInstance->pOutputSamples   += (LVM_INT16)(*pNumSamples * 2);
-#endif
     pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
 
     /*
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
index ff2c90a..bb3652e 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
@@ -70,23 +70,17 @@
      (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)      &&
      (pParams->SampleRate != LVM_FS_88200) && (pParams->SampleRate != LVM_FS_96000) &&
      (pParams->SampleRate != LVM_FS_176400) && (pParams->SampleRate != LVM_FS_192000))      ||
-#ifdef SUPPORT_MC
         ((pParams->SourceFormat != LVM_STEREO) &&
          (pParams->SourceFormat != LVM_MONOINSTEREO) &&
          (pParams->SourceFormat != LVM_MONO) &&
          (pParams->SourceFormat != LVM_MULTICHANNEL)) ||
-#else
-        ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) ||
-#endif
         (pParams->SpeakerType > LVM_EX_HEADPHONES))
     {
         return (LVM_OUTOFRANGE);
     }
 
-#ifdef SUPPORT_MC
     pInstance->Params.NrChannels = pParams->NrChannels;
     pInstance->Params.ChMask     = pParams->ChMask;
-#endif
     /*
      * Cinema Sound parameters
      */
@@ -528,10 +522,8 @@
     } while ((pInstance->ControlPending != LVM_FALSE) &&
              (Count > 0));
 
-#ifdef SUPPORT_MC
     pInstance->NrChannels = LocalParams.NrChannels;
     pInstance->ChMask = LocalParams.ChMask;
-#endif
 
     /* Clear all internal data if format change*/
     if(LocalParams.SourceFormat != pInstance->Params.SourceFormat)
@@ -638,9 +630,7 @@
         DBE_Params.HeadroomdB       = 0;
         DBE_Params.VolumeControl    = LVDBE_VOLUME_OFF;
         DBE_Params.VolumedB         = 0;
-#ifdef SUPPORT_MC
         DBE_Params.NrChannels         = LocalParams.NrChannels;
-#endif
 
         /*
          * Make the changes
@@ -690,7 +680,6 @@
         {
             EQNB_Params.SourceFormat = LVEQNB_STEREO;
         }
-#ifdef SUPPORT_MC
         /* Note: Currently SourceFormat field of EQNB is not been
          *       used by the module.
          */
@@ -698,14 +687,11 @@
         {
             EQNB_Params.SourceFormat = LVEQNB_MULTICHANNEL;
         }
-#endif
         else
         {
             EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO;     /* Force to Mono-in-Stereo mode */
         }
-#ifdef SUPPORT_MC
         EQNB_Params.NrChannels         = LocalParams.NrChannels;
-#endif
 
         /*
          * Set the control flag
@@ -766,16 +752,12 @@
             CS_Params.SpeakerType  = LVCS_HEADPHONES;
         }
 
-#ifdef SUPPORT_MC
         /* Concert sound module processes only the left and right channels
          * data. So the Source Format is set to LVCS_STEREO for multichannel
          * input also.
          */
         if (LocalParams.SourceFormat == LVM_STEREO ||
             LocalParams.SourceFormat == LVM_MULTICHANNEL)
-#else
-        if (LocalParams.SourceFormat == LVM_STEREO)    /* Mono format not supported */
-#endif
         {
             CS_Params.SourceFormat = LVCS_STEREO;
         }
@@ -786,9 +768,7 @@
         CS_Params.SampleRate  = LocalParams.SampleRate;
         CS_Params.ReverbLevel = LocalParams.VirtualizerReverbLevel;
         CS_Params.EffectLevel = LocalParams.CS_EffectLevel;
-#ifdef SUPPORT_MC
         CS_Params.NrChannels  = LocalParams.NrChannels;
-#endif
 
         /*
          * Set the control flag
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
index 5620529..58c18dd 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
@@ -20,6 +20,7 @@
 /*  Includes                                                                        */
 /*                                                                                  */
 /************************************************************************************/
+#include <stdlib.h>
 
 #include "LVM_Private.h"
 #include "LVM_Tables.h"
@@ -28,479 +29,31 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                LVM_GetMemoryTable                                          */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the memory       */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pCapabilities           Pointer to the default capabilities                         */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVM_SUCCESS             Succeeded                                                   */
-/*  LVM_NULLADDRESS         When one of pMemoryTable or pInstParams is NULL             */
-/*  LVM_OUTOFRANGE          When any of the Instance parameters are out of range        */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVM_Process function                    */
-/*  2.  The scratch memory is the largest required by any of the sub-modules plus any   */
-/*      additional scratch requirements of the bundle                                   */
-/*                                                                                      */
-/****************************************************************************************/
-
-/*
- * 4 Types of Memory Regions of LVM
- * TODO: Allocate on the fly.
- * i)   LVM_MEMREGION_PERSISTENT_SLOW_DATA - For Instance Handles
- * ii)  LVM_MEMREGION_PERSISTENT_FAST_DATA - Persistent Buffers
- * iii) LVM_MEMREGION_PERSISTENT_FAST_COEF - For Holding Structure values
- * iv)  LVM_MEMREGION_TEMPORARY_FAST       - For Holding Structure values
- *
- * LVM_MEMREGION_PERSISTENT_SLOW_DATA:
- *   Total Memory size:
- *     sizeof(LVM_Instance_t) + \
- *     sizeof(LVM_Buffer_t) + \
- *     sizeof(LVPSA_InstancePr_t) + \
- *     sizeof(LVM_Buffer_t) - needed if buffer mode is LVM_MANAGED_BUFFER
- *
- * LVM_MEMREGION_PERSISTENT_FAST_DATA:
- *   Total Memory size:
- *     sizeof(LVM_TE_Data_t) + \
- *     2 * pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t) + \
- *     sizeof(LVCS_Data_t) + \
- *     sizeof(LVDBE_Data_FLOAT_t) + \
- *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
- *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
- *     pInstParams->EQNB_NumBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
- *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BandDef_t) + \
- *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BiquadType_en) + \
- *     2 * LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t) + \
- *     PSA_InitParams.nBands * sizeof(Biquad_1I_Order2_Taps_t) + \
- *     PSA_InitParams.nBands * sizeof(QPD_Taps_t)
- *
- * LVM_MEMREGION_PERSISTENT_FAST_COEF:
- *   Total Memory size:
- *     sizeof(LVM_TE_Coefs_t) + \
- *     sizeof(LVCS_Coefficient_t) + \
- *     sizeof(LVDBE_Coef_FLOAT_t) + \
- *     sizeof(Biquad_FLOAT_Instance_t) + \
- *     sizeof(Biquad_FLOAT_Instance_t) + \
- *     pInstParams->EQNB_NumBands * sizeof(Biquad_FLOAT_Instance_t) + \
- *     PSA_InitParams.nBands * sizeof(Biquad_Instance_t) + \
- *     PSA_InitParams.nBands * sizeof(QPD_State_t)
- *
- * LVM_MEMREGION_TEMPORARY_FAST (Scratch):
- *   Total Memory Size:
- *     BundleScratchSize + \
- *     MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT) + \
- *     MaxScratchOf (CS, EQNB, DBE, PSA)
- *
- *     a)BundleScratchSize:
- *         3 * LVM_MAX_CHANNELS \
- *         * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_FLOAT)
- *       This Memory is allocated only when Buffer mode is LVM_MANAGED_BUFFER.
- *     b)MaxScratchOf (CS, EQNB, DBE, PSA)
- *       This Memory is needed for scratch usage for CS, EQNB, DBE, PSA.
- *       CS   = (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
- *               * pCapabilities->MaxBlockSize)
- *       EQNB = (LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
- *               * pCapabilities->MaxBlockSize)
- *       DBE  = (LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT)
- *               * pCapabilities->MaxBlockSize)
- *       PSA  = (2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT))
- *              one MaxInputBlockSize for input and another for filter output
- *     c)MAX_INTERNAL_BLOCKSIZE
- *       This Memory is needed for PSAInput - Temp memory to store output
- *       from McToMono block and given as input to PSA block
- */
-
-LVM_ReturnStatus_en LVM_GetMemoryTable(LVM_Handle_t         hInstance,
-                                       LVM_MemTab_t         *pMemoryTable,
-                                       LVM_InstParams_t     *pInstParams)
-{
-
-    LVM_Instance_t      *pInstance = (LVM_Instance_t *)hInstance;
-    LVM_UINT32          AlgScratchSize;
-    LVM_UINT32          BundleScratchSize;
-    LVM_UINT16          InternalBlockSize;
-    INST_ALLOC          AllocMem[LVM_NR_MEMORY_REGIONS];
-    LVM_INT16           i;
-
-    /*
-     * Check parameters
-     */
-    if(pMemoryTable == LVM_NULL)
-    {
-        return LVM_NULLADDRESS;
-    }
-
-    /*
-     * Return memory table if the instance has already been created
-     */
-    if (hInstance != LVM_NULL)
-    {
-       /* Read back memory allocation table */
-        *pMemoryTable = pInstance->MemoryTable;
-        return(LVM_SUCCESS);
-    }
-
-    if(pInstParams == LVM_NULL)
-    {
-        return LVM_NULLADDRESS;
-    }
-
-    /*
-     *  Power Spectrum Analyser
-     */
-    if(pInstParams->PSA_Included > LVM_PSA_ON)
-    {
-        return (LVM_OUTOFRANGE);
-    }
-
-    /*
-     * Check the instance parameters
-     */
-    if( (pInstParams->BufferMode != LVM_MANAGED_BUFFERS) && (pInstParams->BufferMode != LVM_UNMANAGED_BUFFERS) )
-    {
-        return (LVM_OUTOFRANGE);
-    }
-
-    /* N-Band Equalizer */
-    if( pInstParams->EQNB_NumBands > 32 )
-    {
-        return (LVM_OUTOFRANGE);
-    }
-
-    if(pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
-    {
-        if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_MANAGED_MAX_MAXBLOCKSIZE ) )
-        {
-            return (LVM_OUTOFRANGE);
-        }
-    }
-    else
-    {
-        if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_UNMANAGED_MAX_MAXBLOCKSIZE) )
-        {
-            return (LVM_OUTOFRANGE);
-        }
-    }
-
-    /*
-    * Initialise the AllocMem structures
-    */
-    for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
-    {
-        InstAlloc_Init(&AllocMem[i], LVM_NULL);
-    }
-    InternalBlockSize = (LVM_UINT16)((pInstParams->MaxBlockSize) & MIN_INTERNAL_BLOCKMASK); /* Force to a multiple of MIN_INTERNAL_BLOCKSIZE */
-
-    if (InternalBlockSize < MIN_INTERNAL_BLOCKSIZE)
-    {
-        InternalBlockSize = MIN_INTERNAL_BLOCKSIZE;
-    }
-
-    /* Maximum Internal Black Size should not be more than MAX_INTERNAL_BLOCKSIZE*/
-    if(InternalBlockSize > MAX_INTERNAL_BLOCKSIZE)
-    {
-        InternalBlockSize = MAX_INTERNAL_BLOCKSIZE;
-    }
-
-    /*
-    * Bundle requirements
-    */
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-        sizeof(LVM_Instance_t));
-
-    /*
-     * Set the algorithm and bundle scratch requirements
-     */
-    AlgScratchSize    = 0;
-    if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
-    {
-        BundleScratchSize = 3 * LVM_MAX_CHANNELS \
-                            * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
-                            * sizeof(LVM_FLOAT);
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],        /* Scratch buffer */
-                            BundleScratchSize);
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-                            sizeof(LVM_Buffer_t));
-    }
-
-    /*
-     * Treble Enhancement requirements
-     */
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                        sizeof(LVM_TE_Data_t));
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                        sizeof(LVM_TE_Coefs_t));
-
-    /*
-     * N-Band Equalizer requirements
-     */
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],      /* Local storage */
-                        (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],      /* User storage */
-                        (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
-
-    /*
-     * Concert Sound requirements
-     */
-    {
-        LVCS_MemTab_t           CS_MemTab;
-        LVCS_Capabilities_t     CS_Capabilities;
-
-        /*
-         * Set the capabilities
-         */
-        CS_Capabilities.MaxBlockSize     = InternalBlockSize;
-
-        /*
-         * Get the memory requirements
-         */
-        LVCS_Memory(LVM_NULL,
-                    &CS_MemTab,
-                    &CS_Capabilities);
-
-        /*
-         * Update the memory allocation structures
-         */
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                            CS_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                            CS_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
-        if (CS_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = CS_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
-
-    }
-
-    /*
-     * Dynamic Bass Enhancement requirements
-     */
-    {
-        LVDBE_MemTab_t          DBE_MemTab;
-        LVDBE_Capabilities_t    DBE_Capabilities;
-
-        /*
-         * Set the capabilities
-         */
-        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
-                                           LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
-                                           LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
-                                           LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
-                                           LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
-                                           LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
-                                           LVDBE_CAP_FS_192000;
-        DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
-        DBE_Capabilities.MaxBlockSize    = InternalBlockSize;
-
-        /*
-         * Get the memory requirements
-         */
-        LVDBE_Memory(LVM_NULL,
-                    &DBE_MemTab,
-
-                    &DBE_Capabilities);
-        /*
-         * Update the bundle table
-         */
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                            DBE_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                            DBE_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
-        if (DBE_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = DBE_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
-
-    }
-
-    /*
-     * N-Band equaliser requirements
-     */
-    {
-        LVEQNB_MemTab_t         EQNB_MemTab;            /* For N-Band Equaliser */
-        LVEQNB_Capabilities_t   EQNB_Capabilities;
-
-        /*
-         * Set the capabilities
-         */
-        EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
-                                         LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
-                                         LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
-                                         LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
-                                         LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
-                                         LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
-                                         LVEQNB_CAP_FS_192000;
-        EQNB_Capabilities.SourceFormat = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
-        EQNB_Capabilities.MaxBlockSize = InternalBlockSize;
-        EQNB_Capabilities.MaxBands     = pInstParams->EQNB_NumBands;
-
-        /*
-         * Get the memory requirements
-         */
-        LVEQNB_Memory(LVM_NULL,
-                      &EQNB_MemTab,
-                      &EQNB_Capabilities);
-
-        /*
-         * Update the bundle table
-         */
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                            EQNB_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
-        InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                            EQNB_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
-        if (EQNB_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = EQNB_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
-
-    }
-
-    /*
-     * Headroom management memory allocation
-     */
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                       (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                       (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
-
-    /*
-     * Spectrum Analyzer memory requirements
-     */
-    {
-        pLVPSA_Handle_t     hPSAInst = LVM_NULL;
-        LVPSA_MemTab_t      PSA_MemTab;
-        LVPSA_InitParams_t  PSA_InitParams;
-        LVPSA_FilterParam_t FiltersParams[9];
-        LVPSA_RETURN        PSA_Status;
-
-        if(pInstParams->PSA_Included == LVM_PSA_ON)
-        {
-            PSA_InitParams.SpectralDataBufferDuration   = (LVM_UINT16) 500;
-            PSA_InitParams.MaxInputBlockSize            = (LVM_UINT16) 1000;
-            PSA_InitParams.nBands                       = (LVM_UINT16) 9;
-
-            PSA_InitParams.pFiltersParams = &FiltersParams[0];
-            for(i = 0; i < PSA_InitParams.nBands; i++)
-            {
-                FiltersParams[i].CenterFrequency    = (LVM_UINT16) 1000;
-                FiltersParams[i].QFactor            = (LVM_UINT16) 25;
-                FiltersParams[i].PostGain           = (LVM_INT16)  0;
-            }
-
-            /*
-            * Get the memory requirements
-            */
-            PSA_Status = LVPSA_Memory (hPSAInst,
-                                        &PSA_MemTab,
-                                        &PSA_InitParams);
-
-            if (PSA_Status != LVPSA_OK)
-            {
-                return((LVM_ReturnStatus_en) LVM_ALGORITHMPSA);
-            }
-
-            /*
-            * Update the bundle table
-            */
-            /* Slow Data */
-            InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-                PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].Size);
-
-            /* Fast Data */
-            InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].Size);
-
-            /* Fast Coef */
-            InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
-
-            /* Fast Temporary */
-            InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
-                                MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT));
-
-            if (PSA_MemTab.Region[LVM_TEMPORARY_FAST].Size > AlgScratchSize)
-            {
-                AlgScratchSize = PSA_MemTab.Region[LVM_TEMPORARY_FAST].Size;
-            }
-        }
-    }
-
-    /*
-     * Return the memory table
-     */
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA]);
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].Type         = LVM_PERSISTENT_SLOW_DATA;
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = LVM_NULL;
-
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA]);
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Type         = LVM_PERSISTENT_FAST_DATA;
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress = LVM_NULL;
-    if (pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size < 4)
-    {
-        pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size = 0;
-    }
-
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF]);
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Type         = LVM_PERSISTENT_FAST_COEF;
-    pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
-    if (pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size < 4)
-    {
-        pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size = 0;
-    }
-
-    InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
-                        AlgScratchSize);
-    pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size             = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST]);
-    pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Type             = LVM_TEMPORARY_FAST;
-    pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].pBaseAddress     = LVM_NULL;
-    if (pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size < 4)
-    {
-        pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size = 0;
-    }
-
-    return(LVM_SUCCESS);
-
-}
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                LVM_GetInstanceHandle                                       */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
-/*  This function is used to create a bundle instance. It returns the created instance  */
-/*  handle through phInstance. All parameters are set to their default, inactive state. */
+/*  This function is used to create a bundle instance.                                  */
+/*  All parameters are set to their default, inactive state.                            */
 /*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  phInstance              pointer to the instance handle                              */
-/*  pMemoryTable            Pointer to the memory definition table                      */
-/*  pInstParams             Pointer to the initialisation capabilities                  */
+/*  phInstance              Pointer to the instance handle                              */
+/*  pInstParams             Pointer to the instance parameters                          */
 /*                                                                                      */
 /* RETURNS:                                                                             */
 /*  LVM_SUCCESS             Initialisation succeeded                                    */
+/*  LVM_NULLADDRESS         One or more memory has a NULL pointer                       */
 /*  LVM_OUTOFRANGE          When any of the Instance parameters are out of range        */
-/*  LVM_NULLADDRESS         When one of phInstance, pMemoryTable or pInstParams are NULL*/
 /*                                                                                      */
 /* NOTES:                                                                               */
 /*  1. This function must not be interrupted by the LVM_Process function                */
 /*                                                                                      */
 /****************************************************************************************/
-
 LVM_ReturnStatus_en LVM_GetInstanceHandle(LVM_Handle_t           *phInstance,
-                                          LVM_MemTab_t           *pMemoryTable,
                                           LVM_InstParams_t       *pInstParams)
 {
 
     LVM_ReturnStatus_en     Status = LVM_SUCCESS;
     LVM_Instance_t          *pInstance;
-    INST_ALLOC              AllocMem[LVM_NR_MEMORY_REGIONS];
     LVM_INT16               i;
     LVM_UINT16              InternalBlockSize;
     LVM_INT32               BundleScratchSize;
@@ -508,24 +61,12 @@
     /*
      * Check valid points have been given
      */
-    if ((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pInstParams == LVM_NULL))
+    if ((phInstance == LVM_NULL) || (pInstParams == LVM_NULL))
     {
         return (LVM_NULLADDRESS);
     }
 
     /*
-     * Check the memory table for NULL pointers
-     */
-    for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
-    {
-        if ((pMemoryTable->Region[i].Size != 0) &&
-            (pMemoryTable->Region[i].pBaseAddress==LVM_NULL))
-        {
-            return(LVM_NULLADDRESS);
-        }
-    }
-
-    /*
      * Check the instance parameters
      */
     if( (pInstParams->BufferMode != LVM_MANAGED_BUFFERS) && (pInstParams->BufferMode != LVM_UNMANAGED_BUFFERS) )
@@ -559,29 +100,19 @@
     }
 
     /*
-     * Initialise the AllocMem structures
+     * Create the instance handle
      */
-    for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
+    *phInstance  = (LVM_Handle_t)calloc(1, sizeof(*pInstance));
+    if (*phInstance == LVM_NULL)
     {
-        InstAlloc_Init(&AllocMem[i],
-                       pMemoryTable->Region[i].pBaseAddress);
+        return LVM_NULLADDRESS;
     }
+    pInstance = (LVM_Instance_t  *)*phInstance;
+
+    pInstance->InstParams = *pInstParams;
 
     /*
-     * Set the instance handle
-     */
-    *phInstance  = (LVM_Handle_t)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-                                                     sizeof(LVM_Instance_t));
-    pInstance =(LVM_Instance_t  *)*phInstance;
-
-    /*
-     * Save the memory table, parameters and capabilities
-     */
-    pInstance->MemoryTable    = *pMemoryTable;
-    pInstance->InstParams     = *pInstParams;
-
-    /*
-     * Set the bundle scratch memory and initialse the buffer management
+     * Create the bundle scratch memory and initialse the buffer management
      */
     InternalBlockSize = (LVM_UINT16)((pInstParams->MaxBlockSize) & MIN_INTERNAL_BLOCKMASK); /* Force to a multiple of MIN_INTERNAL_BLOCKSIZE */
     if (InternalBlockSize < MIN_INTERNAL_BLOCKSIZE)
@@ -600,23 +131,31 @@
      * Common settings for managed and unmanaged buffers
      */
     pInstance->SamplesToProcess = 0;                /* No samples left to process */
+    BundleScratchSize = (LVM_INT32)
+                        (3 * LVM_MAX_CHANNELS \
+                         * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
+                         * sizeof(LVM_FLOAT));
+    pInstance->pScratch = calloc(1, BundleScratchSize);
+    if (pInstance->pScratch == LVM_NULL)
+    {
+        return LVM_NULLADDRESS;
+    }
+
     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
     {
         /*
          * Managed buffers required
          */
         pInstance->pBufferManagement = (LVM_Buffer_t *)
-            InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-                                                           sizeof(LVM_Buffer_t));
-        BundleScratchSize = (LVM_INT32)
-                            (3 * LVM_MAX_CHANNELS \
-                             * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
-                             * sizeof(LVM_FLOAT));
-        pInstance->pBufferManagement->pScratch = (LVM_FLOAT *)
-            InstAlloc_AddMember(
-                         &AllocMem[LVM_MEMREGION_TEMPORARY_FAST], /* Scratch 1 buffer */
-                                                  (LVM_UINT32)BundleScratchSize);
-        LoadConst_Float(0,                                   /* Clear the input delay buffer */
+                    calloc(1, sizeof(*(pInstance->pBufferManagement)));
+        if (pInstance->pBufferManagement == LVM_NULL)
+        {
+            return LVM_NULLADDRESS;
+        }
+
+        pInstance->pBufferManagement->pScratch = (LVM_FLOAT *)pInstance->pScratch;
+
+        LoadConst_Float(0, /* Clear the input delay buffer */
                         (LVM_FLOAT *)&pInstance->pBufferManagement->InDelayBuffer,
                         (LVM_INT16)(LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE));
         pInstance->pBufferManagement->InDelaySamples = MIN_INTERNAL_BLOCKSIZE; /* Set the number of delay samples */
@@ -642,20 +181,21 @@
     /*
      * DC removal filter
      */
-#ifdef SUPPORT_MC
     DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-#else
-    DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-#endif
 
     /*
      * Treble Enhancement
      */
-    pInstance->pTE_Taps  = (LVM_TE_Data_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                                                sizeof(LVM_TE_Data_t));
-
-    pInstance->pTE_State = (LVM_TE_Coefs_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                                                                 sizeof(LVM_TE_Coefs_t));
+    pInstance->pTE_Taps  = (LVM_TE_Data_t *)calloc(1, sizeof(*(pInstance->pTE_Taps)));
+    if (pInstance->pTE_Taps == LVM_NULL)
+    {
+        return LVM_NULLADDRESS;
+    }
+    pInstance->pTE_State = (LVM_TE_Coefs_t *)calloc(1, sizeof(*(pInstance->pTE_State)));
+    if (pInstance->pTE_State == LVM_NULL)
+    {
+        return LVM_NULLADDRESS;
+    }
     pInstance->Params.TE_OperatingMode = LVM_TE_OFF;
     pInstance->Params.TE_EffectLevel   = 0;
     pInstance->TE_Active               = LVM_FALSE;
@@ -699,21 +239,26 @@
     LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
 
     /*
-     * Set the default EQNB pre-gain and pointer to the band definitions
+     * Create the default EQNB pre-gain and pointer to the band definitions
      */
-    pInstance->pEQNB_BandDefs =
-        (LVM_EQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                   (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
-    pInstance->pEQNB_UserDefs =
-        (LVM_EQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                   (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
+    pInstance->pEQNB_BandDefs = (LVM_EQNB_BandDef_t *)
+        calloc(pInstParams->EQNB_NumBands, sizeof(*(pInstance->pEQNB_BandDefs)));
+    if (pInstance->pEQNB_BandDefs == LVM_NULL)
+    {
+        return LVM_NULLADDRESS;
+    }
+    pInstance->pEQNB_UserDefs = (LVM_EQNB_BandDef_t *)
+         calloc(pInstParams->EQNB_NumBands, sizeof(*(pInstance->pEQNB_UserDefs)));
+    if (pInstance->pEQNB_UserDefs == LVM_NULL)
+    {
+        return LVM_NULLADDRESS;
+    }
 
     /*
      * Initialise the Concert Sound module
      */
     {
         LVCS_Handle_t           hCSInstance;                /* Instance handle */
-        LVCS_MemTab_t           CS_MemTab;                  /* Memory table */
         LVCS_Capabilities_t     CS_Capabilities;            /* Initial capabilities */
         LVCS_ReturnStatus_en    LVCS_Status;                /* Function call status */
 
@@ -733,26 +278,12 @@
         CS_Capabilities.pBundleInstance = (void*)pInstance;
 
         /*
-         * Get the memory requirements and then set the address pointers, forcing alignment
-         */
-        LVCS_Status = LVCS_Memory(LVM_NULL,                /* Get the memory requirements */
-                                  &CS_MemTab,
-                                  &CS_Capabilities);
-        CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = &pInstance->CS_Instance;
-        CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                                                                                         CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].Size);
-        CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                                                                                                         CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].Size);
-        CS_MemTab.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress       = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
-                                                                                                         0);
-
-        /*
          * Initialise the Concert Sound instance and save the instance handle
          */
         hCSInstance = LVM_NULL;                            /* Set to NULL to return handle */
-        LVCS_Status = LVCS_Init(&hCSInstance,              /* Initiailse */
-                                &CS_MemTab,
-                                &CS_Capabilities);
+        LVCS_Status = LVCS_Init(&hCSInstance,              /* Create and initiailse */
+                                &CS_Capabilities,
+                                pInstance->pScratch);
         if (LVCS_Status != LVCS_SUCCESS) return((LVM_ReturnStatus_en)LVCS_Status);
         pInstance->hCSInstance = hCSInstance;              /* Save the instance handle */
 
@@ -763,7 +294,6 @@
      */
     {
         LVDBE_Handle_t          hDBEInstance;               /* Instance handle */
-        LVDBE_MemTab_t          DBE_MemTab;                 /* Memory table */
         LVDBE_Capabilities_t    DBE_Capabilities;           /* Initial capabilities */
         LVDBE_ReturnStatus_en   LVDBE_Status;               /* Function call status */
 
@@ -787,30 +317,19 @@
                                            LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
                                            LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
                                            LVDBE_CAP_FS_192000;
-        DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
-        DBE_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
 
-        /*
-         * Get the memory requirements and then set the address pointers
-         */
-        LVDBE_Status = LVDBE_Memory(LVM_NULL,               /* Get the memory requirements */
-                                    &DBE_MemTab,
-                                    &DBE_Capabilities);
-        DBE_MemTab.Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress        = &pInstance->DBE_Instance;
-        DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                                                                                      DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size);
-        DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                                                                                                      DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size);
-        DBE_MemTab.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress         = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
-                                                                                                      0);
+        DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz |
+                                            LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz |
+                                            LVDBE_CAP_CENTRE_90Hz;
+        DBE_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
 
         /*
          * Initialise the Dynamic Bass Enhancement instance and save the instance handle
          */
         hDBEInstance = LVM_NULL;                            /* Set to NULL to return handle */
-        LVDBE_Status = LVDBE_Init(&hDBEInstance,            /* Initiailse */
-                                  &DBE_MemTab,
-                                  &DBE_Capabilities);
+        LVDBE_Status = LVDBE_Init(&hDBEInstance,            /* Create and initiailse */
+                                  &DBE_Capabilities,
+                                  pInstance->pScratch);
         if (LVDBE_Status != LVDBE_SUCCESS) return((LVM_ReturnStatus_en)LVDBE_Status);
         pInstance->hDBEInstance = hDBEInstance;             /* Save the instance handle */
     }
@@ -820,7 +339,6 @@
      */
     {
         LVEQNB_Handle_t          hEQNBInstance;             /* Instance handle */
-        LVEQNB_MemTab_t          EQNB_MemTab;               /* Memory table */
         LVEQNB_Capabilities_t    EQNB_Capabilities;         /* Initial capabilities */
         LVEQNB_ReturnStatus_en   LVEQNB_Status;             /* Function call status */
 
@@ -842,6 +360,7 @@
                                             LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
                                             LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
                                             LVEQNB_CAP_FS_192000;
+
         EQNB_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
         EQNB_Capabilities.MaxBands        = pInstParams->EQNB_NumBands;
         EQNB_Capabilities.SourceFormat    = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
@@ -849,26 +368,12 @@
         EQNB_Capabilities.pBundleInstance  = (void*)pInstance;
 
         /*
-         * Get the memory requirements and then set the address pointers, forcing alignment
-         */
-        LVEQNB_Status = LVEQNB_Memory(LVM_NULL,             /* Get the memory requirements */
-                                      &EQNB_MemTab,
-                                      &EQNB_Capabilities);
-        EQNB_MemTab.Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress        = &pInstance->EQNB_Instance;
-        EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                                                                                        EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size);
-        EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                                                                                                        EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size);
-        EQNB_MemTab.Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress         = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
-                                                                                                        0);
-
-        /*
          * Initialise the Dynamic Bass Enhancement instance and save the instance handle
          */
         hEQNBInstance = LVM_NULL;                           /* Set to NULL to return handle */
-        LVEQNB_Status = LVEQNB_Init(&hEQNBInstance,         /* Initiailse */
-                                    &EQNB_MemTab,
-                                    &EQNB_Capabilities);
+        LVEQNB_Status = LVEQNB_Init(&hEQNBInstance,         /* Create and initiailse */
+                                    &EQNB_Capabilities,
+                                    pInstance->pScratch);
         if (LVEQNB_Status != LVEQNB_SUCCESS) return((LVM_ReturnStatus_en)LVEQNB_Status);
         pInstance->hEQNBInstance = hEQNBInstance;           /* Save the instance handle */
     }
@@ -878,11 +383,17 @@
      */
     {
         pInstance->pHeadroom_BandDefs = (LVM_HeadroomBandDef_t *)
-              InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                       (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
+            calloc(LVM_HEADROOM_MAX_NBANDS, sizeof(*(pInstance->pHeadroom_BandDefs)));
+        if (pInstance->pHeadroom_BandDefs == LVM_NULL)
+        {
+            return LVM_NULLADDRESS;
+        }
         pInstance->pHeadroom_UserDefs = (LVM_HeadroomBandDef_t *)
-              InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                                       (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
+            calloc(LVM_HEADROOM_MAX_NBANDS, sizeof(*(pInstance->pHeadroom_UserDefs)));
+        if (pInstance->pHeadroom_UserDefs == LVM_NULL)
+        {
+            return LVM_NULLADDRESS;
+        }
 
         /* Headroom management parameters initialisation */
         pInstance->NewHeadroomParams.NHeadroomBands = 2;
@@ -903,7 +414,6 @@
      */
     {
         pLVPSA_Handle_t     hPSAInstance = LVM_NULL;   /* Instance handle */
-        LVPSA_MemTab_t      PSA_MemTab;
         LVPSA_RETURN        PSA_Status;                 /* Function call status */
         LVPSA_FilterParam_t FiltersParams[9];
 
@@ -920,41 +430,18 @@
                 FiltersParams[i].PostGain           = (LVM_INT16)  0;
             }
 
-            /*Get the memory requirements and then set the address pointers*/
-            PSA_Status = LVPSA_Memory (hPSAInstance,
-                                          &PSA_MemTab,
-                                          &pInstance->PSA_InitParams);
-
-            if (PSA_Status != LVPSA_OK)
-            {
-                return((LVM_ReturnStatus_en) LVM_ALGORITHMPSA);
-            }
-
-            /* Slow Data */
-            PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
-                PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].Size);
-
-            /* Fast Data */
-            PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
-                PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].Size);
-
-            /* Fast Coef */
-            PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
-                PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
-
-            /* Fast Temporary */
-            pInstance->pPSAInput = (LVM_FLOAT *)InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
-                                                       (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * \
-                                                       sizeof(LVM_FLOAT));
-            PSA_MemTab.Region[LVM_TEMPORARY_FAST].pBaseAddress       = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],0);
-
             /*Initialise PSA instance and save the instance handle*/
             pInstance->PSA_ControlParams.Fs = LVM_FS_48000;
             pInstance->PSA_ControlParams.LevelDetectionSpeed  = LVPSA_SPEED_MEDIUM;
+            pInstance->pPSAInput = (LVM_FLOAT *)calloc(MAX_INTERNAL_BLOCKSIZE, sizeof(LVM_FLOAT));
+            if (pInstance->pPSAInput == LVM_NULL)
+            {
+                return LVM_NULLADDRESS;
+            }
             PSA_Status = LVPSA_Init (&hPSAInstance,
                                     &pInstance->PSA_InitParams,
                                     &pInstance->PSA_ControlParams,
-                                    &PSA_MemTab);
+                                    pInstance->pScratch);
 
             if (PSA_Status != LVPSA_OK)
             {
@@ -1007,6 +494,111 @@
 
     return(Status);
 }
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                LVM_DelInstanceHandle                                       */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*  This function is used to create a bundle instance. It returns the created instance  */
+/*  handle through phInstance. All parameters are set to their default, inactive state. */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance              Pointer to the instance handle                              */
+/*                                                                                      */
+/* NOTES:                                                                               */
+/*  1. This function must not be interrupted by the LVM_Process function                */
+/*                                                                                      */
+/****************************************************************************************/
+void LVM_DelInstanceHandle(LVM_Handle_t *phInstance)
+{
+    LVM_Instance_t *pInstance = (LVM_Instance_t *)*phInstance;
+
+    if (pInstance->pScratch != LVM_NULL) {
+        free(pInstance->pScratch);
+        pInstance->pScratch = LVM_NULL;
+    }
+
+    if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS) {
+        /*
+         * Managed buffers required
+         */
+        if (pInstance->pBufferManagement != LVM_NULL) {
+            free(pInstance->pBufferManagement);
+            pInstance->pBufferManagement = LVM_NULL;
+        }
+    }
+
+    /*
+     * Treble Enhancement
+     */
+    if (pInstance->pTE_Taps != LVM_NULL) {
+        free(pInstance->pTE_Taps);
+        pInstance->pTE_Taps = LVM_NULL;
+    }
+    if (pInstance->pTE_State != LVM_NULL) {
+        free(pInstance->pTE_State);
+        pInstance->pTE_State = LVM_NULL;
+    }
+
+    /*
+     * Free the default EQNB pre-gain and pointer to the band definitions
+     */
+    if (pInstance->pEQNB_BandDefs != LVM_NULL) {
+        free(pInstance->pEQNB_BandDefs);
+        pInstance->pEQNB_BandDefs = LVM_NULL;
+    }
+    if (pInstance->pEQNB_UserDefs != LVM_NULL) {
+        free(pInstance->pEQNB_UserDefs);
+        pInstance->pEQNB_UserDefs = LVM_NULL;
+    }
+
+    /*
+     * De-initialise the Concert Sound module
+     */
+    if (pInstance->hCSInstance != LVM_NULL) {
+        LVCS_DeInit(&pInstance->hCSInstance);
+    }
+
+    /*
+     * De-initialise the Bass Enhancement module
+     */
+    if (pInstance->hDBEInstance != LVM_NULL) {
+        LVDBE_DeInit(&pInstance->hDBEInstance);
+    }
+
+    /*
+     * De-initialise the N-Band Equaliser module
+     */
+    if (pInstance->hEQNBInstance != LVM_NULL) {
+        LVEQNB_DeInit(&pInstance->hEQNBInstance);
+    }
+
+    /*
+     * Free Headroom management memory.
+     */
+    if (pInstance->pHeadroom_BandDefs != LVM_NULL) {
+        free(pInstance->pHeadroom_BandDefs);
+        pInstance->pHeadroom_BandDefs = LVM_NULL;
+    }
+    if (pInstance->pHeadroom_UserDefs != LVM_NULL) {
+        free(pInstance->pHeadroom_UserDefs);
+        pInstance->pHeadroom_UserDefs = LVM_NULL;
+    }
+
+    /*
+     * De-initialise the PSA module
+     */
+    if (pInstance->hPSAInstance != LVM_NULL) {
+        LVPSA_DeInit(&pInstance->hPSAInstance);
+    }
+    if (pInstance->pPSAInput != LVM_NULL) {
+        free(pInstance->pPSAInput);
+        pInstance->pPSAInput = LVM_NULL;
+    }
+
+    free(*phInstance);
+    return;
+}
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -1029,7 +621,6 @@
 
 LVM_ReturnStatus_en LVM_ClearAudioBuffers(LVM_Handle_t  hInstance)
 {
-    LVM_MemTab_t            MemTab;                                     /* Memory table */
     LVM_InstParams_t        InstParams;                                 /* Instance parameters */
     LVM_ControlParams_t     Params;                                     /* Control Parameters */
     LVM_Instance_t          *pInstance  = (LVM_Instance_t  *)hInstance; /* Pointer to Instance */
@@ -1045,17 +636,11 @@
     /*Save the headroom parameters*/
     LVM_GetHeadroomParams(hInstance, &HeadroomParams);
 
-    /*  Retrieve allocated buffers in memtab */
-    LVM_GetMemoryTable(hInstance, &MemTab,  LVM_NULL);
 
     /*  Save the instance parameters */
     InstParams = pInstance->InstParams;
 
     /*  Call  LVM_GetInstanceHandle to re-initialise the bundle */
-    LVM_GetInstanceHandle( &hInstance,
-                           &MemTab,
-                           &InstParams);
-
     /* Restore control parameters */ /* coverity[unchecked_value] */ /* Do not check return value internal function calls */
     LVM_SetControlParameters(hInstance, &Params);
 
@@ -1063,11 +648,7 @@
     LVM_SetHeadroomParams(hInstance, &HeadroomParams);
 
     /* DC removal filter */
-#ifdef SUPPORT_MC
     DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-#else
-    DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
-#endif
 
     return LVM_SUCCESS;
 }
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
index ddaac99..a9492a1 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -113,40 +113,15 @@
 /*                                                                                  */
 /************************************************************************************/
 
-/* Memory region definition */
-typedef struct
-{
-    LVM_UINT32              Size;               /* Region size in bytes */
-    LVM_UINT16              Alignment;          /* Byte alignment */
-    LVM_MemoryTypes_en      Type;               /* Region type */
-    void                    *pBaseAddress;      /* Pointer to the region base address */
-} LVM_IntMemoryRegion_t;
-
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVM_IntMemoryRegion_t   Region[LVM_NR_MEMORY_REGIONS];  /* One definition for each region */
-} LVM_IntMemTab_t;
-
 /* Buffer Management */
 typedef struct
 {
     LVM_FLOAT               *pScratch;          /* Bundle scratch buffer */
 
     LVM_INT16               BufferState;        /* Buffer status */
-#ifdef SUPPORT_MC
     LVM_FLOAT               InDelayBuffer[3 * LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE];
-#else
-    LVM_FLOAT               InDelayBuffer[6 * MIN_INTERNAL_BLOCKSIZE]; /* Input buffer delay line, \
-                                                                           left and right */
-#endif
     LVM_INT16               InDelaySamples;     /* Number of samples in the input delay buffer */
-#ifdef SUPPORT_MC
     LVM_FLOAT               OutDelayBuffer[LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE];
-#else
-    LVM_FLOAT               OutDelayBuffer[2 * MIN_INTERNAL_BLOCKSIZE]; /* Output buffer delay \
-                                                                                      line */
-#endif
     LVM_INT16               OutDelaySamples;    /* Number of samples in the output delay buffer, \
                                                                              left and right */
     LVM_INT16               SamplesToOutput;    /* Samples to write to the output */
@@ -167,7 +142,6 @@
 typedef struct
 {
     /* Public parameters */
-    LVM_MemTab_t            MemoryTable;        /* Instance memory allocation table */
     LVM_ControlParams_t     Params;             /* Control parameters */
     LVM_InstParams_t        InstParams;         /* Instance parameters */
 
@@ -236,10 +210,9 @@
 
     LVM_INT16              NoSmoothVolume;      /* Enable or disable smooth volume changes*/
 
-#ifdef SUPPORT_MC
     LVM_INT16              NrChannels;
     LVM_INT32              ChMask;
-#endif
+    void                   *pScratch;           /* Pointer to bundle scratch buffer*/
 
 } LVM_Instance_t;
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
index dc86cfd..3af2327 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
@@ -64,11 +64,9 @@
     LVM_FLOAT           *pToProcess = (LVM_FLOAT *)pInData;
     LVM_FLOAT           *pProcessed = pOutData;
     LVM_ReturnStatus_en  Status;
-#ifdef SUPPORT_MC
     LVM_INT32           NrChannels  = pInstance->NrChannels;
     LVM_INT32           ChMask      = pInstance->ChMask;
 #define NrFrames SampleCount  // alias for clarity
-#endif
 
     /*
      * Check if the number of samples is zero
@@ -114,11 +112,9 @@
     if (pInstance->ControlPending == LVM_TRUE)
     {
         Status = LVM_ApplyNewSettings(hInstance);
-#ifdef SUPPORT_MC
         /* Update the local variable NrChannels from pInstance->NrChannels value */
         NrChannels = pInstance->NrChannels;
         ChMask     = pInstance->ChMask;
-#endif
 
         if(Status != LVM_SUCCESS)
         {
@@ -136,10 +132,8 @@
                        (LVM_INT16)NumSamples);                 /* Number of input samples */
         pInput     = pOutData;
         pToProcess = pOutData;
-#ifdef SUPPORT_MC
         NrChannels = 2;
         ChMask     = AUDIO_CHANNEL_OUT_STEREO;
-#endif
     }
 
     /*
@@ -179,18 +173,11 @@
              */
             if (pInstance->VC_Active!=0)
             {
-#ifdef SUPPORT_MC
                 LVC_MixSoft_Mc_D16C31_SAT(&pInstance->VC_Volume,
                                        pToProcess,
                                        pProcessed,
                                        (LVM_INT16)(NrFrames),
                                        NrChannels);
-#else
-                LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
-                                       pToProcess,
-                                       pProcessed,
-                                       (LVM_INT16)(2 * SampleCount));     /* Left and right*/
-#endif
                 pToProcess = pProcessed;
             }
 
@@ -224,15 +211,9 @@
              */
             if (pToProcess != pProcessed)
             {
-#ifdef SUPPORT_MC
                 Copy_Float(pToProcess,                             /* Source */
                            pProcessed,                             /* Destination */
                            (LVM_INT16)(NrChannels * NrFrames));    /* Copy all samples */
-#else
-                Copy_Float(pToProcess,                             /* Source */
-                           pProcessed,                             /* Destination */
-                           (LVM_INT16)(2 * SampleCount));          /* Left and right */
-#endif
             }
 
             /*
@@ -243,21 +224,13 @@
                 /*
                  * Apply the filter
                  */
-#ifdef SUPPORT_MC
                 FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
                                            pProcessed,
                                            pProcessed,
                                            (LVM_INT16)NrFrames,
                                            (LVM_INT16)NrChannels);
-#else
-                FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
-                                           pProcessed,
-                                           pProcessed,
-                                           (LVM_INT16)SampleCount);
-#endif
 
             }
-#ifdef SUPPORT_MC
             /*
              * Volume balance
              */
@@ -267,15 +240,6 @@
                                           NrFrames,
                                           NrChannels,
                                           ChMask);
-#else
-            /*
-             * Volume balance
-             */
-            LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
-                                          pProcessed,
-                                          pProcessed,
-                                          SampleCount);
-#endif
 
             /*
              * Perform Parametric Spectum Analysis
@@ -283,16 +247,10 @@
             if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
                                             (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
             {
-#ifdef SUPPORT_MC
                 FromMcToMono_Float(pProcessed,
                                    pInstance->pPSAInput,
                                    (LVM_INT16)(NrFrames),
                                    NrChannels);
-#else
-                From2iToMono_Float(pProcessed,
-                                   pInstance->pPSAInput,
-                                   (LVM_INT16)(SampleCount));
-#endif
 
                 LVPSA_Process(pInstance->hPSAInstance,
                         pInstance->pPSAInput,
@@ -303,18 +261,11 @@
             /*
              * DC removal
              */
-#ifdef SUPPORT_MC
             DC_Mc_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
                                  pProcessed,
                                  pProcessed,
                                  (LVM_INT16)NrFrames,
                                  NrChannels);
-#else
-            DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
-                                 pProcessed,
-                                 pProcessed,
-                                 (LVM_INT16)SampleCount);
-#endif
         }
         /*
          * Manage the output buffer
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index bef7fa1..6160452 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -54,14 +54,12 @@
                                  const LVM_FLOAT            *pMonoSrc,      /* Mono source */
                                  LVM_FLOAT                  *pDst,          /* Stereo destination */
                                  LVM_UINT16                 n);             /* Number of samples */
-#ifdef SUPPORT_MC
 void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t  *pInstance,  /* Instance pointer */
                                  const LVM_FLOAT            *pStSrc,      /* Source */
                                  const LVM_FLOAT            *pMonoSrc,    /* Mono source */
                                  LVM_FLOAT                  *pDst,        /* Destination */
                                  LVM_UINT16                 NrFrames,     /* Number of frames */
                                  LVM_UINT16                 NrChannels);  /* Number of channels */
-#endif
 
 #endif  /* __AGC_H__ */
 
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index c050cd0..b1eefb1 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -24,7 +24,6 @@
 ***********************************************************************************/
 typedef struct
 {
-#ifdef SUPPORT_MC
     /* The memory region created by this structure instance is typecast
      * into another structure containing a pointer and an array of filter
      * coefficients. In one case this memory region is used for storing
@@ -32,9 +31,6 @@
      */
     LVM_FLOAT *pStorage;
     LVM_FLOAT Storage[LVM_MAX_CHANNELS];
-#else
-    LVM_FLOAT Storage[6];
-#endif
 } Biquad_FLOAT_Instance_t;
 /**********************************************************************************
    COEFFICIENT TYPE DEFINITIONS
@@ -94,12 +90,8 @@
 
 typedef struct
 {
-#ifdef SUPPORT_MC
     /* LVM_MAX_CHANNELS channels, two taps of size LVM_FLOAT */
     LVM_FLOAT Storage[ (LVM_MAX_CHANNELS * 2) ];
-#else
-    LVM_FLOAT Storage[ (2 * 2) ];  /* Two channels, two taps of size LVM_FLOAT */
-#endif
 } Biquad_2I_Order1_FLOAT_Taps_t;
 
 /*** Types used for biquad, band pass and peaking filter **************************/
@@ -110,12 +102,8 @@
 
 typedef struct
 {
-#ifdef SUPPORT_MC
     /* LVM_MAX_CHANNELS, four taps of size LVM_FLOAT */
     LVM_FLOAT Storage[ (LVM_MAX_CHANNELS * 4) ];
-#else
-    LVM_FLOAT Storage[ (2 * 4) ];  /* Two channels, four taps of size LVM_FLOAT */
-#endif
 } Biquad_2I_Order2_FLOAT_Taps_t;
 /* The names of the functions are changed to satisfy QAC rules: Name should be Unique withing 16 characters*/
 #define BQ_2I_D32F32Cll_TRC_WRA_01_Init  Init_BQ_2I_D32F32Cll_TRC_WRA_01
@@ -185,13 +173,11 @@
                                             LVM_FLOAT                    *pDataIn,
                                             LVM_FLOAT                    *pDataOut,
                                             LVM_INT16                 NrSamples);
-#ifdef SUPPORT_MC
 void BQ_MC_D32F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t      *pInstance,
                                             LVM_FLOAT                    *pDataIn,
                                             LVM_FLOAT                    *pDataOut,
                                             LVM_INT16                    NrFrames,
                                             LVM_INT16                    NrChannels);
-#endif
 
 /**********************************************************************************
    FUNCTION PROTOTYPES: FIRST ORDER FILTERS
@@ -223,13 +209,11 @@
                                  LVM_FLOAT                     *pDataIn,
                                  LVM_FLOAT                     *pDataOut,
                                  LVM_INT16                     NrSamples);
-#ifdef SUPPORT_MC
 void FO_Mc_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t  *pInstance,
                                      LVM_FLOAT                *pDataIn,
                                      LVM_FLOAT                *pDataOut,
                                      LVM_INT16                NrFrames,
                                      LVM_INT16                NrChannels);
-#endif
 /**********************************************************************************
    FUNCTION PROTOTYPES: BAND PASS FILTERS
 ***********************************************************************************/
@@ -266,20 +250,17 @@
                                     LVM_FLOAT               *pDataIn,
                                     LVM_FLOAT               *pDataOut,
                                     LVM_INT16               NrSamples);
-#ifdef SUPPORT_MC
 void PK_Mc_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
                                    LVM_FLOAT               *pDataIn,
                                    LVM_FLOAT               *pDataOut,
                                    LVM_INT16               NrFrames,
                                    LVM_INT16               NrChannels);
-#endif
 
 /**********************************************************************************
    FUNCTION PROTOTYPES: DC REMOVAL FILTERS
 ***********************************************************************************/
 
 /*** 16 bit data path STEREO ******************************************************/
-#ifdef SUPPORT_MC
 void DC_Mc_D16_TRC_WRA_01_Init     (        Biquad_FLOAT_Instance_t       *pInstance);
 
 void DC_Mc_D16_TRC_WRA_01          (        Biquad_FLOAT_Instance_t       *pInstance,
@@ -287,14 +268,6 @@
                                             LVM_FLOAT               *pDataOut,
                                             LVM_INT16               NrFrames,
                                             LVM_INT16               NrChannels);
-#else
-void DC_2I_D16_TRC_WRA_01_Init     (        Biquad_FLOAT_Instance_t       *pInstance);
-
-void DC_2I_D16_TRC_WRA_01          (        Biquad_FLOAT_Instance_t       *pInstance,
-                                            LVM_FLOAT               *pDataIn,
-                                            LVM_FLOAT               *pDataOut,
-                                            LVM_INT16               NrSamples);
-#endif
 
 /**********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 8b687f6..008d192 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -54,26 +54,6 @@
 
 #define LVM_NR_MEMORY_REGIONS                   4   /* Number of memory regions */
 
-/* Memory partition type */
-#define LVM_MEM_PARTITION0      0                   /* 1st memory partition */
-#define LVM_MEM_PARTITION1      1                   /* 2nd memory partition */
-#define LVM_MEM_PARTITION2      2                   /* 3rd memory partition */
-#define LVM_MEM_PARTITION3      3                   /* 4th memory partition */
-
-/* Use type */
-#define LVM_MEM_PERSISTENT      0                   /* Persistent memory type */
-#define LVM_MEM_SCRATCH         4                   /* Scratch  memory type */
-
-/* Access type */
-#define LVM_MEM_INTERNAL        0                   /* Internal (fast) access memory */
-#define LVM_MEM_EXTERNAL        8                   /* External (slow) access memory */
-
-/* Platform specific */
-#define LVM_PERSISTENT          (LVM_MEM_PARTITION0+LVM_MEM_PERSISTENT+LVM_MEM_INTERNAL)
-#define LVM_PERSISTENT_DATA     (LVM_MEM_PARTITION1+LVM_MEM_PERSISTENT+LVM_MEM_INTERNAL)
-#define LVM_PERSISTENT_COEF     (LVM_MEM_PARTITION2+LVM_MEM_PERSISTENT+LVM_MEM_INTERNAL)
-#define LVM_SCRATCH             (LVM_MEM_PARTITION3+LVM_MEM_SCRATCH+LVM_MEM_INTERNAL)
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Basic types                                                                         */
@@ -102,11 +82,7 @@
 typedef     float               effect_buffer_t;
 
 
-#ifdef SUPPORT_MC
 #define LVM_MAX_CHANNELS 8 // FCC_8
-#else
-#define LVM_MAX_CHANNELS 2 // FCC_2
-#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -128,9 +104,7 @@
     LVM_STEREO          = 0,
     LVM_MONOINSTEREO    = 1,
     LVM_MONO            = 2,
-#ifdef SUPPORT_MC
     LVM_MULTICHANNEL    = 3,
-#endif
     LVM_SOURCE_DUMMY    = LVM_MAXENUM
 } LVM_Format_en;
 
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index b27bac5..cbde91d 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -31,7 +31,6 @@
 void Copy_Float(                 const LVM_FLOAT *src,
                                  LVM_FLOAT *dst,
                                  LVM_INT16 n );
-#ifdef SUPPORT_MC
 void Copy_Float_Mc_Stereo(       const LVM_FLOAT *src,
                                  LVM_FLOAT *dst,
                                  LVM_INT16 NrFrames,
@@ -41,7 +40,6 @@
                                  LVM_FLOAT *dst,
                                  LVM_INT16 NrFrames,
                                  LVM_INT32 NrChannels);
-#endif
 
 /*********************************************************************************
  * note: In Mult3s_16x16() saturation of result is not taken care when           *
@@ -110,12 +108,10 @@
 void From2iToMono_Float(         const LVM_FLOAT  *src,
                                  LVM_FLOAT  *dst,
                                  LVM_INT16 n);
-#ifdef SUPPORT_MC
 void FromMcToMono_Float(const LVM_FLOAT *src,
                         LVM_FLOAT *dst,
                         LVM_INT16 NrFrames,
                         LVM_INT16 NrChannels);
-#endif
 void MSTo2i_Sat_Float(        const LVM_FLOAT *srcM,
                               const LVM_FLOAT *srcS,
                               LVM_FLOAT *dst,
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
index e18aa78..07fc0d1 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
@@ -172,7 +172,6 @@
 
     return;
 }
-#ifdef SUPPORT_MC
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                  AGC_MIX_VOL_Mc1Mon_D32_WRA                                */
@@ -314,4 +313,3 @@
 
     return;
 }
-#endif /*SUPPORT_MC*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
index 78d1ba1..189fb9e 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
@@ -120,7 +120,6 @@
 
     }
 
-#ifdef SUPPORT_MC
 /**************************************************************************
  ASSUMPTIONS:
  COEFS-
@@ -197,5 +196,4 @@
         }
 
     }
-#endif /*SUPPORT_MC*/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 3a50554..4b44f28 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -83,7 +83,6 @@
 
     return;
 }
-#ifdef SUPPORT_MC
 // Extract out the stereo channel pair from multichannel source.
 void Copy_Float_Mc_Stereo(const LVM_FLOAT *src,
                  LVM_FLOAT *dst,
@@ -143,5 +142,4 @@
         StereoOut -= 2;
     }
 }
-#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
index a7ce4d3..f2b5813 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
@@ -61,7 +61,6 @@
         pBiquadState->RightDC = RightDC;
 
     }
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       DC_Mc_D16_TRC_WRA_01
  *
@@ -112,4 +111,3 @@
         }
 
     }
-#endif
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
index beee112..42d98f2 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
@@ -23,7 +23,6 @@
     pBiquadState->LeftDC        = 0.0f;
     pBiquadState->RightDC       = 0.0f;
 }
-#ifdef SUPPORT_MC
 void  DC_Mc_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t   *pInstance)
 {
     PFilter_FLOAT_State_Mc pBiquadState  = (PFilter_FLOAT_State_Mc) pInstance;
@@ -33,4 +32,3 @@
         pBiquadState->ChDC[i] = 0.0f;
     }
 }
-#endif
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
index 6508b73..999abea 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
@@ -18,7 +18,7 @@
 #ifndef _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
 #define _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
 
-#define DC_FLOAT_STEP   0.0000002384f;
+#define DC_FLOAT_STEP   0.0000002384f
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.*/
@@ -28,11 +28,9 @@
     LVM_FLOAT  RightDC;    /* RightDC  */
 }Filter_FLOAT_State;
 typedef Filter_FLOAT_State * PFilter_FLOAT_State ;
-#ifdef SUPPORT_MC
 typedef struct _Filter_FLOAT_State_Mc_
 {
     LVM_FLOAT  ChDC[LVM_MAX_CHANNELS];     /* ChannelDC  */
 } Filter_FLOAT_State_Mc;
 typedef Filter_FLOAT_State_Mc * PFilter_FLOAT_State_Mc ;
-#endif
 #endif /* _DC_2I_D16_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
index 6ca819a..605932d 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
@@ -113,7 +113,6 @@
         }
 
     }
-#ifdef SUPPORT_MC
 /**************************************************************************
 ASSUMPTIONS:
 COEFS-
@@ -195,4 +194,3 @@
             pDelays -= NrChannels * 2;
         }
     }
-#endif
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
index a8688b4..6b52feb 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
@@ -67,7 +67,6 @@
 
     return;
 }
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       FromMcToMono_Float
  *
@@ -107,6 +106,5 @@
 
     return;
 }
-#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
index 14d61bd..d4f42de 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
@@ -56,7 +56,6 @@
     }
 
 }
-#ifdef SUPPORT_MC
 void LVC_Core_MixHard_1St_MC_float_SAT (Mix_Private_FLOAT_st **ptrInstance,
                                          const LVM_FLOAT      *src,
                                          LVM_FLOAT            *dst,
@@ -80,5 +79,4 @@
         }
     }
 }
-#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
index 318138d..7d13d5c 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
@@ -113,7 +113,6 @@
     }
     pInstance->Current = Current;
 }
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       LVC_Core_MixInSoft_Mc_D16C31_SAT
  *
@@ -245,5 +244,4 @@
     pInstance->Current = Current;
 }
 
-#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
index 1f4b08a..784f339 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
@@ -145,7 +145,6 @@
     pInstanceR->Current = CurrentR;
 
 }
-#ifdef SUPPORT_MC
 void LVC_Core_MixSoft_1St_MC_float_WRA (Mix_Private_FLOAT_st **ptrInstance,
                                          const LVM_FLOAT      *src,
                                          LVM_FLOAT            *dst,
@@ -189,5 +188,4 @@
         ptrInstance[ch]->Current = tempCurrent[ch];
     }
 }
-#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
index 5d8aadc..57f037e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
@@ -105,7 +105,6 @@
     pInstance->Current=Current;
 }
 
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       LVC_Core_MixSoft_Mc_D16C31_WRA
  *
@@ -214,6 +213,5 @@
     }
     pInstance->Current=Current;
 }
-#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.cpp
index 2bec3be..ede6dee 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.cpp
@@ -105,7 +105,6 @@
 
 }
 
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       LVC_MixInSoft_Mc_D16C31_SAT
  *
@@ -202,6 +201,5 @@
     }
 
 }
-#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
index 3153ada..8fced60 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
@@ -37,7 +37,6 @@
 /**********************************************************************************
    FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
 ***********************************************************************************/
-#ifdef SUPPORT_MC
 /* This threshold is used to decide on the processing to be applied on
  * front center and back center channels
  */
@@ -231,7 +230,6 @@
         }
     }
 }
-#endif
 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
                                     const LVM_FLOAT             *src,
                                     LVM_FLOAT             *dst,
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp
index 4d229da..f893919 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp
@@ -102,7 +102,6 @@
         }
     }
 }
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       LVC_MixSoft_Mc_D16C31_SAT
  *
@@ -195,6 +194,5 @@
     }
 }
 
-#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.cpp
index 54ab79d..2958637 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.cpp
@@ -67,7 +67,6 @@
     }
 }
 
-#ifdef SUPPORT_MC
 /*
  * FUNCTION:       LVC_MixSoft_2Mc_D16C31_SAT
  *
@@ -128,6 +127,5 @@
                                         src1, src2, dst, NrFrames * NrChannels);
     }
 }
-#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index ce42d2e..6206273 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -88,53 +88,45 @@
                                 const LVM_FLOAT       *src,
                                       LVM_FLOAT       *dst,
                                       LVM_INT16       n);
-#ifdef SUPPORT_MC
 void LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
                                const LVM_FLOAT       *src,
                                      LVM_FLOAT       *dst,
                                      LVM_INT16       NrFrames,
                                      LVM_INT16       NrChannels);
-#endif
 
 void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
                               const LVM_FLOAT       *src,
                                     LVM_FLOAT       *dst,
                                     LVM_INT16       n);
-#ifdef SUPPORT_MC
 void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *pInstance,
                                  const LVM_FLOAT       *src,
                                        LVM_FLOAT       *dst,
                                        LVM_INT16       NrFrames,
                                        LVM_INT16       NrChannels);
-#endif
 
 void LVC_MixSoft_2St_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
                                 const LVM_FLOAT       *src1,
                                 const LVM_FLOAT       *src2,
                                 LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
                                 LVM_INT16             n);
-#ifdef SUPPORT_MC
 void LVC_MixSoft_2Mc_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
                                 const LVM_FLOAT       *src1,
                                 const LVM_FLOAT       *src2,
                                 LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
                                 LVM_INT16             NrFrames,
                                 LVM_INT16             NrChannels);
-#endif
 /**********************************************************************************/
 /* For applying different gains to Left and right chennals                        */
 /* MixerStream[0] applies to Left channel                                         */
 /* MixerStream[1] applies to Right channel                                        */
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
-#ifdef SUPPORT_MC
 void LVC_MixSoft_1St_MC_float_SAT(LVMixer3_2St_FLOAT_st *pInstance,
                                    const   LVM_FLOAT     *src,
                                    LVM_FLOAT             *dst,   /* dst can be equal to src */
                                    LVM_INT16             NrFrames,
                                    LVM_INT32             NrChannels,
                                    LVM_INT32             ChMask);
-#endif
 void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st *pInstance,
                                    const   LVM_FLOAT     *src,
                                    LVM_FLOAT             *dst,   /* dst can be equal to src */
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index 123d22b..7cba671 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -50,24 +50,20 @@
                                     const LVM_FLOAT     *src,
                                     LVM_FLOAT     *dst,
                                     LVM_INT16     n);
-#ifdef SUPPORT_MC
 void LVC_Core_MixInSoft_Mc_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
                                     const LVM_FLOAT     *src,
                                           LVM_FLOAT     *dst,
                                           LVM_INT16     NrFrames,
                                           LVM_INT16     NrChannels);
-#endif
 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
                                       const LVM_FLOAT     *src,
                                       LVM_FLOAT     *dst,
                                       LVM_INT16     n);
-#ifdef SUPPORT_MC
 void LVC_Core_MixSoft_Mc_D16C31_WRA(LVMixer3_FLOAT_st *ptrInstance,
                                     const LVM_FLOAT     *src,
                                           LVM_FLOAT     *dst,
                                           LVM_INT16     NrFrames,
                                           LVM_INT16     NrChannels);
-#endif
 void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_FLOAT_st *pInstance1,
                                       LVMixer3_FLOAT_st         *pInstance2,
                                       const LVM_FLOAT     *src1,
@@ -81,13 +77,11 @@
 /* ptrInstance2 applies to Right channel                                          */
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
-#ifdef SUPPORT_MC
 void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st **ptrInstance,
                                          const LVM_FLOAT      *src,
                                          LVM_FLOAT            *dst,
                                          LVM_INT16            NrFrames,
                                          LVM_INT16            NrChannels);
-#endif
 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st        *ptrInstance1,
                                          LVMixer3_FLOAT_st        *ptrInstance2,
                                          const LVM_FLOAT    *src,
@@ -100,13 +94,11 @@
 /* ptrInstance2 applies to Right channel                                          */
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
-#ifdef SUPPORT_MC
 void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st **ptrInstance,
                                          const LVM_FLOAT      *src,
                                          LVM_FLOAT            *dst,
                                          LVM_INT16            NrFrames,
                                          LVM_INT16            NrChannels);
-#endif
 void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st        *ptrInstance1,
                                          LVMixer3_FLOAT_st        *ptrInstance2,
                                          const LVM_FLOAT    *src,
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
index 3f62f99..23b4fae 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
@@ -117,7 +117,6 @@
 
     }
 
-#ifdef SUPPORT_MC
 /**************************************************************************
 DELAYS-
 pBiquadState->pDelays[0] to
@@ -189,4 +188,3 @@
         }
 
     }
-#endif
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index c5ddf77..41e2bb5 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -86,13 +86,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory table */
-#define LVEQNB_MEMREGION_INSTANCE          0   /* Offset to the instance memory region */
-#define LVEQNB_MEMREGION_PERSISTENT_DATA   1   /* Offset to persistent data memory region */
-#define LVEQNB_MEMREGION_PERSISTENT_COEF   2   /* Offset to persistent coefficient region */
-#define LVEQNB_MEMREGION_SCRATCH           3   /* Offset to data scratch memory region */
-#define LVEQNB_NR_MEMORY_REGIONS           4   /* Number of memory regions */
-
 /* Callback events */
 #define LVEQNB_EVENT_NONE                   0x0000    /* Not a valid event */
 #define LVEQNB_EVENT_ALGOFF                 0x0001    /* EQNB has completed switch off */
@@ -122,16 +115,6 @@
     LVEQNB_FILTER_DUMMY = LVM_MAXINT_32
 } LVEQNB_FilterMode_en;
 
-/* Memory Types */
-typedef enum
-{
-    LVEQNB_PERSISTENT      = 0,
-    LVEQNB_PERSISTENT_DATA = 1,
-    LVEQNB_PERSISTENT_COEF = 2,
-    LVEQNB_SCRATCH         = 3,
-    LVEQNB_MEMORY_MAX      = LVM_MAXINT_32
-} LVEQNB_MemoryTypes_en;
-
 /* Function return status */
 typedef enum
 {
@@ -173,9 +156,7 @@
 {
     LVEQNB_STEREO       = 0,
     LVEQNB_MONOINSTEREO = 1,
-#ifdef SUPPORT_MC
     LVEQNB_MULTICHANNEL = 2,
-#endif
     LVEQNB_SOURCE_MAX   = LVM_MAXINT_32
 } LVEQNB_SourceFormat_en;
 
@@ -220,21 +201,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory region definition */
-typedef struct
-{
-    LVM_UINT32                  Size;                   /* Region size in bytes */
-    LVM_UINT16                  Alignment;              /* Region alignment in bytes */
-    LVEQNB_MemoryTypes_en       Type;                   /* Region type */
-    void                        *pBaseAddress;          /* Pointer to the region base address */
-} LVEQNB_MemoryRegion_t;
-
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVEQNB_MemoryRegion_t       Region[LVEQNB_NR_MEMORY_REGIONS];  /* One definition for each region */
-} LVEQNB_MemTab_t;
-
 /* Equaliser band definition */
 typedef struct
 {
@@ -254,9 +220,7 @@
     /* Equaliser parameters */
     LVM_UINT16                  NBands;                 /* Number of bands */
     LVEQNB_BandDef_t            *pBandDefinition;       /* Pointer to equaliser definitions */
-#ifdef SUPPORT_MC
     LVM_INT16                   NrChannels;
-#endif
 } LVEQNB_Params_t;
 
 /* Capability structure */
@@ -283,78 +247,44 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                LVEQNB_Memory                                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the memory       */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pCapabilities           Pointer to the default capabilities                         */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVEQNB_SUCCESS          Succeeded                                                   */
-/*  LVEQNB_NULLADDRESS      When any of pMemoryTable and pCapabilities is NULL address  */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVEQNB_Process function                 */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVEQNB_ReturnStatus_en LVEQNB_Memory(LVEQNB_Handle_t            hInstance,
-                                     LVEQNB_MemTab_t            *pMemoryTable,
-                                     LVEQNB_Capabilities_t      *pCapabilities);
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                LVEQNB_Init                                                 */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
-/*  Create and initialisation function for the N-Band equalliser module                 */
-/*                                                                                      */
-/*  This function can be used to create an algorithm instance by calling with           */
-/*  hInstance set to NULL. In this case the algorithm returns the new instance          */
-/*  handle.                                                                             */
-/*                                                                                      */
-/*  This function can be used to force a full re-initialisation of the algorithm        */
-/*  by calling with hInstance = Instance Handle. In this case the memory table          */
-/*  should be correct for the instance, this can be ensured by calling the function     */
-/*  LVEQNB_Memory before calling this function.                                         */
+/*  Create and initialisation function for the N-Band equaliser module.                 */
 /*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  hInstance               Instance handle                                             */
-/*  pMemoryTable            Pointer to the memory definition table                      */
+/*  phInstance              Pointer to instance handle                                  */
 /*  pCapabilities           Pointer to the initialisation capabilities                  */
+/*  pScratch                Pointer to bundle scratch buffer                            */
 /*                                                                                      */
 /* RETURNS:                                                                             */
 /*  LVEQNB_SUCCESS          Initialisation succeeded                                    */
-/*  LVEQNB_NULLADDRESS        When pCapabilities or pMemoryTableis or phInstance are NULL */
-/*  LVEQNB_NULLADDRESS        One or more of the memory regions has a NULL base address   */
-/*                          pointer for a memory region with a non-zero size.           */
-/*                                                                                      */
+/*  LVEQNB_NULLADDRESS      When pCapabilities or phInstance are NULL                   */
+/*  LVEQNB_NULLADDRESS      When allocated memory has a NULL base address               */
 /*                                                                                      */
 /* NOTES:                                                                               */
-/*  1.  The instance handle is the pointer to the base address of the first memory      */
-/*      region.                                                                         */
-/*  2.  This function must not be interrupted by the LVEQNB_Process function            */
+/*  1.  This function must not be interrupted by the LVEQNB_Process function            */
 /*                                                                                      */
 /****************************************************************************************/
-
 LVEQNB_ReturnStatus_en LVEQNB_Init(LVEQNB_Handle_t          *phInstance,
-                                   LVEQNB_MemTab_t          *pMemoryTable,
-                                   LVEQNB_Capabilities_t    *pCapabilities);
+                                   LVEQNB_Capabilities_t    *pCapabilities,
+                                   void                     *pScratch);
+
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                LVEQNB_DeInit                                               */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*    Free the memories created during LVEQNB_Init including instance handle            */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance              Pointer to instance handle                                  */
+/*                                                                                      */
+/* NOTES:                                                                               */
+/*  1.  This function must not be interrupted by the LVEQNB_Process function            */
+/*                                                                                      */
+/****************************************************************************************/
+void LVEQNB_DeInit(LVEQNB_Handle_t        *phInstance);
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
index 271a914..932af71 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
@@ -21,6 +21,7 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#include <stdlib.h>
 #include "LVEQNB.h"
 #include "LVEQNB_Private.h"
 #include "InstAlloc.h"
@@ -28,255 +29,75 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                LVEQNB_Memory                                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the memory       */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pCapabilities           Pointer to the instance capabilities                        */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVEQNB_SUCCESS          Succeeded                                                   */
-/*  LVEQNB_NULLADDRESS      When any of pMemoryTable and pCapabilities is NULL address  */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVEQNB_Process function                 */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVEQNB_ReturnStatus_en LVEQNB_Memory(LVEQNB_Handle_t            hInstance,
-                                     LVEQNB_MemTab_t            *pMemoryTable,
-                                     LVEQNB_Capabilities_t      *pCapabilities)
-{
-
-    INST_ALLOC          AllocMem;
-    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t *)hInstance;
-
-    if((pMemoryTable == LVM_NULL)|| (pCapabilities == LVM_NULL))
-    {
-        return LVEQNB_NULLADDRESS;
-    }
-
-    /*
-     * Fill in the memory table
-     */
-    if (hInstance == LVM_NULL)
-    {
-        /*
-         * Instance memory
-         */
-        InstAlloc_Init(&AllocMem,
-                       LVM_NULL);
-        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
-                            sizeof(LVEQNB_Instance_t));
-        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Size         = InstAlloc_GetTotal(&AllocMem);
-        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Alignment    = LVEQNB_INSTANCE_ALIGN;
-        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Type         = LVEQNB_PERSISTENT;
-        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
-
-        /*
-         * Persistant data memory
-         */
-        InstAlloc_Init(&AllocMem,
-                       LVM_NULL);
-        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
-                            sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
-        InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
-                            sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
-        /* Equaliser Biquad Taps */
-        InstAlloc_AddMember(&AllocMem,
-                            (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t)));
-        /* Filter definitions */
-        InstAlloc_AddMember(&AllocMem,
-                            (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t)));
-        /* Biquad types */
-        InstAlloc_AddMember(&AllocMem,
-                            (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en)));
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size         = InstAlloc_GetTotal(&AllocMem);
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Alignment    = LVEQNB_DATA_ALIGN;
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Type         = LVEQNB_PERSISTENT_DATA;
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
-
-        /*
-         * Persistant coefficient memory
-         */
-        InstAlloc_Init(&AllocMem,
-                       LVM_NULL);
-        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
-                            sizeof(Biquad_FLOAT_Instance_t));
-        InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
-                            sizeof(Biquad_FLOAT_Instance_t));
-        /* Equaliser Biquad Instance */
-        InstAlloc_AddMember(&AllocMem,
-                            pCapabilities->MaxBands * sizeof(Biquad_FLOAT_Instance_t));
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size         = InstAlloc_GetTotal(&AllocMem);
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Alignment    = LVEQNB_COEF_ALIGN;
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Type         = LVEQNB_PERSISTENT_COEF;
-        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
-
-        /*
-         * Scratch memory
-         */
-        InstAlloc_Init(&AllocMem,
-                       LVM_NULL);
-        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
-                            LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * \
-                                             pCapabilities->MaxBlockSize);
-        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Size              = InstAlloc_GetTotal(&AllocMem);
-        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Alignment         = LVEQNB_SCRATCH_ALIGN;
-        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Type              = LVEQNB_SCRATCH;
-        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress      = LVM_NULL;
-    }
-    else
-    {
-        /* Read back memory allocation table */
-        *pMemoryTable = pInstance->MemoryTable;
-    }
-
-    return(LVEQNB_SUCCESS);
-}
-
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                LVEQNB_Init                                                 */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
-/*  Create and initialisation function for the N-Band equaliser module                  */
-/*                                                                                      */
-/*  This function can be used to create an algorithm instance by calling with           */
-/*  hInstance set to NULL. In this case the algorithm returns the new instance          */
-/*  handle.                                                                             */
-/*                                                                                      */
-/*  This function can be used to force a full re-initialisation of the algorithm        */
-/*  by calling with hInstance = Instance Handle. In this case the memory table          */
-/*  should be correct for the instance, this can be ensured by calling the function     */
-/*  DBE_Memory before calling this function.                                            */
+/*  Create and initialisation function for the N-Band equaliser module.                 */
 /*                                                                                      */
 /* PARAMETERS:                                                                          */
-/*  hInstance               Instance handle                                             */
-/*  pMemoryTable            Pointer to the memory definition table                      */
-/*  pCapabilities           Pointer to the instance capabilities                        */
+/*  phInstance              Pointer to instance handle                                  */
+/*  pCapabilities           Pointer to the initialisation capabilities                  */
+/*  pScratch                Pointer to bundle scratch buffer                            */
 /*                                                                                      */
 /* RETURNS:                                                                             */
 /*  LVEQNB_SUCCESS          Initialisation succeeded                                    */
-/*  LVEQNB_NULLADDRESS        When pCapabilities or pMemoryTableis or phInstance are NULL */
-/*  LVEQNB_NULLADDRESS        One or more of the memory regions has a NULL base address   */
-/*                          pointer for a memory region with a non-zero size.           */
+/*  LVEQNB_NULLADDRESS      One or more memory has a NULL pointer - malloc failure      */
 /*                                                                                      */
 /* NOTES:                                                                               */
-/*  1.  The instance handle is the pointer to the base address of the first memory      */
-/*      region.                                                                         */
-/*  2.  This function must not be interrupted by the LVEQNB_Process function            */
+/*  1.  This function must not be interrupted by the LVEQNB_Process function            */
 /*                                                                                      */
 /****************************************************************************************/
 
 LVEQNB_ReturnStatus_en LVEQNB_Init(LVEQNB_Handle_t          *phInstance,
-                                   LVEQNB_MemTab_t          *pMemoryTable,
-                                   LVEQNB_Capabilities_t    *pCapabilities)
+                                   LVEQNB_Capabilities_t    *pCapabilities,
+                                   void                     *pScratch)
 {
 
     LVEQNB_Instance_t   *pInstance;
-    LVM_UINT32          MemSize;
-    INST_ALLOC          AllocMem;
-    LVM_INT32           i;
 
-    /*
-     * Check for NULL pointers
-     */
-    if((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pCapabilities == LVM_NULL))
+    *phInstance = calloc(1, sizeof(*pInstance));
+    if (phInstance == LVM_NULL)
+    {
+        return LVEQNB_NULLADDRESS;
+    }
+    pInstance =(LVEQNB_Instance_t  *)*phInstance;
+
+    pInstance->Capabilities = *pCapabilities;
+    pInstance->pScratch = pScratch;
+
+    /* Equaliser Biquad Instance */
+    LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pEQNB_FilterState_Float));
+    pInstance->pEQNB_FilterState_Float = (Biquad_FLOAT_Instance_t *)calloc(1, MemSize);
+    if (pInstance->pEQNB_FilterState_Float == LVM_NULL)
     {
         return LVEQNB_NULLADDRESS;
     }
 
-    /*
-     * Check the memory table for NULL pointers
-     */
-    for (i = 0; i < LVEQNB_NR_MEMORY_REGIONS; i++)
+    MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pEQNB_Taps_Float)));
+    pInstance->pEQNB_Taps_Float = (Biquad_2I_Order2_FLOAT_Taps_t *)calloc(1, MemSize);
+    if (pInstance->pEQNB_Taps_Float == LVM_NULL)
     {
-        if (pMemoryTable->Region[i].Size!=0)
-        {
-            if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
-            {
-                return(LVEQNB_NULLADDRESS);
-            }
-        }
+        return LVEQNB_NULLADDRESS;
     }
 
-    /*
-     * Set the instance handle if not already initialised
-     */
-
-    InstAlloc_Init(&AllocMem,  pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress);
-
-    if (*phInstance == LVM_NULL)
+    MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions)));
+    pInstance->pBandDefinitions  = (LVEQNB_BandDef_t *)calloc(1, MemSize);
+    if (pInstance->pBandDefinitions == LVM_NULL)
     {
-        *phInstance = InstAlloc_AddMember(&AllocMem, sizeof(LVEQNB_Instance_t));
+        return LVEQNB_NULLADDRESS;
     }
-    pInstance =(LVEQNB_Instance_t  *)*phInstance;
-
-    /*
-     * Save the memory table in the instance structure
-     */
-    pInstance->Capabilities = *pCapabilities;
-
-    /*
-     * Save the memory table in the instance structure and
-     * set the structure pointers
-     */
-    pInstance->MemoryTable       = *pMemoryTable;
-
-    /*
-     * Allocate coefficient memory
-     */
-    InstAlloc_Init(&AllocMem,
-                   pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
-
-    /* Equaliser Biquad Instance */
-    pInstance->pEQNB_FilterState_Float = (Biquad_FLOAT_Instance_t *)
-        InstAlloc_AddMember(&AllocMem, pCapabilities->MaxBands * \
-                                                       sizeof(Biquad_FLOAT_Instance_t));
-
-    /*
-     * Allocate data memory
-     */
-    InstAlloc_Init(&AllocMem,
-                   pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
-
-    MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
-    pInstance->pEQNB_Taps_Float = (Biquad_2I_Order2_FLOAT_Taps_t *)InstAlloc_AddMember(&AllocMem,
-                                                                                       MemSize);
-    MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
-    pInstance->pBandDefinitions  = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
-                                                                           MemSize);
     // clear all the bands, setting their gain to 0, otherwise when applying new params,
     // it will compare against uninitialized values
     memset(pInstance->pBandDefinitions, 0, MemSize);
-    MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en));
-    pInstance->pBiquadType = (LVEQNB_BiquadType_en *)InstAlloc_AddMember(&AllocMem,
-                                                                         MemSize);
 
-    /*
-     * Internally map, structure and allign scratch memory
-     */
-    InstAlloc_Init(&AllocMem,
-                   pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
+    MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pBiquadType)));
+    pInstance->pBiquadType = (LVEQNB_BiquadType_en *)calloc(1, MemSize);
+    if (pInstance->pBiquadType == LVM_NULL)
+    {
+        return LVEQNB_NULLADDRESS;
+    }
 
-    pInstance->pFastTemporary = (LVM_FLOAT *)InstAlloc_AddMember(&AllocMem,
-                                                                 sizeof(LVM_FLOAT));
+    pInstance->pFastTemporary = (LVM_FLOAT *)pScratch;
 
     /*
      * Update the instance parameters
@@ -319,4 +140,48 @@
 
     return(LVEQNB_SUCCESS);
 }
+/****************************************************************************************/
+/*                                                                                      */
+/* FUNCTION:                LVEQNB_DeInit                                               */
+/*                                                                                      */
+/* DESCRIPTION:                                                                         */
+/*    Free the memories created during LVEQNB_Init including instance handle            */
+/*                                                                                      */
+/* PARAMETERS:                                                                          */
+/*  phInstance              Pointer to instance handle                                  */
+/*                                                                                      */
+/* NOTES:                                                                               */
+/*  1.  This function must not be interrupted by the LVEQNB_Process function            */
+/*                                                                                      */
+/****************************************************************************************/
+
+void LVEQNB_DeInit(LVEQNB_Handle_t          *phInstance)
+{
+
+    LVEQNB_Instance_t   *pInstance;
+    if (phInstance == LVM_NULL) {
+        return;
+    }
+    pInstance =(LVEQNB_Instance_t  *)*phInstance;
+
+    /* Equaliser Biquad Instance */
+    if (pInstance->pEQNB_FilterState_Float != LVM_NULL) {
+        free(pInstance->pEQNB_FilterState_Float);
+        pInstance->pEQNB_FilterState_Float = LVM_NULL;
+    }
+    if (pInstance->pEQNB_Taps_Float != LVM_NULL) {
+        free(pInstance->pEQNB_Taps_Float);
+        pInstance->pEQNB_Taps_Float = LVM_NULL;
+    }
+    if (pInstance->pBandDefinitions != LVM_NULL) {
+        free(pInstance->pBandDefinitions);
+        pInstance->pBandDefinitions = LVM_NULL;
+    }
+    if (pInstance->pBiquadType != LVM_NULL) {
+        free(pInstance->pBiquadType);
+        pInstance->pBiquadType = LVM_NULL;
+    }
+    free(pInstance);
+    *phInstance = LVM_NULL;
+}
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 40facfb..9569d85 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -36,19 +36,6 @@
 
 /* General */
 #define LVEQNB_INVALID              0xFFFF              /* Invalid init parameter */
-
-/* Memory */
-#define LVEQNB_INSTANCE_ALIGN       4                   /* 32-bit alignment for instance structures */
-#define LVEQNB_DATA_ALIGN           4                   /* 32-bit alignment for structures */
-#define LVEQNB_COEF_ALIGN           4                   /* 32-bit alignment for long words */
-#ifdef SUPPORT_MC
-/* Number of buffers required for inplace processing */
-#define LVEQNB_SCRATCHBUFFERS       (LVM_MAX_CHANNELS * 2)
-#else
-#define LVEQNB_SCRATCHBUFFERS       4                   /* Number of buffers required for inplace processing */
-#endif
-#define LVEQNB_SCRATCH_ALIGN        4                   /* 32-bit alignment for long data */
-
 #define LVEQNB_BYPASS_MIXER_TC      100                 /* Bypass Mixer TC */
 
 /****************************************************************************************/
@@ -77,7 +64,7 @@
 typedef struct
 {
     /* Public parameters */
-    LVEQNB_MemTab_t                 MemoryTable;        /* Instance memory allocation table */
+    void                            *pScratch;          /* Pointer to bundle scratch buffer */
     LVEQNB_Params_t                 Params;             /* Instance parameters */
     LVEQNB_Capabilities_t           Capabilities;       /* Instance capabilities */
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
index 65eff53..8dd5587 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
@@ -65,13 +65,9 @@
 {                                     // updated to use samples = frames * channels.
     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
 
-#ifdef SUPPORT_MC
     // Mono passed in as stereo
     const LVM_INT32 NrChannels = pInstance->Params.NrChannels == 1
         ? 2 : pInstance->Params.NrChannels;
-#else
-    const LVM_INT32 NrChannels = 2; // FCC_2
-#endif
     const LVM_INT32 NrSamples = NrChannels * NrFrames;
 
      /* Check for NULL pointers */
@@ -129,18 +125,11 @@
                     {
                         case LVEQNB_SinglePrecision_Float:
                         {
-#ifdef SUPPORT_MC
                             PK_Mc_D32F32C14G11_TRC_WRA_01(pBiquad,
                                                           pScratch,
                                                           pScratch,
                                                           (LVM_INT16)NrFrames,
                                                           (LVM_INT16)NrChannels);
-#else
-                            PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
-                                                          pScratch,
-                                                          pScratch,
-                                                          (LVM_INT16)NrFrames);
-#endif
                             break;
                         }
                         default:
@@ -151,20 +140,12 @@
         }
 
         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
-#ifdef SUPPORT_MC
             LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->BypassMixer,
                                        pScratch,
                                        pInData,
                                        pScratch,
                                        (LVM_INT16)NrFrames,
                                        (LVM_INT16)NrChannels);
-#else
-            LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
-                                       pScratch,
-                                       pInData,
-                                       pScratch,
-                                       (LVM_INT16)NrSamples);
-#endif
             // duplicate with else clause(s)
             Copy_Float(pScratch,                         /* Source */
                        pOutData,                         /* Destination */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.cpp
index 2a75559..7a68c21 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.cpp
@@ -69,14 +69,10 @@
         && (pNewParams->SampleRate != LVM_FS_88200) && (pNewParams->SampleRate != LVM_FS_96000)
         && (pNewParams->SampleRate != LVM_FS_176400) && (pNewParams->SampleRate != LVM_FS_192000)
         )
-#ifdef SUPPORT_MC
         || ((pNewParams->SourceFormat != LVM_STEREO)       &&
             (pNewParams->SourceFormat != LVM_MONOINSTEREO) &&
             (pNewParams->SourceFormat != LVM_MONO)         &&
             (pNewParams->SourceFormat != LVM_MULTICHANNEL)))
-#else
-        || ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
-#endif
     {
         return (LVREV_OUTOFRANGE);
     }
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
index c9fa7ad..0ba662a 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
@@ -22,28 +22,9 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*  CONSTANTS DEFINITIONS                                                               */
-/*                                                                                      */
-/****************************************************************************************/
-
-/* Memory table*/
-#define     LVPSA_NR_MEMORY_REGIONS                  4      /* Number of memory regions                                          */
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  TYPES DEFINITIONS                                                                   */
 /*                                                                                      */
 /****************************************************************************************/
-/* Memory Types */
-typedef enum
-{
-    LVPSA_PERSISTENT      = LVM_PERSISTENT,
-    LVPSA_PERSISTENT_DATA = LVM_PERSISTENT_DATA,
-    LVPSA_PERSISTENT_COEF = LVM_PERSISTENT_COEF,
-    LVPSA_SCRATCH         = LVM_SCRATCH,
-    LVPSA_MEMORY_DUMMY = LVM_MAXINT_32                      /* Force 32 bits enum, don't use it!                                 */
-} LVPSA_MemoryTypes_en;
-
 /* Level detection speed control parameters */
 typedef enum
 {
@@ -80,20 +61,6 @@
 
 } LVPSA_ControlParams_t, *pLVPSA_ControlParams_t;
 
-/* Memory region definition */
-typedef struct
-{
-    LVM_UINT32                 Size;                        /* Region size in bytes                                              */
-    LVPSA_MemoryTypes_en       Type;                        /* Region type                                                       */
-    void                       *pBaseAddress;               /* Pointer to the region base address                                */
-} LVPSA_MemoryRegion_t;
-
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVPSA_MemoryRegion_t       Region[LVPSA_NR_MEMORY_REGIONS];/* One definition for each region                                 */
-} LVPSA_MemTab_t;
-
 /* Audio time type */
 typedef LVM_INT32 LVPSA_Time;
 
@@ -113,62 +80,43 @@
 /*********************************************************************************************************************************
    FUNCTIONS PROTOTYPE
 **********************************************************************************************************************************/
-/*********************************************************************************************************************************/
-/*                                                                                                                               */
-/* FUNCTION:            LVPSA_Memory                                                                                         */
-/*                                                                                                                               */
-/* DESCRIPTION:                                                                                                                  */
-/*  This function is used for memory allocation and free. It can be called in                                                    */
-/*  two ways:                                                                                                                    */
-/*                                                                                                                               */
-/*      hInstance = NULL                Returns the memory requirements                                                          */
-/*      hInstance = Instance handle     Returns the memory requirements and                                                      */
-/*                                      allocated base addresses for the instance                                                */
-/*                                                                                                                               */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory                                               */
-/*  base address pointers are NULL on return.                                                                                    */
-/*                                                                                                                               */
-/*  When the function is called for free (hInstance = Instance Handle) the memory                                                */
-/*  table returns the allocated memory and base addresses used during initialisation.                                            */
-/*                                                                                                                               */
-/* PARAMETERS:                                                                                                                   */
-/*  hInstance           Instance Handle                                                                                          */
-/*  pMemoryTable        Pointer to an empty memory definition table                                                              */
-/*  pInitParams         Pointer to the instance init parameters                                                                  */
-/*                                                                                                                               */
-/* RETURNS:                                                                                                                      */
-/*  LVPSA_OK            Succeeds                                                                                                 */
-/*  otherwise           Error due to bad parameters                                                                              */
-/*                                                                                                                               */
-/*********************************************************************************************************************************/
-LVPSA_RETURN LVPSA_Memory            ( pLVPSA_Handle_t             hInstance,
-                                       LVPSA_MemTab_t             *pMemoryTable,
-                                       LVPSA_InitParams_t         *pInitParams    );
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:            LVPSA_Init                                                  */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*  Create and Initialize the LVPSA module including instance handle                */
+/*                                                                                  */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance          Pointer to the instance handle                              */
+/*  InitParams          Init parameters structure                                   */
+/*  ControlParams       Control parameters structure                                */
+/*  pScratch            Pointer to bundle scratch memory area                       */
+/*                                                                                  */
+/*                                                                                  */
+/* RETURNS:                                                                         */
+/*  LVPSA_OK            Succeeds                                                    */
+/*  otherwise           Error due to bad parameters                                 */
+/*                                                                                  */
+/************************************************************************************/
+LVPSA_RETURN LVPSA_Init(pLVPSA_Handle_t             *phInstance,
+                        LVPSA_InitParams_t          *pInitParams,
+                        LVPSA_ControlParams_t       *pControlParams,
+                        void                        *pScratch);
 
-/*********************************************************************************************************************************/
-/*                                                                                                                               */
-/* FUNCTION:            LVPSA_Init                                                                                               */
-/*                                                                                                                               */
-/* DESCRIPTION:                                                                                                                  */
-/*  Initializes the LVPSA module.                                                                                                */
-/*                                                                                                                               */
-/*                                                                                                                               */
-/* PARAMETERS:                                                                                                                   */
-/*  phInstance          Pointer to the instance Handle                                                                           */
-/*  pInitParams         Pointer to the instance init parameters                                                                  */
-/*  pControlParams      Pointer to the instance control parameters                                                               */
-/*  pMemoryTable        Pointer to the memory definition table                                                                   */
-/*                                                                                                                               */
-/*                                                                                                                               */
-/* RETURNS:                                                                                                                      */
-/*  LVPSA_OK            Succeeds                                                                                                 */
-/*  otherwise           Error due to bad parameters                                                                              */
-/*                                                                                                                               */
-/*********************************************************************************************************************************/
-LVPSA_RETURN LVPSA_Init              ( pLVPSA_Handle_t             *phInstance,
-                                       LVPSA_InitParams_t          *pInitParams,
-                                       LVPSA_ControlParams_t       *pControlParams,
-                                       LVPSA_MemTab_t              *pMemoryTable  );
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:            LVPSA_DeInit                                                */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*    Free the memories created in LVPSA_Init call including instance handle        */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance          Pointer to the instance handle                              */
+/*                                                                                  */
+/************************************************************************************/
+void LVPSA_DeInit(pLVPSA_Handle_t             *phInstance);
 
 /*********************************************************************************************************************************/
 /*                                                                                                                               */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
index 9fcd82f..be3c68f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#include    <stdlib.h>
 #include    "LVPSA.h"
 #include    "LVPSA_Private.h"
 #include    "InstAlloc.h"
@@ -24,14 +25,14 @@
 /* FUNCTION:            LVPSA_Init                                                  */
 /*                                                                                  */
 /* DESCRIPTION:                                                                     */
-/*  Initialize the LVPSA module                                                     */
+/*  Create and Initialize the LVPSA module including instance handle                */
 /*                                                                                  */
 /*                                                                                  */
 /* PARAMETERS:                                                                      */
-/*  phInstance          Pointer to pointer to the instance                          */
+/*  phInstance          Pointer to the instance handle                              */
 /*  InitParams          Init parameters structure                                   */
 /*  ControlParams       Control parameters structure                                */
-/*  pMemoryTable        Memory table that contains memory areas definition          */
+/*  pScratch            Pointer to bundle scratch memory area                       */
 /*                                                                                  */
 /*                                                                                  */
 /* RETURNS:                                                                         */
@@ -39,10 +40,10 @@
 /*  otherwise           Error due to bad parameters                                 */
 /*                                                                                  */
 /************************************************************************************/
-LVPSA_RETURN LVPSA_Init              ( pLVPSA_Handle_t             *phInstance,
-                                       LVPSA_InitParams_t          *pInitParams,
-                                       LVPSA_ControlParams_t       *pControlParams,
-                                       LVPSA_MemTab_t              *pMemoryTable )
+LVPSA_RETURN LVPSA_Init(pLVPSA_Handle_t             *phInstance,
+                        LVPSA_InitParams_t          *pInitParams,
+                        LVPSA_ControlParams_t       *pControlParams,
+                        void                        *pScratch)
 {
     LVPSA_InstancePr_t          *pLVPSA_Inst;
     LVPSA_RETURN                errorCode       = LVPSA_OK;
@@ -50,64 +51,15 @@
     extern LVM_FLOAT            LVPSA_Float_GainTable[];
     LVM_UINT32                  BufferLength = 0;
 
-    /* Ints_Alloc instances, needed for memory alignment management */
-    INST_ALLOC          Instance;
-    INST_ALLOC          Scratch;
-    INST_ALLOC          Data;
-    INST_ALLOC          Coef;
-
-    /* Check parameters */
-    if((phInstance == LVM_NULL) || (pInitParams == LVM_NULL) || (pControlParams == LVM_NULL) || (pMemoryTable == LVM_NULL))
-    {
-        return(LVPSA_ERROR_NULLADDRESS);
-    }
-    if( (pInitParams->SpectralDataBufferDuration > LVPSA_MAXBUFFERDURATION)   ||
-        (pInitParams->SpectralDataBufferDuration == 0)                        ||
-        (pInitParams->MaxInputBlockSize > LVPSA_MAXINPUTBLOCKSIZE)      ||
-        (pInitParams->MaxInputBlockSize == 0)                           ||
-        (pInitParams->nBands < LVPSA_NBANDSMIN)                         ||
-        (pInitParams->nBands > LVPSA_NBANDSMAX)                         ||
-        (pInitParams->pFiltersParams == 0))
-    {
-        return(LVPSA_ERROR_INVALIDPARAM);
-    }
-    for(ii = 0; ii < pInitParams->nBands; ii++)
-    {
-        if((pInitParams->pFiltersParams[ii].CenterFrequency > LVPSA_MAXCENTERFREQ) ||
-           (pInitParams->pFiltersParams[ii].PostGain        > LVPSA_MAXPOSTGAIN)   ||
-           (pInitParams->pFiltersParams[ii].PostGain        < LVPSA_MINPOSTGAIN)   ||
-           (pInitParams->pFiltersParams[ii].QFactor < LVPSA_MINQFACTOR)            ||
-           (pInitParams->pFiltersParams[ii].QFactor > LVPSA_MAXQFACTOR))
-           {
-                return(LVPSA_ERROR_INVALIDPARAM);
-           }
-    }
-
-    /*Inst_Alloc instances initialization */
-    InstAlloc_Init( &Instance   , pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].pBaseAddress);
-    InstAlloc_Init( &Scratch    , pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress);
-    InstAlloc_Init( &Data       , pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].pBaseAddress);
-    InstAlloc_Init( &Coef       , pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].pBaseAddress);
-
     /* Set the instance handle if not already initialised */
+    *phInstance = calloc(1, sizeof(*pLVPSA_Inst));
     if (*phInstance == LVM_NULL)
     {
-        *phInstance = InstAlloc_AddMember( &Instance, sizeof(LVPSA_InstancePr_t) );
+        return LVPSA_ERROR_NULLADDRESS;
     }
     pLVPSA_Inst =(LVPSA_InstancePr_t*)*phInstance;
 
-    /* Check the memory table for NULL pointers */
-    for (ii = 0; ii < LVPSA_NR_MEMORY_REGIONS; ii++)
-    {
-        if (pMemoryTable->Region[ii].Size!=0)
-        {
-            if (pMemoryTable->Region[ii].pBaseAddress==LVM_NULL)
-            {
-                return(LVPSA_ERROR_NULLADDRESS);
-            }
-            pLVPSA_Inst->MemoryTable.Region[ii] = pMemoryTable->Region[ii];
-        }
-    }
+    pLVPSA_Inst->pScratch = pScratch;
 
     /* Initialize module's internal parameters */
     pLVPSA_Inst->bControlPending = LVM_FALSE;
@@ -137,31 +89,61 @@
     }
 
     /* Assign the pointers */
-    pLVPSA_Inst->pPostGains             =
-        (LVM_FLOAT *)InstAlloc_AddMember(&Instance, pInitParams->nBands * sizeof(LVM_FLOAT));
-    pLVPSA_Inst->pFiltersParams             = (LVPSA_FilterParam_t *)
-        InstAlloc_AddMember(&Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t));
-    pLVPSA_Inst->pSpectralDataBufferStart   = (LVM_UINT8 *)
-        InstAlloc_AddMember(&Instance, pInitParams->nBands * \
-                                pLVPSA_Inst->SpectralDataBufferLength * sizeof(LVM_UINT8));
-    pLVPSA_Inst->pPreviousPeaks             = (LVM_UINT8 *)
-                  InstAlloc_AddMember(&Instance, pInitParams->nBands * sizeof(LVM_UINT8));
-    pLVPSA_Inst->pBPFiltersPrecision        = (LVPSA_BPFilterPrecision_en *)
-                  InstAlloc_AddMember(&Instance, pInitParams->nBands * \
-                                                       sizeof(LVPSA_BPFilterPrecision_en));
-    pLVPSA_Inst->pBP_Instances          = (Biquad_FLOAT_Instance_t *)
-                  InstAlloc_AddMember(&Coef, pInitParams->nBands * \
-                                                          sizeof(Biquad_FLOAT_Instance_t));
-    pLVPSA_Inst->pQPD_States            = (QPD_FLOAT_State_t *)
-                  InstAlloc_AddMember(&Coef, pInitParams->nBands * \
-                                                                sizeof(QPD_FLOAT_State_t));
-
-    pLVPSA_Inst->pBP_Taps               = (Biquad_1I_Order2_FLOAT_Taps_t *)
-        InstAlloc_AddMember(&Data, pInitParams->nBands * \
-                                                     sizeof(Biquad_1I_Order2_FLOAT_Taps_t));
-    pLVPSA_Inst->pQPD_Taps              = (QPD_FLOAT_Taps_t *)
-        InstAlloc_AddMember(&Data, pInitParams->nBands * \
-                                                    sizeof(QPD_FLOAT_Taps_t));
+    pLVPSA_Inst->pPostGains = (LVM_FLOAT *)
+                    calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pPostGains)));
+    if (pLVPSA_Inst->pPostGains == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pFiltersParams = (LVPSA_FilterParam_t *)
+                    calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pFiltersParams)));
+    if (pLVPSA_Inst->pFiltersParams == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pSpectralDataBufferStart = (LVM_UINT8 *)
+                    calloc(pInitParams->nBands, pLVPSA_Inst->SpectralDataBufferLength * \
+                            sizeof(*(pLVPSA_Inst->pSpectralDataBufferStart)));
+    if (pLVPSA_Inst->pSpectralDataBufferStart == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pPreviousPeaks = (LVM_UINT8 *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pPreviousPeaks)));
+    if (pLVPSA_Inst->pPreviousPeaks == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pBPFiltersPrecision = (LVPSA_BPFilterPrecision_en *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBPFiltersPrecision)));
+    if (pLVPSA_Inst->pBPFiltersPrecision == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pBP_Instances = (Biquad_FLOAT_Instance_t *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Instances)));
+    if (pLVPSA_Inst->pBP_Instances == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pQPD_States = (QPD_FLOAT_State_t *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_States)));
+    if (pLVPSA_Inst->pQPD_States == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pBP_Taps = (Biquad_1I_Order2_FLOAT_Taps_t *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Taps)));
+    if (pLVPSA_Inst->pBP_Taps == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
+    pLVPSA_Inst->pQPD_Taps = (QPD_FLOAT_Taps_t *)
+                        calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_Taps)));
+    if (pLVPSA_Inst->pQPD_Taps == LVM_NULL)
+    {
+        return LVPSA_ERROR_NULLADDRESS;
+    }
 
     /* Copy filters parameters in the private instance */
     for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
@@ -195,3 +177,60 @@
     return(errorCode);
 }
 
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:            LVPSA_DeInit                                                */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*    Free the memories created in LVPSA_Init call including instance handle        */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance          Pointer to the instance handle                              */
+/*                                                                                  */
+/************************************************************************************/
+void LVPSA_DeInit(pLVPSA_Handle_t *phInstance)
+{
+    LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t *)*phInstance;
+    if (pLVPSA_Inst == LVM_NULL) {
+        return;
+    }
+    if (pLVPSA_Inst->pPostGains != LVM_NULL) {
+        free(pLVPSA_Inst->pPostGains);
+        pLVPSA_Inst->pPostGains = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pFiltersParams != LVM_NULL) {
+        free(pLVPSA_Inst->pFiltersParams);
+        pLVPSA_Inst->pFiltersParams = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pSpectralDataBufferStart != LVM_NULL) {
+        free(pLVPSA_Inst->pSpectralDataBufferStart);
+        pLVPSA_Inst->pSpectralDataBufferStart = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pPreviousPeaks != LVM_NULL) {
+        free(pLVPSA_Inst->pPreviousPeaks);
+        pLVPSA_Inst->pPreviousPeaks = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pBPFiltersPrecision != LVM_NULL) {
+        free(pLVPSA_Inst->pBPFiltersPrecision);
+        pLVPSA_Inst->pBPFiltersPrecision = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pBP_Instances != LVM_NULL) {
+        free(pLVPSA_Inst->pBP_Instances);
+        pLVPSA_Inst->pBP_Instances = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pQPD_States != LVM_NULL) {
+        free(pLVPSA_Inst->pQPD_States);
+        pLVPSA_Inst->pQPD_States = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pBP_Taps != LVM_NULL) {
+        free(pLVPSA_Inst->pBP_Taps);
+        pLVPSA_Inst->pBP_Taps = LVM_NULL;
+    }
+    if (pLVPSA_Inst->pQPD_Taps != LVM_NULL) {
+        free(pLVPSA_Inst->pQPD_Taps);
+        pLVPSA_Inst->pQPD_Taps = LVM_NULL;
+    }
+    free(pLVPSA_Inst);
+    *phInstance = LVM_NULL;
+}
+
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.cpp
deleted file mode 100644
index eafcbe6..0000000
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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    "LVPSA.h"
-#include    "LVPSA_Private.h"
-#include    "InstAlloc.h"
-
-/****************************************************************************************/
-/*                                                                                      */
-/* FUNCTION:                LVEQNB_Memory                                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL         Returns the memory requirements                        */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
-/*  base address pointers are NULL on return.                                           */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the memory       */
-/*  table returns the allocated memory and base addresses used during initialisation.   */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  InitParams              Pointer to the instance init parameters                     */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVPSA_OK            Succeeds                                                        */
-/*  otherwise           Error due to bad parameters                                     */
-/*                                                                                      */
-/****************************************************************************************/
-LVPSA_RETURN LVPSA_Memory            ( pLVPSA_Handle_t             hInstance,
-                                       LVPSA_MemTab_t             *pMemoryTable,
-                                       LVPSA_InitParams_t         *pInitParams    )
-{
-    LVM_UINT32          ii;
-    LVM_UINT32          BufferLength;
-    INST_ALLOC          Instance;
-    INST_ALLOC          Scratch;
-    INST_ALLOC          Data;
-    INST_ALLOC          Coef;
-    LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
-
-    InstAlloc_Init( &Instance   , LVM_NULL);
-    InstAlloc_Init( &Scratch    , LVM_NULL);
-    InstAlloc_Init( &Data       , LVM_NULL);
-    InstAlloc_Init( &Coef       , LVM_NULL);
-
-    if((pMemoryTable == LVM_NULL) || (pInitParams == LVM_NULL))
-    {
-        return(LVPSA_ERROR_NULLADDRESS);
-    }
-
-    /*
-     * Fill in the memory table
-     */
-    if (hInstance == LVM_NULL)
-    {
-
-        /* Check init parameter */
-        if( (pInitParams->SpectralDataBufferDuration > LVPSA_MAXBUFFERDURATION)   ||
-            (pInitParams->SpectralDataBufferDuration == 0)                        ||
-            (pInitParams->MaxInputBlockSize > LVPSA_MAXINPUTBLOCKSIZE)      ||
-            (pInitParams->MaxInputBlockSize == 0)                           ||
-            (pInitParams->nBands < LVPSA_NBANDSMIN)                         ||
-            (pInitParams->nBands > LVPSA_NBANDSMAX)                         ||
-            (pInitParams->pFiltersParams == 0))
-        {
-            return(LVPSA_ERROR_INVALIDPARAM);
-        }
-        for(ii = 0; ii < pInitParams->nBands; ii++)
-        {
-            if((pInitParams->pFiltersParams[ii].CenterFrequency > LVPSA_MAXCENTERFREQ) ||
-               (pInitParams->pFiltersParams[ii].PostGain        > LVPSA_MAXPOSTGAIN)   ||
-               (pInitParams->pFiltersParams[ii].PostGain        < LVPSA_MINPOSTGAIN)   ||
-               (pInitParams->pFiltersParams[ii].QFactor < LVPSA_MINQFACTOR)            ||
-               (pInitParams->pFiltersParams[ii].QFactor > LVPSA_MAXQFACTOR))
-               {
-                    return(LVPSA_ERROR_INVALIDPARAM);
-               }
-        }
-
-        /*
-         * Instance memory
-         */
-
-        InstAlloc_AddMember( &Instance, sizeof(LVPSA_InstancePr_t) );
-        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_FLOAT) );
-        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
-
-        {
-            /* for avoiding QAC warnings as MUL32x32INTO32 works on LVM_INT32 only*/
-            LVM_INT32 SDBD=(LVM_INT32)pInitParams->SpectralDataBufferDuration;
-            LVM_INT32 IRTI=(LVM_INT32)LVPSA_InternalRefreshTimeInv;
-            LVM_INT32 BL;
-
-            MUL32x32INTO32(SDBD,IRTI,BL,LVPSA_InternalRefreshTimeShift)
-            BufferLength=(LVM_UINT32)BL;
-        }
-
-        if((BufferLength * LVPSA_InternalRefreshTime) != pInitParams->SpectralDataBufferDuration)
-        {
-            BufferLength++;
-        }
-        InstAlloc_AddMember( &Instance, pInitParams->nBands * BufferLength * sizeof(LVM_UINT8) );
-        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT8) );
-        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_BPFilterPrecision_en) );
-        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].Size         = InstAlloc_GetTotal(&Instance);
-        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].Type         = LVPSA_PERSISTENT;
-        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
-
-        /*
-         * Scratch memory
-         */
-        InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT) );
-        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Size         = InstAlloc_GetTotal(&Scratch);
-        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Type         = LVPSA_SCRATCH;
-        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
-
-        /*
-         * Persistent coefficients memory
-         */
-        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_FLOAT_Instance_t) );
-        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_FLOAT_State_t) );
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Size         = InstAlloc_GetTotal(&Coef);
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Type         = LVPSA_PERSISTENT_COEF;
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
-
-        /*
-         * Persistent data memory
-         */
-        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_FLOAT_Taps_t) );
-        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_FLOAT_Taps_t) );
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Size         = InstAlloc_GetTotal(&Data);
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Type         = LVPSA_PERSISTENT_DATA;
-        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
-
-    }
-    else
-    {
-        /* Read back memory allocation table */
-        *pMemoryTable = pLVPSA_Inst->MemoryTable;
-    }
-
-    return(LVPSA_OK);
-}
-
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index 61987b5..fc67a75 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -27,16 +27,6 @@
    CONSTANT DEFINITIONS
 ***********************************************************************************/
 
-/* Memory */
-#define LVPSA_INSTANCE_ALIGN             4      /* 32-bit alignment for structures                                  */
-#define LVPSA_SCRATCH_ALIGN              4      /* 32-bit alignment for long data                                   */
-#define LVPSA_COEF_ALIGN                 4      /* 32-bit alignment for long words                                  */
-#define LVPSA_DATA_ALIGN                 4      /* 32-bit alignment for long data                                   */
-
-#define LVPSA_MEMREGION_INSTANCE         0      /* Offset to instance memory region in memory table                 */
-#define LVPSA_MEMREGION_PERSISTENT_COEF  1      /* Offset to persistent coefficients  memory region in memory table */
-#define LVPSA_MEMREGION_PERSISTENT_DATA  2      /* Offset to persistent taps  memory region in memory table         */
-#define LVPSA_MEMREGION_SCRATCH          3      /* Offset to scratch  memory region in memory table                 */
 #define LVPSA_NR_SUPPORTED_RATE          13      /* From 8000Hz to 192000Hz*/
 #define LVPSA_NR_SUPPORTED_SPEED         3      /* LOW, MEDIUM, HIGH                                                */
 
@@ -82,7 +72,8 @@
 
     LVPSA_ControlParams_t       CurrentParams;                      /* Current control parameters of the module                                                     */
     LVPSA_ControlParams_t       NewParams;                          /* New control parameters given by the user                                                     */
-    LVPSA_MemTab_t              MemoryTable;
+    void                        *pScratch;
+    /* Pointer to bundle scratch buffer */
 
     LVPSA_BPFilterPrecision_en *pBPFiltersPrecision;                /* Points a nBands elements array that contains the filter precision for each band              */
     Biquad_FLOAT_Instance_t          *pBP_Instances;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
index 81a88c5..b4d111e 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
@@ -79,8 +79,7 @@
     {
         return(LVPSA_ERROR_INVALIDPARAM);
     }
-
-    pScratch = (LVM_FLOAT*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress;
+    pScratch = (LVM_FLOAT*)pLVPSA_Inst->pScratch;
     pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer;
 
     /******************************************************************************
diff --git a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
index 0adfd1b..58ba8ad 100644
--- a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
+++ b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
@@ -71,13 +71,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory table */
-#define LVCS_MEMREGION_PERSISTENT_SLOW_DATA    0    /* Offset to the instance memory region */
-#define LVCS_MEMREGION_PERSISTENT_FAST_DATA    1    /* Offset to the persistent data memory region */
-#define LVCS_MEMREGION_PERSISTENT_FAST_COEF    2    /* Offset to the persistent coefficient memory region */
-#define LVCS_MEMREGION_TEMPORARY_FAST          3    /* Offset to temporary memory region */
-#define LVCS_NR_MEMORY_REGIONS                 4    /* Number of memory regions */
-
 /* Effect Level */
 #define LVCS_EFFECT_LOW                    16384    /* Effect scaling 50% */
 #define LVCS_EFFECT_MEDIUM                 24576    /* Effect scaling 75% */
@@ -104,24 +97,12 @@
     LVCS_MAX = LVM_MAXENUM
 } LVCS_Modes_en;
 
-/* Memory Types */
-typedef enum
-{
-    LVCS_SCRATCH        = 0,
-    LVCS_DATA           = 1,
-    LVCS_COEFFICIENT    = 2,
-    LVCS_PERSISTENT     = 3,
-    LVCS_MEMORYTYPE_MAX = LVM_MAXENUM
-} LVCS_MemoryTypes_en;
-
 /* Function return status */
 typedef enum
 {
     LVCS_SUCCESS        = 0,                        /* Successful return from a routine */
-    LVCS_ALIGNMENTERROR = 1,                        /* Memory alignment error */
-    LVCS_NULLADDRESS    = 2,                        /* NULL allocation address */
-    LVCS_TOOMANYSAMPLES = 3,                        /* Maximum block size exceeded */
-    LVCS_INVALIDBUFFER  = 4,                        /* Invalid buffer processing request */
+    LVCS_NULLADDRESS    = 1,                        /* NULL allocation address */
+    LVCS_TOOMANYSAMPLES = 2,                        /* Maximum block size exceeded */
     LVCS_STATUSMAX      = LVM_MAXENUM
 } LVCS_ReturnStatus_en;
 
@@ -166,20 +147,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/* Memory region definition */
-typedef struct
-{
-    LVM_UINT32              Size;                   /* Region size in bytes */
-    LVCS_MemoryTypes_en     Type;                   /* Region type */
-    void                    *pBaseAddress;          /* Pointer to the region base address */
-} LVCS_MemoryRegion_t;
-
-/* Memory table containing the region definitions */
-typedef struct
-{
-    LVCS_MemoryRegion_t Region[LVCS_NR_MEMORY_REGIONS]; /* One definition for each region */
-} LVCS_MemTab_t;
-
 /* Concert Sound parameter structure */
 typedef struct
 {
@@ -190,9 +157,7 @@
     LVM_Fs_en               SampleRate;             /* Sampling rate */
     LVM_INT16               EffectLevel;            /* Effect level */
     LVM_UINT16              ReverbLevel;            /* Reverb level in % */
-#ifdef SUPPORT_MC
     LVM_INT32               NrChannels;
-#endif
 } LVCS_Params_t;
 
 /* Concert Sound Capability structure */
@@ -213,82 +178,45 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-/****************************************************************************************/
-/*                                                                                      */
-/* FUNCTION:                LVCS_Memory                                                 */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) it is           */
-/*  passed the default capabilities, of these only the buffer processing setting is     */
-/*  used.                                                                               */
-/*                                                                                      */
-/*  When called for memory allocation the memory base address pointers are NULL on      */
-/*  return.                                                                             */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the              */
-/*  capabilities are ignored and the memory table returns the allocated memory and      */
-/*  base addresses used during initialisation.                                          */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pCapabilities           Pointer to the default capabilites                          */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVCS_Success            Succeeded                                                   */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVCS_Process function                   */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVCS_ReturnStatus_en LVCS_Memory(LVCS_Handle_t          hInstance,
-                                 LVCS_MemTab_t          *pMemoryTable,
-                                 LVCS_Capabilities_t    *pCapabilities);
-
-/****************************************************************************************/
-/*                                                                                      */
-/* FUNCTION:                LVCS_Init                                                   */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  Create and initialisation function for the Concert Sound module                     */
-/*                                                                                      */
-/*  This function can be used to create an algorithm instance by calling with           */
-/*  hInstance set to NULL. In this case the algorithm returns the new instance          */
-/*  handle.                                                                             */
-/*                                                                                      */
-/*  This function can be used to force a full re-initialisation of the algorithm        */
-/*  by calling with hInstance = Instance Handle. In this case the memory table          */
-/*  should be correct for the instance, this can be ensured by calling the function     */
-/*  LVCS_Memory before calling this function.                                           */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance handle                                             */
-/*  pMemoryTable            Pointer to the memory definition table                      */
-/*  pCapabilities           Pointer to the initialisation capabilities                  */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVCS_Success            Initialisation succeeded                                    */
-/*  LVCS_AlignmentError     Instance or scratch memory on incorrect alignment           */
-/*  LVCS_NullAddress        Instance or scratch memory has a NULL pointer               */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  The instance handle is the pointer to the base address of the first memory      */
-/*      region.                                                                         */
-/*  2.  This function must not be interrupted by the LVCS_Process function              */
-/*                                                                                      */
-/****************************************************************************************/
-
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:                LVCS_Init                                               */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*  Create and initialisation function for the Concert Sound module                 */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance              Pointer to instance handle                              */
+/*  pCapabilities           Pointer to the capabilities structure                   */
+/*  pScratch                Pointer to the scratch buffer                           */
+/*                                                                                  */
+/* RETURNS:                                                                         */
+/*  LVCS_Success            Initialisation succeeded                                */
+/*  LVDBE_NULLADDRESS       One or more memory has a NULL pointer                   */
+/*                                                                                  */
+/* NOTES:                                                                           */
+/*  1.  This function must not be interrupted by the LVCS_Process function          */
+/*                                                                                  */
+/************************************************************************************/
 LVCS_ReturnStatus_en LVCS_Init(LVCS_Handle_t            *phInstance,
-                               LVCS_MemTab_t            *pMemoryTable,
-                               LVCS_Capabilities_t      *pCapabilities);
+                               LVCS_Capabilities_t      *pCapabilities,
+                               void                     *pScratch);
+
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:                LVCS_DeInit                                             */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*  Free memories created during the LVCS_Init call including instance handle       */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance              Pointer to instance handle                              */
+/*                                                                                  */
+/* NOTES:                                                                           */
+/*  1.  This function must not be interrupted by the LVCS_Process function          */
+/*                                                                                  */
+/************************************************************************************/
+void LVCS_DeInit(LVCS_Handle_t          *phInstance);
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
index 431b7e3..abadae3 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
@@ -65,11 +65,8 @@
     BQ_FLOAT_Coefs_t      Coeffs;
     const BiquadA012B12CoefsSP_t *pEqualiserCoefTable;
 
-    pData = (LVCS_Data_t *) \
-                pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
-
-    pCoefficients = (LVCS_Coefficient_t *) \
-                pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+    pData         = (LVCS_Data_t *)pInstance->pData;
+    pCoefficients = (LVCS_Coefficient_t *)pInstance->pCoeff;
     /*
      * If the sample rate changes re-initialise the filters
      */
@@ -144,8 +141,7 @@
     LVCS_Equaliser_t    *pConfig   = (LVCS_Equaliser_t  *)&pInstance->Equaliser;
     LVCS_Coefficient_t  *pCoefficients;
 
-    pCoefficients = (LVCS_Coefficient_t *) \
-                  pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+    pCoefficients = (LVCS_Coefficient_t *)pInstance->pCoeff;
 
     /*
      * Check if the equaliser is required
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
index 630ecf7..312885c 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
@@ -20,99 +20,11 @@
 /*  Includes                                                                        */
 /*                                                                                  */
 /************************************************************************************/
-
+#include <stdlib.h>
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_Tables.h"
 
-/****************************************************************************************/
-/*                                                                                      */
-/* FUNCTION:                LVCS_Memory                                                 */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*  This function is used for memory allocation and free. It can be called in           */
-/*  two ways:                                                                           */
-/*                                                                                      */
-/*      hInstance = NULL                Returns the memory requirements                 */
-/*      hInstance = Instance handle     Returns the memory requirements and             */
-/*                                      allocated base addresses for the instance       */
-/*                                                                                      */
-/*  When this function is called for memory allocation (hInstance=NULL) it is           */
-/*  passed the default capabilities.                                                    */
-/*                                                                                      */
-/*  When called for memory allocation the memory base address pointers are NULL on      */
-/*  return.                                                                             */
-/*                                                                                      */
-/*  When the function is called for free (hInstance = Instance Handle) the              */
-/*  capabilities are ignored and the memory table returns the allocated memory and      */
-/*  base addresses used during initialisation.                                          */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  hInstance               Instance Handle                                             */
-/*  pMemoryTable            Pointer to an empty memory definition table                 */
-/*  pCapabilities           Pointer to the default capabilites                          */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  LVCS_Success            Succeeded                                                   */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*  1.  This function may be interrupted by the LVCS_Process function                   */
-/*                                                                                      */
-/****************************************************************************************/
-
-LVCS_ReturnStatus_en LVCS_Memory(LVCS_Handle_t          hInstance,
-                                 LVCS_MemTab_t          *pMemoryTable,
-                                 LVCS_Capabilities_t    *pCapabilities)
-{
-
-    LVM_UINT32          ScratchSize;
-    LVCS_Instance_t     *pInstance = (LVCS_Instance_t *)hInstance;
-
-    /*
-     * Fill in the memory table
-     */
-    if (hInstance == LVM_NULL)
-    {
-        /*
-         * Instance memory
-         */
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].Size         = (LVM_UINT32)sizeof(LVCS_Instance_t);
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].Type         = LVCS_PERSISTENT;
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = LVM_NULL;
-
-        /*
-         * Data memory
-         */
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].Size         = (LVM_UINT32)sizeof(LVCS_Data_t);
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].Type         = LVCS_DATA;
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress = LVM_NULL;
-
-        /*
-         * Coefficient memory
-         */
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].Size         = (LVM_UINT32)sizeof(LVCS_Coefficient_t);
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].Type         = LVCS_COEFFICIENT;
-        pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
-
-        /*
-         * Scratch memory
-         */
-        /* Inplace processing */
-        ScratchSize = (LVM_UINT32) \
-                        (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * pCapabilities->MaxBlockSize);
-        pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].Size         = ScratchSize;
-        pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].Type         = LVCS_SCRATCH;
-        pMemoryTable->Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress = LVM_NULL;
-    }
-    else
-    {
-        /* Read back memory allocation table */
-        *pMemoryTable = pInstance->MemoryTable;
-    }
-
-    return(LVCS_SUCCESS);
-}
-
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:                LVCS_Init                                               */
@@ -120,46 +32,38 @@
 /* DESCRIPTION:                                                                     */
 /*  Create and initialisation function for the Concert Sound module                 */
 /*                                                                                  */
-/*  This function can be used to create an algorithm instance by calling with       */
-/*  hInstance set to LVM_NULL. In this case the algorithm returns the new instance  */
-/*  handle.                                                                         */
-/*                                                                                  */
-/*  This function can be used to force a full re-initialisation of the algorithm    */
-/*  by calling with hInstance = Instance Handle. In this case the memory table      */
-/*  should be correct for the instance, this can be ensured by calling the function */
-/*  LVCS_Memory before calling this function.                                       */
-/*                                                                                  */
 /* PARAMETERS:                                                                      */
-/*  hInstance               Instance handle                                         */
-/*  pMemoryTable            Pointer to the memory definition table                  */
+/*  phInstance              Pointer to instance handle                              */
 /*  pCapabilities           Pointer to the capabilities structure                   */
+/*  pScratch                Pointer to scratch buffer                               */
 /*                                                                                  */
 /* RETURNS:                                                                         */
 /*  LVCS_Success            Initialisation succeeded                                */
+/*  LVDBE_NULLADDRESS       One or more memory has a NULL pointer - malloc failure  */
 /*                                                                                  */
 /* NOTES:                                                                           */
-/*  1.  The instance handle is the pointer to the base address of the first memory  */
-/*      region.                                                                     */
-/*  2.  This function must not be interrupted by the LVCS_Process function          */
-/*  3.  This function must be called with the same capabilities as used for the     */
-/*      call to the memory function                                                 */
+/*  1.  This function must not be interrupted by the LVCS_Process function          */
 /*                                                                                  */
 /************************************************************************************/
 
 LVCS_ReturnStatus_en LVCS_Init(LVCS_Handle_t         *phInstance,
-                               LVCS_MemTab_t         *pMemoryTable,
-                               LVCS_Capabilities_t   *pCapabilities)
+                               LVCS_Capabilities_t   *pCapabilities,
+                               void                  *pScratch)
 {
 
-    LVCS_Instance_t                 *pInstance;
-    LVCS_VolCorrect_t               *pLVCS_VolCorrectTable;
+    LVCS_Instance_t    *pInstance;
+    LVCS_VolCorrect_t  *pLVCS_VolCorrectTable;
 
     /*
-     * Set the instance handle if not already initialised
+     * Create the instance handle if not already initialised
      */
     if (*phInstance == LVM_NULL)
     {
-        *phInstance = (LVCS_Handle_t)pMemoryTable->Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress;
+        *phInstance = calloc(1, sizeof(*pInstance));
+    }
+    if (*phInstance == LVM_NULL)
+    {
+        return LVCS_NULLADDRESS;
     }
     pInstance =(LVCS_Instance_t  *)*phInstance;
 
@@ -168,10 +72,7 @@
      */
     pInstance->Capabilities = *pCapabilities;
 
-    /*
-     * Save the memory table in the instance structure
-     */
-    pInstance->MemoryTable = *pMemoryTable;
+    pInstance->pScratch     = pScratch;
 
     /*
      * Set all initial parameters to invalid to force a full initialisation
@@ -208,3 +109,35 @@
     return(LVCS_SUCCESS);
 }
 
+/************************************************************************************/
+/*                                                                                  */
+/* FUNCTION:                LVCS_DeInit                                             */
+/*                                                                                  */
+/* DESCRIPTION:                                                                     */
+/*  Free memories created during the LVCS_Init call including instance handle       */
+/*                                                                                  */
+/* PARAMETERS:                                                                      */
+/*  phInstance              Pointer to instance handle                              */
+/*                                                                                  */
+/* NOTES:                                                                           */
+/*  1.  This function must not be interrupted by the LVCS_Process function          */
+/*                                                                                  */
+/************************************************************************************/
+void LVCS_DeInit(LVCS_Handle_t *phInstance)
+{
+    LVCS_Instance_t *pInstance = (LVCS_Instance_t *)*phInstance;
+    if (pInstance == LVM_NULL) {
+        return;
+    }
+    if (pInstance->pCoeff != LVM_NULL) {
+        free(pInstance->pCoeff);
+        pInstance->pCoeff = LVM_NULL;
+    }
+    if (pInstance->pData != LVM_NULL) {
+        free(pInstance->pData);
+        pInstance->pData = LVM_NULL;
+    }
+    free(pInstance);
+    *phInstance = LVM_NULL;
+    return;
+}
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index 154ea55..7adfb50 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -54,12 +54,7 @@
 #define LVCS_COMPGAINFRAME          64          /* Compressor gain update interval */
 
 /* Memory */
-#ifdef SUPPORT_MC
 #define LVCS_SCRATCHBUFFERS              8      /* Number of buffers required for inplace processing */
-#else
-#define LVCS_SCRATCHBUFFERS              6      /* Number of buffers required for inplace processing */
-#endif
-#ifdef SUPPORT_MC
 /*
  * The Concert Surround module applies processing only on the first two
  * channels of a multichannel input. The data of first two channels is copied
@@ -67,7 +62,6 @@
  * are used for this purpose
  */
 #define LVCS_MC_SCRATCHBUFFERS           2
-#endif
 
 /* General */
 #define LVCS_INVALID                0xFFFF      /* Invalid init parameter */
@@ -110,7 +104,6 @@
 typedef struct
 {
     /* Public parameters */
-    LVCS_MemTab_t           MemoryTable;        /* Instance memory allocation table */
     LVCS_Params_t           Params;             /* Instance parameters */
     LVCS_Capabilities_t     Capabilities;       /* Initialisation capabilities */
 
@@ -133,6 +126,9 @@
     LVM_INT16               bTimerDone;                         /* Timer completion flag */
     LVM_Timer_Params_t      TimerParams;                        /* Timer parameters */
     LVM_Timer_Instance_t    TimerInstance;                      /* Timer instance */
+    void                    *pCoeff;           /* pointer to buffer for equaliser filter coeffs */
+    void                    *pData;            /* pointer to buffer for equaliser filter states */
+    void                    *pScratch;         /* Pointer to bundle scratch buffer */
 
 } LVCS_Instance_t;
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
index 8e09be2..72b4c8b 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
@@ -74,7 +74,6 @@
     LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
     LVM_FLOAT           *pScratch;
     LVCS_ReturnStatus_en err;
-#ifdef SUPPORT_MC
     LVM_FLOAT           *pStIn;
     LVM_INT32           channels = pInstance->Params.NrChannels;
 #define NrFrames NumSamples  // alias for clarity
@@ -89,15 +88,12 @@
     {
         channels = 2;
     }
-#endif
 
-    pScratch  = (LVM_FLOAT *) \
-                  pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+    pScratch  = (LVM_FLOAT *)pInstance->pScratch;
 
     /*
      * Check if the processing is inplace
      */
-#ifdef SUPPORT_MC
     /*
      * The pInput buffer holds the first 2 (Left, Right) channels information.
      * Hence the memory required by this buffer is 2 * NumFrames.
@@ -115,35 +111,13 @@
     Copy_Float((LVM_FLOAT *)pInput,
                (LVM_FLOAT *)pStIn,
                (LVM_INT16)(2 * NrFrames));
-#else
-    if (pInData == pOutData)
-    {
-        /* Processing inplace */
-        pInput = pScratch + (2 * NumSamples);
-        Copy_Float((LVM_FLOAT *)pInData,           /* Source */
-                   (LVM_FLOAT *)pInput,            /* Destination */
-                   (LVM_INT16)(2 * NumSamples));     /* Left and right */
-    }
-    else
-    {
-        /* Processing outplace */
-        pInput = pInData;
-    }
-#endif
     /*
      * Call the stereo enhancer
      */
-#ifdef SUPPORT_MC
     err = LVCS_StereoEnhancer(hInstance,              /* Instance handle */
                               pStIn,                  /* Pointer to the input data */
                               pOutData,               /* Pointer to the output data */
                               NrFrames);              /* Number of frames to process */
-#else
-    err = LVCS_StereoEnhancer(hInstance,              /* Instance handle */
-                              pInData,                    /* Pointer to the input data */
-                              pOutData,                   /* Pointer to the output data */
-                              NumSamples);                /* Number of samples to process */
-#endif
 
     /*
      * Call the reverb generator
@@ -210,7 +184,6 @@
 
     LVCS_Instance_t *pInstance = (LVCS_Instance_t  *)hInstance;
     LVCS_ReturnStatus_en err;
-#ifdef SUPPORT_MC
     /*Extract number of Channels info*/
     LVM_INT32 channels = pInstance->Params.NrChannels;
 #define NrFrames NumSamples  // alias for clarity
@@ -218,7 +191,6 @@
     {
         channels = 2;
     }
-#endif
     /*
      * Check the number of samples is not too large
      */
@@ -232,7 +204,6 @@
      */
     if (pInstance->Params.OperatingMode != LVCS_OFF)
     {
-#ifdef SUPPORT_MC
         LVM_FLOAT *pStereoOut;
         /*
          * LVCS_Process_CS uses output buffer to store intermediate outputs of StereoEnhancer,
@@ -248,10 +219,8 @@
            * second and fourth are used as input buffers by pInput and pStIn in LVCS_Process_CS.
            * Hence, pStereoOut is pointed to use unused third portion of scratch memory.
            */
-            pStereoOut = (LVM_FLOAT *) \
-                          pInstance->MemoryTable. \
-                          Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress +
-                          ((LVCS_SCRATCHBUFFERS - 4) * NrFrames);
+            pStereoOut = (LVM_FLOAT *)pInstance->pScratch +
+                                     ((LVCS_SCRATCHBUFFERS - 4) * NrFrames);
         }
         else
         {
@@ -265,12 +234,6 @@
                                   pInData,
                                   pStereoOut,
                                   NrFrames);
-#else
-            err = LVCS_Process_CS(hInstance,
-                                  pInData,
-                                  pOutData,
-                                  NumSamples);
-#endif
 
         /*
          * Compress to reduce expansion effect of Concert Sound and correct volume
@@ -289,17 +252,10 @@
 
             if(NumSamples < LVCS_COMPGAINFRAME)
             {
-#ifdef SUPPORT_MC
                 NonLinComp_Float(Gain,                    /* Compressor gain setting */
                                  pStereoOut,
                                  pStereoOut,
                                  (LVM_INT32)(2 * NrFrames));
-#else
-                NonLinComp_Float(Gain,                    /* Compressor gain setting */
-                                 pOutData,
-                                 pOutData,
-                                 (LVM_INT32)(2 * NumSamples));
-#endif
             }
             else
             {
@@ -328,11 +284,7 @@
 
                 FinalGain = Gain;
                 Gain = pInstance->CompressGain;
-#ifdef SUPPORT_MC
                 pOutPtr = pStereoOut;
-#else
-                pOutPtr = pOutData;
-#endif
 
                 while(SampleToProcess > 0)
                 {
@@ -396,33 +348,22 @@
                             (LVM_INT16)NumSamples);
             }
         }
-#ifdef SUPPORT_MC
         Copy_Float_Stereo_Mc(pInData,
                              pStereoOut,
                              pOutData,
                              NrFrames,
                              channels);
-#endif
     }
     else
     {
         if (pInData != pOutData)
         {
-#ifdef SUPPORT_MC
             /*
              * The algorithm is disabled so just copy the data
              */
             Copy_Float((LVM_FLOAT *)pInData,               /* Source */
                        (LVM_FLOAT *)pOutData,                  /* Destination */
                        (LVM_INT16)(channels * NrFrames));    /* All Channels*/
-#else
-            /*
-             * The algorithm is disabled so just copy the data
-             */
-            Copy_Float((LVM_FLOAT *)pInData,               /* Source */
-                       (LVM_FLOAT *)pOutData,                  /* Destination */
-                       (LVM_INT16)(2 * NumSamples));             /* Left and right */
-#endif
         }
     }
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
index d0e6e09..441b667 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
@@ -20,7 +20,7 @@
 /*  Includes                                                                        */
 /*                                                                                  */
 /************************************************************************************/
-
+#include <stdlib.h>
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_ReverbGenerator.h"
@@ -70,11 +70,31 @@
     BQ_FLOAT_Coefs_t         Coeffs;
     const BiquadA012B12CoefsSP_t  *pReverbCoefTable;
 
-    pData = (LVCS_Data_t *) \
-                 pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
-
-    pCoefficients = (LVCS_Coefficient_t *) \
-                 pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+    if (pInstance->pData == LVM_NULL)
+    {
+        pInstance->pData = pData = (LVCS_Data_t *)calloc(1, sizeof(*pData));
+        if (pData == LVM_NULL)
+        {
+            return LVCS_NULLADDRESS;
+        }
+    }
+    else
+    {
+        pData = (LVCS_Data_t *)pInstance->pData;
+    }
+    if (pInstance->pCoeff == LVM_NULL)
+    {
+        pInstance->pCoeff = pCoefficients = (LVCS_Coefficient_t *)calloc(1, \
+                                                                          sizeof(*pCoefficients));
+        if (pCoefficients == LVM_NULL)
+        {
+            return LVCS_NULLADDRESS;
+        }
+    }
+    else
+    {
+        pCoefficients = (LVCS_Coefficient_t *)pInstance->pCoeff;
+    }
 
     /*
      * Initialise the delay and filters if:
@@ -192,11 +212,8 @@
     LVCS_Coefficient_t      *pCoefficients;
     LVM_FLOAT               *pScratch;
 
-    pCoefficients = (LVCS_Coefficient_t *)\
-                   pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
-
-    pScratch  = (LVM_FLOAT *)\
-                    pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+    pCoefficients = (LVCS_Coefficient_t *)pInstance->pCoeff;
+    pScratch      = (LVM_FLOAT *)pInstance->pScratch;
 
     /*
      * Copy the data to the output in outplace processing
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
index 7fd8444..6929015 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
@@ -62,11 +62,8 @@
     BQ_FLOAT_Coefs_t          CoeffsSide;
     const BiquadA012B12CoefsSP_t *pSESideCoefs;
 
-    pData     = (LVCS_Data_t *) \
-                  pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress;
-
-    pCoefficient = (LVCS_Coefficient_t *) \
-                  pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
+    pData        = (LVCS_Data_t *)pInstance->pData;
+    pCoefficient = (LVCS_Coefficient_t *)pInstance->pCoeff;
 
     /*
      * If the sample rate or speaker type has changed update the filters
@@ -188,12 +185,8 @@
     LVCS_StereoEnhancer_t   *pConfig   = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer;
     LVCS_Coefficient_t      *pCoefficient;
     LVM_FLOAT               *pScratch;
-
-    pCoefficient = (LVCS_Coefficient_t *) \
-                   pInstance->MemoryTable.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress;
-
-    pScratch  = (LVM_FLOAT *) \
-                    pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+    pCoefficient = (LVCS_Coefficient_t *)pInstance->pCoeff;
+    pScratch     = (LVM_FLOAT *)pInstance->pScratch;
     /*
      * Check if the Stereo Enhancer is enabled
      */
diff --git a/media/libeffects/lvm/tests/Android.bp b/media/libeffects/lvm/tests/Android.bp
index 674c246..aea7703 100644
--- a/media/libeffects/lvm/tests/Android.bp
+++ b/media/libeffects/lvm/tests/Android.bp
@@ -44,6 +44,36 @@
 }
 
 cc_test {
+    name: "reverb_test",
+    host_supported: false,
+    proprietary: true,
+
+    include_dirs: [
+        "frameworks/av/media/libeffects/lvm/wrapper/Reverb"
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+        "libreverbwrapper",
+    ],
+
+    srcs: [
+        "reverb_test.cpp",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+cc_test {
     name: "snr",
     host_supported: false,
 
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
new file mode 100755
index 0000000..0c3b0b5
--- /dev/null
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+#
+# reverb test
+#
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Android build environment not set"
+    exit -1
+fi
+
+# ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+mm -j
+
+echo "waiting for device"
+
+adb root && adb wait-for-device remount
+
+# location of test files
+testdir="/data/local/tmp/revTest"
+
+echo "========================================"
+echo "testing reverb"
+adb shell mkdir -p $testdir
+adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
+
+E_VAL=1
+cmds="adb push $OUT/testcases/reverb_test/arm/reverb_test $testdir"
+
+fs_arr=(
+    8000
+    16000
+    22050
+    32000
+    44100
+    48000
+    88200
+    96000
+    176400
+    192000
+)
+
+flags_arr=(
+    "--M --fch 1"
+    "--fch 2"
+)
+
+# run reverb at different configs, saving only the stereo channel
+# pair.
+error_count=0
+testcase_count=0
+for cmd in "${cmds[@]}"
+do
+    $cmd
+    for flags in "${flags_arr[@]}"
+    do
+        for preset_val in {0..6}
+        do
+            for fs in ${fs_arr[*]}
+            do
+                for chMask in {0..22}
+                do
+                    adb shell LD_LIBRARY_PATH=/system/vendor/lib/soundfx $testdir/reverb_test \
+                        --input $testdir/sinesweepraw.raw \
+                        --output $testdir/sinesweep_$((chMask))_$((fs)).raw \
+                        --chMask $chMask $flags --fs $fs --preset $preset_val
+
+                    shell_ret=$?
+                    if [ $shell_ret -ne 0 ]; then
+                        echo "error: $shell_ret"
+                        ((++error_count))
+                    fi
+
+                    if [[ "$chMask" -gt 0 ]] && [[ $flags != *"--fch 2"* ]]
+                    then
+                        # single channel files should be identical to higher channel
+                        # computation (first channel).
+                        adb shell cmp $testdir/sinesweep_0_$((fs)).raw \
+                            $testdir/sinesweep_$((chMask))_$((fs)).raw
+                    elif [[ "$chMask" -gt 1 ]]
+                    then
+                        # two channel files should be identical to higher channel
+                        # computation (first 2 channels).
+                        adb shell cmp $testdir/sinesweep_1_$((fs)).raw \
+                            $testdir/sinesweep_$((chMask))_$((fs)).raw
+                    fi
+
+                    # cmp returns EXIT_FAILURE on mismatch.
+                    shell_ret=$?
+                    if [ $shell_ret -ne 0 ]; then
+                        echo "error: $shell_ret"
+                        ((++error_count))
+                    fi
+                    ((++testcase_count))
+                done
+            done
+        done
+    done
+done
+
+adb shell rm -r $testdir
+echo "$testcase_count tests performed"
+echo "$error_count errors"
+exit $error_count
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index a4ace6c..59b27ad 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -182,49 +182,6 @@
   printf("\n           Enable Equalizer");
 }
 
-//----------------------------------------------------------------------------
-// LvmEffect_free()
-//----------------------------------------------------------------------------
-// Purpose: Free all memory associated with the Bundle.
-//
-// Inputs:
-//  pContext:   effect engine context
-//
-// Outputs:
-//
-//----------------------------------------------------------------------------
-
-void LvmEffect_free(struct EffectContext *pContext) {
-  LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
-  LVM_MemTab_t MemTab;
-
-  /* Free the algorithm memory */
-  LvmStatus = LVM_GetMemoryTable(pContext->pBundledContext->hInstance, &MemTab,
-                                 LVM_NULL);
-
-  LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmEffect_free")
-
-  for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
-    if (MemTab.Region[i].Size != 0) {
-      if (MemTab.Region[i].pBaseAddress != NULL) {
-        ALOGV("\tLvmEffect_free - START freeing %" PRIu32
-              " bytes for region %u at %p\n",
-              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-
-        free(MemTab.Region[i].pBaseAddress);
-
-        ALOGV("\tLvmEffect_free - END   freeing %" PRIu32
-              " bytes for region %u at %p\n",
-              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-      } else {
-        ALOGE(
-            "\tLVM_ERROR : LvmEffect_free - trying to free with NULL pointer "
-            "%" PRIu32 " bytes for region %u at %p ERROR\n",
-            MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-      }
-    }
-  }
-} /* end LvmEffect_free */
 
 //----------------------------------------------------------------------------
 // LvmBundle_init()
@@ -263,8 +220,7 @@
     ALOGV(
         "\tLvmBundle_init pContext->pBassBoost != NULL "
         "-> Calling pContext->pBassBoost->free()");
-
-    LvmEffect_free(pContext);
+    LVM_DelInstanceHandle(&pContext->pBundledContext->hInstance);
 
     ALOGV(
         "\tLvmBundle_init pContext->pBassBoost != NULL "
@@ -276,8 +232,6 @@
   LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
   LVM_HeadroomParams_t HeadroomParams;         /* Headroom parameters */
   LVM_HeadroomBandDef_t HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS];
-  LVM_MemTab_t MemTab; /* Memory allocation table */
-  bool bMallocFailure = LVM_FALSE;
 
   /* Set the capabilities */
   InstParams.BufferMode = LVM_UNMANAGED_BUFFERS;
@@ -285,63 +239,8 @@
   InstParams.EQNB_NumBands = MAX_NUM_BANDS;
   InstParams.PSA_Included = LVM_PSA_ON;
 
-  /* Allocate memory, forcing alignment */
-  LvmStatus = LVM_GetMemoryTable(LVM_NULL, &MemTab, &InstParams);
-
-  LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmBundle_init");
-  if (LvmStatus != LVM_SUCCESS) return -EINVAL;
-
-  ALOGV("\tCreateInstance Succesfully called LVM_GetMemoryTable\n");
-
-  /* Allocate memory */
-  for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
-    if (MemTab.Region[i].Size != 0) {
-      MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
-
-      if (MemTab.Region[i].pBaseAddress == LVM_NULL) {
-        ALOGE(
-            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate "
-            "%" PRIu32 " bytes for region %u\n",
-            MemTab.Region[i].Size, i);
-        bMallocFailure = LVM_TRUE;
-        break;
-      } else {
-        ALOGV("\tLvmBundle_init CreateInstance allocated %" PRIu32
-              " bytes for region %u at %p\n",
-              MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-      }
-    }
-  }
-
-  /* If one or more of the memory regions failed to allocate, free the regions
-   * that were
-   * succesfully allocated and return with an error
-   */
-  if (bMallocFailure == LVM_TRUE) {
-    for (int i = 0; i < LVM_NR_MEMORY_REGIONS; i++) {
-      if (MemTab.Region[i].pBaseAddress == LVM_NULL) {
-        ALOGE(
-            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate "
-            "%" PRIu32 " bytes for region %u Not freeing\n",
-            MemTab.Region[i].Size, i);
-      } else {
-        ALOGE(
-            "\tLVM_ERROR :LvmBundle_init CreateInstance Failed: but allocated "
-            "%" PRIu32 " bytes for region %u at %p- free\n",
-            MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-        free(MemTab.Region[i].pBaseAddress);
-      }
-    }
-    return -EINVAL;
-  }
-  ALOGV("\tLvmBundle_init CreateInstance Succesfully malloc'd memory\n");
-
-  /* Initialise */
-  pContext->pBundledContext->hInstance = LVM_NULL;
-
-  /* Init sets the instance handle */
   LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance,
-                                    &MemTab, &InstParams);
+                                    &InstParams);
 
   LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "LvmBundle_init");
   if (LvmStatus != LVM_SUCCESS) return -EINVAL;
@@ -812,7 +711,7 @@
   /* Free the allocated buffers */
   if (context.pBundledContext != nullptr) {
     if (context.pBundledContext->hInstance != nullptr) {
-      LvmEffect_free(&context);
+      LVM_DelInstanceHandle(&context.pBundledContext->hInstance);
     }
     free(context.pBundledContext);
   }
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
new file mode 100644
index 0000000..f403229
--- /dev/null
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2020 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 <assert.h>
+#include <getopt.h>
+#include <inttypes.h>
+#include <iterator>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <log/log.h>
+#include <system/audio.h>
+
+#include "EffectReverb.h"
+
+// This is the only symbol that needs to be exported
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+
+// Global Variables
+enum ReverbParams {
+  ARG_HELP = 1,
+  ARG_INPUT,
+  ARG_OUTPUT,
+  ARG_FS,
+  ARG_CH_MASK,
+  ARG_PRESET,
+  ARG_AUX,
+  ARG_MONO_MODE,
+  ARG_FILE_CH,
+};
+
+const effect_uuid_t kReverbUuids[] = {
+    {0x172cdf00,
+     0xa3bc,
+     0x11df,
+     0xa72f,
+     {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-insert mode
+    {0xf29a1400,
+     0xa3bb,
+     0x11df,
+     0x8ddc,
+     {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-aux mode
+};
+
+// structures
+struct reverbConfigParams_t {
+  int fChannels = 2;
+  int monoMode = false;
+  int frameLength = 256;
+  int preset = 0;
+  int nrChannels = 2;
+  int sampleRate = 48000;
+  int auxiliary = 0;
+  audio_channel_mask_t chMask = AUDIO_CHANNEL_OUT_STEREO;
+};
+
+constexpr audio_channel_mask_t kReverbConfigChMask[] = {
+    AUDIO_CHANNEL_OUT_MONO,
+    AUDIO_CHANNEL_OUT_STEREO,
+    AUDIO_CHANNEL_OUT_2POINT1,
+    AUDIO_CHANNEL_OUT_2POINT0POINT2,
+    AUDIO_CHANNEL_OUT_QUAD,
+    AUDIO_CHANNEL_OUT_QUAD_BACK,
+    AUDIO_CHANNEL_OUT_QUAD_SIDE,
+    AUDIO_CHANNEL_OUT_SURROUND,
+    (1 << 4) - 1,
+    AUDIO_CHANNEL_OUT_2POINT1POINT2,
+    AUDIO_CHANNEL_OUT_3POINT0POINT2,
+    AUDIO_CHANNEL_OUT_PENTA,
+    (1 << 5) - 1,
+    AUDIO_CHANNEL_OUT_3POINT1POINT2,
+    AUDIO_CHANNEL_OUT_5POINT1,
+    AUDIO_CHANNEL_OUT_5POINT1_BACK,
+    AUDIO_CHANNEL_OUT_5POINT1_SIDE,
+    (1 << 6) - 1,
+    AUDIO_CHANNEL_OUT_6POINT1,
+    (1 << 7) - 1,
+    AUDIO_CHANNEL_OUT_5POINT1POINT2,
+    AUDIO_CHANNEL_OUT_7POINT1,
+    (1 << 8) - 1,
+};
+
+constexpr int kReverbConfigChMaskCount = std::size(kReverbConfigChMask);
+
+int reverbCreateEffect(effect_handle_t *pEffectHandle, effect_config_t *pConfig, int sessionId,
+                       int ioId, int auxFlag) {
+  if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kReverbUuids[auxFlag], sessionId,
+                                                               ioId, pEffectHandle);
+      status != 0) {
+    ALOGE("Reverb create returned an error = %d\n", status);
+    return EXIT_FAILURE;
+  }
+  int reply = 0;
+  uint32_t replySize = sizeof(reply);
+  (**pEffectHandle)
+      ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), pConfig,
+                &replySize, &reply);
+  return reply;
+}
+
+int reverbSetConfigParam(uint32_t paramType, uint32_t paramValue, effect_handle_t effectHandle) {
+  int reply = 0;
+  uint32_t replySize = sizeof(reply);
+  uint32_t paramData[2] = {paramType, paramValue};
+  effect_param_t *effectParam =
+      (effect_param_t *)malloc(sizeof(*effectParam) + sizeof(paramData));
+  memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+  effectParam->psize = sizeof(paramData[0]);
+  effectParam->vsize = sizeof(paramData[1]);
+  int status =
+      (*effectHandle)
+          ->command(effectHandle, EFFECT_CMD_SET_PARAM,
+                    sizeof(effect_param_t) + sizeof(paramData), effectParam, &replySize, &reply);
+  free(effectParam);
+  if (status != 0) {
+    ALOGE("Reverb set config returned an error = %d\n", status);
+    return status;
+  }
+  return reply;
+}
+
+void printUsage() {
+  printf("\nUsage: ");
+  printf("\n     <executable> [options]\n");
+  printf("\nwhere options are, ");
+  printf("\n     --input <inputfile>");
+  printf("\n           path to the input file");
+  printf("\n     --output <outputfile>");
+  printf("\n           path to the output file");
+  printf("\n     --help");
+  printf("\n           prints this usage information");
+  printf("\n     --chMask <channel_mask>\n");
+  printf("\n           0  - AUDIO_CHANNEL_OUT_MONO");
+  printf("\n           1  - AUDIO_CHANNEL_OUT_STEREO");
+  printf("\n           2  - AUDIO_CHANNEL_OUT_2POINT1");
+  printf("\n           3  - AUDIO_CHANNEL_OUT_2POINT0POINT2");
+  printf("\n           4  - AUDIO_CHANNEL_OUT_QUAD");
+  printf("\n           5  - AUDIO_CHANNEL_OUT_QUAD_BACK");
+  printf("\n           6  - AUDIO_CHANNEL_OUT_QUAD_SIDE");
+  printf("\n           7  - AUDIO_CHANNEL_OUT_SURROUND");
+  printf("\n           8  - canonical channel index mask for 4 ch: (1 << 4) - 1");
+  printf("\n           9  - AUDIO_CHANNEL_OUT_2POINT1POINT2");
+  printf("\n           10 - AUDIO_CHANNEL_OUT_3POINT0POINT2");
+  printf("\n           11 - AUDIO_CHANNEL_OUT_PENTA");
+  printf("\n           12 - canonical channel index mask for 5 ch: (1 << 5) - 1");
+  printf("\n           13 - AUDIO_CHANNEL_OUT_3POINT1POINT2");
+  printf("\n           14 - AUDIO_CHANNEL_OUT_5POINT1");
+  printf("\n           15 - AUDIO_CHANNEL_OUT_5POINT1_BACK");
+  printf("\n           16 - AUDIO_CHANNEL_OUT_5POINT1_SIDE");
+  printf("\n           17 - canonical channel index mask for 6 ch: (1 << 6) - 1");
+  printf("\n           18 - AUDIO_CHANNEL_OUT_6POINT1");
+  printf("\n           19 - canonical channel index mask for 7 ch: (1 << 7) - 1");
+  printf("\n           20 - AUDIO_CHANNEL_OUT_5POINT1POINT2");
+  printf("\n           21 - AUDIO_CHANNEL_OUT_7POINT1");
+  printf("\n           22 - canonical channel index mask for 8 ch: (1 << 8) - 1");
+  printf("\n           default 0");
+  printf("\n     --fs <sampling_freq>");
+  printf("\n           Sampling frequency in Hz, default 48000.");
+  printf("\n     --preset <preset_value>");
+  printf("\n           0 - None");
+  printf("\n           1 - Small Room");
+  printf("\n           2 - Medium Room");
+  printf("\n           3 - Large Room");
+  printf("\n           4 - Medium Hall");
+  printf("\n           5 - Large Hall");
+  printf("\n           6 - Plate");
+  printf("\n           default 0");
+  printf("\n     --fch <file_channels>");
+  printf("\n           number of channels in input file (1 through 8), default 1");
+  printf("\n     --M");
+  printf("\n           Mono mode (force all input audio channels to be identical)");
+  printf("\n     --aux <auxiliary_flag> ");
+  printf("\n           0 - Insert Mode on");
+  printf("\n           1 - auxiliary Mode on");
+  printf("\n           default 0");
+  printf("\n");
+}
+
+int main(int argc, const char *argv[]) {
+  if (argc == 1) {
+    printUsage();
+    return EXIT_FAILURE;
+  }
+
+  reverbConfigParams_t revConfigParams{};  // default initialize
+  const char *inputFile = nullptr;
+  const char *outputFile = nullptr;
+
+  const option long_opts[] = {
+      {"help", no_argument, nullptr, ARG_HELP},
+      {"input", required_argument, nullptr, ARG_INPUT},
+      {"output", required_argument, nullptr, ARG_OUTPUT},
+      {"fs", required_argument, nullptr, ARG_FS},
+      {"chMask", required_argument, nullptr, ARG_CH_MASK},
+      {"preset", required_argument, nullptr, ARG_PRESET},
+      {"aux", required_argument, nullptr, ARG_AUX},
+      {"M", no_argument, &revConfigParams.monoMode, true},
+      {"fch", required_argument, nullptr, ARG_FILE_CH},
+      {nullptr, 0, nullptr, 0},
+  };
+
+  while (true) {
+    const int opt = getopt_long(argc, (char *const *)argv, "i:o:", long_opts, nullptr);
+    if (opt == -1) {
+      break;
+    }
+    switch (opt) {
+      case ARG_HELP:
+        printUsage();
+        return EXIT_SUCCESS;
+      case ARG_INPUT: {
+        inputFile = (char *)optarg;
+        break;
+      }
+      case ARG_OUTPUT: {
+        outputFile = (char *)optarg;
+        break;
+      }
+      case ARG_FS: {
+        revConfigParams.sampleRate = atoi(optarg);
+        break;
+      }
+      case ARG_CH_MASK: {
+        int chMaskIdx = atoi(optarg);
+        if (chMaskIdx < 0 or chMaskIdx > kReverbConfigChMaskCount) {
+          ALOGE("Channel Mask index not in correct range\n");
+          printUsage();
+          return EXIT_FAILURE;
+        }
+        revConfigParams.chMask = kReverbConfigChMask[chMaskIdx];
+        break;
+      }
+      case ARG_PRESET: {
+        revConfigParams.preset = atoi(optarg);
+        break;
+      }
+      case ARG_AUX: {
+        revConfigParams.auxiliary = atoi(optarg);
+        break;
+      }
+      case ARG_MONO_MODE: {
+        break;
+      }
+      case ARG_FILE_CH: {
+        revConfigParams.fChannels = atoi(optarg);
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  if (inputFile == nullptr) {
+    ALOGE("Error: missing input files\n");
+    printUsage();
+    return EXIT_FAILURE;
+  }
+  std::unique_ptr<FILE, decltype(&fclose)> inputFp(fopen(inputFile, "rb"), &fclose);
+
+  if (inputFp == nullptr) {
+    ALOGE("Cannot open input file %s\n", inputFile);
+    return EXIT_FAILURE;
+  }
+
+  if (outputFile == nullptr) {
+    ALOGE("Error: missing output files\n");
+    printUsage();
+    return EXIT_FAILURE;
+  }
+  std::unique_ptr<FILE, decltype(&fclose)> outputFp(fopen(outputFile, "wb"), &fclose);
+
+  if (outputFp == nullptr) {
+    ALOGE("Cannot open output file %s\n", outputFile);
+    return EXIT_FAILURE;
+  }
+
+  int32_t sessionId = 1;
+  int32_t ioId = 1;
+  effect_handle_t effectHandle = nullptr;
+  effect_config_t config;
+  config.inputCfg.samplingRate = config.outputCfg.samplingRate = revConfigParams.sampleRate;
+  config.inputCfg.channels = config.outputCfg.channels = revConfigParams.chMask;
+  config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+  if (AUDIO_CHANNEL_OUT_MONO == revConfigParams.chMask) {
+    config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+  }
+  if (int status =
+          reverbCreateEffect(&effectHandle, &config, sessionId, ioId, revConfigParams.auxiliary);
+      status != 0) {
+    ALOGE("Create effect call returned error %i", status);
+    return EXIT_FAILURE;
+  }
+
+  int reply = 0;
+  uint32_t replySize = sizeof(reply);
+  (*effectHandle)->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
+  if (reply != 0) {
+    ALOGE("Command enable call returned error %d\n", reply);
+    return EXIT_FAILURE;
+  }
+
+  if (int status = reverbSetConfigParam(REVERB_PARAM_PRESET, (uint32_t)revConfigParams.preset,
+                                        effectHandle);
+      status != 0) {
+    ALOGE("Invalid reverb preset. Error %d\n", status);
+    return EXIT_FAILURE;
+  }
+
+  revConfigParams.nrChannels = audio_channel_count_from_out_mask(revConfigParams.chMask);
+  const int channelCount = revConfigParams.nrChannels;
+  const int frameLength = revConfigParams.frameLength;
+#ifdef BYPASS_EXEC
+  const int frameSize = (int)channelCount * sizeof(float);
+#endif
+  const int ioChannelCount = revConfigParams.fChannels;
+  const int ioFrameSize = ioChannelCount * sizeof(short);
+  const int maxChannelCount = std::max(channelCount, ioChannelCount);
+  /*
+   * Mono input will be converted to 2 channels internally in the process call
+   * by copying the same data into the second channel.
+   * Hence when channelCount is 1, output buffer should be allocated for
+   * 2 channels. The outChannelCount takes care of allocation of sufficient
+   * memory for the output buffer.
+   */
+  const int outChannelCount = (channelCount == 1 ? 2 : channelCount);
+
+  std::vector<short> in(frameLength * maxChannelCount);
+  std::vector<short> out(frameLength * maxChannelCount);
+  std::vector<float> floatIn(frameLength * channelCount);
+  std::vector<float> floatOut(frameLength * outChannelCount);
+
+  int frameCounter = 0;
+
+  while (fread(in.data(), ioFrameSize, frameLength, inputFp.get()) == (size_t)frameLength) {
+    if (ioChannelCount != channelCount) {
+      adjust_channels(in.data(), ioChannelCount, in.data(), channelCount, sizeof(short),
+                      frameLength * ioFrameSize);
+    }
+    memcpy_to_float_from_i16(floatIn.data(), in.data(), frameLength * channelCount);
+
+    // Mono mode will replicate the first channel to all other channels.
+    // This ensures all audio channels are identical. This is useful for testing
+    // Bass Boost, which extracts a mono signal for processing.
+    if (revConfigParams.monoMode && channelCount > 1) {
+      for (int i = 0; i < frameLength; ++i) {
+        auto *fp = &floatIn[i * channelCount];
+        std::fill(fp + 1, fp + channelCount, *fp);  // replicate ch 0
+      }
+    }
+
+    audio_buffer_t inputBuffer, outputBuffer;
+    inputBuffer.frameCount = outputBuffer.frameCount = frameLength;
+    inputBuffer.f32 = floatIn.data();
+    outputBuffer.f32 = floatOut.data();
+#ifndef BYPASS_EXEC
+    if (int status = (*effectHandle)->process(effectHandle, &inputBuffer, &outputBuffer);
+        status != 0) {
+      ALOGE("\nError: Process returned with error %d\n", status);
+      return EXIT_FAILURE;
+    }
+#else
+    memcpy(floatOut.data(), floatIn.data(), frameLength * frameSize);
+#endif
+    memcpy_to_i16_from_float(out.data(), floatOut.data(), frameLength * outChannelCount);
+
+    if (ioChannelCount != outChannelCount) {
+      adjust_channels(out.data(), outChannelCount, out.data(), ioChannelCount, sizeof(short),
+                      frameLength * outChannelCount * sizeof(short));
+    }
+    (void)fwrite(out.data(), ioFrameSize, frameLength, outputFp.get());
+    frameCounter += frameLength;
+  }
+
+  if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle);
+      status != 0) {
+    ALOGE("Audio Preprocessing release returned an error = %d\n", status);
+    return EXIT_FAILURE;
+  }
+  printf("frameCounter: [%d]\n", frameCounter);
+
+  return EXIT_SUCCESS;
+}
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index afc4220..f08caec 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -13,7 +13,6 @@
 
     cppflags: [
         "-fvisibility=hidden",
-        "-DSUPPORT_MC",
 
         "-Wall",
         "-Werror",
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 6fca0e7..dac283e 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -136,7 +136,6 @@
 int  LvmBundle_init            (EffectContext *pContext);
 int  LvmEffect_enable          (EffectContext *pContext);
 int  LvmEffect_disable         (EffectContext *pContext);
-void LvmEffect_free            (EffectContext *pContext);
 int  Effect_setConfig          (EffectContext *pContext, effect_config_t *pConfig);
 void Effect_getConfig          (EffectContext *pContext, effect_config_t *pConfig);
 int  BassBoost_setParameter    (EffectContext *pContext,
@@ -433,7 +432,7 @@
         pSessionContext->bBundledEffectsEnabled = LVM_FALSE;
         pSessionContext->pBundledContext = LVM_NULL;
         ALOGV("\tEffectRelease: Freeing LVM Bundle memory\n");
-        LvmEffect_free(pContext);
+        LVM_DelInstanceHandle(&pContext->pBundledContext->hInstance);
         ALOGV("\tEffectRelease: Deleting LVM Bundle context %p\n", pContext->pBundledContext);
         if (pContext->pBundledContext->workBuffer != NULL) {
             free(pContext->pBundledContext->workBuffer);
@@ -529,8 +528,7 @@
     if (pContext->pBundledContext->hInstance != NULL){
         ALOGV("\tLvmBundle_init pContext->pBassBoost != NULL "
                 "-> Calling pContext->pBassBoost->free()");
-
-        LvmEffect_free(pContext);
+        LVM_DelInstanceHandle(&pContext->pBundledContext->hInstance);
 
         ALOGV("\tLvmBundle_init pContext->pBassBoost != NULL "
                 "-> Called pContext->pBassBoost->free()");
@@ -542,8 +540,6 @@
     LVM_EQNB_BandDef_t      BandDefs[MAX_NUM_BANDS];        /* Equaliser band definitions */
     LVM_HeadroomParams_t    HeadroomParams;                 /* Headroom parameters */
     LVM_HeadroomBandDef_t   HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS];
-    LVM_MemTab_t            MemTab;                         /* Memory allocation table */
-    bool                    bMallocFailure = LVM_FALSE;
 
     /* Set the capabilities */
     InstParams.BufferMode       = LVM_UNMANAGED_BUFFERS;
@@ -551,58 +547,7 @@
     InstParams.EQNB_NumBands    = MAX_NUM_BANDS;
     InstParams.PSA_Included     = LVM_PSA_ON;
 
-    /* Allocate memory, forcing alignment */
-    LvmStatus = LVM_GetMemoryTable(LVM_NULL,
-                                  &MemTab,
-                                  &InstParams);
-
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmBundle_init")
-    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-
-    ALOGV("\tCreateInstance Succesfully called LVM_GetMemoryTable\n");
-
-    /* Allocate memory */
-    for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
-        if (MemTab.Region[i].Size != 0){
-            MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
-
-            if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                ALOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %" PRIu32
-                        " bytes for region %u\n", MemTab.Region[i].Size, i );
-                bMallocFailure = LVM_TRUE;
-            }else{
-                ALOGV("\tLvmBundle_init CreateInstance allocated %" PRIu32
-                        " bytes for region %u at %p\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-            }
-        }
-    }
-
-    /* If one or more of the memory regions failed to allocate, free the regions that were
-     * succesfully allocated and return with an error
-     */
-    if(bMallocFailure == LVM_TRUE){
-        for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
-            if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                ALOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %" PRIu32
-                        " bytes for region %u Not freeing\n", MemTab.Region[i].Size, i );
-            }else{
-                ALOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed: but allocated %" PRIu32
-                     " bytes for region %u at %p- free\n",
-                     MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-                free(MemTab.Region[i].pBaseAddress);
-            }
-        }
-        return -EINVAL;
-    }
-    ALOGV("\tLvmBundle_init CreateInstance Succesfully malloc'd memory\n");
-
-    /* Initialise */
-    pContext->pBundledContext->hInstance = LVM_NULL;
-
-    /* Init sets the instance handle */
     LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance,
-                                      &MemTab,
                                       &InstParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "LvmBundle_init")
@@ -618,9 +563,7 @@
     params.SpeakerType            = LVM_HEADPHONES;
 
     pContext->pBundledContext->SampleRate = LVM_FS_44100;
-#ifdef SUPPORT_MC
     pContext->pBundledContext->ChMask = AUDIO_CHANNEL_OUT_STEREO;
-#endif
 
     /* Concert Sound parameters */
     params.VirtualizerOperatingMode   = LVM_MODE_OFF;
@@ -666,11 +609,9 @@
     params.TE_OperatingMode       = LVM_TE_OFF;
     params.TE_EffectLevel         = 0;
 
-#ifdef SUPPORT_MC
     params.NrChannels             =
         audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
     params.ChMask                 = AUDIO_CHANNEL_OUT_STEREO;
-#endif
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance,
                                          &params);
@@ -1030,41 +971,6 @@
     return 0;
 }
 
-//----------------------------------------------------------------------------
-// LvmEffect_free()
-//----------------------------------------------------------------------------
-// Purpose: Free all memory associated with the Bundle.
-//
-// Inputs:
-//  pContext:   effect engine context
-//
-// Outputs:
-//
-//----------------------------------------------------------------------------
-
-void LvmEffect_free(EffectContext *pContext){
-    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;         /* Function call status */
-    LVM_MemTab_t            MemTab;
-
-    /* Free the algorithm memory */
-    LvmStatus = LVM_GetMemoryTable(pContext->pBundledContext->hInstance,
-                                   &MemTab,
-                                   LVM_NULL);
-
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "LvmEffect_free")
-
-    for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
-        if (MemTab.Region[i].Size != 0){
-            if (MemTab.Region[i].pBaseAddress != NULL){
-                free(MemTab.Region[i].pBaseAddress);
-            }else{
-                ALOGV("\tLVM_ERROR : LvmEffect_free - trying to free with NULL pointer %" PRIu32
-                        " bytes for region %u at %p ERROR\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
-            }
-        }
-    }
-}    /* end LvmEffect_free */
 
 //----------------------------------------------------------------------------
 // Effect_setConfig()
@@ -1090,11 +996,7 @@
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
-#ifdef SUPPORT_MC
     CHECK_ARG(audio_channel_count_from_out_mask(pConfig->inputCfg.channels) <= LVM_MAX_CHANNELS);
-#else
-    CHECK_ARG(pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
-#endif
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
     CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT);
@@ -1147,12 +1049,8 @@
         return -EINVAL;
     }
 
-#ifdef SUPPORT_MC
     if (pContext->pBundledContext->SampleRate != SampleRate ||
         pContext->pBundledContext->ChMask != pConfig->inputCfg.channels) {
-#else
-    if(pContext->pBundledContext->SampleRate != SampleRate){
-#endif
 
         LVM_ControlParams_t     ActiveParams;
         LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;
@@ -1168,19 +1066,15 @@
 
         ActiveParams.SampleRate = SampleRate;
 
-#ifdef SUPPORT_MC
         ActiveParams.NrChannels = NrChannels;
         ActiveParams.ChMask = pConfig->inputCfg.channels;
-#endif
 
         LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
 
         LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "Effect_setConfig")
         ALOGV("\tEffect_setConfig Succesfully called LVM_SetControlParameters\n");
         pContext->pBundledContext->SampleRate = SampleRate;
-#ifdef SUPPORT_MC
         pContext->pBundledContext->ChMask = pConfig->inputCfg.channels;
-#endif
 
         LvmEffect_limitLevel(pContext);
 
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 524e103..63bc45c 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -94,9 +94,7 @@
     int                             frameCount;
     int32_t                         bandGaindB[FIVEBAND_NUMBANDS];
     int                             volume;
-#ifdef SUPPORT_MC
     LVM_INT32                       ChMask;
-#endif
 
     /* Bitmask whether drain is in progress due to disabling the effect.
        The corresponding bit to an effect is set by 1 << lvm_effect_en. */
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 39f5bb6..4411a7d 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -259,6 +259,7 @@
 
     int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
 
+    channels = (pContext->auxiliary == true)? channels : FCC_2;
     // Allocate memory for reverb process (*2 is for STEREO)
     pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * channels;
     pContext->bufferSizeOut = LVREV_MAX_FRAME_SIZE * sizeof(process_buffer_t) * FCC_2;
@@ -343,9 +344,9 @@
     int channels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
     LVREV_ReturnStatus_en   LvmStatus = LVREV_SUCCESS;              /* Function call status */
 
-    // Check that the input is either mono or stereo
-    if (!(channels == 1 || channels == FCC_2) ) {
-        ALOGE("\tLVREV_ERROR : process invalid PCM format");
+    // Reverb only effects the stereo channels in multichannel source.
+    if (channels < 1 || channels > LVM_MAX_CHANNELS) {
+        ALOGE("\tLVREV_ERROR : process invalid PCM channels %d", channels);
         return -EINVAL;
     }
 
@@ -380,11 +381,20 @@
         static_assert(std::is_same<decltype(*pIn), decltype(*pContext->InFrames)>::value,
                 "pIn and InFrames must be same type");
         memcpy(pContext->InFrames, pIn, frameCount * channels * sizeof(*pIn));
+    } else {
+        // mono input is duplicated
+        if (channels >= FCC_2) {
+            for (int i = 0; i < frameCount; i++) {
+                pContext->InFrames[FCC_2 * i] =
+                            (process_buffer_t)pIn[channels * i] * REVERB_SEND_LEVEL;
+                pContext->InFrames[FCC_2 * i + 1] =
+                            (process_buffer_t)pIn[channels * i + 1] * REVERB_SEND_LEVEL;
+            }
         } else {
-        // insert reverb input is always stereo
-        for (int i = 0; i < frameCount; i++) {
-            pContext->InFrames[2 * i] = (process_buffer_t)pIn[2 * i] * REVERB_SEND_LEVEL;
-            pContext->InFrames[2 * i + 1] = (process_buffer_t)pIn[2 * i + 1] * REVERB_SEND_LEVEL;
+            for (int i = 0; i < frameCount; i++) {
+                pContext->InFrames[FCC_2 * i] = pContext->InFrames[FCC_2 * i + 1] =
+                            (process_buffer_t)pIn[i] * REVERB_SEND_LEVEL;
+            }
         }
     }
 
@@ -412,9 +422,18 @@
     if (pContext->auxiliary) {
         // nothing to do here
     } else {
-        for (int i = 0; i < frameCount * FCC_2; i++) { // always stereo here
-            // Mix with dry input
-            pContext->OutFrames[i] += pIn[i];
+        if (channels >= FCC_2) {
+            for (int i = 0; i < frameCount; i++) {
+                // Mix with dry input
+                pContext->OutFrames[FCC_2 * i] += pIn[channels * i];
+                pContext->OutFrames[FCC_2 * i + 1] += pIn[channels * i + 1];
+            }
+        } else {
+            for (int i = 0; i < frameCount; i++) {
+                // Mix with dry input
+                pContext->OutFrames[FCC_2 * i] += pIn[i];
+                pContext->OutFrames[FCC_2 * i + 1] += pIn[i];
+            }
         }
         // apply volume with ramp if needed
         if ((pContext->leftVolume != pContext->prevLeftVolume ||
@@ -450,18 +469,33 @@
         }
     }
 
-
-    // Accumulate if required
-    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
-        //ALOGV("\tBuffer access is ACCUMULATE");
-        for (int i = 0; i < frameCount * FCC_2; i++) { // always stereo here
-            pOut[i] += pContext->OutFrames[i];
+    if (channels > 2) {
+        //Accumulate if required
+        if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+            for (int i = 0; i < frameCount; i++) {
+                pOut[channels * i] += pContext->OutFrames[FCC_2 * i];
+                pOut[channels * i + 1] += pContext->OutFrames[FCC_2 * i + 1];
+            }
+        } else {
+            for (int i = 0; i < frameCount; i++) {
+                pOut[channels * i] = pContext->OutFrames[FCC_2 * i];
+                pOut[channels * i + 1] = pContext->OutFrames[FCC_2 * i + 1];
+            }
         }
-    }else{
-        //ALOGV("\tBuffer access is WRITE");
-        memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2);
+        for (int i = 0; i < frameCount; i++) {
+            for (int j = FCC_2; j < channels; j++) {
+                pOut[channels * i + j] = pIn[channels * i + j];
+            }
+        }
+    } else {
+        if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+            for (int i = 0; i < frameCount * FCC_2; i++) {
+                pOut[i] += pContext->OutFrames[i];
+            }
+        } else {
+            memcpy(pOut, pContext->OutFrames, frameCount * sizeof(*pOut) * FCC_2);
+        }
     }
-
     return 0;
 }    /* end process */
 
@@ -525,9 +559,12 @@
 
     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
+    int inputChannels = audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
     CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
-              ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
-    CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
+              ((!pContext->auxiliary) &&
+              (inputChannels <= LVM_MAX_CHANNELS)));
+    int outputChannels = audio_channel_count_from_out_mask(pConfig->outputCfg.channels);
+    CHECK_ARG(outputChannels >= FCC_2 && outputChannels <= LVM_MAX_CHANNELS);
     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
     CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT);
@@ -691,7 +728,7 @@
     /* Allocate memory */
     for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
         if (MemTab.Region[i].Size != 0){
-            MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
+            MemTab.Region[i].pBaseAddress = calloc(1, MemTab.Region[i].Size);
 
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
                 ALOGV("\tLVREV_ERROR :Reverb_init CreateInstance Failed to allocate %" PRIu32
@@ -749,6 +786,9 @@
         params.SourceFormat   = LVM_STEREO;
     }
 
+    if ((pContext->auxiliary == false) && (params.SourceFormat == LVM_MONO)) {
+        params.SourceFormat   = LVM_STEREO;
+    }
     /* Reverb parameters */
     params.Level          = 0;
     params.LPF            = 23999;
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index c87635f..16cd0ad 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -8,12 +8,6 @@
 
     srcs: ["PreProcessing.cpp"],
 
-    include_dirs: [
-        "external/webrtc",
-        "external/webrtc/webrtc/modules/include",
-        "external/webrtc/webrtc/modules/audio_processing/include",
-    ],
-
     shared_libs: [
         "libwebrtc_audio_preprocessing",
         "libspeexresampler",
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 5fab5be..c7afe2f 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1240,9 +1240,9 @@
             memcpy(outBuffer->s16,
                   session->outBuf,
                   fr * session->outChannelCount * sizeof(int16_t));
-            memcpy(session->outBuf,
-                  session->outBuf + fr * session->outChannelCount,
-                  (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+            memmove(session->outBuf,
+                    session->outBuf + fr * session->outChannelCount,
+                    (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
             session->framesOut -= fr;
             framesWr += fr;
         }
@@ -1303,9 +1303,9 @@
                                                         session->procFrame->data_,
                                                         &frOut);
             }
-            memcpy(session->inBuf,
-                   session->inBuf + frIn * session->inChannelCount,
-                   (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
+            memmove(session->inBuf,
+                    session->inBuf + frIn * session->inChannelCount,
+                    (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
             session->framesIn -= frIn;
         } else {
             size_t fr = session->frameCount - session->framesIn;
@@ -1381,9 +1381,9 @@
         memcpy(outBuffer->s16 + framesWr * session->outChannelCount,
               session->outBuf,
               fr * session->outChannelCount * sizeof(int16_t));
-        memcpy(session->outBuf,
-              session->outBuf + fr * session->outChannelCount,
-              (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
+        memmove(session->outBuf,
+                session->outBuf + fr * session->outChannelCount,
+                (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
         session->framesOut -= fr;
         outBuffer->frameCount += fr;
 
@@ -1837,9 +1837,9 @@
                                                         session->revFrame->data_,
                                                         &frOut);
             }
-            memcpy(session->revBuf,
-                   session->revBuf + frIn * session->inChannelCount,
-                   (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
+            memmove(session->revBuf,
+                    session->revBuf + frIn * session->inChannelCount,
+                    (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
             session->framesRev -= frIn;
         } else {
             size_t fr = session->frameCount - session->framesRev;
diff --git a/media/libeffects/preprocessing/tests/Android.bp b/media/libeffects/preprocessing/tests/Android.bp
new file mode 100644
index 0000000..71f6e8f
--- /dev/null
+++ b/media/libeffects/preprocessing/tests/Android.bp
@@ -0,0 +1,30 @@
+// audio preprocessing unit test
+cc_test {
+    name: "AudioPreProcessingTest",
+
+    vendor: true,
+
+    relative_install_path: "soundfx",
+
+    srcs: ["PreProcessingTest.cpp"],
+
+    shared_libs: [
+        "libaudiopreprocessing",
+        "libaudioutils",
+        "liblog",
+        "libutils",
+        "libwebrtc_audio_preprocessing",
+    ],
+
+    cflags: [
+        "-DWEBRTC_POSIX",
+        "-fvisibility=default",
+        "-Wall",
+        "-Werror",
+    ],
+
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+}
diff --git a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
new file mode 100644
index 0000000..5c81d78
--- /dev/null
+++ b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2020 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 <audio_effects/effect_aec.h>
+#include <audio_effects/effect_agc.h>
+#include <audio_effects/effect_ns.h>
+#include <audio_processing.h>
+#include <getopt.h>
+#include <hardware/audio_effect.h>
+#include <module_common_types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <log/log.h>
+#include <system/audio.h>
+
+// This is the only symbol that needs to be imported
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+
+//------------------------------------------------------------------------------
+// local definitions
+//------------------------------------------------------------------------------
+
+// types of pre processing modules
+enum PreProcId {
+  PREPROC_AGC,  // Automatic Gain Control
+  PREPROC_AEC,  // Acoustic Echo Canceler
+  PREPROC_NS,   // Noise Suppressor
+  PREPROC_NUM_EFFECTS
+};
+
+enum PreProcParams {
+  ARG_HELP = 1,
+  ARG_INPUT,
+  ARG_OUTPUT,
+  ARG_FAR,
+  ARG_FS,
+  ARG_CH_MASK,
+  ARG_AGC_TGT_LVL,
+  ARG_AGC_COMP_LVL,
+  ARG_AEC_DELAY,
+  ARG_NS_LVL,
+};
+
+struct preProcConfigParams_t {
+  int samplingFreq = 16000;
+  audio_channel_mask_t chMask = AUDIO_CHANNEL_IN_MONO;
+  int nsLevel = 0;         // a value between 0-3
+  int agcTargetLevel = 3;  // in dB
+  int agcCompLevel = 9;    // in dB
+  int aecDelay = 0;        // in ms
+};
+
+const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = {
+    {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // agc uuid
+    {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // aec uuid
+    {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // ns  uuid
+};
+
+constexpr audio_channel_mask_t kPreProcConfigChMask[] = {
+    AUDIO_CHANNEL_IN_MONO,
+    AUDIO_CHANNEL_IN_STEREO,
+    AUDIO_CHANNEL_IN_FRONT_BACK,
+    AUDIO_CHANNEL_IN_6,
+    AUDIO_CHANNEL_IN_2POINT0POINT2,
+    AUDIO_CHANNEL_IN_2POINT1POINT2,
+    AUDIO_CHANNEL_IN_3POINT0POINT2,
+    AUDIO_CHANNEL_IN_3POINT1POINT2,
+    AUDIO_CHANNEL_IN_5POINT1,
+    AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO,
+    AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO,
+    AUDIO_CHANNEL_IN_VOICE_CALL_MONO,
+};
+
+constexpr int kPreProcConfigChMaskCount = std::size(kPreProcConfigChMask);
+
+void printUsage() {
+  printf("\nUsage: ");
+  printf("\n     <executable> [options]\n");
+  printf("\nwhere options are, ");
+  printf("\n     --input <inputfile>");
+  printf("\n           path to the input file");
+  printf("\n     --output <outputfile>");
+  printf("\n           path to the output file");
+  printf("\n     --help");
+  printf("\n           Prints this usage information");
+  printf("\n     --fs <sampling_freq>");
+  printf("\n           Sampling frequency in Hz, default 16000.");
+  printf("\n     -ch_mask <channel_mask>\n");
+  printf("\n         0  - AUDIO_CHANNEL_IN_MONO");
+  printf("\n         1  - AUDIO_CHANNEL_IN_STEREO");
+  printf("\n         2  - AUDIO_CHANNEL_IN_FRONT_BACK");
+  printf("\n         3  - AUDIO_CHANNEL_IN_6");
+  printf("\n         4  - AUDIO_CHANNEL_IN_2POINT0POINT2");
+  printf("\n         5  - AUDIO_CHANNEL_IN_2POINT1POINT2");
+  printf("\n         6  - AUDIO_CHANNEL_IN_3POINT0POINT2");
+  printf("\n         7  - AUDIO_CHANNEL_IN_3POINT1POINT2");
+  printf("\n         8  - AUDIO_CHANNEL_IN_5POINT1");
+  printf("\n         9  - AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO");
+  printf("\n         10 - AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO ");
+  printf("\n         11 - AUDIO_CHANNEL_IN_VOICE_CALL_MONO ");
+  printf("\n         default 0");
+  printf("\n     --far <farend_file>");
+  printf("\n           Path to far-end file needed for echo cancellation");
+  printf("\n     --aec");
+  printf("\n           Enable Echo Cancellation, default disabled");
+  printf("\n     --ns");
+  printf("\n           Enable Noise Suppression, default disabled");
+  printf("\n     --agc");
+  printf("\n           Enable Gain Control, default disabled");
+  printf("\n     --ns_lvl <ns_level>");
+  printf("\n           Noise Suppression level in dB, default value 0dB");
+  printf("\n     --agc_tgt_lvl <target_level>");
+  printf("\n           AGC Target Level in dB, default value 3dB");
+  printf("\n     --agc_comp_lvl <comp_level>");
+  printf("\n           AGC Comp Level in dB, default value 9dB");
+  printf("\n     --aec_delay <delay>");
+  printf("\n           AEC delay value in ms, default value 0ms");
+  printf("\n");
+}
+
+constexpr float kTenMilliSecVal = 0.01;
+
+int preProcCreateEffect(effect_handle_t *pEffectHandle, uint32_t effectType,
+                        effect_config_t *pConfig, int sessionId, int ioId) {
+  if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kPreProcUuids[effectType],
+                                                               sessionId, ioId, pEffectHandle);
+      status != 0) {
+    ALOGE("Audio Preprocessing create returned an error = %d\n", status);
+    return EXIT_FAILURE;
+  }
+  int reply = 0;
+  uint32_t replySize = sizeof(reply);
+  if (effectType == PREPROC_AEC) {
+    (**pEffectHandle)
+        ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE, sizeof(effect_config_t), pConfig,
+                  &replySize, &reply);
+  }
+  (**pEffectHandle)
+      ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), pConfig,
+                &replySize, &reply);
+  return reply;
+}
+
+int preProcSetConfigParam(uint32_t paramType, uint32_t paramValue, effect_handle_t effectHandle) {
+  int reply = 0;
+  uint32_t replySize = sizeof(reply);
+  uint32_t paramData[2] = {paramType, paramValue};
+  effect_param_t *effectParam =
+      (effect_param_t *)malloc(sizeof(*effectParam) + sizeof(paramData));
+  memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+  effectParam->psize = sizeof(paramData[0]);
+  (*effectHandle)
+      ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam,
+                &replySize, &reply);
+  free(effectParam);
+  return reply;
+}
+
+int main(int argc, const char *argv[]) {
+  if (argc == 1) {
+    printUsage();
+    return EXIT_FAILURE;
+  }
+  const char *inputFile = nullptr;
+  const char *outputFile = nullptr;
+  const char *farFile = nullptr;
+  int effectEn[PREPROC_NUM_EFFECTS] = {0};
+
+  const option long_opts[] = {
+      {"help", no_argument, nullptr, ARG_HELP},
+      {"input", required_argument, nullptr, ARG_INPUT},
+      {"output", required_argument, nullptr, ARG_OUTPUT},
+      {"far", required_argument, nullptr, ARG_FAR},
+      {"fs", required_argument, nullptr, ARG_FS},
+      {"ch_mask", required_argument, nullptr, ARG_CH_MASK},
+      {"agc_tgt_lvl", required_argument, nullptr, ARG_AGC_TGT_LVL},
+      {"agc_comp_lvl", required_argument, nullptr, ARG_AGC_COMP_LVL},
+      {"aec_delay", required_argument, nullptr, ARG_AEC_DELAY},
+      {"ns_lvl", required_argument, nullptr, ARG_NS_LVL},
+      {"aec", no_argument, &effectEn[PREPROC_AEC], 1},
+      {"agc", no_argument, &effectEn[PREPROC_AGC], 1},
+      {"ns", no_argument, &effectEn[PREPROC_NS], 1},
+      {nullptr, 0, nullptr, 0},
+  };
+  struct preProcConfigParams_t preProcCfgParams {};
+
+  while (true) {
+    const int opt = getopt_long(argc, (char *const *)argv, "i:o:", long_opts, nullptr);
+    if (opt == -1) {
+      break;
+    }
+    switch (opt) {
+      case ARG_HELP:
+        printUsage();
+        return 0;
+      case ARG_INPUT: {
+        inputFile = (char *)optarg;
+        break;
+      }
+      case ARG_OUTPUT: {
+        outputFile = (char *)optarg;
+        break;
+      }
+      case ARG_FAR: {
+        farFile = (char *)optarg;
+        break;
+      }
+      case ARG_FS: {
+        preProcCfgParams.samplingFreq = atoi(optarg);
+        break;
+      }
+      case ARG_CH_MASK: {
+        int chMaskIdx = atoi(optarg);
+        if (chMaskIdx < 0 or chMaskIdx > kPreProcConfigChMaskCount) {
+          ALOGE("Channel Mask index not in correct range\n");
+          printUsage();
+          return EXIT_FAILURE;
+        }
+        preProcCfgParams.chMask = kPreProcConfigChMask[chMaskIdx];
+        break;
+      }
+      case ARG_AGC_TGT_LVL: {
+        preProcCfgParams.agcTargetLevel = atoi(optarg);
+        break;
+      }
+      case ARG_AGC_COMP_LVL: {
+        preProcCfgParams.agcCompLevel = atoi(optarg);
+        break;
+      }
+      case ARG_AEC_DELAY: {
+        preProcCfgParams.aecDelay = atoi(optarg);
+        break;
+      }
+      case ARG_NS_LVL: {
+        preProcCfgParams.nsLevel = atoi(optarg);
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  if (inputFile == nullptr) {
+    ALOGE("Error: missing input file\n");
+    printUsage();
+    return EXIT_FAILURE;
+  }
+
+  std::unique_ptr<FILE, decltype(&fclose)> inputFp(fopen(inputFile, "rb"), &fclose);
+  if (inputFp == nullptr) {
+    ALOGE("Cannot open input file %s\n", inputFile);
+    return EXIT_FAILURE;
+  }
+
+  std::unique_ptr<FILE, decltype(&fclose)> farFp(fopen(farFile, "rb"), &fclose);
+  std::unique_ptr<FILE, decltype(&fclose)> outputFp(fopen(outputFile, "wb"), &fclose);
+  if (effectEn[PREPROC_AEC]) {
+    if (farFile == nullptr) {
+      ALOGE("Far end signal file required for echo cancellation \n");
+      return EXIT_FAILURE;
+    }
+    if (farFp == nullptr) {
+      ALOGE("Cannot open far end stream file %s\n", farFile);
+      return EXIT_FAILURE;
+    }
+    struct stat statInput, statFar;
+    (void)fstat(fileno(inputFp.get()), &statInput);
+    (void)fstat(fileno(farFp.get()), &statFar);
+    if (statInput.st_size != statFar.st_size) {
+      ALOGE("Near and far end signals are of different sizes");
+      return EXIT_FAILURE;
+    }
+  }
+  if (outputFile != nullptr && outputFp == nullptr) {
+    ALOGE("Cannot open output file %s\n", outputFile);
+    return EXIT_FAILURE;
+  }
+
+  int32_t sessionId = 1;
+  int32_t ioId = 1;
+  effect_handle_t effectHandle[PREPROC_NUM_EFFECTS] = {nullptr};
+  effect_config_t config;
+  config.inputCfg.samplingRate = config.outputCfg.samplingRate = preProcCfgParams.samplingFreq;
+  config.inputCfg.channels = config.outputCfg.channels = preProcCfgParams.chMask;
+  config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+
+  // Create all the effect handles
+  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+    if (int status = preProcCreateEffect(&effectHandle[i], i, &config, sessionId, ioId);
+        status != 0) {
+      ALOGE("Create effect call returned error %i", status);
+      return EXIT_FAILURE;
+    }
+  }
+
+  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+    if (effectEn[i] == 1) {
+      int reply = 0;
+      uint32_t replySize = sizeof(reply);
+      (*effectHandle[i])
+          ->command(effectHandle[i], EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
+      if (reply != 0) {
+        ALOGE("Command enable call returned error %d\n", reply);
+        return EXIT_FAILURE;
+      }
+    }
+  }
+
+  // Set Config Params of the effects
+  if (effectEn[PREPROC_AGC]) {
+    if (int status = preProcSetConfigParam(AGC_PARAM_TARGET_LEVEL,
+                                           (uint32_t)preProcCfgParams.agcTargetLevel,
+                                           effectHandle[PREPROC_AGC]);
+        status != 0) {
+      ALOGE("Invalid AGC Target Level. Error %d\n", status);
+      return EXIT_FAILURE;
+    }
+    if (int status =
+            preProcSetConfigParam(AGC_PARAM_COMP_GAIN, (uint32_t)preProcCfgParams.agcCompLevel,
+                                  effectHandle[PREPROC_AGC]);
+        status != 0) {
+      ALOGE("Invalid AGC Comp Gain. Error %d\n", status);
+      return EXIT_FAILURE;
+    }
+  }
+  if (effectEn[PREPROC_NS]) {
+    if (int status = preProcSetConfigParam(NS_PARAM_LEVEL, (uint32_t)preProcCfgParams.nsLevel,
+                                           effectHandle[PREPROC_NS]);
+        status != 0) {
+      ALOGE("Invalid Noise Suppression level Error %d\n", status);
+      return EXIT_FAILURE;
+    }
+  }
+
+  // Process Call
+  const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal);
+  const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask);
+  const int ioFrameSize = ioChannelCount * sizeof(short);
+  int frameCounter = 0;
+  while (true) {
+    std::vector<short> in(frameLength * ioChannelCount);
+    std::vector<short> out(frameLength * ioChannelCount);
+    std::vector<short> farIn(frameLength * ioChannelCount);
+    size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get());
+    if (samplesRead == 0) {
+      break;
+    }
+    audio_buffer_t inputBuffer, outputBuffer;
+    audio_buffer_t farInBuffer{};
+    inputBuffer.frameCount = samplesRead;
+    outputBuffer.frameCount = samplesRead;
+    inputBuffer.s16 = in.data();
+    outputBuffer.s16 = out.data();
+
+    if (farFp != nullptr) {
+      samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get());
+      if (samplesRead == 0) {
+        break;
+      }
+      farInBuffer.frameCount = samplesRead;
+      farInBuffer.s16 = farIn.data();
+    }
+
+    for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+      if (effectEn[i] == 1) {
+        if (i == PREPROC_AEC) {
+          if (int status =
+                  preProcSetConfigParam(AEC_PARAM_ECHO_DELAY, (uint32_t)preProcCfgParams.aecDelay,
+                                        effectHandle[PREPROC_AEC]);
+              status != 0) {
+            ALOGE("preProcSetConfigParam returned Error %d\n", status);
+            return EXIT_FAILURE;
+          }
+        }
+        if (int status =
+                (*effectHandle[i])->process(effectHandle[i], &inputBuffer, &outputBuffer);
+            status != 0) {
+          ALOGE("\nError: Process i = %d returned with error %d\n", i, status);
+          return EXIT_FAILURE;
+        }
+        if (i == PREPROC_AEC) {
+          if (int status = (*effectHandle[i])
+                               ->process_reverse(effectHandle[i], &farInBuffer, &outputBuffer);
+              status != 0) {
+            ALOGE("\nError: Process reverse i = %d returned with error %d\n", i, status);
+            return EXIT_FAILURE;
+          }
+        }
+      }
+    }
+    if (outputFp != nullptr) {
+      size_t samplesWritten =
+          fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get());
+      if (samplesWritten != outputBuffer.frameCount) {
+        ALOGE("\nError: Output file writing failed");
+        break;
+      }
+    }
+    frameCounter += frameLength;
+  }
+  // Release all the effect handles created
+  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle[i]);
+        status != 0) {
+      ALOGE("Audio Preprocessing release returned an error = %d\n", status);
+      return EXIT_FAILURE;
+    }
+  }
+  return EXIT_SUCCESS;
+}
diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp
index 42e44f0..c010d68 100644
--- a/media/libeffects/proxy/EffectProxy.cpp
+++ b/media/libeffects/proxy/EffectProxy.cpp
@@ -30,7 +30,7 @@
 #include <media/EffectsFactoryApi.h>
 
 namespace android {
-// This is a dummy proxy descriptor just to return to Factory during the initial
+// This is a stub proxy descriptor just to return to Factory during the initial
 // GetDescriptor call. Later in the factory, it is replaced with the
 // SW sub effect descriptor
 // proxy UUID af8da7e0-2ca1-11e3-b71d-0002a5d5c51b
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 3fd3fc3..1caee04 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -17,6 +17,22 @@
     ],
 }
 
+cc_library_headers {
+    name: "libmedia_datasource_headers",
+    export_include_dirs: ["include"],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+    ],
+    min_sdk_version: "29",
+}
+
 filegroup {
     name: "libmedia_omx_aidl",
     srcs: [
@@ -203,7 +219,7 @@
     ],
 
     header_libs: [
-        "libmedia_headers",
+        "libmedia_datasource_headers",
         "media_ndk_headers",
     ],
 
@@ -220,6 +236,14 @@
         ],
         cfi: true,
     },
+
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_shared {
@@ -309,11 +333,13 @@
     header_libs: [
         "libstagefright_headers",
         "media_ndk_headers",
+        "jni_headers",
     ],
 
     export_header_lib_headers: [
         "libstagefright_headers",
         "media_ndk_headers",
+        "jni_headers",
     ],
 
     shared_libs: [
@@ -372,3 +398,36 @@
         cfi: true,
     },
 }
+
+cc_library_static {
+    name: "libmedia_ndkformatpriv",
+
+    host_supported: true,
+
+    srcs: [
+        "NdkMediaFormatPriv.cpp",
+        "NdkMediaErrorPriv.cpp",
+    ],
+
+    header_libs: [
+        "libstagefright_foundation_headers",
+        "libstagefright_headers",
+        "media_ndk_headers",
+    ],
+
+    cflags: [
+        "-DEXPORT=__attribute__((visibility(\"default\")))",
+        "-Werror",
+        "-Wall",
+    ],
+
+    export_include_dirs: ["include"],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
+    apex_available: ["com.android.media"],
+}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 637322f..8be961c 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -240,7 +240,10 @@
 
     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoCodec failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoCodec *videoCodec =
         new MediaProfiles::VideoCodec(static_cast<video_encoder>(codec),
@@ -262,7 +265,10 @@
           !strcmp("channels",   atts[6]));
     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioCodec failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioCodec *audioCodec =
         new MediaProfiles::AudioCodec(static_cast<audio_encoder>(codec),
@@ -282,7 +288,10 @@
 
     const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]);
     const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioDecoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioDecoderCap *cap =
         new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec));
@@ -298,7 +307,10 @@
 
     const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]);
     const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoDecoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoDecoderCap *cap =
         new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec));
@@ -322,7 +334,10 @@
 
     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoEncoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoEncoderCap *cap =
         new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec),
@@ -346,7 +361,10 @@
 
     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioEncoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioEncoderCap *cap =
         new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]),
@@ -386,11 +404,17 @@
     const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/
             sizeof(sCamcorderQualityNameMap[0]);
     const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]);
-    CHECK(quality != -1);
+    if (quality == -1) {
+      ALOGE("MediaProfiles::createCamcorderProfile failed to locate quality %s", atts[1]);
+      return nullptr;
+    }
 
     const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
     const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]);
-    CHECK(fileFormat != -1);
+    if (fileFormat == -1) {
+      ALOGE("MediaProfiles::createCamcorderProfile failed to locate file format %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
     profile->mCameraId = cameraId;
@@ -462,24 +486,39 @@
         createAudioCodec(atts, profiles);
     } else if (strcmp("VideoEncoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mVideoEncoders.add(createVideoEncoderCap(atts));
+        MediaProfiles::VideoEncoderCap* cap = createVideoEncoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mVideoEncoders.add(cap);
+        }
     } else if (strcmp("AudioEncoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mAudioEncoders.add(createAudioEncoderCap(atts));
+        MediaProfiles::AudioEncoderCap* cap = createAudioEncoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mAudioEncoders.add(cap);
+        }
     } else if (strcmp("VideoDecoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mVideoDecoders.add(createVideoDecoderCap(atts));
+        MediaProfiles::VideoDecoderCap* cap = createVideoDecoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mVideoDecoders.add(cap);
+        }
     } else if (strcmp("AudioDecoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mAudioDecoders.add(createAudioDecoderCap(atts));
+        MediaProfiles::AudioDecoderCap* cap = createAudioDecoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mAudioDecoders.add(cap);
+        }
     } else if (strcmp("EncoderOutputFileFormat", name) == 0) {
         profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
     } else if (strcmp("CamcorderProfiles", name) == 0) {
         profiles->mCurrentCameraId = getCameraId(atts);
         profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts);
     } else if (strcmp("EncoderProfile", name) == 0) {
-        profiles->mCamcorderProfiles.add(
-            createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
+      MediaProfiles::CamcorderProfile* profile = createCamcorderProfile(
+          profiles->mCurrentCameraId, atts, profiles->mCameraIds);
+      if (profile != nullptr) {
+        profiles->mCamcorderProfiles.add(profile);
+      }
     } else if (strcmp("ImageEncoding", name) == 0) {
         profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
     }
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index 0936a99..fe86d27 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -35,7 +35,7 @@
     this->value = value;
 }
 
-MediaResource::MediaResource(Type type, const std::vector<int8_t> &id, int64_t value) {
+MediaResource::MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value) {
     this->type = type;
     this->subType = SubType::kUnspecifiedSubType;
     this->id = id;
@@ -66,11 +66,11 @@
 }
 
 //static
-MediaResource MediaResource::DrmSessionResource(const std::vector<int8_t> &id, int64_t value) {
+MediaResource MediaResource::DrmSessionResource(const std::vector<uint8_t> &id, int64_t value) {
     return MediaResource(Type::kDrmSession, id, value);
 }
 
-static String8 bytesToHexString(const std::vector<int8_t> &bytes) {
+static String8 bytesToHexString(const std::vector<uint8_t> &bytes) {
     String8 str;
     for (auto &b : bytes) {
         str.appendFormat("%02x", b);
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index e71ea2c..da272e3 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -18,8 +18,9 @@
 #define LOG_TAG "MidiIoWrapper"
 #include <utils/Log.h>
 
-#include <sys/stat.h>
 #include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include <media/MidiIoWrapper.h>
 #include <media/MediaExtractorPluginApi.h>
diff --git a/media/libmedia/NdkMediaFormatPriv.cpp b/media/libmedia/NdkMediaFormatPriv.cpp
index 3a9fb8b..7983184 100644
--- a/media/libmedia/NdkMediaFormatPriv.cpp
+++ b/media/libmedia/NdkMediaFormatPriv.cpp
@@ -24,8 +24,6 @@
 #include <media/NdkMediaFormatPriv.h>
 #include <media/stagefright/foundation/AMessage.h>
 
-#include <jni.h>
-
 using namespace android;
 
 namespace android {
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h
index e7362c1..4927d28 100644
--- a/media/libmedia/include/media/MediaResource.h
+++ b/media/libmedia/include/media/MediaResource.h
@@ -35,13 +35,13 @@
     MediaResource() = delete;
     MediaResource(Type type, int64_t value);
     MediaResource(Type type, SubType subType, int64_t value);
-    MediaResource(Type type, const std::vector<int8_t> &id, int64_t value);
+    MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value);
 
     static MediaResource CodecResource(bool secure, bool video);
     static MediaResource GraphicMemoryResource(int64_t value);
     static MediaResource CpuBoostResource();
     static MediaResource VideoBatteryResource();
-    static MediaResource DrmSessionResource(const std::vector<int8_t> &id, int64_t value);
+    static MediaResource DrmSessionResource(const std::vector<uint8_t> &id, int64_t value);
 };
 
 inline static const char *asString(MediaResource::Type i, const char *def = "??") {
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 6fcbc7b..b46c98a 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -3,6 +3,12 @@
     vendor_available: true,
     min_sdk_version: "29",
     export_include_dirs: ["include"],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library {
@@ -27,4 +33,10 @@
         "libmedia_helper_headers",
     ],
     clang: true,
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/libmediahelper/TypeConverter.cpp b/media/libmediahelper/TypeConverter.cpp
index 6382ce4..705959a 100644
--- a/media/libmediahelper/TypeConverter.cpp
+++ b/media/libmediahelper/TypeConverter.cpp
@@ -57,6 +57,8 @@
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_HEADSET),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HEARING_AID),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ECHO_CANCELLER),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLE_HEADSET),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLE_SPEAKER),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_DEFAULT),
     // STUB must be after DEFAULT, so the latter is picked up by toString first.
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
@@ -96,6 +98,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ECHO_REFERENCE),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLE_HEADSET),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
     // STUB must be after DEFAULT, so the latter is picked up by toString first.
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
new file mode 100644
index 0000000..5a52ea5
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "StagefrightRecorderTest",
+    gtest: true,
+
+    srcs: [
+        "StagefrightRecorderTest.cpp",
+    ],
+
+    include_dirs: [
+        "system/media/audio/include",
+        "frameworks/av/include",
+        "frameworks/av/camera/include",
+        "frameworks/av/media/libmediaplayerservice",
+        "frameworks/av/media/libmediametrics/include",
+        "frameworks/av/media/ndk/include",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libmedia",
+        "libbinder",
+        "libutils",
+        "libmediaplayerservice",
+        "libstagefright",
+        "libmediandk",
+    ],
+
+    compile_multilib: "32",
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
new file mode 100644
index 0000000..ac17ef3
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2020 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 "StagefrightRecorderTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <thread>
+
+#include <MediaPlayerService.h>
+#include <media/NdkMediaExtractor.h>
+#include <media/stagefright/MediaCodec.h>
+#include <system/audio-base.h>
+
+#include "StagefrightRecorder.h"
+
+#define OUTPUT_INFO_FILE_NAME "/data/local/tmp/stfrecorder_audio.info"
+#define OUTPUT_FILE_NAME_AUDIO "/data/local/tmp/stfrecorder_audio.raw"
+
+const bool kDebug = false;
+constexpr int32_t kMaxLoopCount = 10;
+constexpr int32_t kClipDurationInSec = 4;
+constexpr int32_t kPauseTimeInSec = 2;
+// Tolerance value for extracted clipduration is maximum 10% of total clipduration
+constexpr int32_t kToleranceValueInUs = kClipDurationInSec * 100000;
+
+using namespace android;
+
+class StagefrightRecorderTest
+    : public ::testing::TestWithParam<std::pair<output_format, audio_encoder>> {
+  public:
+    StagefrightRecorderTest() : mStfRecorder(nullptr), mOutputAudioFp(nullptr) {
+        mExpectedDurationInMs = 0;
+        mExpectedPauseInMs = 0;
+    }
+
+    ~StagefrightRecorderTest() {
+        if (mStfRecorder) free(mStfRecorder);
+        if (mOutputAudioFp) fclose(mOutputAudioFp);
+    }
+
+    void SetUp() override {
+        mStfRecorder = new StagefrightRecorder(String16(LOG_TAG));
+        ASSERT_NE(mStfRecorder, nullptr) << "Failed to create the instance of recorder";
+
+        mOutputAudioFp = fopen(OUTPUT_FILE_NAME_AUDIO, "wb");
+        ASSERT_NE(mOutputAudioFp, nullptr) << "Failed to open output file "
+                                           << OUTPUT_FILE_NAME_AUDIO << " for stagefright recorder";
+
+        int32_t fd = fileno(mOutputAudioFp);
+        ASSERT_GE(fd, 0) << "Failed to get the file descriptor of the output file for "
+                         << OUTPUT_FILE_NAME_AUDIO;
+
+        status_t status = mStfRecorder->setOutputFile(fd);
+        ASSERT_EQ(status, OK) << "Failed to set the output file " << OUTPUT_FILE_NAME_AUDIO
+                              << " for stagefright recorder";
+    }
+
+    void TearDown() override {
+        if (mOutputAudioFp) {
+            fclose(mOutputAudioFp);
+            mOutputAudioFp = nullptr;
+        }
+        if (!kDebug) {
+            int32_t status = remove(OUTPUT_FILE_NAME_AUDIO);
+            ASSERT_EQ(status, 0) << "Unable to delete the output file " << OUTPUT_FILE_NAME_AUDIO;
+        }
+    }
+
+    void setAudioRecorderFormat(output_format outputFormat, audio_encoder encoder,
+                                audio_source_t audioSource = AUDIO_SOURCE_DEFAULT);
+    void recordMedia(bool isPaused = false, int32_t numStart = 0, int32_t numPause = 0);
+    void dumpInfo();
+    void setupExtractor(AMediaExtractor *extractor, int32_t &trackCount);
+    void validateOutput();
+
+    MediaRecorderBase *mStfRecorder;
+    FILE *mOutputAudioFp;
+    double mExpectedDurationInMs;
+    double mExpectedPauseInMs;
+};
+
+void StagefrightRecorderTest::setAudioRecorderFormat(output_format outputFormat,
+                                                     audio_encoder encoder,
+                                                     audio_source_t audioSource) {
+    status_t status = mStfRecorder->setAudioSource(audioSource);
+    ASSERT_EQ(status, OK) << "Failed to set the audio source: " << audioSource;
+
+    status = mStfRecorder->setOutputFormat(outputFormat);
+    ASSERT_EQ(status, OK) << "Failed to set the output format: " << outputFormat;
+
+    status = mStfRecorder->setAudioEncoder(encoder);
+    ASSERT_EQ(status, OK) << "Failed to set the audio encoder: " << encoder;
+}
+
+void StagefrightRecorderTest::recordMedia(bool isPause, int32_t numStart, int32_t numPause) {
+    status_t status = mStfRecorder->init();
+    ASSERT_EQ(status, OK) << "Failed to initialize stagefright recorder";
+
+    status = mStfRecorder->prepare();
+    ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+    // first start should succeed.
+    status = mStfRecorder->start();
+    ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+    for (int32_t count = 0; count < numStart; count++) {
+        status = mStfRecorder->start();
+    }
+
+    auto tStart = std::chrono::high_resolution_clock::now();
+    // Recording media for 4 secs
+    std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+    auto tEnd = std::chrono::high_resolution_clock::now();
+    mExpectedDurationInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+    if (isPause) {
+        // first pause should succeed.
+        status = mStfRecorder->pause();
+        ASSERT_EQ(status, OK) << "Failed to pause the recorder";
+
+        tStart = std::chrono::high_resolution_clock::now();
+        // Paused recorder for 2 secs
+        std::this_thread::sleep_for(std::chrono::seconds(kPauseTimeInSec));
+
+        for (int32_t count = 0; count < numPause; count++) {
+            status = mStfRecorder->pause();
+        }
+
+        tEnd = std::chrono::high_resolution_clock::now();
+        mExpectedPauseInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+        status = mStfRecorder->resume();
+        ASSERT_EQ(status, OK) << "Failed to resume the recorder";
+
+        auto tStart = std::chrono::high_resolution_clock::now();
+        // Recording media for 4 secs
+        std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+        auto tEnd = std::chrono::high_resolution_clock::now();
+        mExpectedDurationInMs += std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+    }
+    status = mStfRecorder->stop();
+    ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+}
+
+void StagefrightRecorderTest::dumpInfo() {
+    FILE *dumpOutput = fopen(OUTPUT_INFO_FILE_NAME, "wb");
+    int32_t dumpFd = fileno(dumpOutput);
+    Vector<String16> args;
+    status_t status = mStfRecorder->dump(dumpFd, args);
+    ASSERT_EQ(status, OK) << "Failed to dump the info for the recorder";
+    fclose(dumpOutput);
+}
+
+void StagefrightRecorderTest::setupExtractor(AMediaExtractor *extractor, int32_t &trackCount) {
+    int32_t fd = open(OUTPUT_FILE_NAME_AUDIO, O_RDONLY);
+    ASSERT_GE(fd, 0) << "Failed to open recorder's output file " << OUTPUT_FILE_NAME_AUDIO
+                     << " to validate";
+
+    struct stat buf;
+    int32_t status = fstat(fd, &buf);
+    ASSERT_EQ(status, 0) << "Failed to get properties of input file " << OUTPUT_FILE_NAME_AUDIO
+                         << " for extractor";
+
+    size_t fileSize = buf.st_size;
+    ASSERT_GT(fileSize, 0) << "Size of input file " << OUTPUT_FILE_NAME_AUDIO
+                           << " to extractor cannot be zero";
+    ALOGV("Size of input file to extractor: %zu", fileSize);
+
+    status = AMediaExtractor_setDataSourceFd(extractor, fd, 0, fileSize);
+    ASSERT_EQ(status, AMEDIA_OK) << "Failed to set data source for extractor";
+
+    trackCount = AMediaExtractor_getTrackCount(extractor);
+    ALOGV("Number of tracks reported by extractor : %d", trackCount);
+}
+
+// Validate recoder's output using extractor
+void StagefrightRecorderTest::validateOutput() {
+    int32_t trackCount = -1;
+    AMediaExtractor *extractor = AMediaExtractor_new();
+    ASSERT_NE(extractor, nullptr) << "Failed to create extractor";
+    ASSERT_NO_FATAL_FAILURE(setupExtractor(extractor, trackCount));
+    ASSERT_EQ(trackCount, 1) << "Expected 1 track, saw " << trackCount;
+
+    for (int32_t idx = 0; idx < trackCount; idx++) {
+        AMediaExtractor_selectTrack(extractor, idx);
+        AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, idx);
+        ASSERT_NE(format, nullptr) << "Track format is NULL";
+        ALOGI("Track format = %s", AMediaFormat_toString(format));
+
+        int64_t clipDurationUs;
+        AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &clipDurationUs);
+        int32_t diff = abs((mExpectedDurationInMs * 1000) - clipDurationUs);
+        ASSERT_LE(diff, kToleranceValueInUs)
+                << "Expected duration: " << (mExpectedDurationInMs * 1000)
+                << " Actual duration: " << clipDurationUs << " Difference: " << diff
+                << " Difference is expected to be less than tolerance value: " << kToleranceValueInUs;
+
+        const char *mime = nullptr;
+        AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+        ASSERT_NE(mime, nullptr) << "Track mime is NULL";
+        ALOGI("Track mime = %s", mime);
+
+        int32_t sampleRate, channelCount, bitRate;
+        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
+        ALOGI("Channel count reported by extractor: %d", channelCount);
+        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
+        ALOGI("Sample Rate reported by extractor: %d", sampleRate);
+        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitRate);
+        ALOGI("Bit Rate reported by extractor: %d", bitRate);
+    }
+}
+
+TEST_F(StagefrightRecorderTest, RecordingAudioSanityTest) {
+    ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+
+    int32_t maxAmplitude = -1;
+    status_t status = mStfRecorder->getMaxAmplitude(&maxAmplitude);
+    ASSERT_EQ(maxAmplitude, 0) << "Invalid value of max amplitude";
+
+    ASSERT_NO_FATAL_FAILURE(recordMedia());
+
+    // Verify getMetrics() behavior
+    Parcel parcel;
+    status = mStfRecorder->getMetrics(&parcel);
+    ASSERT_EQ(status, OK) << "Failed to get the parcel from getMetrics";
+    ALOGV("Size of the Parcel returned by getMetrics: %zu", parcel.dataSize());
+    ASSERT_GT(parcel.dataSize(), 0) << "Parcel size reports empty record";
+    ASSERT_NO_FATAL_FAILURE(validateOutput());
+    if (kDebug) {
+        ASSERT_NO_FATAL_FAILURE(dumpInfo());
+    }
+}
+
+TEST_P(StagefrightRecorderTest, MultiFormatAudioRecordTest) {
+    output_format outputFormat = GetParam().first;
+    audio_encoder audioEncoder = GetParam().second;
+    ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(outputFormat, audioEncoder));
+    ASSERT_NO_FATAL_FAILURE(recordMedia());
+    // TODO(b/161687761)
+    // Skip for AMR-NB/WB output format
+    if (!(outputFormat == OUTPUT_FORMAT_AMR_NB || outputFormat == OUTPUT_FORMAT_AMR_WB)) {
+        ASSERT_NO_FATAL_FAILURE(validateOutput());
+    }
+    if (kDebug) {
+        ASSERT_NO_FATAL_FAILURE(dumpInfo());
+    }
+}
+
+TEST_F(StagefrightRecorderTest, GetActiveMicrophonesTest) {
+    ASSERT_NO_FATAL_FAILURE(
+            setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT, AUDIO_SOURCE_MIC));
+
+    status_t status = mStfRecorder->init();
+    ASSERT_EQ(status, OK) << "Init failed for stagefright recorder";
+
+    status = mStfRecorder->prepare();
+    ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+    status = mStfRecorder->start();
+    ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+    // Record media for 4 secs
+    std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+
+    std::vector<media::MicrophoneInfo> activeMicrophones{};
+    status = mStfRecorder->getActiveMicrophones(&activeMicrophones);
+    ASSERT_EQ(status, OK) << "Failed to get Active Microphones";
+    ASSERT_GT(activeMicrophones.size(), 0) << "No active microphones are found";
+
+    status = mStfRecorder->stop();
+    ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+    if (kDebug) {
+        ASSERT_NO_FATAL_FAILURE(dumpInfo());
+    }
+}
+
+TEST_F(StagefrightRecorderTest, MultiStartPauseTest) {
+    ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+    ASSERT_NO_FATAL_FAILURE(recordMedia(true, kMaxLoopCount, kMaxLoopCount));
+    ASSERT_NO_FATAL_FAILURE(validateOutput());
+    if (kDebug) {
+        ASSERT_NO_FATAL_FAILURE(dumpInfo());
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        StagefrightRecorderTestAll, StagefrightRecorderTest,
+        ::testing::Values(std::make_pair(OUTPUT_FORMAT_AMR_NB, AUDIO_ENCODER_AMR_NB),
+                          std::make_pair(OUTPUT_FORMAT_AMR_WB, AUDIO_ENCODER_AMR_WB),
+                          std::make_pair(OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_AAC),
+                          std::make_pair(OUTPUT_FORMAT_OGG, AUDIO_ENCODER_OPUS)));
+
+int main(int argc, char **argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGV("Test result = %d\n", status);
+    return status;
+}
diff --git a/media/libnbaio/include/media/nbaio/Pipe.h b/media/libnbaio/include/media/nbaio/Pipe.h
index 0431976..54dc08f 100644
--- a/media/libnbaio/include/media/nbaio/Pipe.h
+++ b/media/libnbaio/include/media/nbaio/Pipe.h
@@ -23,7 +23,7 @@
 namespace android {
 
 // Pipe is multi-thread safe for readers (see PipeReader), but safe for only a single writer thread.
-// It cannot UNDERRUN on write, unless we allow designation of a master reader that provides the
+// It cannot UNDERRUN on write, unless we allow designation of a primary reader that provides the
 // time-base. Readers can be added and removed dynamically, and it's OK to have no readers.
 class Pipe : public NBAIO_Sink {
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 63ab654..5aa90c9 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -887,7 +887,7 @@
 
             sp<DataConverter> converter = mConverter[portIndex];
             if (converter != NULL) {
-                // here we assume sane conversions of max 4:1, so result fits in int32
+                // here we assume conversions of max 4:1, so result fits in int32
                 if (portIndex == kPortIndexInput) {
                     conversionBufferSize = converter->sourceSize(bufSize);
                 } else {
@@ -2237,6 +2237,12 @@
             }
             err = setupG711Codec(encoder, sampleRate, numChannels);
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_OPUS)) {
+        int32_t numChannels = 1, sampleRate = 48000;
+        if (msg->findInt32("channel-count", &numChannels) &&
+            msg->findInt32("sample-rate", &sampleRate)) {
+            err = setupOpusCodec(encoder, sampleRate, numChannels);
+        }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
         // numChannels needs to be set to properly communicate PCM values.
         int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1;
@@ -2602,15 +2608,15 @@
     unsigned int numLayers = 0;
     unsigned int numBLayers = 0;
     int tags;
-    char dummy;
+    char tmp;
     OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
         OMX_VIDEO_AndroidTemporalLayeringPatternNone;
-    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
             && numLayers > 0) {
         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
     } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
-                    &numLayers, &dummy, &numBLayers, &dummy))
-            && (tags == 1 || (tags == 3 && dummy == '+'))
+                    &numLayers, &tmp, &numBLayers, &tmp))
+            && (tags == 1 || (tags == 3 && tmp == '+'))
             && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
         numLayers += numBLayers;
         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
@@ -3110,6 +3116,26 @@
             kPortIndexInput, sampleRate, numChannels);
 }
 
+status_t ACodec::setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels) {
+    if (encoder) {
+        return INVALID_OPERATION;
+    }
+    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = kPortIndexInput;
+    status_t err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
+    if (err != OK) {
+        ALOGE("setupOpusCodec(): Error %d getting OMX_IndexParamAudioAndroidOpus parameter", err);
+        return err;
+    }
+    def.nSampleRate = sampleRate;
+    def.nChannels = numChannels;
+    err = mOMXNode->setParameter(
+           (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
+    return err;
+}
+
 status_t ACodec::setupFlacCodec(
         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
         AudioEncoding encoding) {
@@ -4757,15 +4783,15 @@
         unsigned int numLayers = 0;
         unsigned int numBLayers = 0;
         int tags;
-        char dummy;
-        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+        char tmp;
+        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
                 && numLayers > 0) {
             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
             tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
             tsLayers = numLayers;
         } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
-                        &numLayers, &dummy, &numBLayers, &dummy))
-                && (tags == 1 || (tags == 3 && dummy == '+'))
+                        &numLayers, &tmp, &numBLayers, &tmp))
+                && (tags == 1 || (tags == 3 && tmp == '+'))
                 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
             // VPX does not have a concept of B-frames, so just count all layers
@@ -7631,8 +7657,8 @@
         mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
     }
 
-    int32_t dummy;
-    if (params->findInt32("request-sync", &dummy)) {
+    int32_t tmp;
+    if (params->findInt32("request-sync", &tmp)) {
         status_t err = requestIDRFrame();
 
         if (err != OK) {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 3bccb7b..c180edf 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -8,6 +8,12 @@
         "com.android.media.swcodec",
     ],
     min_sdk_version: "29",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_static {
@@ -34,6 +40,12 @@
         "libstagefright_foundation",
         "libutils"
     ],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_static {
@@ -58,9 +70,18 @@
     },
 
     header_libs: [
+        "libaudioclient_headers",
         "libstagefright_foundation_headers",
+        "media_ndk_headers",
     ],
-    shared_libs: ["libmediandk"],
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
     export_include_dirs: ["include"],
 }
 
@@ -132,8 +153,10 @@
 
     header_libs: [
         "libaudioclient_headers",
-        "libmedia_headers",
+        "libbase_headers",
+        "libmedia_datasource_headers",
         "media_ndk_headers",
+        "media_plugin_headers",
     ],
 
     cflags: [
@@ -150,6 +173,18 @@
             "signed-integer-overflow",
         ],
     },
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+        linux: {
+            cflags: [
+                "-DDISABLE_AUDIO_SYSTEM_OFFLOAD",
+            ],
+        }
+    },
 }
 
 cc_library_shared {
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index b347453..0e4eae2 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -30,6 +30,8 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
 
+#define UNUSED_PARAM __attribute__((unused))
+
 namespace android {
 
 static const uint8_t kHevcNalUnitTypes[5] = {
@@ -376,7 +378,7 @@
 }
 
 status_t HevcParameterSets::parsePps(
-        const uint8_t* data __unused, size_t size __unused) {
+        const uint8_t* data UNUSED_PARAM, size_t size UNUSED_PARAM) {
     return OK;
 }
 
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index c6e753d..7c981b3 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -59,7 +59,7 @@
             sp<IMediaExtractor> ex;
             mediaExService->makeExtractor(
                     CreateIDataSourceFromDataSource(source),
-                    mime ? std::make_unique<std::string>(mime) : nullptr,
+                    mime ? std::optional<std::string>(mime) : std::nullopt,
                     &ex);
             return ex;
         } else {
diff --git a/media/libstagefright/OWNERS b/media/libstagefright/OWNERS
new file mode 100644
index 0000000..819389d
--- /dev/null
+++ b/media/libstagefright/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+chz@google.com
+essick@google.com
+lajos@google.com
+marcone@google.com
+taklee@google.com
+wonsik@google.com
\ No newline at end of file
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a1e4d43..d67874f 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1135,7 +1135,7 @@
         // assertion, let's be lenient for now...
         // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
 
-        size_t lengthSize __unused = 1 + (ptr[4] & 3);
+        // we can get lengthSize value from 1 + (ptr[4] & 3)
 
         // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
         // violates it...
@@ -2178,7 +2178,11 @@
     }
     // Check if offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming
+#ifdef DISABLE_AUDIO_SYSTEM_OFFLOAD
+    return false;
+#else
     return AudioSystem::isOffloadSupported(info);
+#endif
 }
 
 HLSTime::HLSTime(const sp<AMessage>& meta) :
diff --git a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
index 168d140..157cab6 100644
--- a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
+++ b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
@@ -217,7 +217,7 @@
         }
         else { // handle other used encoder target levels
 
-            // Sanity check: DRC presentation mode is only specified for max. 5.1 channels
+            // Validation check: DRC presentation mode is only specified for max. 5.1 channels
             if (mStreamNrAACChan > 6) {
                 drcPresMode = 0;
             }
@@ -308,7 +308,7 @@
             } // switch()
         } // if (mEncoderTarget  == GPM_ENCODER_TARGET_LEVEL)
 
-        // sanity again
+        // validation check again
         if (newHeavy == 1) {
             newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
             newAttFactor = 127;
diff --git a/media/libstagefright/codecs/amrnb/dec/test/AndroidTest.xml b/media/libstagefright/codecs/amrnb/dec/test/AndroidTest.xml
new file mode 100644
index 0000000..1a9e678
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/dec/test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for Amr-nb Decoder unit test">
+    <option name="test-suite-tag" value="AmrnbDecoderTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="AmrnbDecoderTest->/data/local/tmp/AmrnbDecoderTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest.zip?unzip=true"
+            value="/data/local/tmp/AmrnbDecoderTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="AmrnbDecoderTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/AmrnbDecoderTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/codecs/amrnb/dec/test/README.md b/media/libstagefright/codecs/amrnb/dec/test/README.md
index 62e13ae..e9073e4 100644
--- a/media/libstagefright/codecs/amrnb/dec/test/README.md
+++ b/media/libstagefright/codecs/amrnb/dec/test/README.md
@@ -22,13 +22,18 @@
 adb push ${OUT}/data/nativetest/AmrnbDecoderTest/AmrnbDecoderTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/13cM4tAaVFrmr-zGFqaAzFBbKs75pnm9b). Push these files into device for testing.
-Download amr-nb folder and push all the files in this folder to /data/local/tmp/ on the device.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest.zip). Download, unzip and push these files into device for testing.
+
 ```
-adb push amr-nb/. /data/local/tmp/
+adb push AmrnbDecoderTestRes/. /data/local/tmp/
 ```
 
 usage: AmrnbDecoderTest -P \<path_to_folder\>
 ```
-adb shell /data/local/tmp/AmrnbDecoderTest -P /data/local/tmp/
+adb shell /data/local/tmp/AmrnbDecoderTest -P /data/local/tmp/AmrnbDecoderTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest AmrnbDecoderTest -- --enable-module-dynamic-download=true
 ```
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp b/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
index f8da589..08a5c15 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
@@ -1106,7 +1106,7 @@
     // the real, quantized gains)
     gc_pred(pred_st, MR475, sf1_code_nosharp,
             &sf1_exp_gcode0, &sf1_frac_gcode0,
-            &sf0_exp_gcode0, &sf0_gcode0); // last two args are dummy
+            &sf0_exp_gcode0, &sf0_gcode0); // last two args are unused
     sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
 
     tmp = add (tmp, 2);
@@ -1426,7 +1426,7 @@
        the real, quantized gains)                                   */
     gc_pred(pred_st, MR475, sf1_code_nosharp,
             &sf1_exp_gcode0, &sf1_frac_gcode0,
-            &sf0_exp_gcode0, &sf0_gcode0, /* dummy args */
+            &sf0_exp_gcode0, &sf0_gcode0, /* unused args */
             pOverflow);
 
     sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/Android.bp b/media/libstagefright/codecs/amrnb/fuzzer/Android.bp
index 54de1cc..c1eaa53 100644
--- a/media/libstagefright/codecs/amrnb/fuzzer/Android.bp
+++ b/media/libstagefright/codecs/amrnb/fuzzer/Android.bp
@@ -34,4 +34,10 @@
             enabled: false,
         },
     },
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
 }
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
index d4e7e5c..c7a7378 100644
--- a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
+++ b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
@@ -26,8 +26,10 @@
 constexpr int32_t kBitsPerSample = 16;
 constexpr int32_t kOutputBufferSize = kSamplesPerFrame * kBitsPerSample / 8;
 const bitstream_format kBitStreamFormats[2] = {MIME_IETF, IF2};
-const int32_t kLocalWmfDecBytesPerFrame[8] = {12, 13, 15, 17, 19, 20, 26, 31};
-const int32_t kLocalIf2DecBytesPerFrame[8] = {13, 14, 16, 18, 19, 21, 26, 31};
+const int32_t kLocalWmfDecBytesPerFrame[16] = {12, 13, 15, 17, 19, 20, 26, 31,
+                                               5,  6,  5,  5,  0,  0,  0,  0};
+const int32_t kLocalIf2DecBytesPerFrame[16] = {13, 14, 16, 18, 19, 21, 26, 31,
+                                               13, 14, 16, 18, 19, 21, 26, 31};
 
 class Codec {
  public:
@@ -52,7 +54,7 @@
     bitstream_format bitsreamFormat = kBitStreamFormats[bit];
     int32_t frameSize = 0;
     /* Find frame type */
-    Frame_Type_3GPP frameType = static_cast<Frame_Type_3GPP>((mode >> 3) & 0x07);
+    Frame_Type_3GPP frameType = static_cast<Frame_Type_3GPP>((mode >> 3) & 0x0f);
     ++data;
     --size;
     if (bit) {
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/Android.bp b/media/libstagefright/codecs/amrwb/fuzzer/Android.bp
index 46f77e3..7106a30 100644
--- a/media/libstagefright/codecs/amrwb/fuzzer/Android.bp
+++ b/media/libstagefright/codecs/amrwb/fuzzer/Android.bp
@@ -32,4 +32,10 @@
             enabled: false,
         },
     },
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
 }
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.h b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
index ef86915..d5885a6 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.h
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
@@ -20,9 +20,7 @@
 
 #include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
-extern "C" {
 #include "gsm.h"
-}
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index 4303565..7a33c54 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -6,23 +6,18 @@
         "com.android.media.swcodec",
     ],
     min_sdk_version: "29",
+    host_supported: true,
     shared_libs: ["liblog"],
 
     srcs: [
-        "src/adaptive_smooth_no_mmx.cpp",
         "src/bitstream.cpp",
         "src/block_idct.cpp",
         "src/cal_dc_scaler.cpp",
-        "src/chvr_filter.cpp",
-        "src/chv_filter.cpp",
         "src/combined_decode.cpp",
         "src/conceal.cpp",
         "src/datapart_decode.cpp",
         "src/dcac_prediction.cpp",
         "src/dec_pred_intra_dc.cpp",
-        "src/deringing_chroma.cpp",
-        "src/deringing_luma.cpp",
-        "src/find_min_max.cpp",
         "src/get_pred_adv_b_add.cpp",
         "src/get_pred_outside.cpp",
         "src/idct.cpp",
@@ -31,9 +26,6 @@
         "src/mb_utils.cpp",
         "src/packet_util.cpp",
         "src/post_filter.cpp",
-        "src/post_proc_semaphore.cpp",
-        "src/pp_semaphore_chroma_inter.cpp",
-        "src/pp_semaphore_luma.cpp",
         "src/pvdec_api.cpp",
         "src/scaling_tab.cpp",
         "src/vlc_decode.cpp",
@@ -43,11 +35,6 @@
         "src/zigzag_tab.cpp",
     ],
 
-    header_libs: [
-        "media_plugin_headers",
-        "libstagefright_headers"
-    ],
-
     local_include_dirs: ["src"],
     export_include_dirs: ["include"],
 
@@ -63,6 +50,12 @@
         ],
         cfi: true,
     },
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 //###############################################################################
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
index 1f404ce..06aee07 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
@@ -42,13 +42,6 @@
 #define OSCL_EXPORT_REF /* empty */
 #endif
 
-/* flag for post-processing  4/25/00 */
-
-#ifdef DEC_NOPOSTPROC
-#undef PV_POSTPROC_ON   /* enable compilation of post-processing code */
-#else
-#define PV_POSTPROC_ON
-#endif
 
 #define PV_NO_POST_PROC 0
 #define PV_DEBLOCK 1
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
deleted file mode 100644
index e2761eb..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-
- Description: Separated modules into one function per file and put into
-    new template.
-
- Description: Optimizing C code and adding comments.  Also changing variable
-    names to make them more meaningful.
-
- Who:                   Date:
- Description:
-
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-
-    Rec_Y = pointer to 0th position in buffer containing luminance values
-        of type uint8.
-    y_start = value of y coordinate of type int that specifies the first
-        row of pixels to be used in the filter algorithm.
-    x_start = value of x coordinate of type int that specifies the first
-        column of pixels to be used in the filter algorithm.
-    y_blk_start = value of the y coordinate of type int that specifies the
-        row of pixels which contains the start of a block. The row
-        specified by y_blk_start+BLK_SIZE is the last row of pixels
-        that are used in the filter algorithm.
-    x_blk_start = value of the x coordinate of type int that specifies the
-        column of pixels which contains the start of a block.  The
-        column specified by x_blk_start+BLK_SIZE is the last column of
-        pixels that are used in the filter algorithm.
-    thr = value of type int that is compared to the elements in Rec_Y to
-        determine if a particular value in Rec_Y will be modified by
-        the filter or not
-    width = value of type int that specifies the width of the display
-        in pixels (or pels, equivalently).
-    max_diff = value of type int that specifies the value that may be added
-        or subtracted from the pixel in Rec_Y that is being filtered
-        if the filter algorithm decides to change that particular
-        pixel's luminance value.
-
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    None
-
- Pointers and Buffers Modified:
-    Buffer pointed to by Rec_Y is modified with the filtered
-    luminance values.
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function implements a motion compensated noise filter using adaptive
- weighted averaging of luminance values.  *Rec_Y contains the luminance values
- that are being filtered.
-
- The picture below depicts a 3x3 group of pixel luminance values.  The "u", "c",
- and "l" stand for "upper", "center" and "lower", respectively.  The location
- of pelc0 is specified by x_start and y_start in the 1-D array "Rec_Y" as
- follows (assuming x_start=0):
-
- location of pelc0 = [(y_start+1) * width] + x_start
-
- Moving up or down 1 row (moving from pelu2 to pelc2, for example) is done by
- incrementing or decrementing "width" elements within Rec_Y.
-
- The coordinates of the upper left hand corner of a block (not the group of
- 9 pixels depicted in the figure below) is specified by
- (y_blk_start, x_blk_start).  The width and height of the block is BLKSIZE.
- (y_start,x_start) may be specified independently of (y_blk_start, x_blk_start).
-
-    (y_start,x_start)
- -----------|--------------------------
-    |   |   |   |   |
-    |   X   | pelu1 | pelu2 |
-    | pelu0 |   |   |
-    |   |   |   |
- --------------------------------------
-    |   |   |   |
-    | pelc0 | pelc1 | pelc2 |
-    |   |   |   |
-    |   |   |   |
- --------------------------------------
-    |   |   |   |
-    | pell0 | pell1 | pell2 |
-    |   |   |   |
-    |   |   |   |
- --------------------------------------
-
- The filtering of the luminance values is achieved by comparing the 9
- luminance values to a threshold value ("thr") and then changing the
- luminance value of pelc1 if all of the values are above or all of the values
- are below the threshold.  The amount that the luminance value is changed
- depends on a weighted sum of the 9 luminance values. The position of Pelc1
- is then advanced to the right by one (as well as all of the surrounding pixels)
- and the same calculation is performed again for the luminance value of the new
- Pelc1. This continues row-wise until pixels in the last row of the block are
- filtered.
-
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None.
-
-------------------------------------------------------------------------------
- REFERENCES
-
- ..\corelibs\decoder\common\src\post_proc.c
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-------------------------------------------------------------------------------
- RESOURCES USED
-   When the code is written for a specific target processor the
-     the resources used should be documented below.
-
- STACK USAGE: [stack count for this module] + [variable to represent
-          stack usage for each subroutine called]
-
-     where: [stack usage variable] = stack usage for [subroutine
-         name] (see [filename].ext)
-
- DATA MEMORY USED: x words
-
- PROGRAM MEMORY USED: x words
-
- CLOCK CYCLES: [cycle count equation for this module] + [variable
-           used to represent cycle count for each subroutine
-           called]
-
-     where: [cycle count variable] = cycle count for [subroutine
-        name] (see [filename].ext)
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_lib.h"
-#include    "post_proc.h"
-#include    "mp4def.h"
-
-#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void AdaptiveSmooth_NoMMX(
-    uint8 *Rec_Y,       /* i/o  */
-    int y_start,        /* i    */
-    int x_start,        /* i    */
-    int y_blk_start,    /* i    */
-    int x_blk_start,    /* i    */
-    int thr,        /* i    */
-    int width,      /* i    */
-    int max_diff        /* i    */
-)
-{
-
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int  sign_v[15];
-    int sum_v[15];
-    int *sum_V_ptr;
-    int *sign_V_ptr;
-    uint8 pelu;
-    uint8 pelc;
-    uint8 pell;
-    uint8 *pelp;
-    uint8 oldrow[15];
-    int  sum;
-    int sum1;
-    uint8 *Rec_Y_ptr;
-    int32  addr_v;
-    int row_cntr;
-    int col_cntr;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    /*  first row
-    */
-    addr_v = (int32)(y_start + 1) * width;  /* y coord of 1st element in the row  /
-                     /containing pelc pixel /     */
-    Rec_Y_ptr = &Rec_Y[addr_v + x_start];  /* initializing pointer to
-                           /  pelc0 position  */
-    sum_V_ptr = &sum_v[0];  /* initializing pointer to 0th element of array
-                /   that will contain weighted sums of pixel
-                /   luminance values */
-    sign_V_ptr = &sign_v[0];  /*  initializing pointer to 0th element of
-                  /   array that will contain sums that indicate
-                  /    how many of the 9 pixels are above or below
-                  /    the threshold value (thr)    */
-    pelp = &oldrow[0];  /* initializing pointer to the 0th element of array
-                /    that will contain current values of pelc that
-                /   are saved and used as values of pelu when the
-                /   next row of pixels are filtered */
-
-    pelu = *(Rec_Y_ptr - width);  /* assigning value of pelu0 to pelu  */
-    *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc0 to pelc and
-                     /  storing this value in pelp which
-                     /   will be used as value of pelu0 when
-                     /  next row is filtered */
-    pell = *(Rec_Y_ptr + width);  /* assigning value of pell0 to pell */
-    Rec_Y_ptr++; /* advancing pointer from pelc0 to pelc1 */
-    *sum_V_ptr++ = pelu + (pelc << 1) + pell;  /* weighted sum of pelu0,
-                         /  pelc0 and pell0  */
-    /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
-    /is above thr)  */
-    *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
-
-
-    pelu = *(Rec_Y_ptr - width);  /* assigning value of pelu1 to pelu */
-    *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc1 to pelc and
-                     /  storing this value in pelp which
-                     /  will be used as the value of pelu1 when
-                     /  next row is filtered */
-    pell = *(Rec_Y_ptr + width);  /* assigning value of pell1 to pell */
-    Rec_Y_ptr++;  /* advancing pointer from pelc1 to pelc2 */
-    *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu1,
-                        / pelc1 and pell1  */
-    /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
-    /is above thr)  */
-    *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
-
-    /* The loop below performs the filtering for the first row of
-    /   pixels in the region.  It steps across the remaining pixels in
-    /   the row and alters the luminance value of pelc1 if necessary,
-    /   depending on the luminance values of the adjacent pixels*/
-
-    for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
-    {
-        pelu = *(Rec_Y_ptr - width);  /* assigning value of pelu2 to
-                        /   pelu */
-        *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc2 to pelc
-                         / and storing this value in pelp
-                         / which will be used   as value of pelu2
-                         / when next row is filtered */
-        pell = *(Rec_Y_ptr + width); /* assigning value of pell2 to pell */
-
-        /* weighted sum of pelu1, pelc1 and pell1  */
-        *sum_V_ptr = pelu + (pelc << 1) + pell;
-        /* sum of 0's and 1's (0 if pixel value is below thr,
-        /1 if value is above thr)  */
-        *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
-                      INDEX(pell, thr);
-        /* the value of sum1 indicates how many of the 9 pixels'
-        /luminance values are above or equal to thr */
-        sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
-
-        /* alter the luminance value of pelc1 if all 9 luminance values
-        /are above or equal to thr or if all 9 values are below thr */
-        if (sum1 == 0 || sum1 == 9)
-        {
-            /* sum is a weighted average of the 9 pixel luminance
-            /values   */
-            sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
-                   *sum_V_ptr + 8) >> 4;
-
-            Rec_Y_ptr--;  /* move pointer back to pelc1  */
-            /* If luminance value of pelc1 is larger than
-            / sum by more than max_diff, then subract max_diff
-            / from luminance value of pelc1*/
-            if ((int)(*Rec_Y_ptr - sum) > max_diff)
-            {
-                sum = *Rec_Y_ptr - max_diff;
-            }
-            /* If luminance value of pelc1 is smaller than
-            / sum by more than max_diff, then add max_diff
-            / to luminance value of pelc1*/
-            else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
-            {
-                sum = *Rec_Y_ptr + max_diff;
-            }
-            *Rec_Y_ptr++ = sum; /* assign value of sum to pelc1
-                         and advance pointer to pelc2 */
-        }
-        Rec_Y_ptr++; /* advance pointer to new value of pelc2
-                 /   old pelc2 is now treated as pelc1*/
-        sum_V_ptr++; /* pointer is advanced so next weighted sum may
-                 /  be saved */
-        sign_V_ptr++; /* pointer is advanced so next sum of 0's and
-                  / 1's may be saved  */
-    }
-
-    /* The nested loops below perform the filtering for the remaining rows */
-
-    addr_v = (y_start + 2) * width;  /* advance addr_v to the next row
-                     /   (corresponding to pell0)*/
-    /* The outer loop steps throught the rows.   */
-    for (row_cntr = (y_blk_start + BLKSIZE) - (y_start + 2); row_cntr > 0; row_cntr--)
-    {
-        Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* advance pointer to
-            /the old pell0, which has become the new pelc0 */
-        addr_v += width;  /* move addr_v down 1 row */
-        sum_V_ptr = &sum_v[0];  /* re-initializing pointer */
-        sign_V_ptr = &sign_v[0];  /* re-initilaizing pointer */
-        pelp = &oldrow[0]; /* re-initializing pointer */
-
-        pelu = *pelp; /* setting pelu0 to old value of pelc0 */
-        *pelp++ = pelc = *Rec_Y_ptr;
-        pell = *(Rec_Y_ptr + width);
-        Rec_Y_ptr++;
-        *sum_V_ptr++ = pelu + (pelc << 1) + pell;
-        *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
-                        INDEX(pell, thr);
-
-        pelu = *pelp; /* setting pelu1 to old value of pelc1 */
-        *pelp++ = pelc = *Rec_Y_ptr;
-        pell = *(Rec_Y_ptr + width);
-        Rec_Y_ptr++;
-        *sum_V_ptr++ = pelu + (pelc << 1) + pell;
-        *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
-                        INDEX(pell, thr);
-        /* The inner loop steps through the columns */
-        for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
-        {
-            pelu = *pelp; /* setting pelu2 to old value of pelc2 */
-            *pelp++ = pelc = *Rec_Y_ptr;
-            pell = *(Rec_Y_ptr + width);
-
-            *sum_V_ptr = pelu + (pelc << 1) + pell;
-            *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
-                          INDEX(pell, thr);
-
-            sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
-            /* the "if" statement below is the same as the one in
-            / the first loop */
-            if (sum1 == 0 || sum1 == 9)
-            {
-                sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
-                       *sum_V_ptr + 8) >> 4;
-
-                Rec_Y_ptr--;
-                if ((int)(*Rec_Y_ptr - sum) > max_diff)
-                {
-                    sum = *Rec_Y_ptr - max_diff;
-                }
-                else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
-                {
-                    sum = *Rec_Y_ptr + max_diff;
-                }
-                *Rec_Y_ptr++ = (uint8) sum;
-            }
-            Rec_Y_ptr++;
-            sum_V_ptr++;
-            sign_V_ptr++;
-        }
-    }
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
index 3d10086..bc708e2 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
@@ -506,6 +506,7 @@
 /*----------------------------------------------------------------------------
 ; Function Code FOR idctrow
 ----------------------------------------------------------------------------*/
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow(
     int16 *blk, uint8 *pred, uint8 *dst, int width
 )
@@ -828,6 +829,7 @@
 /*----------------------------------------------------------------------------
 ; Function Code FOR idctcol
 ----------------------------------------------------------------------------*/
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctcol(
     int16 *blk
 )
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
deleted file mode 100644
index 6593b48..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    [input_variable_name] = [description of the input to module, its type
-                 definition, and length (when applicable)]
-
- Local Stores/Buffers/Pointers Needed:
-    [local_store_name] = [description of the local store, its type
-                  definition, and length (when applicable)]
-    [local_buffer_name] = [description of the local buffer, its type
-                   definition, and length (when applicable)]
-    [local_ptr_name] = [description of the local pointer, its type
-                definition, and length (when applicable)]
-
- Global Stores/Buffers/Pointers Needed:
-    [global_store_name] = [description of the global store, its type
-                   definition, and length (when applicable)]
-    [global_buffer_name] = [description of the global buffer, its type
-                definition, and length (when applicable)]
-    [global_ptr_name] = [description of the global pointer, its type
-                 definition, and length (when applicable)]
-
- Outputs:
-    [return_variable_name] = [description of data/pointer returned
-                  by module, its type definition, and length
-                  (when applicable)]
-
- Pointers and Buffers Modified:
-    [variable_bfr_ptr] points to the [describe where the
-      variable_bfr_ptr points to, its type definition, and length
-      (when applicable)]
-    [variable_bfr] contents are [describe the new contents of
-      variable_bfr]
-
- Local Stores Modified:
-    [local_store_name] = [describe new contents, its type
-                  definition, and length (when applicable)]
-
- Global Stores Modified:
-    [global_store_name] = [describe new contents, its type
-                   definition, and length (when applicable)]
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
-   For fast Deblock filtering
-   Newer version (macroblock based processing)
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- [List requirements to be satisfied by this module.]
-
-------------------------------------------------------------------------------
- REFERENCES
-
- [List all references used in designing this module.]
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-------------------------------------------------------------------------------
- RESOURCES USED
-   When the code is written for a specific target processor the
-     the resources used should be documented below.
-
- STACK USAGE: [stack count for this module] + [variable to represent
-          stack usage for each subroutine called]
-
-     where: [stack usage variable] = stack usage for [subroutine
-         name] (see [filename].ext)
-
- DATA MEMORY USED: x words
-
- PROGRAM MEMORY USED: x words
-
- CLOCK CYCLES: [cycle count equation for this module] + [variable
-           used to represent cycle count for each subroutine
-           called]
-
-     where: [cycle count variable] = cycle count for [subroutine
-        name] (see [filename].ext)
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_lib.h"
-#include    "post_proc.h"
-
-#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-//#define FILTER_LEN_8
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-
-----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-
-/*************************************************************************
-    Function prototype : void CombinedHorzVertFilter(   uint8 *rec,
-                                                        int width,
-                                                        int height,
-                                                        int *QP_store,
-                                                        int chr,
-                                                        uint8 *pp_mod)
-    Parameters  :
-        rec     :   pointer to the decoded frame buffer.
-        width   :   width of decoded frame.
-        height  :   height of decoded frame
-        QP_store:   pointer to the array of QP corresponding to the decoded frame.
-                    It had only one value for each MB.
-        chr     :   luma or color indication
-                    == 0 luma
-                    == 1 color
-        pp_mod  :   The semphore used for deblocking
-
-    Remark      :   The function do the deblocking on decoded frames.
-                    First based on the semaphore info., it is divided into hard and soft filtering.
-                    To differentiate real and fake edge, it then check the difference with QP to
-                    decide whether to do the filtering or not.
-
-*************************************************************************/
-
-
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void CombinedHorzVertFilter(
-    uint8 *rec,
-    int width,
-    int height,
-    int16 *QP_store,
-    int chr,
-    uint8 *pp_mod)
-{
-
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int br, bc, mbr, mbc;
-    int QP = 1;
-    uint8 *ptr, *ptr_e;
-    int pp_w, pp_h;
-    int brwidth;
-
-    int jVal0, jVal1, jVal2;
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    pp_w = (width >> 3);
-    pp_h = (height >> 3);
-
-    for (mbr = 0; mbr < pp_h; mbr += 2)         /* row of blocks */
-    {
-        brwidth = mbr * pp_w;               /* number of blocks above current block row */
-        for (mbc = 0; mbc < pp_w; mbc += 2)     /* col of blocks */
-        {
-            if (!chr)
-                QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
-
-            /********* for each block **************/
-            /****************** Horiz. Filtering ********************/
-            for (br = mbr + 1; br < mbr + 3; br++)  /* 2x2 blocks */
-            {
-                brwidth += pp_w;                    /* number of blocks above & left current block row */
-                /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
-                if (br < pp_h)                  /* boundary : don't do it on the lowest row block */
-                    for (bc = mbc; bc < mbc + 2; bc++)
-                    {
-                        /****** check boundary for deblocking ************/
-                        if (bc < pp_w)              /* boundary : don't do it on the most right col block */
-                        {
-                            ptr = rec + (brwidth << 6) + (bc << 3);
-                            jVal0 = brwidth + bc;
-                            if (chr)    QP = QP_store[jVal0];
-
-                            ptr_e = ptr + 8;        /* pointer to where the loop ends */
-
-                            if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
-                            {
-                                /* Horiz Hard filter */
-                                do
-                                {
-                                    jVal0 = *(ptr - width);     /* C */
-                                    jVal1 = *ptr;               /* D */
-                                    jVal2 = jVal1 - jVal0;
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
-                                    {
-                                        /* differentiate between real and fake edge */
-                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (D+C)/2 */
-                                        *(ptr - width) = (uint8)(jVal0);    /*  C */
-                                        *ptr = (uint8)(jVal0);          /*  D */
-
-                                        jVal0 = *(ptr - (width << 1));      /* B */
-                                        jVal1 = *(ptr + width);         /* E */
-                                        jVal2 = jVal1 - jVal0;      /* E-B */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal0 += ((jVal2 + 3) >> 2);
-                                            jVal1 -= ((jVal2 + 3) >> 2);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
-                                            *(ptr + width) = (uint8)jVal1;          /* store E */
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal0 -= ((3 - jVal2) >> 2);
-                                            jVal1 += ((3 - jVal2) >> 2);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
-                                            *(ptr + width) = (uint8)jVal1;          /* store E */
-                                        }
-
-                                        jVal0 = *(ptr - (width << 1) - width);  /* A */
-                                        jVal1 = *(ptr + (width << 1));      /* F */
-                                        jVal2 = jVal1 - jVal0;              /* (F-A) */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal0 += ((jVal2 + 7) >> 3);
-                                            jVal1 -= ((jVal2 + 7) >> 3);
-                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
-                                            *(ptr + (width << 1)) = (uint8)(jVal1);
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal0 -= ((7 - jVal2) >> 3);
-                                            jVal1 += ((7 - jVal2) >> 3);
-                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
-                                            *(ptr + (width << 1)) = (uint8)(jVal1);
-                                        }
-                                    }/* a3_0 > 2QP */
-                                }
-                                while (++ptr < ptr_e);
-                            }
-                            else   /* Horiz soft filter*/
-                            {
-                                do
-                                {
-                                    jVal0 = *(ptr - width); /* B */
-                                    jVal1 = *ptr;           /* C */
-                                    jVal2 = jVal1 - jVal0;  /* C-B */
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP)))) /* (C-B) compared with QP */
-                                    {
-
-                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (B+C)/2 cannot overflow; ceil() */
-                                        *(ptr - width) = (uint8)(jVal0);    /* B = (B+C)/2 */
-                                        *ptr = (uint8)jVal0;            /* C = (B+C)/2 */
-
-                                        jVal0 = *(ptr - (width << 1));      /* A */
-                                        jVal1 = *(ptr + width);         /* D */
-                                        jVal2 = jVal1 - jVal0;          /* D-A */
-
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= ((jVal2 + 7) >> 3);
-                                            jVal0 += ((jVal2 + 7) >> 3);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /* A */
-                                            *(ptr + width) = (uint8)jVal1;          /* D */
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 += ((7 - jVal2) >> 3);
-                                            jVal0 -= ((7 - jVal2) >> 3);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /* A */
-                                            *(ptr + width) = (uint8)jVal1;          /* D */
-                                        }
-                                    }
-                                }
-                                while (++ptr < ptr_e);
-                            } /* Soft filter*/
-                        }/* boundary checking*/
-                    }/*bc*/
-            }/*br*/
-            brwidth -= (pp_w << 1);
-            /****************** Vert. Filtering ********************/
-            for (br = mbr; br < mbr + 2; br++)
-            {
-                if (br < pp_h)
-                    for (bc = mbc + 1; bc < mbc + 3; bc++)
-                    {
-                        /****** check boundary for deblocking ************/
-                        if (bc < pp_w)
-                        {
-                            ptr = rec + (brwidth << 6) + (bc << 3);
-                            jVal0 = brwidth + bc;
-                            if (chr)    QP = QP_store[jVal0];
-
-                            ptr_e = ptr + (width << 3);
-
-                            if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
-                            {
-                                /* Vert Hard filter */
-                                do
-                                {
-                                    jVal1 = *ptr;       /* D */
-                                    jVal0 = *(ptr - 1); /* C */
-                                    jVal2 = jVal1 - jVal0;  /* D-C */
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
-                                    {
-                                        jVal1 = (jVal0 + jVal1) >> 1;   /* (C+D)/2 */
-                                        *ptr        =   jVal1;
-                                        *(ptr - 1)  =   jVal1;
-
-                                        jVal1 = *(ptr + 1);     /* E */
-                                        jVal0 = *(ptr - 2);     /* B */
-                                        jVal2 = jVal1 - jVal0;      /* E-B */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= ((jVal2 + 3) >> 2);        /* E = E -(E-B)/4 */
-                                            jVal0 += ((jVal2 + 3) >> 2);        /* B = B +(E-B)/4 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 += ((3 - jVal2) >> 2);        /* E = E -(E-B)/4 */
-                                            jVal0 -= ((3 - jVal2) >> 2);        /* B = B +(E-B)/4 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-                                        }
-
-                                        jVal1 = *(ptr + 2);     /* F */
-                                        jVal0 = *(ptr - 3);     /* A */
-
-                                        jVal2 = jVal1 - jVal0;          /* (F-A) */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= ((jVal2 + 7) >> 3);    /* F -= (F-A)/8 */
-                                            jVal0 += ((jVal2 + 7) >> 3);    /* A += (F-A)/8 */
-                                            *(ptr + 2) = jVal1;
-                                            *(ptr - 3) = jVal0;
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 -= ((jVal2 - 7) >> 3);    /* F -= (F-A)/8 */
-                                            jVal0 += ((jVal2 - 7) >> 3);    /* A += (F-A)/8 */
-                                            *(ptr + 2) = jVal1;
-                                            *(ptr - 3) = jVal0;
-                                        }
-                                    }   /* end of ver hard filetering */
-                                }
-                                while ((ptr += width) < ptr_e);
-                            }
-                            else   /* Vert soft filter*/
-                            {
-                                do
-                                {
-                                    jVal1 = *ptr;               /* C */
-                                    jVal0 = *(ptr - 1);         /* B */
-                                    jVal2 = jVal1 - jVal0;
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP))))
-                                    {
-
-                                        jVal1 = (jVal0 + jVal1 + 1) >> 1;
-                                        *ptr = jVal1;           /* C */
-                                        *(ptr - 1) = jVal1;     /* B */
-
-                                        jVal1 = *(ptr + 1);     /* D */
-                                        jVal0 = *(ptr - 2);     /* A */
-                                        jVal2 = (jVal1 - jVal0);        /* D- A */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= (((jVal2) + 7) >> 3);      /* D -= (D-A)/8 */
-                                            jVal0 += (((jVal2) + 7) >> 3);      /* A += (D-A)/8 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 += ((7 - (jVal2)) >> 3);      /* D -= (D-A)/8 */
-                                            jVal0 -= ((7 - (jVal2)) >> 3);      /* A += (D-A)/8 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-                                        }
-                                    }
-                                }
-                                while ((ptr += width) < ptr_e);
-                            } /* Soft filter*/
-                        } /* boundary*/
-                    } /*bc*/
-                brwidth += pp_w;
-            }/*br*/
-            brwidth -= (pp_w << 1);
-        }/*mbc*/
-        brwidth += (pp_w << 1);
-    }/*mbr*/
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-void CombinedHorzVertFilter_NoSoftDeblocking(
-    uint8 *rec,
-    int width,
-    int height,
-    int16 *QP_store,
-    int chr,
-    uint8 *pp_mod)
-{
-
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int br, bc, mbr, mbc;
-    int QP = 1;
-    uint8 *ptr, *ptr_e;
-    int pp_w, pp_h;
-    int brwidth;
-
-    int jVal0, jVal1, jVal2;
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    pp_w = (width >> 3);
-    pp_h = (height >> 3);
-
-    for (mbr = 0; mbr < pp_h; mbr += 2)         /* row of blocks */
-    {
-        brwidth = mbr * pp_w;               /* number of blocks above current block row */
-        for (mbc = 0; mbc < pp_w; mbc += 2)     /* col of blocks */
-        {
-            if (!chr)
-                QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
-
-            /********* for each block **************/
-            /****************** Horiz. Filtering ********************/
-            for (br = mbr + 1; br < mbr + 3; br++)  /* 2x2 blocks */
-            {
-                brwidth += pp_w;                    /* number of blocks above & left current block row */
-                /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
-                if (br < pp_h)                  /* boundary : don't do it on the lowest row block */
-                    for (bc = mbc; bc < mbc + 2; bc++)
-                    {
-                        /****** check boundary for deblocking ************/
-                        if (bc < pp_w)              /* boundary : don't do it on the most right col block */
-                        {
-                            ptr = rec + (brwidth << 6) + (bc << 3);
-                            jVal0 = brwidth + bc;
-                            if (chr)    QP = QP_store[jVal0];
-
-                            ptr_e = ptr + 8;        /* pointer to where the loop ends */
-
-                            if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
-                            {
-                                /* Horiz Hard filter */
-                                do
-                                {
-                                    jVal0 = *(ptr - width);     /* C */
-                                    jVal1 = *ptr;               /* D */
-                                    jVal2 = jVal1 - jVal0;
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
-                                    {
-                                        /* differentiate between real and fake edge */
-                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (D+C)/2 */
-                                        *(ptr - width) = (uint8)(jVal0);    /*  C */
-                                        *ptr = (uint8)(jVal0);          /*  D */
-
-                                        jVal0 = *(ptr - (width << 1));      /* B */
-                                        jVal1 = *(ptr + width);         /* E */
-                                        jVal2 = jVal1 - jVal0;      /* E-B */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal0 += ((jVal2 + 3) >> 2);
-                                            jVal1 -= ((jVal2 + 3) >> 2);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
-                                            *(ptr + width) = (uint8)jVal1;          /* store E */
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal0 -= ((3 - jVal2) >> 2);
-                                            jVal1 += ((3 - jVal2) >> 2);
-                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
-                                            *(ptr + width) = (uint8)jVal1;          /* store E */
-                                        }
-
-                                        jVal0 = *(ptr - (width << 1) - width);  /* A */
-                                        jVal1 = *(ptr + (width << 1));      /* F */
-                                        jVal2 = jVal1 - jVal0;              /* (F-A) */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal0 += ((jVal2 + 7) >> 3);
-                                            jVal1 -= ((jVal2 + 7) >> 3);
-                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
-                                            *(ptr + (width << 1)) = (uint8)(jVal1);
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal0 -= ((7 - jVal2) >> 3);
-                                            jVal1 += ((7 - jVal2) >> 3);
-                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
-                                            *(ptr + (width << 1)) = (uint8)(jVal1);
-                                        }
-                                    }/* a3_0 > 2QP */
-                                }
-                                while (++ptr < ptr_e);
-                            }
-
-                        }/* boundary checking*/
-                    }/*bc*/
-            }/*br*/
-            brwidth -= (pp_w << 1);
-            /****************** Vert. Filtering ********************/
-            for (br = mbr; br < mbr + 2; br++)
-            {
-                if (br < pp_h)
-                    for (bc = mbc + 1; bc < mbc + 3; bc++)
-                    {
-                        /****** check boundary for deblocking ************/
-                        if (bc < pp_w)
-                        {
-                            ptr = rec + (brwidth << 6) + (bc << 3);
-                            jVal0 = brwidth + bc;
-                            if (chr)    QP = QP_store[jVal0];
-
-                            ptr_e = ptr + (width << 3);
-
-                            if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
-                            {
-                                /* Vert Hard filter */
-                                do
-                                {
-                                    jVal1 = *ptr;       /* D */
-                                    jVal0 = *(ptr - 1); /* C */
-                                    jVal2 = jVal1 - jVal0;  /* D-C */
-
-                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
-                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
-                                    {
-                                        jVal1 = (jVal0 + jVal1) >> 1;   /* (C+D)/2 */
-                                        *ptr        =   jVal1;
-                                        *(ptr - 1)  =   jVal1;
-
-                                        jVal1 = *(ptr + 1);     /* E */
-                                        jVal0 = *(ptr - 2);     /* B */
-                                        jVal2 = jVal1 - jVal0;      /* E-B */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= ((jVal2 + 3) >> 2);        /* E = E -(E-B)/4 */
-                                            jVal0 += ((jVal2 + 3) >> 2);        /* B = B +(E-B)/4 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 += ((3 - jVal2) >> 2);        /* E = E -(E-B)/4 */
-                                            jVal0 -= ((3 - jVal2) >> 2);        /* B = B +(E-B)/4 */
-                                            *(ptr + 1) = jVal1;
-                                            *(ptr - 2) = jVal0;
-                                        }
-
-                                        jVal1 = *(ptr + 2);     /* F */
-                                        jVal0 = *(ptr - 3);     /* A */
-
-                                        jVal2 = jVal1 - jVal0;          /* (F-A) */
-
-                                        if (jVal2 > 0)
-                                        {
-                                            jVal1 -= ((jVal2 + 7) >> 3);    /* F -= (F-A)/8 */
-                                            jVal0 += ((jVal2 + 7) >> 3);    /* A += (F-A)/8 */
-                                            *(ptr + 2) = jVal1;
-                                            *(ptr - 3) = jVal0;
-                                        }
-                                        else if (jVal2)
-                                        {
-                                            jVal1 -= ((jVal2 - 7) >> 3);    /* F -= (F-A)/8 */
-                                            jVal0 += ((jVal2 - 7) >> 3);    /* A += (F-A)/8 */
-                                            *(ptr + 2) = jVal1;
-                                            *(ptr - 3) = jVal0;
-                                        }
-                                    }   /* end of ver hard filetering */
-                                }
-                                while ((ptr += width) < ptr_e);
-                            }
-
-                        } /* boundary*/
-                    } /*bc*/
-                brwidth += pp_w;
-            }/*br*/
-            brwidth -= (pp_w << 1);
-        }/*mbc*/
-        brwidth += (pp_w << 1);
-    }/*mbr*/
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
deleted file mode 100644
index 795cf71..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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    "mp4dec_lib.h"
-#include    "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void CombinedHorzVertRingFilter(
-    uint8 *rec,
-    int width,
-    int height,
-    int16 *QP_store,
-    int chr,
-    uint8 *pp_mod)
-{
-
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int index, counter;
-    int br, bc, incr, mbr, mbc;
-    int QP = 1;
-    int v[5];
-    uint8 *ptr, *ptr_c, *ptr_n;
-    int w1, w2, w3, w4;
-    int pp_w, pp_h, brwidth;
-    int sum, delta;
-    int a3_0, a3_1, a3_2, A3_0;
-    /* for Deringing Threshold approach (MPEG4)*/
-    int max_diff, thres, v0, h0, min_blk, max_blk;
-    int cnthflag;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    /* Calculate the width and height of the area in blocks (divide by 8) */
-    pp_w = (width >> 3);
-    pp_h = (height >> 3);
-
-    /* Set up various values needed for updating pointers into rec */
-    w1 = width;             /* Offset to next row in pixels */
-    w2 = width << 1;        /* Offset to two rows in pixels */
-    w3 = w1 + w2;           /* Offset to three rows in pixels */
-    w4 = w2 << 1;           /* Offset to four rows in pixels */
-    incr = width - BLKSIZE; /* Offset to next row after processing block */
-
-    /* Work through the area hortizontally by two rows per step */
-    for (mbr = 0; mbr < pp_h; mbr += 2)
-    {
-        /* brwidth contains the block number of the leftmost block
-         * of the current row */
-        brwidth = mbr * pp_w;
-
-        /* Work through the area vertically by two columns per step */
-        for (mbc = 0; mbc < pp_w; mbc += 2)
-        {
-            /* if the data is luminance info, get the correct
-                    * quantization paramenter. One parameter per macroblock */
-            if (!chr)
-            {
-                /* brwidth/4 is the macroblock number and mbc/2 is the macroblock col number*/
-                QP = QP_store[(brwidth>>2) + (mbc>>1)];
-            }
-
-            /****************** Horiz. Filtering ********************/
-            /* Process four blocks for the filtering        */
-            /********************************************************/
-            /* Loop over two rows of blocks */
-            for (br = mbr + 1; br < mbr + 3; br++)    /* br is the row counter in blocks */
-            {
-                /* Set brwidth to the first (leftmost) block number of the next row */
-                /* brwidth is used as an index when counting blocks */
-                brwidth += pp_w;
-
-                /* Loop over two columns of blocks in the row */
-                for (bc = mbc; bc < mbc + 2; bc++)    /* bc is the column counter in blocks */
-                {
-                    /****** check boundary for deblocking ************/
-                    /* Execute if the row and column counters are within the area */
-                    if (br < pp_h && bc < pp_w)
-                    {
-                        /* Set the ptr to the first pixel of the first block of the second row
-                        * brwidth * 64 is the pixel row offset
-                        * bc * 8 is the pixel column offset */
-                        ptr = rec + (brwidth << 6) + (bc << 3);
-
-                        /* Set the index to the current block of the second row counting in blocks */
-                        index = brwidth + bc;
-
-                        /* if the data is chrominance info, get the correct
-                         * quantization paramenter. One parameter per block. */
-                        if (chr)
-                        {
-                            QP = QP_store[index];
-                        }
-
-                        /* Execute hard horizontal filter if semaphore for horizontal deblocking
-                          * is set for the current block and block immediately above it */
-                        if (((pp_mod[index]&0x02) != 0) && ((pp_mod[index-pp_w]&0x02) != 0))
-                        {   /* Hard filter */
-
-                            /* Set HorzHflag (bit 4) in the pp_mod location */
-                            pp_mod[index-pp_w] |= 0x10; /*  4/26/00 reuse pp_mod for HorzHflag*/
-
-                            /* Filter across the 8 pixels of the block */
-                            for (index = BLKSIZE; index > 0; index--)
-                            {
-                                /* Difference between the current pixel and the pixel above it */
-                                a3_0 = *ptr - *(ptr - w1);
-
-                                /* if the magnitude of the difference is greater than the KThH threshold
-                                 * and within the quantization parameter, apply hard filter */
-                                if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
-                                {
-                                    ptr_c = ptr - w3;   /* Points to pixel three rows above */
-                                    ptr_n = ptr + w1;   /* Points to pixel one row below */
-                                    v[0] = (int)(*(ptr_c - w3));
-                                    v[1] = (int)(*(ptr_c - w2));
-                                    v[2] = (int)(*(ptr_c - w1));
-                                    v[3] = (int)(*ptr_c);
-                                    v[4] = (int)(*(ptr_c + w1));
-
-                                    sum = v[0]
-                                          + v[1]
-                                          + v[2]
-                                          + *ptr_c
-                                          + v[4]
-                                          + (*(ptr_c + w2))
-                                          + (*(ptr_c + w3));  /* Current pixel */
-
-                                    delta = (sum + *ptr_c + 4) >> 3;   /* Average pixel values with rounding */
-                                    *(ptr_c) = (uint8) delta;
-
-                                    /* Move pointer down one row of pixels (points to pixel two rows
-                                     * above current pixel) */
-                                    ptr_c += w1;
-
-                                    for (counter = 0; counter < 5; counter++)
-                                    {
-                                        /* Subtract off highest pixel and add in pixel below */
-                                        sum = sum - v[counter] + *ptr_n;
-                                        /* Average the pixel values with rounding */
-                                        delta = (sum + *ptr_c + 4) >> 3;
-                                        *ptr_c = (uint8)(delta);
-
-                                        /* Increment pointers to next pixel row */
-                                        ptr_c += w1;
-                                        ptr_n += w1;
-                                    }
-                                }
-                                /* Increment pointer to next pixel */
-                                ++ptr;
-                            } /* index*/
-                        }
-                        else
-                        { /* soft filter*/
-
-                            /* Clear HorzHflag (bit 4) in the pp_mod location */
-                            pp_mod[index-pp_w] &= 0xef; /* reset 1110,1111 */
-
-                            for (index = BLKSIZE; index > 0; index--)
-                            {
-                                /* Difference between the current pixel and the pixel above it */
-                                a3_0 = *(ptr) - *(ptr - w1);
-
-                                /* if the magnitude of the difference is greater than the KTh threshold,
-                                 * apply soft filter */
-                                if ((a3_0 > KTh || a3_0 < -KTh))
-                                {
-
-                                    /* Sum of weighted differences */
-                                    a3_0 += ((*(ptr - w2) - *(ptr + w1)) << 1) + (a3_0 << 2);
-
-                                    /* Check if sum is less than the quantization parameter */
-                                    if (PV_ABS(a3_0) < (QP << 3))
-                                    {
-                                        a3_1 = *(ptr - w2) - *(ptr - w3);
-                                        a3_1 += ((*(ptr - w4) - *(ptr - w1)) << 1) + (a3_1 << 2);
-
-                                        a3_2  = *(ptr + w2) - *(ptr + w1);
-                                        a3_2 += ((*(ptr) - *(ptr + w3)) << 1) + (a3_2 << 2);
-
-                                        A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
-
-                                        if (A3_0 > 0)
-                                        {
-                                            A3_0 += A3_0 << 2;
-                                            A3_0 = (A3_0 + 32) >> 6;
-                                            if (a3_0 > 0)
-                                            {
-                                                A3_0 = -A3_0;
-                                            }
-
-                                            delta = (*(ptr - w1) - *(ptr)) >> 1;
-                                            if (delta >= 0)
-                                            {
-                                                if (delta >= A3_0)
-                                                {
-                                                    delta = PV_MAX(A3_0, 0);
-                                                }
-                                            }
-                                            else
-                                            {
-                                                if (A3_0 > 0)
-                                                {
-                                                    delta = 0;
-                                                }
-                                                else
-                                                {
-                                                    delta = PV_MAX(A3_0, delta);
-                                                }
-                                            }
-
-                                            *(ptr - w1) = (uint8)(*(ptr - w1) - delta);
-                                            *(ptr) = (uint8)(*(ptr) + delta);
-                                        }
-                                    } /*threshold*/
-                                }
-                                /* Increment pointer to next pixel */
-                                ++ptr;
-                            } /*index*/
-                        } /* Soft filter*/
-                    }/* boundary checking*/
-                }/*bc*/
-            }/*br*/
-            brwidth -= (pp_w << 1);
-
-
-            /****************** Vert. Filtering *********************/
-            /* Process four blocks for the filtering        */
-            /********************************************************/
-            /* Loop over two rows of blocks */
-            for (br = mbr; br < mbr + 2; br++)      /* br is the row counter in blocks */
-            {
-                for (bc = mbc + 1; bc < mbc + 3; bc++)  /* bc is the column counter in blocks */
-                {
-                    /****** check boundary for deblocking ************/
-                    /* Execute if the row and column counters are within the area */
-                    if (br < pp_h && bc < pp_w)
-                    {
-                        /* Set the ptr to the first pixel of the first block of the second row
-                        * brwidth * 64 is the pixel row offset
-                        * bc * 8 is the pixel column offset */
-                        ptr = rec + (brwidth << 6) + (bc << 3);
-
-                        /* Set the index to the current block of the second row counting in blocks */
-                        index = brwidth + bc;
-
-                        /* if the data is chrominance info, get the correct
-                         * quantization paramenter. One parameter per block. */
-                        if (chr)
-                        {
-                            QP = QP_store[index];
-                        }
-
-                        /* Execute hard vertical filter if semaphore for vertical deblocking
-                          * is set for the current block and block immediately left of it */
-                        if (((pp_mod[index-1]&0x01) != 0) && ((pp_mod[index]&0x01) != 0))
-                        {   /* Hard filter */
-
-                            /* Set VertHflag (bit 5) in the pp_mod location of previous block*/
-                            pp_mod[index-1] |= 0x20; /*  4/26/00 reuse pp_mod for VertHflag*/
-
-                            /* Filter across the 8 pixels of the block */
-                            for (index = BLKSIZE; index > 0; index--)
-                            {
-                                /* Difference between the current pixel
-                                * and the pixel to left of it */
-                                a3_0 = *ptr - *(ptr - 1);
-
-                                /* if the magnitude of the difference is greater than the KThH threshold
-                                 * and within the quantization parameter, apply hard filter */
-                                if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
-                                {
-                                    ptr_c = ptr - 3;
-                                    ptr_n = ptr + 1;
-                                    v[0] = (int)(*(ptr_c - 3));
-                                    v[1] = (int)(*(ptr_c - 2));
-                                    v[2] = (int)(*(ptr_c - 1));
-                                    v[3] = (int)(*ptr_c);
-                                    v[4] = (int)(*(ptr_c + 1));
-
-                                    sum = v[0]
-                                          + v[1]
-                                          + v[2]
-                                          + *ptr_c
-                                          + v[4]
-                                          + (*(ptr_c + 2))
-                                          + (*(ptr_c + 3));
-
-                                    delta = (sum + *ptr_c + 4) >> 3;
-                                    *(ptr_c) = (uint8) delta;
-
-                                    /* Move pointer down one pixel to the right */
-                                    ptr_c += 1;
-                                    for (counter = 0; counter < 5; counter++)
-                                    {
-                                        /* Subtract off highest pixel and add in pixel below */
-                                        sum = sum - v[counter] + *ptr_n;
-                                        /* Average the pixel values with rounding */
-                                        delta = (sum + *ptr_c + 4) >> 3;
-                                        *ptr_c = (uint8)(delta);
-
-                                        /* Increment pointers to next pixel */
-                                        ptr_c += 1;
-                                        ptr_n += 1;
-                                    }
-                                }
-                                /* Increment pointers to next pixel row */
-                                ptr += w1;
-                            } /* index*/
-                        }
-                        else
-                        { /* soft filter*/
-
-                            /* Clear VertHflag (bit 5) in the pp_mod location */
-                            pp_mod[index-1] &= 0xdf; /* reset 1101,1111 */
-                            for (index = BLKSIZE; index > 0; index--)
-                            {
-                                /* Difference between the current pixel and the pixel above it */
-                                a3_0 = *(ptr) - *(ptr - 1);
-
-                                /* if the magnitude of the difference is greater than the KTh threshold,
-                                 * apply soft filter */
-                                if ((a3_0 > KTh || a3_0 < -KTh))
-                                {
-
-                                    /* Sum of weighted differences */
-                                    a3_0 += ((*(ptr - 2) - *(ptr + 1)) << 1) + (a3_0 << 2);
-
-                                    /* Check if sum is less than the quantization parameter */
-                                    if (PV_ABS(a3_0) < (QP << 3))
-                                    {
-                                        a3_1 = *(ptr - 2) - *(ptr - 3);
-                                        a3_1 += ((*(ptr - 4) - *(ptr - 1)) << 1) + (a3_1 << 2);
-
-                                        a3_2  = *(ptr + 2) - *(ptr + 1);
-                                        a3_2 += ((*(ptr) - *(ptr + 3)) << 1) + (a3_2 << 2);
-
-                                        A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
-
-                                        if (A3_0 > 0)
-                                        {
-                                            A3_0 += A3_0 << 2;
-                                            A3_0 = (A3_0 + 32) >> 6;
-                                            if (a3_0 > 0)
-                                            {
-                                                A3_0 = -A3_0;
-                                            }
-
-                                            delta = (*(ptr - 1) - *(ptr)) >> 1;
-                                            if (delta >= 0)
-                                            {
-                                                if (delta >= A3_0)
-                                                {
-                                                    delta = PV_MAX(A3_0, 0);
-                                                }
-                                            }
-                                            else
-                                            {
-                                                if (A3_0 > 0)
-                                                {
-                                                    delta = 0;
-                                                }
-                                                else
-                                                {
-                                                    delta = PV_MAX(A3_0, delta);
-                                                }
-                                            }
-
-                                            *(ptr - 1) = (uint8)(*(ptr - 1) - delta);
-                                            *(ptr) = (uint8)(*(ptr) + delta);
-                                        }
-                                    } /*threshold*/
-                                }
-                                ptr += w1;
-                            } /*index*/
-                        } /* Soft filter*/
-                    } /* boundary*/
-                } /*bc*/
-                /* Increment pointer to next row of pixels */
-                brwidth += pp_w;
-            }/*br*/
-            brwidth -= (pp_w << 1);
-
-            /****************** Deringing ***************************/
-            /* Process four blocks for the filtering        */
-            /********************************************************/
-            /* Loop over two rows of blocks */
-            for (br = mbr; br < mbr + 2; br++)
-            {
-                /* Loop over two columns of blocks in the row */
-                for (bc = mbc; bc < mbc + 2; bc++)
-                {
-                    /* Execute if the row and column counters are within the area */
-                    if (br < pp_h && bc < pp_w)
-                    {
-                        /* Set the index to the current block */
-                        index = brwidth + bc;
-
-                        /* Execute deringing if semaphore for deringing (bit-3 of pp_mod)
-                         * is set for the current block */
-                        if ((pp_mod[index]&0x04) != 0)
-                        {
-                            /* Don't process deringing if on an edge block */
-                            if (br > 0 && bc > 0 && br < pp_h - 1 && bc < pp_w - 1)
-                            {
-                                /* cnthflag = weighted average of HorzHflag of current,
-                                 * one above, previous blocks*/
-                                cnthflag = ((pp_mod[index] & 0x10) +
-                                            (pp_mod[index-pp_w] & 0x10) +
-                                            ((pp_mod[index-1] >> 1) & 0x10) +
-                                            ((pp_mod[index] >> 1) & 0x10)) >> 4; /* 4/26/00*/
-
-                                /* Do the deringing if decision flags indicate it's necessary */
-                                if (cnthflag < 3)
-                                {
-                                    /* if the data is chrominance info, get the correct
-                                     * quantization paramenter. One parameter per block. */
-                                    if (chr)
-                                    {
-                                        QP = QP_store[index];
-                                    }
-
-                                    /* Set amount to change luminance if it needs to be changed
-                                     * based on quantization parameter */
-                                    max_diff = (QP >> 2) + 4;
-
-                                    /* Set pointer to first pixel of current block */
-                                    ptr = rec + (brwidth << 6) + (bc << 3);
-
-                                    /* Find minimum and maximum value of pixel block */
-                                    FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
-                                    /* threshold determination */
-                                    thres = (max_blk + min_blk + 1) >> 1;
-
-                                    /* If pixel range is greater or equal than DERING_THR, smooth the region */
-                                    if ((max_blk - min_blk) >= DERING_THR) /*smooth 8x8 region*/
-#ifndef NoMMX
-                                    {
-                                        /* smooth all pixels in the block*/
-                                        DeringAdaptiveSmoothMMX(ptr, width, thres, max_diff);
-                                    }
-#else
-                                    {
-                                        /* Setup the starting point of the region to smooth */
-                                        v0 = (br << 3) - 1;
-                                        h0 = (bc << 3) - 1;
-
-                                        /*smooth 8x8 region*/
-                                        AdaptiveSmooth_NoMMX(rec, v0, h0, v0 + 1, h0 + 1, thres, width, max_diff);
-                                    }
-#endif
-                                }/*cnthflag*/
-                            } /*dering br==1 or bc==1 (boundary block)*/
-                            else    /* Process the boundary blocks */
-                            {
-                                /* Decide to perform deblocking based on the semaphore flags
-                                   * of the neighboring blocks in each case. A certain number of
-                                 * hard filtering flags have to be set in order to signal need
-                                 * for smoothing */
-                                if (br > 0 && br < pp_h - 1)
-                                {
-                                    if (bc > 0)
-                                    {
-                                        cnthflag = ((pp_mod[index-pp_w] & 0x10) +
-                                                    (pp_mod[index] & 0x10) +
-                                                    ((pp_mod[index-1] >> 1) & 0x10)) >> 4;
-                                    }
-                                    else
-                                    {
-                                        cnthflag = ((pp_mod[index] & 0x10) +
-                                                    (pp_mod[index-pp_w] & 0x10) +
-                                                    ((pp_mod[index] >> 1) & 0x10)) >> 4;
-                                    }
-                                }
-                                else if (bc > 0 && bc < pp_w - 1)
-                                {
-                                    if (br > 0)
-                                    {
-                                        cnthflag = ((pp_mod[index-pp_w] & 0x10) +
-                                                    ((pp_mod[index-1] >> 1) & 0x10) +
-                                                    ((pp_mod[index] >> 1) & 0x10)) >> 4;
-                                    }
-                                    else
-                                    {
-                                        cnthflag = ((pp_mod[index] & 0x10) +
-                                                    ((pp_mod[index-1] >> 1) & 0x10) +
-                                                    ((pp_mod[index] >> 1) & 0x10)) >> 4;
-                                    }
-                                }
-                                else /* at the corner do default*/
-                                {
-                                    cnthflag = 0;
-                                }
-
-                                /* Do the deringing if decision flags indicate it's necessary */
-                                if (cnthflag < 2)
-                                {
-
-                                    /* if the data is chrominance info, get the correct
-                                                         * quantization paramenter. One parameter per block. */
-                                    if (chr)
-                                    {
-                                        QP = QP_store[index];
-                                    }
-
-                                    /* Set amount to change luminance if it needs to be changed
-                                     * based on quantization parameter */
-                                    max_diff = (QP >> 2) + 4;
-
-                                    /* Set pointer to first pixel of current block */
-                                    ptr = rec + (brwidth << 6) + (bc << 3);
-
-                                    /* Find minimum and maximum value of pixel block */
-                                    FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
-                                    /* threshold determination */
-                                    thres = (max_blk + min_blk + 1) >> 1;
-
-                                    /* Setup the starting point of the region to smooth
-                                     * This is going to be a 4x4 region */
-                                    v0 = (br << 3) + 1;
-                                    h0 = (bc << 3) + 1;
-
-                                    /* If pixel range is greater or equal than DERING_THR, smooth the region */
-                                    if ((max_blk - min_blk) >= DERING_THR)
-                                    {
-                                        /* Smooth 4x4 region */
-                                        AdaptiveSmooth_NoMMX(rec, v0, h0, v0 - 3, h0 - 3, thres, width, max_diff);
-                                    }
-                                }/*cnthflag*/
-                            } /* br==0, bc==0*/
-                        }  /* dering*/
-                    } /*boundary condition*/
-                }/*bc*/
-                brwidth += pp_w;
-            }/*br*/
-            brwidth -= (pp_w << 1);
-        }/*mbc*/
-        brwidth += (pp_w << 1);
-    }/*mbr*/
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return ;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
index 6499233..72cbe83 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
@@ -544,30 +544,12 @@
     int16 DC_coeff;
     PV_STATUS status;
 
-#ifdef PV_POSTPROC_ON
-    /* post-processing */
-    uint8 *pp_mod[6];
-    int TotalMB = video->nTotalMB;
-    int MB_in_width = video->nMBPerRow;
-#endif
     int y_pos = video->mbnum_row;
     int x_pos = video->mbnum_col;
     int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4);
 
     /* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */
     /*  are chrominance blocks.   04/03/2000.                          */
-#ifdef PV_POSTPROC_ON
-    if (video->postFilterType != PV_NO_POST_PROC)
-    {
-        /** post-processing ***/
-        pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
-        pp_mod[1] = pp_mod[0] + 1;
-        pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
-        pp_mod[3] = pp_mod[2] + 1;
-        pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
-        pp_mod[5] = pp_mod[4] + TotalMB;
-    }
-#endif
 
     /*  oscl_memset(mblock->block, 0, sizeof(typeMBStore));    Aug 9,2005 */
 
@@ -645,10 +627,6 @@
             }
             no_coeff[comp] = ncoeffs[comp];
 
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
-#endif
         }
         MBlockIDCT(video);
     }
@@ -677,20 +655,6 @@
                 BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
                           mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
 
-#ifdef PV_POSTPROC_ON
-                /* for inter just test for ringing */
-                if (video->postFilterType != PV_NO_POST_PROC)
-                    *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
-            }
-            else
-            {
-                /* no IDCT for all zeros blocks  03/28/2002 */
-                /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-                if (video->postFilterType != PV_NO_POST_PROC)
-                    *pp_mod[comp] = 0;
-#endif
             }
         }
 
@@ -707,20 +671,6 @@
             BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
                       mblock->bitmapcol[4], mblock->bitmaprow[4]);
 
-#ifdef PV_POSTPROC_ON
-            /* for inter just test for ringing */
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
-        }
-        else
-        {
-            /* no IDCT for all zeros blocks  03/28/2002 */
-            /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[4] = 0;
-#endif
         }
         (*DC)[5] = mid_gray;
         if (CBP & 1)
@@ -731,20 +681,6 @@
             BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
                       mblock->bitmapcol[5], mblock->bitmaprow[5]);
 
-#ifdef PV_POSTPROC_ON
-            /* for inter just test for ringing */
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
-        }
-        else
-        {
-            /* no IDCT for all zeros blocks  03/28/2002 */
-            /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[5] = 0;
-#endif
         }
         video->QPMB[mbnum] = QP;  /* restore the QP values  ANNEX_T*/
 #else
@@ -759,20 +695,6 @@
                 BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
                           mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
 
-#ifdef PV_POSTPROC_ON
-                /* for inter just test for ringing */
-                if (video->postFilterType != PV_NO_POST_PROC)
-                    *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
-            }
-            else
-            {
-                /* no IDCT for all zeros blocks  03/28/2002 */
-                /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-                if (video->postFilterType != PV_NO_POST_PROC)
-                    *pp_mod[comp] = 0;
-#endif
             }
         }
 
@@ -785,20 +707,11 @@
             BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
                       mblock->bitmapcol[4], mblock->bitmaprow[4]);
 
-#ifdef PV_POSTPROC_ON
-            /* for inter just test for ringing */
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
         }
         else
         {
             /* no IDCT for all zeros blocks  03/28/2002 */
             /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[4] = 0;
-#endif
         }
         (*DC)[5] = mid_gray;
         if (CBP & 1)
@@ -809,20 +722,11 @@
             BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
                       mblock->bitmapcol[5], mblock->bitmaprow[5]);
 
-#ifdef PV_POSTPROC_ON
-            /* for inter just test for ringing */
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
         }
         else
         {
             /* no IDCT for all zeros blocks  03/28/2002 */
             /*              BlockIDCT();                */
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[5] = 0;
-#endif
 #endif  // PV_ANNEX_IJKT_SUPPORT
 
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
index 00db04b..6071f40 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
@@ -635,29 +635,9 @@
     int QP_tmp = QP;
 
     int y_pos = video->mbnum_row;
-#ifdef PV_POSTPROC_ON
-    uint8 *pp_mod[6];
-    int TotalMB = video->nTotalMB;
-    int MB_in_width = video->nMBPerRow;
-#endif
 
 
 
-    /*****
-    *     Decoding of the 6 blocks (depending on transparent pattern)
-    *****/
-#ifdef PV_POSTPROC_ON
-    if (video->postFilterType != PV_NO_POST_PROC)
-    {
-        /** post-processing ***/
-        pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
-        pp_mod[1] = pp_mod[0] + 1;
-        pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
-        pp_mod[3] = pp_mod[2] + 1;
-        pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
-        pp_mod[5] = pp_mod[4] + TotalMB;
-    }
-#endif
 
     /*  oscl_memset(mblock->block, 0, sizeof(typeMBStore));    Aug 9,2005 */
 
@@ -698,10 +678,6 @@
             /*  modified to new semaphore for post-proc */
             // Future work:: can be combined in the dequant function
             // @todo Deblocking Semaphore for INTRA block
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
-#endif
         }
         MBlockIDCT(video);
     }
@@ -738,10 +714,6 @@
             }
 
             /*  @todo Deblocking Semaphore for INTRA block, for inter just test for ringing  */
-#ifdef PV_POSTPROC_ON
-            if (video->postFilterType != PV_NO_POST_PROC)
-                *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
         }
 
         (*DC)[4] = mid_gray;
@@ -760,10 +732,6 @@
         {
             ncoeffs[4] = 0;
         }
-#ifdef PV_POSTPROC_ON
-        if (video->postFilterType != PV_NO_POST_PROC)
-            *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
         (*DC)[5] = mid_gray;
         if (CBP & 1)
         {
@@ -780,10 +748,6 @@
         {
             ncoeffs[5] = 0;
         }
-#ifdef PV_POSTPROC_ON
-        if (video->postFilterType != PV_NO_POST_PROC)
-            *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
 
 
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
deleted file mode 100644
index ce779b0..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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    "mp4dec_lib.h"
-#include    "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void Deringing_Chroma(
-    uint8 *Rec_C,
-    int width,
-    int height,
-    int16 *QP_store,
-    int,
-    uint8 *pp_mod
-)
-{
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int thres;
-    int v_blk, h_blk;
-    int max_diff;
-    int v_pel, h_pel;
-    int max_blk, min_blk;
-    int v0, h0;
-    uint8 *ptr;
-    int sum, sum1, incr;
-    int32 addr_v;
-    int sign_v[10], sum_v[10];
-    int *ptr2, *ptr3;
-    uint8 pelu, pelc, pell;
-    incr = width - BLKSIZE;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    /* chrominance */
-    /* Do the first line (7 pixels at a time => Don't use MMX)*/
-    for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
-    {
-        max_diff = (QP_store[h_blk>>3] >> 2) + 4;
-        ptr = &Rec_C[h_blk];
-        max_blk = min_blk = *ptr;
-        FindMaxMin(ptr, &min_blk, &max_blk, width);
-        h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
-        if (max_blk - min_blk >= 4)
-        {
-            thres = (max_blk + min_blk + 1) >> 1;
-
-
-            for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
-            {
-                addr_v = (int32)v_pel * width;
-                ptr = &Rec_C[addr_v + h0 - 1];
-                ptr2 = &sum_v[0];
-                ptr3 = &sign_v[0];
-
-                pelu = *(ptr - width);
-                pelc = *ptr;
-                pell = *(ptr + width);
-                ptr++;
-                *ptr2++ = pelu + (pelc << 1) + pell;
-                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                pelu = *(ptr - width);
-                pelc = *ptr;
-                pell = *(ptr + width);
-                ptr++;
-                *ptr2++ = pelu + (pelc << 1) + pell;
-                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
-                {
-                    pelu = *(ptr - width);
-                    pelc = *ptr;
-                    pell = *(ptr + width);
-
-                    *ptr2 = pelu + (pelc << 1) + pell;
-                    *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                    sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
-                    if (sum1 == 0 || sum1 == 9)
-                    {
-                        sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
-
-                        ptr--;
-                        if (PV_ABS(*ptr - sum) > max_diff)
-                        {
-                            if (sum > *ptr)
-                                sum = *ptr + max_diff;
-                            else
-                                sum = *ptr - max_diff;
-                        }
-                        *ptr++ = (uint8) sum;
-                    }
-                    ptr++;
-                    ptr2++;
-                    ptr3++;
-                }
-            }
-        }
-    }
-
-    for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
-    {
-        v0 = v_blk - 1;
-        /* Do the first block (pixels=7 => No MMX) */
-        max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
-        ptr = &Rec_C[(int32)v_blk * width];
-        max_blk = min_blk = *ptr;
-        FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
-        if (max_blk - min_blk >= 4)
-        {
-            thres = (max_blk + min_blk + 1) >> 1;
-
-            for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
-            {
-                addr_v = v_pel * width;
-                ptr = &Rec_C[addr_v];
-                ptr2 = &sum_v[0];
-                ptr3 = &sign_v[0];
-
-                pelu = *(ptr - width);
-                pelc = *ptr;
-                pell = *(ptr + width);
-                ptr++;
-                *ptr2++ = pelu + (pelc << 1) + pell;
-                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                pelu = *(ptr - width);
-                pelc = *ptr;
-                pell = *(ptr + width);
-                ptr++;
-                *ptr2++ = pelu + (pelc << 1) + pell;
-                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
-                {
-                    pelu = *(ptr - width);
-                    pelc = *ptr;
-                    pell = *(ptr + width);
-
-                    *ptr2 = pelu + (pelc << 1) + pell;
-                    *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
-                    sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
-                    if (sum1 == 0 || sum1 == 9)
-                    {
-                        sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
-
-                        ptr--;
-                        if (PV_ABS(*ptr - sum) > max_diff)
-                        {
-                            if (sum > *ptr)
-                                sum = *ptr + max_diff;
-                            else
-                                sum = *ptr - max_diff;
-                        }
-                        *ptr++ = (uint8) sum;
-                    }
-                    ptr++;
-                    ptr2++;
-                    ptr3++;
-                }
-            }
-        }
-
-
-        /* Do the rest in MMX */
-        for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
-        {
-            if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
-            {
-                max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
-                ptr = &Rec_C[(int32)v_blk * width + h_blk];
-                max_blk = min_blk = *ptr;
-                FindMaxMin(ptr, &min_blk, &max_blk, incr);
-                h0 = h_blk - 1;
-
-                if (max_blk - min_blk >= 4)
-                {
-                    thres = (max_blk + min_blk + 1) >> 1;
-#ifdef NoMMX
-                    AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
-#else
-                    DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
-#endif
-                }
-            }
-        }
-    } /* macroblock level */
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
deleted file mode 100644
index b5574b4..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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    "mp4dec_lib.h"
-#include    "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void Deringing_Luma(
-    uint8 *Rec_Y,
-    int width,
-    int height,
-    int16 *QP_store,
-    int,
-    uint8 *pp_mod)
-{
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int thres[4], range[4], max_range_blk, max_thres_blk;
-    int MB_V, MB_H, BLK_V, BLK_H;
-    int v_blk, h_blk;
-    int max_diff;
-    int max_blk, min_blk;
-    int v0, h0;
-    uint8 *ptr;
-    int thr, blks, incr;
-    int mb_indx, blk_indx;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    incr = width - BLKSIZE;
-
-    /* Dering the first line of macro blocks */
-    for (MB_H = 0; MB_H < width; MB_H += MBSIZE)
-    {
-        max_diff = (QP_store[(MB_H)>>4] >> 2) + 4;
-
-        /* threshold determination */
-        max_range_blk = max_thres_blk = 0;
-        blks = 0;
-
-        for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
-        {
-            for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
-            {
-                ptr = &Rec_Y[(int32)(BLK_V) * width + MB_H + BLK_H];
-                FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
-                thres[blks] = (max_blk + min_blk + 1) >> 1;
-                range[blks] = max_blk - min_blk;
-
-                if (range[blks] >= max_range_blk)
-                {
-                    max_range_blk = range[blks];
-                    max_thres_blk = thres[blks];
-                }
-                blks++;
-            }
-        }
-
-        blks = 0;
-        for (v_blk = 0; v_blk < MBSIZE; v_blk += BLKSIZE)
-        {
-            v0 = ((v_blk - 1) >= 1) ? (v_blk - 1) : 1;
-            for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
-            {
-                h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
-                /* threshold rearrangement for flat region adjacent to non-flat region */
-                if (range[blks]<32 && max_range_blk >= 64)
-                    thres[blks] = max_thres_blk;
-
-                /* threshold rearrangement for deblocking
-                (blockiness annoying at DC dominant region) */
-                if (max_range_blk >= 16)
-                {
-                    /* adaptive smoothing */
-                    thr = thres[blks];
-
-                    AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
-                                         thr, width, max_diff);
-                }
-                blks++;
-            } /* block level (Luminance) */
-        }
-    } /* macroblock level */
-
-
-    /* Do the rest of the macro-block-lines */
-    for (MB_V = MBSIZE; MB_V < height; MB_V += MBSIZE)
-    {
-        /* First macro-block */
-        max_diff = (QP_store[((((int32)MB_V*width)>>4))>>4] >> 2) + 4;
-        /* threshold determination */
-        max_range_blk = max_thres_blk = 0;
-        blks = 0;
-        for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
-        {
-            for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
-            {
-                ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + BLK_H];
-                FindMaxMin(ptr, &min_blk, &max_blk, incr);
-                thres[blks] = (max_blk + min_blk + 1) >> 1;
-                range[blks] = max_blk - min_blk;
-
-                if (range[blks] >= max_range_blk)
-                {
-                    max_range_blk = range[blks];
-                    max_thres_blk = thres[blks];
-                }
-                blks++;
-            }
-        }
-
-        blks = 0;
-        for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
-        {
-            v0 = v_blk - 1;
-            for (h_blk = 0; h_blk < MBSIZE; h_blk += BLKSIZE)
-            {
-                h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
-                /* threshold rearrangement for flat region adjacent to non-flat region */
-                if (range[blks]<32 && max_range_blk >= 64)
-                    thres[blks] = max_thres_blk;
-
-                /* threshold rearrangement for deblocking
-                (blockiness annoying at DC dominant region) */
-                if (max_range_blk >= 16)
-                {
-                    /* adaptive smoothing */
-                    thr = thres[blks];
-
-                    AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
-                                         thr, width, max_diff);
-                }
-                blks++;
-            }
-        } /* block level (Luminance) */
-
-        /* Rest of the macro-blocks */
-        for (MB_H = MBSIZE; MB_H < width; MB_H += MBSIZE)
-        {
-            max_diff = (QP_store[((((int32)MB_V*width)>>4)+MB_H)>>4] >> 2) + 4;
-
-            /* threshold determination */
-            max_range_blk = max_thres_blk = 0;
-            blks = 0;
-
-            mb_indx = (MB_V / 8) * (width / 8) + MB_H / 8;
-            for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
-            {
-                for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
-                {
-                    blk_indx = mb_indx + (BLK_V / 8) * width / 8 + BLK_H / 8;
-                    /* Update based on pp_mod only */
-                    if ((pp_mod[blk_indx]&0x4) != 0)
-                    {
-                        ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + MB_H + BLK_H];
-                        FindMaxMin(ptr, &min_blk, &max_blk, incr);
-                        thres[blks] = (max_blk + min_blk + 1) >> 1;
-                        range[blks] = max_blk - min_blk;
-
-                        if (range[blks] >= max_range_blk)
-                        {
-                            max_range_blk = range[blks];
-                            max_thres_blk = thres[blks];
-                        }
-                    }
-                    blks++;
-                }
-            }
-
-            blks = 0;
-            for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
-            {
-                v0 = v_blk - 1;
-                mb_indx = (v_blk / 8) * (width / 8);
-                for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
-                {
-                    h0 = h_blk - 1;
-                    blk_indx = mb_indx + h_blk / 8;
-                    if ((pp_mod[blk_indx]&0x4) != 0)
-                    {
-                        /* threshold rearrangement for flat region adjacent to non-flat region */
-                        if (range[blks]<32 && max_range_blk >= 64)
-                            thres[blks] = max_thres_blk;
-
-                        /* threshold rearrangement for deblocking
-                        (blockiness annoying at DC dominant region) */
-                        if (max_range_blk >= 16)
-                        {
-                            /* adaptive smoothing */
-                            thr = thres[blks];
-#ifdef NoMMX
-                            AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
-                                                 thr, width, max_diff);
-#else
-                            DeringAdaptiveSmoothMMX(&Rec_Y[v0*width+h0],
-                                                    width, thr, max_diff);
-#endif
-                        }
-                    }
-                    blks++;
-                }
-            } /* block level (Luminance) */
-        } /* macroblock level */
-    } /* macroblock level */
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
deleted file mode 100644
index 1ac88a1..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    input_ptr = pointer to the buffer containing values of type UChar
-            in a 2D block of data.
-    min_ptr = pointer to the minimum value of type Int to be found in a
-          square block of size BLKSIZE contained in 2D block of data.
-    max_ptr = pointer to the maximum value of type Int to be found in a
-          square block of size BLKSIZE contained in 2D block of data.
-    incr = value of type Int representing the width of 2D block of data.
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    None
-
- Pointers and Buffers Modified:
-    min_ptr points to the found minimum value in the square block of
-    size BLKSIZE contained in 2D block of data.
-
-    max_ptr points to the found maximum value in the square block of
-    size BLKSIZE contained in 2D block of data.
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function finds the maximum and the minimum values in a square block of
- data of size BLKSIZE * BLKSIZE. The data is contained in the buffer which
- represents a 2D block of data that is larger than BLKSIZE * BLKSIZE.
- This is illustrated below.
-
-    mem loc x + 00h -> o o o o o o o o o o o o o o o o
-    mem loc x + 10h -> o o o o o X X X X X X X X o o o
-    mem loc x + 20h -> o o o o o X X X X X X X X o o o
-    mem loc x + 30h -> o o o o o X X X X X X X X o o o
-    mem loc x + 40h -> o o o o o X X X X X X X X o o o
-    mem loc x + 50h -> o o o o o X X X X X X X X o o o
-    mem loc x + 60h -> o o o o o X X X X X X X X o o o
-    mem loc x + 70h -> o o o o o X X X X X X X X o o o
-    mem loc x + 80h -> o o o o o X X X X X X X X o o o
-    mem loc x + 90h -> o o o o o o o o o o o o o o o o
-    mem loc x + A0h -> o o o o o o o o o o o o o o o o
-    mem loc x + B0h -> o o o o o o o o o o o o o o o o
-
-For illustration purposes, the diagram assumes that BLKSIZE is equal to 8
-but this is not a requirement. In this diagram, the buffer starts at
-location x but the input pointer, input_ptr, passed into this function
-would be the first row of data to be searched which is at x + 15h. The
-value of incr passed onto this function represents the amount the input_ptr
-needs to be incremented to point to the next row of data.
-
-This function compares each value in a row to the current maximum and
-minimum. After each row, input_ptr is incremented to point to the next row.
-This is repeated until all rows have been processed. When the search is
-complete the location pointed to by min_ptr contains the minimum value
-found and the location pointed to by max_ptr contains the maximum value found.
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_lib.h"
-#include    "post_proc.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void  FindMaxMin(
-    uint8 *input_ptr,
-    int *min_ptr,
-    int *max_ptr,
-    int incr)
-{
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    uint    i, j;
-    int min, max;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    max = min = *input_ptr;
-    /*  incr = incr - BLKSIZE; */   /*  09/06/2001, already passed in as width - BLKSIZE */
-
-    for (i = BLKSIZE; i > 0; i--)
-    {
-        for (j = BLKSIZE; j > 0; j--)
-        {
-            if (*input_ptr > max)
-            {
-                max = *input_ptr;
-            }
-            else if (*input_ptr < min)
-            {
-                min = *input_ptr;
-            }
-            input_ptr += 1;
-        }
-
-        /* set pointer to the beginning of the next row*/
-        input_ptr += incr;
-    }
-
-    *max_ptr = max;
-    *min_ptr = min;
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
index f35ce4f..0ba4944 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
@@ -94,6 +94,7 @@
     return;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow2(int16 *blk, uint8 *pred, uint8 *dst, int width)
 {
     int32 x0, x1, x2, x4, x5;
@@ -182,6 +183,7 @@
     return ;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow3(int16 *blk, uint8 *pred, uint8 *dst, int width)
 {
     int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -291,6 +293,7 @@
 }
 
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow4(int16 *blk, uint8 *pred, uint8 *dst, int width)
 {
     int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -368,6 +371,7 @@
     return ;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctcol4(int16 *blk)
 {
     int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -445,6 +449,7 @@
     return;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow2_intra(int16 *blk, PIXEL *comp, int width)
 {
     int32 x0, x1, x2, x4, x5, temp;
@@ -502,6 +507,7 @@
     return ;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow3_intra(int16 *blk, PIXEL *comp, int width)
 {
     int32 x0, x1, x2, x3, x4, x5, x6, x7, x8, temp;
@@ -575,6 +581,7 @@
     return ;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow4_intra(int16 *blk, PIXEL *comp, int width)
 {
     int32 x0, x1, x2, x3, x4, x5, x6, x7, x8, temp;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
index 877723d..79760f5 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
@@ -154,14 +154,6 @@
     int xpred, ypred;
     int xsum;
     int round1;
-#ifdef PV_POSTPROC_ON // 2/14/2001      
-    /* Total number of pixels in the VOL */
-    int32 size = (int32) video->nTotalMB << 8;
-    uint8 *pp_dec_y, *pp_dec_u;
-    int ll[4];
-    int tmp = 0;
-    uint8 msk_deblock = 0;
-#endif
     /*----------------------------------------------------------------------------
     ; Function body here
     ----------------------------------------------------------------------------*/
@@ -404,43 +396,6 @@
     /* Call function to set de-blocking and de-ringing */
     /*   semaphores for luminance                      */
 
-#ifdef PV_POSTPROC_ON
-    if (video->postFilterType != PV_NO_POST_PROC)
-    {
-        if (mode&INTER_1VMASK)
-        {
-            pp_dec_y = video->pstprcTypCur + imv;
-            ll[0] = 1;
-            ll[1] = mvwidth - 1;
-            ll[2] = 1;
-            ll[3] = -mvwidth - 1;
-            msk_deblock = pp_semaphore_luma(xpred, ypred, pp_dec_y,
-                                            video->pstprcTypPrv, ll, &tmp, px[0], py[0], mvwidth,
-                                            width, height);
-
-            pp_dec_u = video->pstprcTypCur + (size >> 6) +
-                       ((imv + (xpos >> 3)) >> 2);
-
-            pp_semaphore_chroma_inter(xpred, ypred, pp_dec_u,
-                                      video->pstprcTypPrv, dx, dy, mvwidth, height, size,
-                                      tmp, msk_deblock);
-        }
-        else
-        {
-            /* Post-processing mode (MBM_INTER8) */
-            /* deblocking and deringing) */
-            pp_dec_y = video->pstprcTypCur + imv;
-            *pp_dec_y = 4;
-            *(pp_dec_y + 1) = 4;
-            *(pp_dec_y + mvwidth) = 4;
-            *(pp_dec_y + mvwidth + 1) = 4;
-            pp_dec_u = video->pstprcTypCur + (size >> 6) +
-                       ((imv + (xpos >> 3)) >> 2);
-            *pp_dec_u = 4;
-            pp_dec_u[size>>8] = 4;
-        }
-    }
-#endif
 
 
     /* xpred and ypred calculation for Chrominance is */
@@ -566,13 +521,6 @@
     PIXEL *cv_comp, *cv_prev;
     int width, width_uv;
     int32 offset;
-#ifdef PV_POSTPROC_ON // 2/14/2001      
-    int imv;
-    int32 size = (int32) video->nTotalMB << 8;
-    uint8 *pp_dec_y, *pp_dec_u;
-    uint8 *pp_prev1;
-    int mvwidth = video->nMBPerRow << 1;
-#endif
 
     width = video->width;
     width_uv  = width >> 1;
@@ -609,28 +557,6 @@
     PutSKIPPED_B(cv_comp, cv_prev, width_uv);
 
     /*  10/24/2000 post_processing semaphore generation */
-#ifdef PV_POSTPROC_ON // 2/14/2001
-    if (video->postFilterType != PV_NO_POST_PROC)
-    {
-        imv = (offset >> 6) - (xpos >> 6) + (xpos >> 3);
-        /* Post-processing mode (copy previous MB) */
-        pp_prev1 = video->pstprcTypPrv + imv;
-        pp_dec_y = video->pstprcTypCur + imv;
-        *pp_dec_y = *pp_prev1;
-        *(pp_dec_y + 1) = *(pp_prev1 + 1);
-        *(pp_dec_y + mvwidth) = *(pp_prev1 + mvwidth);
-        *(pp_dec_y + mvwidth + 1) = *(pp_prev1 + mvwidth + 1);
-
-        /* chrominance */
-        /*4*MB_in_width*MB_in_height*/
-        pp_prev1 = video->pstprcTypPrv + (size >> 6) +
-                   ((imv + (xpos >> 3)) >> 2);
-        pp_dec_u = video->pstprcTypCur + (size >> 6) +
-                   ((imv + (xpos >> 3)) >> 2);
-        *pp_dec_u = *pp_prev1;
-        pp_dec_u[size>>8] = pp_prev1[size>>8];
-    }
-#endif
     /*----------------------------------------------------------------------------
     ; Return nothing or data or data pointer
     ----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
index 9cd4edc..ce6f9c3 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
@@ -170,37 +170,6 @@
 
     /*--------------------------------------------------------------------------*/
     /* defined in pp_semaphore_chroma_inter.c */
-#ifdef PV_POSTPROC_ON
-    void pp_semaphore_chroma_inter(
-        int xpred,      /* i */
-        int ypred,      /* i */
-        uint8   *pp_dec_u,  /* i/o */
-        uint8   *pstprcTypPrv,  /* i */
-        int dx,     /* i */
-        int dy,     /* i */
-        int mvwidth,    /* i */
-        int height,     /* i */
-        int32   size,       /* i */
-        int mv_loc,     /* i */
-        uint8   msk_deblock /* i */
-    );
-
-    /*--------------------------------------------------------------------------*/
-    /* defined in pp_semaphore_luma.c */
-    uint8 pp_semaphore_luma(
-        int xpred,      /* i */
-        int ypred,      /* i */
-        uint8   *pp_dec_y,  /* i/o */
-        uint8   *pstprcTypPrv,  /* i */
-        int *ll,        /* i */
-        int *mv_loc,    /* i/o */
-        int dx,     /* i */
-        int dy,     /* i */
-        int mvwidth,    /* i */
-        int width,      /* i */
-        int height      /* i */
-    );
-#endif
     /*--------------------------------------------------------------------------*/
     /* defined in get_pred_adv_mb_add.c */
     int GetPredAdvancedMB(
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
index b36050c..37a03a0 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
@@ -24,152 +24,6 @@
 const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};
 #endif
 
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void PostFilter(
-    VideoDecData *video,
-    int filter_type,
-    uint8 *output)
-{
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    uint8 *pp_mod;
-    int16 *QP_store;
-    int combined_with_deblock_filter;
-    int nTotalMB = video->nTotalMB;
-    int width, height;
-    int32 size;
-    int softDeblocking;
-    uint8 *decodedFrame = video->videoDecControls->outputFrame;
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    width = video->width;
-    height = video->height;
-    size = (int32)width * height;
-
-    oscl_memcpy(output, decodedFrame, size);
-    oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
-    oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
-
-    if (filter_type == 0)
-        return;
-
-    /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip  */
-    if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12)))  // MC_sofDeblock
-        softDeblocking = FALSE;
-    else
-        softDeblocking = TRUE;
-
-    combined_with_deblock_filter = filter_type & PV_DEBLOCK;
-    QP_store = video->QPMB;
-
-    /* Luma */
-    pp_mod = video->pstprcTypCur;
-
-    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
-    {
-        CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
-    }
-    else
-    {
-        if (filter_type & PV_DEBLOCK)
-        {
-            if (softDeblocking)
-            {
-                CombinedHorzVertFilter(output, width, height,
-                                       QP_store, 0, pp_mod);
-            }
-            else
-            {
-                CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
-                                                        QP_store, 0, pp_mod);
-            }
-        }
-        if (filter_type & PV_DERING)
-        {
-            Deringing_Luma(output, width, height, QP_store,
-                           combined_with_deblock_filter, pp_mod);
-
-        }
-    }
-
-    /* Chroma */
-
-    pp_mod += (nTotalMB << 2);
-    output += size;
-
-    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
-    {
-        CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
-    }
-    else
-    {
-        if (filter_type & PV_DEBLOCK)
-        {
-            if (softDeblocking)
-            {
-                CombinedHorzVertFilter(output, (int)(width >> 1),
-                                       (int)(height >> 1), QP_store, (int) 1, pp_mod);
-            }
-            else
-            {
-                CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
-                                                        (int)(height >> 1), QP_store, (int) 1, pp_mod);
-            }
-        }
-        if (filter_type & PV_DERING)
-        {
-            Deringing_Chroma(output, (int)(width >> 1),
-                             (int)(height >> 1), QP_store,
-                             combined_with_deblock_filter, pp_mod);
-        }
-    }
-
-    pp_mod += nTotalMB;
-    output += (size >> 2);
-
-    if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
-    {
-        CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
-    }
-    else
-    {
-        if (filter_type & PV_DEBLOCK)
-        {
-            if (softDeblocking)
-            {
-                CombinedHorzVertFilter(output, (int)(width >> 1),
-                                       (int)(height >> 1), QP_store, (int) 1, pp_mod);
-            }
-            else
-            {
-                CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
-                                                        (int)(height >> 1), QP_store, (int) 1, pp_mod);
-            }
-        }
-        if (filter_type & PV_DERING)
-        {
-            Deringing_Chroma(output, (int)(width >> 1),
-                             (int)(height >> 1), QP_store,
-                             combined_with_deblock_filter, pp_mod);
-        }
-    }
-
-    /*  swap current pp_mod to prev_frame pp_mod */
-    pp_mod = video->pstprcTypCur;
-    video->pstprcTypCur = video->pstprcTypPrv;
-    video->pstprcTypPrv = pp_mod;
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return;
-}
-#endif
 
 
 #ifdef PV_ANNEX_IJKT_SUPPORT
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
deleted file mode 100644
index 3abc6be..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    q_block = pointer to buffer of inverse quantized DCT coefficients of type
-              int for intra-VOP mode or buffer of residual data of type int
-              for inter-VOP mode
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    postmode = post processing semaphore with the vertical deblocking,
-               horizontal deblocking, and deringing bits set up accordingly
-
- Pointers and Buffers Modified:
-    None
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function sets up the postmode semaphore based on the contents of the
- buffer pointed to by q_block. The function starts out with the assumption
- that all entries of q_block, except for the first entry (q_block[0]), are
- zero. This case can induce horizontal and vertical blocking artifacts,
- therefore, both horizontal and vertical deblocking bits are enabled.
-
- The following conditions are tested when setting up the horizontal/vertical
- deblocking and deringing bits:
- 1. When only the elements of the top row of the B_SIZE x B_SIZE block
-    (q_block[n], n = 0,..., B_SIZE-1) are non-zero, vertical blocking artifacts
-    may result, therefore, only the vertical deblocking bit is enabled.
-    Otherwise, the vertical deblocking bit is disabled.
- 2. When only the elements of the far left column of the B_SIZE x B_SIZE block
-    (q_block[n*B_SIZE], n = 0, ..., B_SIZE-1) are non-zero, horizontal blocking
-    artifacts may result, therefore, only the horizontal deblocking bit is
-    enabled. Otherwise, the horizontal deblocking bit is disabled.
- 3. If any non-zero elements exist in positions other than q_block[0],
-    q_block[1], or q_block[B_SIZE], the deringing bit is enabled. Otherwise,
-    it is disabled.
-
- The 3 least significant bits of postmode defines vertical or horizontal
- deblocking and deringing.
-
- The valid values are shown below:
- -------------------------------------------------------
- |           Type                 | Enabled | Disabled |
- -------------------------------------------------------
- | Vertical Deblocking (Bit #0)   |    1    |     0    |
- -------------------------------------------------------
- | Horizontal Deblocking (Bit #1) |    1    |     0    |
- -------------------------------------------------------
- | Deringing (Bit #2)             |    1    |     0    |
- -------------------------------------------------------
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_lib.h"
-#include    "mp4def.h"
-#include    "post_proc.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-int PostProcSemaphore(
-    int16 *q_block)
-{
-    /*----------------------------------------------------------------------------
-    ; Define all local variables
-    ----------------------------------------------------------------------------*/
-    int i, j;
-
-    /* Set default value to vertical and horizontal deblocking enabled */
-    /* Initial assumption is that only q_block[0] element is non-zero, */
-    /* therefore, vertical and horizontal deblocking bits are set to 1 */
-    int postmode = 0x3;
-
-    /*----------------------------------------------------------------------------
-    ; Function body here
-    ----------------------------------------------------------------------------*/
-    /* Vertical deblocking bit is enabled when only the entire top row of   */
-    /* the B_SIZE x B_SIZE block, i.e., q_block[n], n = 0,..., B_SIZE-1,    */
-    /* are non-zero. Since initial assumption is that all elements, except  */
-    /* q_block[0], is zero, we need to check the remaining elements in the  */
-    /* top row to  determine if all or some are non-zero.                   */
-    if (q_block[1] != 0)
-    {
-        /* At this point, q_block[0] and q_block[1] are non-zero, while */
-        /* q_block[n], n = 2,..., B_SIZE-1, are zero. Therefore, we     */
-        /* need to disable vertical deblocking                          */
-        postmode &= 0xE;
-    }
-
-    for (i = 2; i < B_SIZE; i++)
-    {
-        if (q_block[i])
-        {
-            /* Check if q_block[n], n = 2,..., B_SIZE-1, are non-zero.*/
-            /* If any of them turn out to be non-zero, we need to     */
-            /* disable vertical deblocking.                           */
-            postmode &= 0xE;
-
-            /* Deringing is enabled if any nonzero elements exist in */
-            /* positions other than q_block[0], q_block[1] or        */
-            /* q_block[B_SIZE].                                      */
-            postmode |= 0x4;
-
-            break;
-        }
-    }
-
-    /* Horizontal deblocking bit is enabled when only the entire far */
-    /* left column, i.e., q_block[n*B_SIZE], n = 0, ..., B_SIZE-1,   */
-    /* are non-zero. Since initial assumption is that all elements,  */
-    /* except q_block[0], is zero, we need to check the remaining    */
-    /* elements in the far left column to determine if all or some   */
-    /* are non-zero.                                                 */
-    if (q_block[B_SIZE])
-    {
-        /* At this point, only q_block[0] and q_block[B_SIZE] are non-zero, */
-        /* while q_block[n*B_SIZE], n = 2, 3,..., B_SIZE-1, are zero.       */
-        /* Therefore, we need to disable horizontal deblocking.             */
-        postmode &= 0xD;
-    }
-
-    for (i = 16; i < NCOEFF_BLOCK; i += B_SIZE)
-    {
-        if (q_block[i])
-        {
-            /* Check if q_block[n], n = 2*B_SIZE,...,(B_SIZE-1)*B_SIZE,  */
-            /* are non-zero. If any of them turn out to be non-zero,     */
-            /* we need to disable horizontal deblocking.                 */
-            postmode &= 0xD;
-
-            /* Deringing is enabled if any nonzero elements exist in */
-            /* positions other than q_block[0], q_block[1] or        */
-            /* q_block[B_SIZE].                                      */
-            postmode |= 0x4;
-
-            break;
-        }
-    }
-
-    /* At this point, only the first row and far left column elements */
-    /* have been tested. If deringing bit is still not set at this    */
-    /* point, check the rest of q_block to determine if the elements  */
-    /* are non-zero. If all elements, besides q_block[0], q_block[1], */
-    /* or q_block[B_SIZE] are non-zero, deringing bit must be set     */
-    if ((postmode & 0x4) == 0)
-    {
-        for (i = 1; i < B_SIZE; i++)
-        {
-            for (j = 1; j < B_SIZE; j++)
-            {
-                if (q_block[(i<<3)+j])
-                {
-                    /* At this point, q_block[0] and another q_block */
-                    /* element are non-zero, therefore, we need to   */
-                    /* disable vertical and horizontal deblocking    */
-                    postmode &= 0xC;
-
-                    /* Deringing is enabled if any nonzero elements exist in */
-                    /* positions other than q_block[0], q_block[1] or        */
-                    /* q_block[B_SIZE].                                      */
-                    postmode |= 0x4;
-
-                    /* Set outer FOR loop count to B_SIZE to get out of */
-                    /* outer FOR loop                                   */
-                    i = B_SIZE;
-
-                    /* Get out of inner FOR loop */
-                    break;
-                }
-            }
-        }
-    }
-
-    /*----------------------------------------------------------------------------
-    ; Return nothing or data or data pointer
-    ----------------------------------------------------------------------------*/
-    return (postmode);
-}
-
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
deleted file mode 100644
index 7c20222..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    xpred = x-axis coordinate of the block used for prediction (int)
-    ypred = y-axis coordinate of the block used for prediction (int)
-    pp_dec_u = pointer to the post processing semaphore for chrominance
-               (uint8)
-    pstprcTypPrv = pointer the previous frame's post processing type
-                   (uint8)
-    dx = horizontal component of the motion vector (int)
-    dy = vertical component of the motion vector (int)
-    mvwidth = number of blocks per row in the luminance VOP (int)
-    height = luminance VOP height in pixels (int)
-    size = total number of pixel in the current luminance VOP (int)
-    mv_loc = flag indicating location of the motion compensated
-         (x,y) position with respect to the luminance MB (int);
-         0 -> inside MB, 1 -> outside MB
-    msk_deblock = flag indicating whether to perform deblocking
-              (msk_deblock = 0) or not (msk_deblock = 1) (uint8)
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    None
-
- Pointers and Buffers Modified:
-    pp_dec_u contents are the updated semaphore propagation data
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This functions performs post processing semaphore propagation processing
- after chrominance prediction in interframe processing mode.
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_api.h"
-#include    "mp4def.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-    /*----------------------------------------------------------------------------
-    ; FUNCTION CODE
-    ----------------------------------------------------------------------------*/
-    void pp_semaphore_chroma_inter(
-        int xpred,      /* i */
-        int ypred,      /* i */
-        uint8   *pp_dec_u,  /* i/o */
-        uint8   *pstprcTypPrv,  /* i */
-        int dx,     /* i */
-        int dy,     /* i */
-        int mvwidth,    /* i */
-        int height,     /* i */
-        int32   size,       /* i */
-        int mv_loc,     /* i */
-        uint8   msk_deblock /* i */
-    )
-    {
-        /*----------------------------------------------------------------------------
-        ; Define all local variables
-        ----------------------------------------------------------------------------*/
-        int mmvy, mmvx, nmvy, nmvx;
-        uint8 *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
-
-        /*----------------------------------------------------------------------------
-        ; Function body here
-        ----------------------------------------------------------------------------*/
-
-        /* 09/28/2000, modify semaphore propagation to */
-        /* accommodate smart indexing */
-        mmvx = xpred >> 4;  /* block x coor */
-        nmvx = mmvx;
-
-        mmvy = ypred >> 4;  /* block y coor */
-        nmvy = mmvy;
-
-        /* Check if MV is outside the frame */
-        if (mv_loc == 1)
-        {
-            /* Perform boundary check */
-            if (nmvx < 0)
-            {
-                nmvx = 0;
-            }
-            else if (nmvx > mvwidth - 1)
-            {
-                nmvx = mvwidth - 1;
-            }
-
-            if (nmvy < 0)
-            {
-                nmvy = 0;
-            }
-            else if (nmvy > (height >> 4) - 1)
-            {
-                nmvy = (height >> 4) - 1;
-            }
-        }
-
-        /* Calculate pointer to first chrominance b semaphores in       */
-        /* pstprcTypPrv, i.e., first chrominance b semaphore is in      */
-        /* (pstprcTypPrv + (size>>6)).                  */
-        /* Since total number of chrominance blocks per row in a VOP    */
-        /* is half of the total number of luminance blocks per row in a */
-        /* VOP, we use (mvwidth >> 1) when calculating the row offset.  */
-        pp_prev1 = pstprcTypPrv + (size >> 6) + nmvx + nmvy * (mvwidth >> 1) ;
-
-        /* Check if MV is a multiple of 16 */
-        /*  1/5/01, make sure it doesn't go out of bound */
-        if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 4) - 1))
-        {   /* dy is not a multiple of 16 */
-
-            /* pp_prev3 is the block below pp_prev1 block */
-            pp_prev3 = pp_prev1 + (mvwidth >> 1);
-        }
-        else
-        {   /* dy is a multiple of 16 */
-            pp_prev3 = pp_prev1;
-        }
-
-        /*  1/5/01, make sure it doesn't go out of bound */
-        if (((dx&0xF) != 0) && (mmvx + 1 < (mvwidth >> 1) - 1))
-        {   /* dx is not a multiple of 16 */
-
-            /* pp_prev2 is the block to the right of pp_prev1 block */
-            pp_prev2 = pp_prev1 + 1;
-
-            /* pp_prev4 is the block to the right of the block */
-            /* below pp_prev1 block                */
-            pp_prev4 = pp_prev3 + 1;
-        }
-        else
-        {   /* dx is a multiple of 16 */
-
-            pp_prev2 = pp_prev1;
-            pp_prev4 = pp_prev3;
-        }
-
-        /* Advance offset to location of first Chrominance R semaphore in */
-        /* pstprcTypPrv. Since the number of pixels in a Chrominance VOP  */
-        /* is (number of pixels in Luminance VOP/4), and there are 64     */
-        /* pixels in an 8x8 Chrominance block, the offset can be      */
-        /* calculated as:                         */
-        /*  mv_loc = (number of pixels in Luminance VOP/(4*64))   */
-        /*         = size/256 = size>>8               */
-        mv_loc = (size >> 8);
-
-        /*  11/3/00, change the propagation for deblocking */
-        if (msk_deblock == 0)
-        {
-
-            /* Deblocking semaphore propagation for Chrominance */
-            /* b semaphores                     */
-            *(pp_dec_u) = 0;
-
-            /* Advance offset to point to Chrominance r semaphores */
-            pp_dec_u += mv_loc;
-
-            /* Deblocking semaphore propagation for Chrominance */
-            /* r semaphores                     */
-            *(pp_dec_u) = 0;
-        }
-        else
-        {
-            /* Deringing semaphore propagation for Chrominance B block */
-            if ((*(pp_dec_u)&4) == 0)
-            {
-                *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
-                                 *(pp_prev3) | *(pp_prev4)) & 0x4);
-            }
-
-            /* Advance offset to point to Chrominance r semaphores */
-            pp_dec_u += mv_loc;
-            pp_prev1 += mv_loc;
-            pp_prev2 += mv_loc;
-            pp_prev3 += mv_loc;
-            pp_prev4 += mv_loc;
-
-            /* Deringing semaphore propagation for Chrominance R */
-            if ((*(pp_dec_u)&4) == 0)
-            {
-                *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
-                                 *(pp_prev3) | *(pp_prev4)) & 0x4);
-            }
-        }
-
-        /*----------------------------------------------------------------------------
-        ; Return nothing or data or data pointer
-        ----------------------------------------------------------------------------*/
-        return;
-    }
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
deleted file mode 100644
index b3a1ebd..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    xpred = x-axis coordinate of the MB used for prediction (int)
-    ypred = y-axis coordinate of the MB used for prediction (int)
-    pp_dec_y = pointer to the post processing semaphore for current
-           luminance frame (uint8)
-    pstprcTypPrv = pointer the previous frame's post processing type
-                   (uint8)
-    ll = pointer to the buffer (int)
-    mv_loc = flag indicating location of the motion compensated
-         (x,y) position with respect to the luminance MB (int);
-         0 -> inside MB, 1 -> outside MB
-    dx = horizontal component of the motion vector (int)
-    dy = vertical component of the motion vector (int)
-    mvwidth = number of blocks per row (int)
-    width = luminance VOP width in pixels (int)
-    height = luminance VOP height in pixels (int)
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    msk_deblock = flag that indicates whether deblocking is to be
-              performed (msk_deblock = 0) or not (msk_deblock =
-              1) (uint8)
-
- Pointers and Buffers Modified:
-    pp_dec_y contents are the updated semapohore propagation data
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This functions performs post processing semaphore propagation processing
- after luminance prediction.
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include    "mp4dec_api.h"
-#include    "mp4def.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-    /*----------------------------------------------------------------------------
-    ; FUNCTION CODE
-    ----------------------------------------------------------------------------*/
-    uint8 pp_semaphore_luma(
-        int xpred,      /* i */
-        int ypred,      /* i */
-        uint8   *pp_dec_y,  /* i/o */
-        uint8   *pstprcTypPrv,  /* i */
-        int *ll,        /* i */
-        int *mv_loc,    /* i/o */
-        int dx,     /* i */
-        int dy,     /* i */
-        int mvwidth,    /* i */
-        int width,      /* i */
-        int height      /* i */
-    )
-    {
-        /*----------------------------------------------------------------------------
-        ; Define all local variables
-        ----------------------------------------------------------------------------*/
-        int kk, mmvy, mmvx, nmvx, nmvy;
-        uint8   *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
-        uint8   msk_deblock = 0;        /*  11/3/00 */
-
-        /*----------------------------------------------------------------------------
-        ; Function body here
-        ----------------------------------------------------------------------------*/
-        /* Interframe Processing - 1 MV per MB */
-
-        /* check whether the MV points outside the frame */
-        if (xpred >= 0 && xpred <= ((width << 1) - (2*MB_SIZE)) && ypred >= 0 &&
-                ypred <= ((height << 1) - (2*MB_SIZE)))
-        {   /*****************************/
-            /* (x,y) is inside the frame */
-            /*****************************/
-
-            /*  10/24/2000 post_processing semaphore */
-            /* generation */
-
-            /*  10/23/2000 no boundary checking*/
-            *mv_loc = 0;
-
-            /* Calculate block x coordinate. Divide by 16 is for  */
-            /* converting half-pixel resolution to block          */
-            mmvx = xpred >> 4;
-
-            /* Calculate block y coordinate. Divide by 16 is for */
-            /* converting half-pixel resolution to block         */
-            mmvy = ypred >> 4;
-
-            /* Find post processing semaphore location for block */
-            /* used for prediction, i.e.,                */
-            /* pp_prev1 = &pstprcTypPrv[mmvy*mvwidth][mmvx]      */
-            pp_prev1 = pstprcTypPrv + mmvx + mmvy * mvwidth;
-
-            /* Check if MV is a multiple of 16 */
-            if ((dx&0xF) != 0)
-            {   /* dx is not a multiple of 16 */
-
-                /* pp_prev2 is the block to the right of */
-                /* pp_prev1 block            */
-                pp_prev2 = pp_prev1 + 1;
-
-                if ((dy&0xF) != 0)
-                {   /* dy is not a multiple of 16 */
-
-                    /* pp_prev3 is the block below */
-                    /* pp_prev1 block          */
-                    pp_prev3 = pp_prev1 + mvwidth;
-                }
-                else
-                {   /* dy is a multiple of 16 */
-
-                    pp_prev3 = pp_prev1;
-                }
-
-                /* pp_prev4 is the block to the right of */
-                /* pp_prev3 block.           */
-                pp_prev4 = pp_prev3 + 1;
-            }
-            else
-            {   /* dx is a multiple of 16 */
-
-                pp_prev2 = pp_prev1;
-
-                if ((dy&0xF) != 0)
-                {   /* dy is not a multiple of 16 */
-
-                    /* pp_prev3 is the block below */
-                    /* pp_prev1 block.         */
-                    pp_prev3 = pp_prev1 + mvwidth;
-                }
-                else
-                {   /* dy is a multiple of 16 */
-
-                    pp_prev3 = pp_prev1;
-                    msk_deblock = 0x3;
-                }
-
-                pp_prev4 = pp_prev3;
-            }
-
-            /* Perform post processing semaphore propagation for each */
-            /* of the 4 blocks in a MB.               */
-            for (kk = 0; kk < 4; kk++)
-            {
-                /* Deringing semaphore propagation */
-                if ((*(pp_dec_y) & 4) == 0)
-                {
-                    *(pp_dec_y) |= ((*(pp_prev1) | *(pp_prev2) |
-                                     *(pp_prev3) | *(pp_prev4)) & 0x4);
-                }
-                /* Deblocking semaphore propagation */
-                /*  11/3/00, change the propagation for deblocking */
-                if (msk_deblock == 0)
-                {
-                    *(pp_dec_y) = 0;
-                }
-
-                pp_dec_y += ll[kk];
-                pp_prev1 += ll[kk];
-                pp_prev2 += ll[kk];
-                pp_prev3 += ll[kk];
-                pp_prev4 += ll[kk];
-            }
-
-        }
-        else
-        {   /******************************/
-            /* (x,y) is outside the frame */
-            /******************************/
-
-            /*  10/24/2000 post_processing semaphore */
-            /* generation */
-
-            /*  10/23/2000 boundary checking*/
-            *mv_loc = 1;
-
-            /* Perform post processing semaphore propagation for each */
-            /* of the 4 blocks in a MB.               */
-            for (kk = 0; kk < 4; kk++)
-            {
-                /* Calculate block x coordinate and round (?).  */
-                /* Divide by 16 is for converting half-pixel    */
-                /* resolution to block.             */
-                mmvx = (xpred + ((kk & 1) << 3)) >> 4;
-                nmvx = mmvx;
-
-                /* Calculate block y coordinate and round (?).  */
-                /* Divide by 16 is for converting half-pixel    */
-                /* resolution to block.             */
-                mmvy = (ypred + ((kk & 2) << 2)) >> 4;
-                nmvy = mmvy;
-
-                /* Perform boundary checking */
-                if (nmvx < 0)
-                {
-                    nmvx = 0;
-                }
-                else if (nmvx > mvwidth - 1)
-                {
-                    nmvx = mvwidth - 1;
-                }
-
-                if (nmvy < 0)
-                {
-                    nmvy = 0;
-                }
-                else if (nmvy > (height >> 3) - 1)
-                {
-                    nmvy = (height >> 3) - 1;
-                }
-
-                /* Find post processing semaphore location for block */
-                /* used for prediction, i.e.,                */
-                /* pp_prev1 = &pstprcTypPrv[nmvy*mvwidth][nmvx]      */
-                pp_prev1 = pstprcTypPrv + nmvx + nmvy * mvwidth;
-
-                /* Check if x component of MV is a multiple of 16    */
-                /* and check if block x coordinate is out of bounds  */
-                if (((dx&0xF) != 0) && (mmvx + 1 < mvwidth - 1))
-                {   /* dx is not a multiple of 16 and the block */
-                    /* x coordinate is within the bounds        */
-
-                    /* pp_prev2 is the block to the right of */
-                    /* pp_prev1 block            */
-                    pp_prev2 = pp_prev1 + 1;
-
-                    /* Check if y component of MV is a multiple */
-                    /* of 16 and check if block y coordinate is */
-                    /* out of bounds                */
-                    if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
-                    {   /* dy is not a multiple of 16 and */
-                        /* the block y coordinate is      */
-                        /* within the bounds              */
-
-                        /* pp_prev3 is the block below */
-                        /* pp_prev1 block          */
-                        pp_prev3 = pp_prev1 + mvwidth;
-
-                        /* all prediction are from different blocks */
-                        msk_deblock = 0x3;
-                    }
-                    else
-                    {   /* dy is a multiple of 16 or the block */
-                        /* y coordinate is out of bounds       */
-
-                        pp_prev3 = pp_prev1;
-                    }
-
-                    /* pp_prev4 is the block to the right of */
-                    /* pp_prev3 block.           */
-                    pp_prev4 = pp_prev3 + 1;
-                }
-                else
-                {   /* dx is a multiple of 16 or the block x */
-                    /* coordinate is out of bounds           */
-
-                    pp_prev2 = pp_prev1;
-
-                    /* Check if y component of MV is a multiple */
-                    /* of 16 and check if block y coordinate is */
-                    /* out of bounds                */
-                    if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
-                    {   /* dy is not a multiple of 16 and */
-                        /* the block y coordinate is      */
-                        /* within the bounds              */
-
-                        /* pp_prev3 is the block below */
-                        /* pp_prev1 block.         */
-                        pp_prev3 = pp_prev1 + mvwidth;
-                    }
-                    else
-                    {   /* dy is a multiple of 16 or the block */
-                        /* y coordinate is out of bounds       */
-
-                        pp_prev3 = pp_prev1;
-                    }
-
-                    pp_prev4 = pp_prev3;
-                }
-
-                /* Deringing semaphore propagation */
-                if ((*(pp_dec_y)&4) == 0)
-                {
-                    *(pp_dec_y) |= ((*(pp_prev1) |
-                                     *(pp_prev2) | *(pp_prev3) |
-                                     *(pp_prev4)) & 0x4);
-                }
-                /* Deblocking semaphore propagation */
-                /*  11/3/00, change the propaga= */
-                /* tion for deblocking */
-                if (msk_deblock == 0)
-                {
-                    *(pp_dec_y) = 0;
-                }
-
-                pp_dec_y += ll[kk];
-            }
-        }
-
-        /*----------------------------------------------------------------------------
-        ; Return nothing or data or data pointer
-        ----------------------------------------------------------------------------*/
-        return (msk_deblock);
-    }
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 9c0fcfa..b0828e4 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -512,60 +512,6 @@
     video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
 #endif
 
-#ifdef PV_POSTPROC_ON
-    /* Allocating space for post-processing Mode */
-#ifdef DEC_INTERNAL_MEMORY_OPT
-    video->pstprcTypCur = IMEM_pstprcTypCur;
-    video->memoryUsage += (nTotalMB * 6);
-    if (video->pstprcTypCur == NULL)
-    {
-        status = PV_FALSE;
-    }
-    else
-    {
-        oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
-    }
-
-    video->pstprcTypPrv = IMEM_pstprcTypPrv;
-    video->memoryUsage += (nTotalMB * 6);
-    if (video->pstprcTypPrv == NULL)
-    {
-        status = PV_FALSE;
-    }
-    else
-    {
-        oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
-    }
-
-#else
-    if (nTotalMB > INT32_MAX / 6) {
-        return PV_FALSE;
-    }
-    video->pstprcTypCur = (uint8 *) oscl_malloc(nTotalMB * 6);
-    video->memoryUsage += (nTotalMB * 6);
-    if (video->pstprcTypCur == NULL)
-    {
-        status = PV_FALSE;
-    }
-    else
-    {
-        oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
-    }
-
-    video->pstprcTypPrv = (uint8 *) oscl_malloc(nTotalMB * 6);
-    video->memoryUsage += (nTotalMB * 6);
-    if (video->pstprcTypPrv == NULL)
-    {
-        status = PV_FALSE;
-    }
-    else
-    {
-        oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
-    }
-
-#endif
-
-#endif
 
     /* initialize the decoder library */
     video->prevVop->predictionType = I_VOP;
@@ -631,10 +577,6 @@
 #ifdef DEC_INTERNAL_MEMORY_OPT
     if (video)
     {
-#ifdef PV_POSTPROC_ON
-        video->pstprcTypCur = NULL;
-        video->pstprcTypPrv = NULL;
-#endif
 
         video->acPredFlag       = NULL;
         video->sliceNo          = NULL;
@@ -699,10 +641,6 @@
 
     if (video)
     {
-#ifdef PV_POSTPROC_ON
-        if (video->pstprcTypCur) oscl_free(video->pstprcTypCur);
-        if (video->pstprcTypPrv) oscl_free(video->pstprcTypPrv);
-#endif
         if (video->predDC) oscl_free(video->predDC);
         video->predDCAC_row = NULL;
         if (video->predDCAC_col) oscl_free(video->predDCAC_col);
@@ -830,7 +768,10 @@
 OSCL_EXPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode)
 {
     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
-    video->postFilterType = mode;
+    if (mode != 0) {
+        ALOGE("Post processing filters are not supported");
+    }
+    video->postFilterType = 0;
 }
 
 
@@ -1621,43 +1562,8 @@
 void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV)
 {
     uint8 *outputBuffer;
-#ifdef PV_POSTPROC_ON
-    VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
-    int32 tmpvar;
-    if (outputYUV)
-    {
-        outputBuffer = outputYUV;
-    }
-    else
-    {
-        if (video->postFilterType)
-        {
-            outputBuffer = video->currVop->yChan;
-        }
-        else
-        {
-            outputBuffer = decCtrl->outputFrame;
-        }
-    }
-
-    if (video->postFilterType)
-    {
-        /* Post-processing,  */
-        PostFilter(video, video->postFilterType, outputBuffer);
-    }
-    else
-    {
-        if (outputYUV)
-        {
-            /* Copy decoded frame to the output buffer. */
-            tmpvar = (int32)video->width * video->height;
-            oscl_memcpy(outputBuffer, decCtrl->outputFrame, tmpvar*3 / 2);           /*  3/3/01 */
-        }
-    }
-#else
     outputBuffer = decCtrl->outputFrame;
     outputYUV;
-#endif
     decCtrl->outputFrame = outputBuffer;
     return;
 }
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp b/media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp
new file mode 100644
index 0000000..56fc782
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "mpeg4_dec_fuzzer",
+    host_supported: true,
+    srcs: [
+        "mpeg4_h263_dec_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libstagefright_m4vh263dec",
+        "liblog",
+    ],
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+        "-DMPEG4",
+    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
+
+cc_fuzz {
+    name: "h263_dec_fuzzer",
+    host_supported: true,
+    srcs: [
+        "mpeg4_h263_dec_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libstagefright_m4vh263dec",
+        "liblog",
+    ],
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/README.md b/media/libstagefright/codecs/m4v_h263/fuzzer/README.md
new file mode 100644
index 0000000..c2a4f69
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/fuzzer/README.md
@@ -0,0 +1,57 @@
+# Fuzzer for libstagefright_m4vh263dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for MPEG4/H263 is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+Dict files (dictionary files) are created for MPEG4 and H263 to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that decoder does not reject any input file in the first check
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by the number of bytes consumed
+   in the decode call.
+ * If the decode operation was un-successful, the input is advanced by 1 byte so that the fuzzer
+   can proceed to feed the next frame.
+
+This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc)
+and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities.
+
+##### Other considerations
+ * Two fuzzer binaries - mpeg4_dec_fuzzer and h263_dec_fuzzer are generated based on the presence
+   of a flag - 'MPEG4'
+ * The number of decode calls are kept to a maximum of 100 so that the fuzzer does not timeout.
+
+## Build
+
+This describes steps to build mpeg4_dec_fuzzer and h263_dec_fuzzer binary.
+
+### Android
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mpeg4_dec_fuzzer
+  $ mm -j$(nproc) h263_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MPEG4 or H263 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
+  $ adb shell /data/fuzz/arm64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict b/media/libstagefright/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
new file mode 100644
index 0000000..591d37e
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code (bytes 0-3)
+kw1="\x00\x00\x80\x02"
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict b/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
new file mode 100644
index 0000000..76241a6
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code (bytes 0-3)
+kw1="\x00\x00\x01\xB0"
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp b/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
new file mode 100644
index 0000000..912c821
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
@@ -0,0 +1,205 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include "mp4dec_api.h"
+#define MPEG4_MAX_WIDTH 1920
+#define MPEG4_MAX_HEIGHT 1080
+#define H263_MAX_WIDTH 352
+#define H263_MAX_HEIGHT 288
+#define DEFAULT_WIDTH 352
+#define DEFAULT_HEIGHT 288
+
+constexpr size_t kMaxNumDecodeCalls = 100;
+constexpr uint8_t kNumOutputBuffers = 2;
+constexpr int kLayer = 1;
+
+struct tagvideoDecControls;
+
+/* == ceil(num / den) * den. T must be integer type, alignment must be positive power of 2 */
+template <class T, class U>
+inline static const T align(const T &num, const U &den) {
+  return (num + (T)(den - 1)) & (T) ~(den - 1);
+}
+
+class Codec {
+ public:
+  Codec() = default;
+  ~Codec() { deInitDecoder(); }
+  bool initDecoder();
+  bool allocOutputBuffer(size_t outputBufferSize);
+  void freeOutputBuffer();
+  void handleResolutionChange();
+  void decodeFrames(const uint8_t *data, size_t size);
+  void deInitDecoder();
+
+ private:
+  tagvideoDecControls *mDecHandle = nullptr;
+  uint8_t *mOutputBuffer[kNumOutputBuffers];
+  bool mInitialized = false;
+  bool mFramesConfigured = false;
+#ifdef MPEG4
+  MP4DecodingMode mInputMode = MPEG4_MODE;
+  size_t mMaxWidth = MPEG4_MAX_WIDTH;
+  size_t mMaxHeight = MPEG4_MAX_HEIGHT;
+#else
+  MP4DecodingMode mInputMode = H263_MODE;
+  size_t mMaxWidth = H263_MAX_WIDTH;
+  size_t mMaxHeight = H263_MAX_HEIGHT;
+#endif
+  uint32_t mNumSamplesOutput = 0;
+  uint32_t mWidth = DEFAULT_WIDTH;
+  uint32_t mHeight = DEFAULT_HEIGHT;
+};
+
+bool Codec::initDecoder() {
+  mDecHandle = new tagvideoDecControls;
+  if (!mDecHandle) {
+    return false;
+  }
+  memset(mDecHandle, 0, sizeof(tagvideoDecControls));
+  return true;
+}
+
+bool Codec::allocOutputBuffer(size_t outputBufferSize) {
+  for (uint8_t i = 0; i < kNumOutputBuffers; ++i) {
+    if (!mOutputBuffer[i]) {
+      mOutputBuffer[i] = static_cast<uint8_t *>(malloc(outputBufferSize));
+      if (!mOutputBuffer[i]) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+void Codec::freeOutputBuffer() {
+  for (uint8_t i = 0; i < kNumOutputBuffers; ++i) {
+    if (mOutputBuffer[i]) {
+      free(mOutputBuffer[i]);
+      mOutputBuffer[i] = nullptr;
+    }
+  }
+}
+
+void Codec::handleResolutionChange() {
+  int32_t dispWidth, dispHeight;
+  PVGetVideoDimensions(mDecHandle, &dispWidth, &dispHeight);
+
+  int32_t bufWidth, bufHeight;
+  PVGetBufferDimensions(mDecHandle, &bufWidth, &bufHeight);
+
+  if (dispWidth != mWidth || dispHeight != mHeight) {
+    mWidth = dispWidth;
+    mHeight = dispHeight;
+  }
+}
+
+void Codec::decodeFrames(const uint8_t *data, size_t size) {
+  size_t outputBufferSize = align(mMaxWidth, 16) * align(mMaxHeight, 16) * 3 / 2;
+  uint8_t *start_code = const_cast<uint8_t *>(data);
+  static const uint8_t volInfo[] = {0x00, 0x00, 0x01, 0xB0};
+  bool volHeader = memcmp(start_code, volInfo, 4) == 0;
+  if (volHeader) {
+    PVCleanUpVideoDecoder(mDecHandle);
+    mInitialized = false;
+  }
+
+  if (!mInitialized) {
+    uint8_t *volData[1]{};
+    int32_t volSize = 0;
+
+    if (volHeader) { /* removed some codec config part */
+      volData[0] = const_cast<uint8_t *>(data);
+      volSize = size;
+    }
+
+    if (!PVInitVideoDecoder(mDecHandle, volData, &volSize, kLayer, mMaxWidth, mMaxHeight,
+                            mInputMode)) {
+      return;
+    }
+    mInitialized = true;
+    MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
+    if (mInputMode != actualMode) {
+      return;
+    }
+
+    PVSetPostProcType(mDecHandle, 0);
+  }
+  size_t yFrameSize = sizeof(uint8) * mDecHandle->size;
+  if (outputBufferSize < yFrameSize * 3 / 2) {
+    return;
+  }
+  if (!allocOutputBuffer(outputBufferSize)) {
+    return;
+  }
+  size_t numDecodeCalls = 0;
+  while ((size > 0) && (numDecodeCalls < kMaxNumDecodeCalls)) {
+    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 = (numDecodeCalls == 0);
+    int32_t tempSize = (int32_t)size;
+    uint8_t *bitstreamTmp = const_cast<uint8_t *>(data);
+    uint32_t timestamp = 0;
+    if (PVDecodeVopHeader(mDecHandle, &bitstreamTmp, &timestamp, &tempSize, &header_info,
+                          &useExtTimestamp, mOutputBuffer[mNumSamplesOutput & 1]) != PV_TRUE) {
+      return;
+    }
+
+    handleResolutionChange();
+
+    PVDecodeVopBody(mDecHandle, &tempSize);
+    uint32_t bytesConsumed = 1;
+    if (size > tempSize) {
+      bytesConsumed = size - tempSize;
+    }
+    data += bytesConsumed;
+    size -= bytesConsumed;
+    ++mNumSamplesOutput;
+    ++numDecodeCalls;
+  }
+  freeOutputBuffer();
+}
+
+void Codec::deInitDecoder() {
+  PVCleanUpVideoDecoder(mDecHandle);
+  delete mDecHandle;
+  mDecHandle = nullptr;
+  mInitialized = false;
+  freeOutputBuffer();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (size < 4) {
+    return 0;
+  }
+  Codec *codec = new Codec();
+  if (!codec) {
+    return 0;
+  }
+  if (codec->initDecoder()) {
+    codec->decodeFrames(data, size);
+  }
+  delete codec;
+  return 0;
+}
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 96106f1..316d63c 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -3,6 +3,7 @@
     vendor_available: true,
     min_sdk_version: "29",
 
+    host_supported:true,
     srcs: [
         "src/pvmp3_normalize.cpp",
         "src/pvmp3_alias_reduction.cpp",
@@ -73,6 +74,12 @@
         "-DOSCL_UNUSED_ARG(x)=(void)(x)",
         "-Werror",
     ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 //###############################################################################
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp b/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp
new file mode 100644
index 0000000..79fa1e9
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "mp3_dec_fuzzer",
+    host_supported: true,
+
+    static_libs: [
+        "libstagefright_mp3dec",
+    ],
+
+    srcs: [
+        "mp3_dec_fuzzer.cpp",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/README.md b/media/libstagefright/codecs/mp3dec/fuzzer/README.md
new file mode 100644
index 0000000..09dd5c3
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libstagefright_mp3dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for mp3 decoder is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+
+This fuzzer makes use of the following config parameters:
+1. Equalizer type (parameter name: `equalizerType`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `equalizerType` | 0. `flat ` 1. `bass_boost ` 2. `rock ` 3. `pop ` 4. `jazz ` 5. `classical ` 6. `talk ` 7. `flat_ ` | Bits 0, 1 and 2 of first byte of input stream |
+| `crcEnabled` | 0. `false ` 1. `true `| Bit 0 of second byte of input stream |
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by the number
+   of bytes used by the decoder.
+ * If the decode operation was un-successful, the input is advanced by 1 byte
+   till it reaches a valid frame or end of stream.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build mp3_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mp3_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mp3 files to that folder.
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mp3_dec_fuzzer/mp3_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/mp3_dec_fuzzer/mp3_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp b/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
new file mode 100644
index 0000000..847c8c4
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdlib.h>
+#include <algorithm>
+
+#include <pvmp3decoder_api.h>
+
+constexpr int kMaxFrameSamples = 4608;
+constexpr int kMaxChannels = 2;
+constexpr e_equalization kEqualizerTypes[] = {flat, bass_boost, rock, pop,
+                                              jazz, classical,  talk, flat_};
+
+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 = 0;
+
+  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 bool checkHeader(uint8 *header, size_t inSize) {
+  size_t frameSize;
+  size_t totalInSize = 0;
+  bool isValidBuffer = false;
+
+  while (totalInSize + 4 < inSize) {
+    isValidBuffer = true;
+    uint32_t val = U32_AT(header + totalInSize);
+    if (!parseMp3Header(val, &frameSize, nullptr, nullptr, nullptr, nullptr)) {
+      return false;
+    }
+    totalInSize += frameSize;
+  }
+
+  return (isValidBuffer);
+}
+
+class Codec {
+ public:
+  Codec() = default;
+  ~Codec() { deInitDecoder(); }
+
+  bool initDecoder();
+  void decodeFrames(uint8_t *data, size_t size);
+  void deInitDecoder();
+
+ private:
+  tPVMP3DecoderExternal *mConfig = nullptr;
+  void *mDecoderBuf = nullptr;
+};
+
+bool Codec::initDecoder() {
+  mConfig = new tPVMP3DecoderExternal{};
+  if (!mConfig) {
+    return false;
+  }
+  size_t decoderBufSize = pvmp3_decoderMemRequirements();
+  mDecoderBuf = malloc(decoderBufSize);
+  if (!mDecoderBuf) {
+    return false;
+  }
+  memset(mDecoderBuf, 0x0, decoderBufSize);
+  pvmp3_InitDecoder(mConfig, mDecoderBuf);
+  return true;
+}
+
+void Codec::decodeFrames(uint8_t *data, size_t size) {
+  uint8_t equalizerTypeValue = (data[0] & 0x7);
+  mConfig->equalizerType = kEqualizerTypes[equalizerTypeValue];
+  mConfig->crcEnabled = data[1] & 0x1;
+
+  while (size > 0) {
+    bool status = checkHeader(data, size);
+    if (!status) {
+      size--;
+      data++;
+      continue;
+    }
+    size_t outBufSize = kMaxFrameSamples * kMaxChannels;
+    size_t usedBytes = 0;
+    int16_t outputBuf[outBufSize];
+    mConfig->inputBufferCurrentLength = size;
+    mConfig->inputBufferUsedLength = 0;
+    mConfig->inputBufferMaxLength = 0;
+    mConfig->pInputBuffer = data;
+    mConfig->pOutputBuffer = outputBuf;
+    mConfig->outputFrameSize = outBufSize / sizeof(int16_t);
+
+    ERROR_CODE decoderErr;
+    decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf);
+    if (decoderErr != NO_DECODING_ERROR) {
+      size--;
+      data++;
+    } else {
+      usedBytes = std::min((int32_t)size, mConfig->inputBufferUsedLength);
+      size -= usedBytes;
+      data += usedBytes;
+    }
+  }
+}
+
+void Codec::deInitDecoder() {
+  if (mDecoderBuf) {
+    free(mDecoderBuf);
+    mDecoderBuf = nullptr;
+  }
+  delete mConfig;
+  mConfig = nullptr;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (size < 4) {
+    return 0;
+  }
+  Codec *codec = new Codec();
+  if (!codec) {
+    return 0;
+  }
+  if (codec->initDecoder()) {
+    codec->decodeFrames(const_cast<uint8_t *>(data), size);
+  }
+  delete codec;
+  return 0;
+}
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
index 1f8018a..c306873 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
@@ -111,6 +111,7 @@
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
 
+__attribute__((no_sanitize("integer")))
 void pvmp3_dct_6(int32 vec[])
 {
 
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
index 8d80e8f..1ba080d 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
@@ -118,7 +118,7 @@
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
 
-
+__attribute__((no_sanitize("integer")))
 void pvmp3_mdct_6(int32 vec[], int32 *history)
 {
     int32 i;
diff --git a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
index 7ff9732..233f9bb 100644
--- a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
+++ b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="Mp3DecoderTest->/data/local/tmp/Mp3DecoderTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.1.zip?unzip=true"
             value="/data/local/tmp/Mp3DecoderTestRes/" />
     </target_preparer>
 
diff --git a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
index 99553ec..0784c0c 100644
--- a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
+++ b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
@@ -185,6 +185,7 @@
 INSTANTIATE_TEST_SUITE_P(Mp3DecoderTestAll, Mp3DecoderTest,
                          ::testing::Values(("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3"),
                                            ("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3"),
+                                           ("bug_136053885.mp3"),
                                            ("bbb_mp3_stereo_192kbps_48000hz.mp3")));
 
 int main(int argc, char **argv) {
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 4f61aa8..5bb1879 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -58,6 +58,8 @@
       mInputBufferCount(0),
       mDecoder(NULL),
       mHeader(NULL),
+      mNumChannels(1),
+      mSamplingRate(kRate),
       mCodecDelay(0),
       mSeekPreRoll(0),
       mAnchorTimeUs(0),
@@ -169,11 +171,11 @@
             }
 
             opusParams->nAudioBandWidth = 0;
-            opusParams->nSampleRate = kRate;
+            opusParams->nSampleRate = mSamplingRate;
             opusParams->nBitRate = 0;
 
             if (!isConfigured()) {
-                opusParams->nChannels = 1;
+                opusParams->nChannels = mNumChannels;
             } else {
                 opusParams->nChannels = mHeader->channels;
             }
@@ -274,7 +276,8 @@
             if (opusParams->nPortIndex != 0) {
                 return OMX_ErrorUndefined;
             }
-
+            mNumChannels = opusParams->nChannels;
+            mSamplingRate = opusParams->nSampleRate;
             return OMX_ErrorNone;
         }
 
@@ -496,6 +499,8 @@
                                    *(reinterpret_cast<int64_t*>(inHeader->pBuffer +
                                                                 inHeader->nOffset)),
                                    kRate);
+                mSamplingRate = kRate;
+                mNumChannels = mHeader->channels;
                 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
                 mOutputPortSettingsChange = AWAITING_DISABLED;
             }
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.h b/media/libstagefright/codecs/opus/dec/SoftOpus.h
index 91cafa1..00058c8 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.h
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.h
@@ -70,6 +70,8 @@
     OpusMSDecoder *mDecoder;
     OpusHeader *mHeader;
 
+    int32_t mNumChannels;
+    int32_t mSamplingRate;
     int64_t mCodecDelay;
     int64_t mSeekPreRoll;
     int64_t mSamplesToDiscard;
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 6571162..dd2eed3 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -295,12 +295,12 @@
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
         <MediaCodec name="c2.android.hevc.encoder" type="video/hevc" variant="!slow-cpu">
-            <!-- profiles and levels:  ProfileMain : MainTierLevel3 -->
-            <Limit name="size" min="2x2" max="960x544" />
+            <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+            <Limit name="size" min="2x2" max="512x512" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="8x8" />
-            <Limit name="block-count" range="1-8160" /> <!-- max 960x544 -->
-            <Limit name="blocks-per-second" range="1-244880" />
+            <Limit name="block-count" range="1-4096" /> <!-- max 512x512 -->
+            <Limit name="blocks-per-second" range="1-122880" />
             <Limit name="frame-rate" range="1-120" />
             <Limit name="bitrate" range="1-10000000" />
             <Limit name="complexity" range="0-10"  default="0" />
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 32b2075..b63353c 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -2,6 +2,7 @@
     name: "libstagefright_flacdec",
     vendor_available: true,
     min_sdk_version: "29",
+    host_supported: true,
 
     srcs: [
         "FLACDecoder.cpp",
@@ -33,6 +34,13 @@
     ],
 
     header_libs: [
-        "libmedia_headers",
+        "libstagefright_foundation_headers",
+        "libstagefright_headers",
     ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index cef0bc6..f5e9532 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -433,7 +433,7 @@
             if (mBuffer == nullptr) {
                 mBufferDataSize = 0;
                 mBufferLen = 0;
-                ALOGE("decodeOneFrame: failed to allocate memory for input buffer");
+                ALOGE("addDataToBuffer: failed to allocate memory for input buffer");
                 return NO_MEMORY;
             }
             mBufferLen = mBufferDataSize + inBufferLen;
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/libstagefright/foundation/ALooperRoster.cpp
index 8a7c3eb..0a4e598 100644
--- a/media/libstagefright/foundation/ALooperRoster.cpp
+++ b/media/libstagefright/foundation/ALooperRoster.cpp
@@ -166,7 +166,7 @@
         }
         s.append("\n");
     }
-    write(fd, s.string(), s.size());
+    (void)write(fd, s.string(), s.size());
 }
 
 }  // namespace android
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index 4bd186c..8722e14 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -387,10 +387,14 @@
     va_start(ap, format);
 
     char *buffer;
-    vasprintf(&buffer, format, ap);
+    int bufferSize = vasprintf(&buffer, format, ap);
 
     va_end(ap);
 
+    if(bufferSize < 0) {
+        return AString();
+    }
+
     AString result(buffer);
 
     free(buffer);
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index f440e00..ebf1035 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -12,6 +12,7 @@
     vndk: {
         enabled: true,
     },
+    host_supported: true,
     double_loadable: true,
     include_dirs: [
         "frameworks/av/include",
@@ -25,7 +26,6 @@
     ],
 
     header_libs: [
-        "libhardware_headers",
         "libstagefright_foundation_headers",
         "media_ndk_headers",
         "media_plugin_headers",
@@ -86,6 +86,9 @@
                 "-DNO_IMEMORY",
             ],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 
     clang: true,
diff --git a/media/libstagefright/foundation/avc_utils.cpp b/media/libstagefright/foundation/avc_utils.cpp
index f53d2c9..9d6887c 100644
--- a/media/libstagefright/foundation/avc_utils.cpp
+++ b/media/libstagefright/foundation/avc_utils.cpp
@@ -559,11 +559,9 @@
     CHECK_NE(video_object_type_indication,
              0x21u /* Fine Granularity Scalable */);
 
-    unsigned video_object_layer_verid __unused;
-    unsigned video_object_layer_priority __unused;
     if (br.getBits(1)) {
-        video_object_layer_verid = br.getBits(4);
-        video_object_layer_priority = br.getBits(3);
+        br.skipBits(4); //video_object_layer_verid
+        br.skipBits(3); //video_object_layer_priority
     }
     unsigned aspect_ratio_info = br.getBits(4);
     if (aspect_ratio_info == 0x0f /* extended PAR */) {
@@ -622,7 +620,7 @@
     unsigned video_object_layer_height = br.getBits(13);
     CHECK(br.getBits(1));  // marker_bit
 
-    unsigned interlaced __unused = br.getBits(1);
+    br.skipBits(1); // interlaced
 
     *width = video_object_layer_width;
     *height = video_object_layer_height;
@@ -668,7 +666,7 @@
         return false;
     }
 
-    unsigned protection __unused = (header >> 16) & 1;
+    // we can get protection value from (header >> 16) & 1
 
     unsigned bitrate_index = (header >> 12) & 0x0f;
 
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
index ab17a02..e4b99bf 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
@@ -148,7 +148,8 @@
     static char *GetDebugName(const char *name);
 
     inline static bool isExperimentEnabled(
-            const char *name __unused /* nonnull */, bool allow __unused = true) {
+            const char *name __attribute__((unused)) /* nonnull */,
+            bool allow __attribute__((unused)) = true) {
 #ifdef ENABLE_STAGEFRIGHT_EXPERIMENTS
         if (!strcmp(name, "legacy-adaptive")) {
             return getExperimentFlag(allow, name, 2, 1); // every other day
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
index af6b357..3b646dc 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
@@ -63,7 +63,7 @@
 
 template<class T>
 void ENSURE_UNSIGNED_TYPE() {
-    T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __unused;
+    T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __attribute__((unused));
 }
 
 // needle is in range [hayStart, hayStart + haySize)
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
new file mode 100644
index 0000000..b28a7bc
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __AVC_UTILS_TEST_ENVIRONMENT_H__
+#define __AVC_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class AVCUtilsTestEnvironment : public::testing::Environment {
+  public:
+    AVCUtilsTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int AVCUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __AVC_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
new file mode 100644
index 0000000..77a8599
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2020 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 "AVCUtilsUnitTest"
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include "media/stagefright/foundation/ABitReader.h"
+#include "media/stagefright/foundation/avc_utils.h"
+
+#include "AVCUtilsTestEnvironment.h"
+
+constexpr size_t kSmallBufferSize = 2;
+constexpr uint8_t kSPSmask = 0x1f;
+constexpr uint8_t kSPSStartCode = 0x07;
+constexpr uint8_t kConfigVersion = 0x01;
+
+using namespace android;
+
+static AVCUtilsTestEnvironment *gEnv = nullptr;
+
+class MpegAudioUnitTest
+    : public ::testing::TestWithParam<
+              tuple</*audioHeader*/ uint32_t, /*frameSize*/ int32_t, /*sampleRate*/ int32_t,
+                    /*numChannels*/ int32_t, /*bitRate*/ int32_t, /*numSamples*/ int32_t>> {};
+
+class VOLDimensionTest
+    : public ::testing::TestWithParam<
+              tuple</*fileName*/ string, /*volWidth*/ int32_t, /*volHeight*/ int32_t>> {};
+
+class AVCUtils {
+  public:
+    bool SetUpAVCUtils(string fileName, string infoFileName) {
+        mInputFile = gEnv->getRes() + fileName;
+        mInputFileStream.open(mInputFile, ifstream::in);
+        if (!mInputFileStream.is_open()) return false;
+
+        mInfoFile = gEnv->getRes() + infoFileName;
+        mInfoFileStream.open(mInfoFile, ifstream::in);
+        if (!mInputFileStream.is_open()) return false;
+        return true;
+    }
+
+    ~AVCUtils() {
+        if (mInputFileStream.is_open()) mInputFileStream.close();
+        if (mInfoFileStream.is_open()) mInfoFileStream.close();
+    }
+
+    string mInputFile;
+    string mInfoFile;
+
+    ifstream mInputFileStream;
+    ifstream mInfoFileStream;
+};
+
+class AVCDimensionTest
+    : public AVCUtils,
+      public ::testing::TestWithParam<
+              tuple</*fileName*/ string, /*infoFileName*/ string,
+                    /*avcWidth*/ size_t, /*avcHeight*/ size_t, /*numberOfNALUnits*/ int32_t>> {
+  public:
+    virtual void SetUp() override {
+        tuple<string, string, size_t, size_t, size_t> params = GetParam();
+        string fileName = get<0>(params);
+        string infoFileName = get<1>(params);
+        AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+
+        mFrameWidth = get<2>(params);
+        mFrameHeight = get<3>(params);
+        mNalUnitsExpected = get<4>(params);
+    }
+
+    size_t mFrameWidth;
+    size_t mFrameHeight;
+    int32_t mNalUnitsExpected;
+};
+
+class AvccBoxTest : public AVCDimensionTest {
+  public:
+    virtual void SetUp() override { AVCDimensionTest::SetUp(); }
+};
+
+class AVCFrameTest
+    : public AVCUtils,
+      public ::testing::TestWithParam<pair</*fileName*/ string, /*infoFileName*/ string>> {
+  public:
+    virtual void SetUp() override {
+        string fileName = GetParam().first;
+        string infoFileName = GetParam().second;
+        AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+    }
+};
+
+TEST_P(MpegAudioUnitTest, AudioProfileTest) {
+    tuple<uint32_t, size_t, int, int, int, int> params = GetParam();
+    uint32_t header = get<0>(params);
+
+    size_t audioFrameSize = get<1>(params);
+    int audioSampleRate = get<2>(params);
+    int audioNumChannels = get<3>(params);
+    int audioBitRate = get<4>(params);
+    int audioNumSamples = get<5>(params);
+
+    size_t frameSize = 0;
+    int sampleRate = 0;
+    int numChannels = 0;
+    int bitRate = 0;
+    int numSamples = 0;
+
+    bool status = GetMPEGAudioFrameSize(header, &frameSize, &sampleRate, &numChannels, &bitRate,
+                                        &numSamples);
+    ASSERT_TRUE(status) << "Failed to get Audio properties";
+
+    ASSERT_EQ(frameSize, audioFrameSize) << "Wrong frame size found";
+
+    ASSERT_EQ(sampleRate, audioSampleRate) << "Wrong sample rate found";
+
+    ASSERT_EQ(numChannels, audioNumChannels) << "Wrong number of channels found";
+
+    ASSERT_EQ(bitRate, audioBitRate) << "Wrong bit rate found";
+
+    ASSERT_EQ(numSamples, audioNumSamples) << "Wrong number of samples found";
+}
+
+TEST_P(VOLDimensionTest, DimensionTest) {
+    tuple<string, int32_t, int32_t> params = GetParam();
+    string inputFile = gEnv->getRes() + get<0>(params);
+    ifstream inputFileStream;
+    inputFileStream.open(inputFile, ifstream::in);
+    ASSERT_TRUE(inputFileStream.is_open()) << "Failed to open: " << inputFile;
+
+    struct stat buf;
+    int8_t err = stat(inputFile.c_str(), &buf);
+    ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+    size_t fileSize = buf.st_size;
+    ASSERT_NE(fileSize, 0) << "Invalid file size found";
+
+    const uint8_t *volBuffer = new uint8_t[fileSize];
+    ASSERT_NE(volBuffer, nullptr) << "Failed to allocate VOL buffer of size: " << fileSize;
+
+    inputFileStream.read((char *)(volBuffer), fileSize);
+    ASSERT_EQ(inputFileStream.gcount(), fileSize)
+            << "Failed to read complete file, bytes read: " << inputFileStream.gcount();
+
+    int32_t width = get<1>(params);
+    int32_t height = get<2>(params);
+    int32_t volWidth = -1;
+    int32_t volHeight = -1;
+
+    bool status = ExtractDimensionsFromVOLHeader(volBuffer, fileSize, &volWidth, &volHeight);
+    ASSERT_TRUE(status)
+            << "Failed to get VOL dimensions from function: ExtractDimensionsFromVOLHeader()";
+
+    ASSERT_EQ(volWidth, width) << "Expected width: " << width << "Found: " << volWidth;
+
+    ASSERT_EQ(volHeight, height) << "Expected height: " << height << "Found: " << volHeight;
+
+    delete[] volBuffer;
+}
+
+TEST_P(AVCDimensionTest, DimensionTest) {
+    int32_t numNalUnits = 0;
+    int32_t avcWidth = -1;
+    int32_t avcHeight = -1;
+    string line;
+    string type;
+    size_t chunkLength;
+    while (getline(mInfoFileStream, line)) {
+        istringstream stringLine(line);
+        stringLine >> type >> chunkLength;
+        ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+        const uint8_t *data = new uint8_t[chunkLength];
+        ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+        const uint8_t *nalStart;
+        size_t nalSize;
+
+        mInputFileStream.read((char *)data, chunkLength);
+        ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+                << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+        size_t smallBufferSize = kSmallBufferSize;
+        const uint8_t *sanityData = new uint8_t[smallBufferSize];
+        memcpy((void *)sanityData, (void *)data, smallBufferSize);
+
+        status_t result = getNextNALUnit(&sanityData, &smallBufferSize, &nalStart, &nalSize, true);
+        ASSERT_EQ(result, -EAGAIN) << "Invalid result found when wrong NAL unit passed";
+
+        while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+            numNalUnits++;
+            // Check if it's an SPS
+            if ((nalStart[0] & kSPSmask) != kSPSStartCode) continue;
+            ASSERT_TRUE(nalSize > 0) << "NAL unit size must be greater than 0";
+
+            sp<ABuffer> spsBuffer = new ABuffer(nalSize);
+            ASSERT_NE(spsBuffer, nullptr) << "ABuffer returned null for size: " << nalSize;
+
+            memcpy(spsBuffer->data(), nalStart, nalSize);
+            FindAVCDimensions(spsBuffer, &avcWidth, &avcHeight);
+            spsBuffer.clear();
+            ASSERT_EQ(avcWidth, mFrameWidth)
+                    << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+            ASSERT_EQ(avcHeight, mFrameHeight)
+                    << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+        }
+        delete[] data;
+    }
+    if (mNalUnitsExpected < 0) {
+        ASSERT_GT(numNalUnits, 0) << "Failed to find an NAL Unit";
+    } else {
+        ASSERT_EQ(numNalUnits, mNalUnitsExpected)
+                << "Expected number of NAL units: " << mNalUnitsExpected
+                << " found: " << numNalUnits;
+    }
+}
+
+TEST_P(AvccBoxTest, AvccBoxValidationTest) {
+    int32_t avcWidth = -1;
+    int32_t avcHeight = -1;
+    int32_t accessUnitLength = 0;
+    int32_t profile = -1;
+    int32_t level = -1;
+    string line;
+    string type;
+    size_t chunkLength;
+    while (getline(mInfoFileStream, line)) {
+        istringstream stringLine(line);
+        stringLine >> type >> chunkLength;
+
+        if (type.compare("SPS") && type.compare("PPS")) continue;
+        ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+        accessUnitLength += chunkLength;
+
+        if (!type.compare("SPS")) {
+            const uint8_t *data = new uint8_t[chunkLength];
+            ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+            const uint8_t *nalStart;
+            size_t nalSize;
+
+            mInputFileStream.read((char *)data, (uint32_t)chunkLength);
+            ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+                    << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+            while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+                // Check if it's an SPS
+                ASSERT_TRUE(nalSize > 0 && (nalStart[0] & kSPSmask) == kSPSStartCode)
+                        << "Failed to get SPS";
+
+                ASSERT_GE(nalSize, 4) << "SPS size must be greater than or equal to 4";
+
+                profile = nalStart[1];
+                level = nalStart[3];
+            }
+            delete[] data;
+        }
+    }
+    const uint8_t *accessUnitData = new uint8_t[accessUnitLength];
+    ASSERT_NE(accessUnitData, nullptr) << "Failed to create a buffer of size: " << accessUnitLength;
+
+    mInputFileStream.seekg(0, ios::beg);
+    mInputFileStream.read((char *)accessUnitData, accessUnitLength);
+    ASSERT_EQ(mInputFileStream.gcount(), accessUnitLength)
+            << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+    sp<ABuffer> accessUnit = new ABuffer(accessUnitLength);
+    ASSERT_NE(accessUnit, nullptr)
+            << "Failed to create an android data buffer of size: " << accessUnitLength;
+
+    memcpy(accessUnit->data(), accessUnitData, accessUnitLength);
+    sp<ABuffer> csdDataBuffer = MakeAVCCodecSpecificData(accessUnit, &avcWidth, &avcHeight);
+    ASSERT_NE(csdDataBuffer, nullptr) << "No data returned from MakeAVCCodecSpecificData()";
+
+    ASSERT_EQ(avcWidth, mFrameWidth) << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+    ASSERT_EQ(avcHeight, mFrameHeight)
+            << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+
+    uint8_t *csdData = csdDataBuffer->data();
+    ASSERT_EQ(*csdData, kConfigVersion) << "Invalid configuration version";
+
+    ASSERT_GE(csdDataBuffer->size(), 4) << "CSD data size must be greater than or equal to 4";
+
+    ASSERT_EQ(*(csdData + 1), profile)
+            << "Expected AVC profile: " << profile << " found: " << *(csdData + 1);
+
+    ASSERT_EQ(*(csdData + 3), level)
+            << "Expected AVC level: " << level << " found: " << *(csdData + 3);
+    csdDataBuffer.clear();
+    delete[] accessUnitData;
+    accessUnit.clear();
+}
+
+TEST_P(AVCFrameTest, FrameTest) {
+    string line;
+    string type;
+    size_t chunkLength;
+    int32_t frameLayerID;
+    while (getline(mInfoFileStream, line)) {
+        uint32_t layerID = 0;
+        istringstream stringLine(line);
+        stringLine >> type >> chunkLength >> frameLayerID;
+        ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+        char *data = new char[chunkLength];
+        ASSERT_NE(data, nullptr) << "Failed to allocation data buffer of size: " << chunkLength;
+
+        mInputFileStream.read(data, chunkLength);
+        ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+                << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+        if (!type.compare("IDR")) {
+            bool isIDR = IsIDR((uint8_t *)data, chunkLength);
+            ASSERT_TRUE(isIDR);
+
+            layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+            ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+        } else if (!type.compare("P") || !type.compare("B")) {
+            sp<ABuffer> accessUnit = new ABuffer(chunkLength);
+            ASSERT_NE(accessUnit, nullptr) << "Unable to create access Unit";
+
+            memcpy(accessUnit->data(), data, chunkLength);
+            bool isReferenceFrame = IsAVCReferenceFrame(accessUnit);
+            ASSERT_TRUE(isReferenceFrame);
+
+            accessUnit.clear();
+            layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+            ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+        }
+        delete[] data;
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, MpegAudioUnitTest,
+                         ::testing::Values(make_tuple(0xFFFB9204, 418, 44100, 2, 128, 1152),
+                                           make_tuple(0xFFFB7604, 289, 48000, 2, 96, 1152),
+                                           make_tuple(0xFFFE5604, 164, 48000, 2, 160, 384)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+        AVCUtilsTestAll, AVCDimensionTest,
+        ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+                                     "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+                          make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+                                     "crowd_640x360p24f300_1000kbps_bp.info", 640, 360, 11),
+                          make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+                                     "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+                          make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+                                     "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14),
+                          make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+                                     "crowd_3840x2160p60f300_68000kbps_bp.info", 3840, 2160, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+        AVCUtilsTestAll, AvccBoxTest,
+        ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+                                     "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+                          make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+                                     "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+                          make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+                                     "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, VOLDimensionTest,
+                         ::testing::Values(make_tuple("volData_720_480", 720, 480),
+                                           make_tuple("volData_1280_720", 1280, 720),
+                                           make_tuple("volData_1920_1080", 1920, 1080)));
+
+// Info File contains the type, length and layer ID for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, AVCFrameTest,
+                         ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+                                                      "crowd_8x8p50f32_200kbps_bp.info"),
+                                           make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+                                                      "crowd_640x360p24f300_1000kbps_bp.info"),
+                                           make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+                                                      "crowd_1280x720p30f300_5000kbps_bp.info"),
+                                           make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+                                                      "crowd_1920x1080p50f300_12000kbps_bp.info"),
+                                           make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+                                                      "crowd_3840x2160p60f300_68000kbps_bp.info")));
+
+int main(int argc, char **argv) {
+    gEnv = new AVCUtilsTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/Android.bp b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
new file mode 100644
index 0000000..5d0e481
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "AVCUtilsUnitTest",
+    gtest: true,
+
+    srcs: [
+        "AVCUtilsUnitTest.cpp",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+    static_libs: [
+        "libstagefright",
+        "libstagefright_foundation",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright/foundation",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
new file mode 100644
index 0000000..6a088a8
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for AVC Utils unit tests">
+    <option name="test-suite-tag" value="AVCUtilsUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="false" />
+        <option name="push" value="AVCUtilsUnitTest->/data/local/tmp/AVCUtilsUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip?unzip=true"
+            value="/data/local/tmp/AVCUtilsUnitTest/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="AVCUtilsUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/AVCUtilsUnitTest/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/foundation/tests/AVCUtils/README.md b/media/libstagefright/foundation/tests/AVCUtils/README.md
new file mode 100644
index 0000000..609d72e
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### AVCUtils Test
+The AVC Utility Unit Test Suite validates the avc_utils librariy available in libstagefright/foundation.
+
+Run the following steps to build the test suite:
+```
+m AVCUtilsUnitTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push AVCUtilsUnitTest /data/local/tmp/
+```
+
+usage: AVCUtilsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/AVCUtilsUnitTest -P /data/local/tmp/AVCUtilsUnitTest/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest AVCUtilsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/foundation/tests/Android.bp b/media/libstagefright/foundation/tests/Android.bp
index f2157c9..45e81e8 100644
--- a/media/libstagefright/foundation/tests/Android.bp
+++ b/media/libstagefright/foundation/tests/Android.bp
@@ -25,3 +25,31 @@
         "Utils_test.cpp",
     ],
 }
+
+cc_test {
+    name: "MetaDataBaseUnitTest",
+    gtest: true,
+
+    srcs: [
+        "MetaDataBaseUnitTest.cpp",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+    static_libs: [
+        "libstagefright",
+        "libstagefright_foundation",
+    ],
+
+    header_libs: [
+        "libmedia_headers",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp b/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp
new file mode 100644
index 0000000..0aed4d2
--- /dev/null
+++ b/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2020 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 <gtest/gtest.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fstream>
+
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataBase.h>
+
+constexpr int32_t kWidth1 = 1920;
+constexpr int32_t kHeight1 = 1080;
+constexpr int32_t kWidth2 = 1280;
+constexpr int32_t kHeight2 = 920;
+constexpr int32_t kWidth3 = 720;
+constexpr int32_t kHeight3 = 480;
+constexpr int32_t kProfile = 1;
+constexpr int32_t kLevel = 1;
+constexpr int32_t kPlatformValue = 1;
+
+// Rectangle margins
+constexpr int32_t kLeft = 100;
+constexpr int32_t kTop = 100;
+constexpr int32_t kRight = 100;
+constexpr int32_t kBottom = 100;
+
+constexpr int64_t kDurationUs = 60000000;
+
+constexpr float kCaptureRate = 30.0;
+
+namespace android {
+
+class MetaDataBaseUnitTest : public ::testing::Test {};
+
+TEST_F(MetaDataBaseUnitTest, CreateMetaDataBaseTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    // Testing copy constructor
+    MetaDataBase *metaDataCopy = metaData;
+    ASSERT_NE(metaDataCopy, nullptr) << "Failed to create meta data copy";
+
+    delete metaData;
+}
+
+TEST_F(MetaDataBaseUnitTest, SetAndFindDataTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    // Setting the different key-value pair type for first time, overwrite
+    // expected to be false
+    bool status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+    ASSERT_FALSE(status) << "Initializing kKeyMIMEType, overwrite is expected to be false";
+
+    status = metaData->setInt32(kKeyWidth, kWidth1);
+    ASSERT_FALSE(status) << "Initializing kKeyWidth, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyHeight, kHeight1);
+    ASSERT_FALSE(status) << "Initializing kKeyHeight, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyVideoProfile, kProfile);
+    ASSERT_FALSE(status) << "Initializing kKeyVideoProfile, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyVideoLevel, kLevel);
+    ASSERT_FALSE(status) << "Initializing kKeyVideoLevel, overwrite is expected to be false";
+
+    status = metaData->setInt64(kKeyDuration, kDurationUs);
+    ASSERT_FALSE(status) << "Initializing kKeyDuration, overwrite is expected to be false";
+
+    status = metaData->setFloat(kKeyCaptureFramerate, kCaptureRate);
+    ASSERT_FALSE(status) << "Initializing kKeyCaptureFramerate, overwrite is expected to be false";
+
+    const int32_t *platform = &kPlatformValue;
+    status = metaData->setPointer(kKeyPlatformPrivate, (void *)platform);
+    ASSERT_FALSE(status) << "Initializing kKeyPlatformPrivate, overwrite is expected to be false";
+
+    status = metaData->setRect(kKeyCropRect, kLeft, kTop, kRight, kBottom);
+    ASSERT_FALSE(status) << "Initializing kKeyCropRect, overwrite is expected to be false";
+
+    // Dump to log for reference
+    metaData->dumpToLog();
+
+    // Find the data which was set
+    const char *mime;
+    status = metaData->findCString(kKeyMIMEType, &mime);
+    ASSERT_TRUE(status) << "kKeyMIMEType key does not exists in metadata";
+    ASSERT_STREQ(mime, MEDIA_MIMETYPE_VIDEO_AVC) << "Incorrect mime type returned";
+
+    int32_t width, height, profile, level;
+    status = metaData->findInt32(kKeyWidth, &width);
+    ASSERT_TRUE(status) << "kKeyWidth key does not exists in metadata";
+    ASSERT_EQ(width, kWidth1) << "Incorrect value of width returned";
+
+    status = metaData->findInt32(kKeyHeight, &height);
+    ASSERT_TRUE(status) << "kKeyHeight key does not exists in metadata";
+    ASSERT_EQ(height, kHeight1) << "Incorrect value of height returned";
+
+    status = metaData->findInt32(kKeyVideoProfile, &profile);
+    ASSERT_TRUE(status) << "kKeyVideoProfile key does not exists in metadata";
+    ASSERT_EQ(profile, kProfile) << "Incorrect value of profile returned";
+
+    status = metaData->findInt32(kKeyVideoLevel, &level);
+    ASSERT_TRUE(status) << "kKeyVideoLevel key does not exists in metadata";
+    ASSERT_EQ(level, kLevel) << "Incorrect value of level returned";
+
+    int64_t duration;
+    status = metaData->findInt64(kKeyDuration, &duration);
+    ASSERT_TRUE(status) << "kKeyDuration key does not exists in metadata";
+    ASSERT_EQ(duration, kDurationUs) << "Incorrect value of duration returned";
+
+    float frameRate;
+    status = metaData->findFloat(kKeyCaptureFramerate, &frameRate);
+    ASSERT_TRUE(status) << "kKeyCaptureFramerate key does not exists in metadata";
+    ASSERT_EQ(frameRate, kCaptureRate) << "Incorrect value of captureFrameRate returned";
+
+    int32_t top, bottom, left, right;
+    status = metaData->findRect(kKeyCropRect, &left, &top, &right, &bottom);
+    ASSERT_TRUE(status) << "kKeyCropRect key does not exists in metadata";
+    ASSERT_EQ(left, kLeft) << "Incorrect value of left margin returned";
+    ASSERT_EQ(top, kTop) << "Incorrect value of top margin returned";
+    ASSERT_EQ(right, kRight) << "Incorrect value of right margin returned";
+    ASSERT_EQ(bottom, kBottom) << "Incorrect value of bottom margin returned";
+
+    void *platformValue;
+    status = metaData->findPointer(kKeyPlatformPrivate, &platformValue);
+    ASSERT_TRUE(status) << "kKeyPlatformPrivate key does not exists in metadata";
+    ASSERT_EQ(platformValue, &kPlatformValue) << "Incorrect value of pointer returned";
+
+    // Check for the key which is not added to metadata
+    int32_t angle;
+    status = metaData->findInt32(kKeyRotation, &angle);
+    ASSERT_FALSE(status) << "Value for an invalid key is returned when the key is not set";
+
+    delete (metaData);
+}
+
+TEST_F(MetaDataBaseUnitTest, OverWriteFunctionalityTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    // set/set/read to check first overwrite operation
+    bool status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+    ASSERT_FALSE(status) << "Initializing kKeyMIMEType, overwrite is expected to be false";
+    // Overwrite the value
+    status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+    ASSERT_TRUE(status) << "Setting kKeyMIMEType again, overwrite is expected to be true";
+    // Check the value
+    const char *mime;
+    status = metaData->findCString(kKeyMIMEType, &mime);
+    ASSERT_TRUE(status) << "kKeyMIMEType key does not exists in metadata";
+    ASSERT_STREQ(mime, MEDIA_MIMETYPE_VIDEO_HEVC) << "Mime value is not overwritten";
+
+    // set/set/set/read to check second overwrite operation
+    status = metaData->setInt32(kKeyWidth, kWidth1);
+    ASSERT_FALSE(status) << "Initializing kKeyWidth, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyHeight, kHeight1);
+    ASSERT_FALSE(status) << "Initializing kKeyHeight, overwrite is expected to be false";
+    // Overwrite the value
+    status = metaData->setInt32(kKeyWidth, kWidth2);
+    ASSERT_TRUE(status) << "Setting kKeyWidth again, overwrite is expected to be true";
+    status = metaData->setInt32(kKeyHeight, kHeight2);
+    ASSERT_TRUE(status) << "Setting kKeyHeight again, overwrite is expected to be true";
+    // Overwrite the value again
+    status = metaData->setInt32(kKeyWidth, kWidth3);
+    ASSERT_TRUE(status) << "Setting kKeyWidth again, overwrite is expected to be true";
+    status = metaData->setInt32(kKeyHeight, kHeight3);
+    ASSERT_TRUE(status) << "Setting kKeyHeight again, overwrite is expected to be true";
+    // Check the value
+    int32_t width, height;
+    status = metaData->findInt32(kKeyWidth, &width);
+    ASSERT_TRUE(status) << "kKeyWidth key does not exists in metadata";
+    ASSERT_EQ(width, kWidth3) << "Value of width is not overwritten";
+
+    status = metaData->findInt32(kKeyHeight, &height);
+    ASSERT_TRUE(status) << "kKeyHeight key does not exists in metadata";
+    ASSERT_EQ(height, kHeight3) << "Value of height is not overwritten";
+
+    delete (metaData);
+}
+
+TEST_F(MetaDataBaseUnitTest, RemoveKeyTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    bool status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+    ASSERT_FALSE(status) << "Initializing kKeyMIMEType, overwrite is expected to be false";
+    // Query the key
+    status = metaData->hasData(kKeyMIMEType);
+    ASSERT_TRUE(status) << "MetaData does not have the mime key";
+
+    status = metaData->remove(kKeyMIMEType);
+    ASSERT_TRUE(status) << "Failed to remove the kKeyMIMEType key";
+
+    // Query the key
+    status = metaData->hasData(kKeyMIMEType);
+    ASSERT_FALSE(status) << "MetaData has mime key after removing it, expected to be false";
+
+    // Remove the non existing key
+    status = metaData->remove(kKeyMIMEType);
+    ASSERT_FALSE(status) << "Removed the non existing key";
+
+    // Check overwriting the removed key
+    metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+    ASSERT_FALSE(status) << "Overwrite should be false since the key was removed";
+
+    status = metaData->setInt32(kKeyWidth, kWidth1);
+    ASSERT_FALSE(status) << "Initializing kKeyWidth, overwrite is expected to be false";
+
+    // Clear whole metadata
+    metaData->clear();
+
+    // Check finding key after clearing the metadata
+    int32_t width;
+    status = metaData->findInt32(kKeyWidth, &width);
+    ASSERT_FALSE(status) << "MetaData found kKeyWidth key after clearing all the items in it, "
+                            "expected to be false";
+
+    // Query the key
+    status = metaData->hasData(kKeyWidth);
+    ASSERT_FALSE(status)
+            << "MetaData has width key after clearing all the items in it, expected to be false";
+
+    status = metaData->hasData(kKeyMIMEType);
+    ASSERT_FALSE(status)
+            << "MetaData has mime key after clearing all the items in it, expected to be false";
+
+    // Check removing key after clearing the metadata
+    status = metaData->remove(kKeyMIMEType);
+    ASSERT_FALSE(status) << "Removed the key, after clearing the metadata";
+
+    // Checking set after clearing the metadata
+    status = metaData->setInt32(kKeyWidth, kWidth1);
+    ASSERT_FALSE(status) << "Overwrite should be false since the metadata was cleared";
+
+    metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+    ASSERT_FALSE(status) << "Overwrite should be false since the metadata was cleared";
+
+    delete (metaData);
+}
+
+TEST_F(MetaDataBaseUnitTest, ConvertToStringTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    String8 info = metaData->toString();
+    ASSERT_EQ(info.length(), 0) << "Empty MetaData length is non-zero: " << info.length();
+
+    bool status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+    ASSERT_FALSE(status) << "Initializing kKeyMIMEType, overwrite is expected to be false";
+
+    status = metaData->setInt32(kKeyWidth, kWidth1);
+    ASSERT_FALSE(status) << "Initializing kKeyWidth, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyHeight, kHeight1);
+    ASSERT_FALSE(status) << "Initializing kKeyHeight, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyVideoProfile, kProfile);
+    ASSERT_FALSE(status) << "Initializing kKeyVideoProfile, overwrite is expected to be false";
+    status = metaData->setInt32(kKeyVideoLevel, kLevel);
+    ASSERT_FALSE(status) << "Initializing kKeyVideoLevel, overwrite is expected to be false";
+
+    info = metaData->toString();
+    ASSERT_GT(info.length(), 0) << "MetaData contains no information";
+
+    // Dump to log for reference
+    metaData->dumpToLog();
+
+    // Clear whole metadata
+    metaData->clear();
+
+    info = metaData->toString();
+    ASSERT_EQ(info.length(), 0) << "MetaData length is non-zero after clearing it: "
+                                << info.length();
+
+    delete (metaData);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/foundation/tests/OpusHeader/Android.bp b/media/libstagefright/foundation/tests/OpusHeader/Android.bp
new file mode 100644
index 0000000..c1251a8
--- /dev/null
+++ b/media/libstagefright/foundation/tests/OpusHeader/Android.bp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "OpusHeaderTest",
+    gtest: true,
+
+    srcs: [
+        "OpusHeaderTest.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+    ],
+
+    static_libs: [
+        "libstagefright_foundation",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
diff --git a/media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml b/media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml
new file mode 100644
index 0000000..afee16a
--- /dev/null
+++ b/media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for opus header unit tests">
+    <option name="test-suite-tag" value="OpusHeaderTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="OpusHeaderTest->/data/local/tmp/OpusHeaderTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/OpusHeader/OpusHeader.zip?unzip=true"
+            value="/data/local/tmp/OpusHeaderTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="OpusHeaderTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/OpusHeaderTestRes/" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
new file mode 100644
index 0000000..e39c915
--- /dev/null
+++ b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2020 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 "OpusHeaderTest"
+#include <utils/Log.h>
+
+#include <fstream>
+#include <stdio.h>
+#include <string.h>
+
+#include <media/stagefright/foundation/OpusHeader.h>
+
+#include "OpusHeaderTestEnvironment.h"
+
+using namespace android;
+
+#define OUTPUT_FILE_NAME "/data/local/tmp/OpusOutput"
+
+// Opus in WebM is a well-known, yet under-documented, format. The codec private data
+// of the track is an Opus Ogg header (https://tools.ietf.org/html/rfc7845#section-5.1)
+// channel mapping offset in opus header
+constexpr size_t kOpusHeaderStreamMapOffset = 21;
+constexpr size_t kMaxOpusHeaderSize = 100;
+// AOPUSHDR + AOPUSHDRLength +
+// (8 + 8 ) +
+// Header(csd) + num_streams + num_coupled + 1
+// (19 + 1 + 1 + 1) +
+// AOPUSDLY + AOPUSDLYLength + DELAY + AOPUSPRL + AOPUSPRLLength + PRL
+// (8 + 8 + 8 + 8 + 8 + 8)
+// = 86
+constexpr size_t kOpusHeaderChannelMapOffset = 86;
+constexpr uint32_t kOpusSampleRate = 48000;
+constexpr uint64_t kOpusSeekPrerollNs = 80000000;
+constexpr int64_t kNsecPerSec = 1000000000ll;
+
+// 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
+constexpr int kMaxChannels = 8;
+constexpr uint8_t kOpusChannelMap[kMaxChannels][kMaxChannels] = {
+        {0},
+        {0, 1},
+        {0, 2, 1},
+        {0, 1, 2, 3},
+        {0, 4, 1, 2, 3},
+        {0, 4, 1, 2, 3, 5},
+        {0, 4, 1, 2, 3, 5, 6},
+        {0, 6, 1, 2, 3, 4, 5, 7},
+};
+
+static OpusHeaderTestEnvironment *gEnv = nullptr;
+
+class OpusHeaderTest {
+  public:
+    OpusHeaderTest() : mInputBuffer(nullptr) {}
+
+    ~OpusHeaderTest() {
+        if (mEleStream.is_open()) mEleStream.close();
+        if (mInputBuffer) {
+            free(mInputBuffer);
+            mInputBuffer = nullptr;
+        }
+    }
+    ifstream mEleStream;
+    uint8_t *mInputBuffer;
+};
+
+class OpusHeaderParseTest : public OpusHeaderTest,
+                            public ::testing::TestWithParam<
+                                    tuple<string /* InputFileName */, int32_t /* ChannelCount */,
+                                          bool /* isHeaderValid */, bool /* isCodecDelayValid */,
+                                          bool /* isSeekPreRollValid */, bool /* isInputValid */>> {
+};
+
+class OpusHeaderWriteTest
+    : public OpusHeaderTest,
+      public ::testing::TestWithParam<tuple<int32_t /* ChannelCount */, int32_t /* skipSamples */,
+                                            string /* referenceFile */>> {};
+
+TEST_P(OpusHeaderWriteTest, WriteTest) {
+    tuple<int32_t, int32_t, string> params = GetParam();
+    OpusHeader writtenHeader;
+    memset(&writtenHeader, 0, sizeof(writtenHeader));
+    int32_t channels = get<0>(params);
+    writtenHeader.channels = channels;
+    writtenHeader.num_streams = channels;
+    writtenHeader.channel_mapping = ((channels > 8) ? 255 : (channels > 2));
+    int32_t skipSamples = get<1>(params);
+    string referenceFileName = gEnv->getRes() + get<2>(params);
+    writtenHeader.skip_samples = skipSamples;
+    uint64_t codecDelayNs = skipSamples * kNsecPerSec / kOpusSampleRate;
+    uint8_t headerData[kMaxOpusHeaderSize];
+    int32_t headerSize = WriteOpusHeaders(writtenHeader, kOpusSampleRate, headerData,
+                                          sizeof(headerData), codecDelayNs, kOpusSeekPrerollNs);
+    ASSERT_GT(headerSize, 0) << "failed to generate Opus header";
+    ASSERT_LE(headerSize, kMaxOpusHeaderSize)
+            << "Invalid header written. Header size can't exceed kMaxOpusHeaderSize";
+
+    ofstream ostrm;
+    ostrm.open(OUTPUT_FILE_NAME, ofstream::binary);
+    ASSERT_TRUE(ostrm.is_open()) << "Failed to open output file " << OUTPUT_FILE_NAME;
+    ostrm.write(reinterpret_cast<char *>(headerData), headerSize);
+    ostrm.close();
+
+    mEleStream.open(referenceFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open referenceFileName " << get<2>(params);
+
+    struct stat buf;
+    int32_t statStatus = stat(referenceFileName.c_str(), &buf);
+    ASSERT_EQ(statStatus, 0) << "Unable to get file properties";
+
+    size_t fileSize = buf.st_size;
+    mInputBuffer = (uint8_t *)malloc(fileSize);
+    ASSERT_NE(mInputBuffer, nullptr) << "Insufficient memory. Malloc failed for size " << fileSize;
+
+    mEleStream.read(reinterpret_cast<char *>(mInputBuffer), fileSize);
+    ASSERT_EQ(mEleStream.gcount(), fileSize) << "mEleStream.gcount() != bytesCount";
+
+    ASSERT_EQ(fileSize, headerSize)
+            << "Mismatch in size between header generated and reference header";
+    int32_t match = memcmp(reinterpret_cast<char *>(mInputBuffer),
+                           reinterpret_cast<char *>(headerData), fileSize);
+    ASSERT_EQ(match, 0) << "Opus header does not match reference file: " << referenceFileName;
+
+    size_t opusHeadSize = 0;
+    size_t codecDelayBufSize = 0;
+    size_t seekPreRollBufSize = 0;
+    void *opusHeadBuf = nullptr;
+    void *codecDelayBuf = nullptr;
+    void *seekPreRollBuf = nullptr;
+    bool status = GetOpusHeaderBuffers(headerData, headerSize, &opusHeadBuf, &opusHeadSize,
+                                       &codecDelayBuf, &codecDelayBufSize, &seekPreRollBuf,
+                                       &seekPreRollBufSize);
+    ASSERT_TRUE(status) << "Encountered error in GetOpusHeaderBuffers";
+
+    uint64_t value = *((uint64_t *)codecDelayBuf);
+    ASSERT_EQ(value, codecDelayNs);
+
+    value = *((uint64_t *)seekPreRollBuf);
+    ASSERT_EQ(value, kOpusSeekPrerollNs);
+
+    OpusHeader parsedHeader;
+    status = ParseOpusHeader((uint8_t *)opusHeadBuf, opusHeadSize, &parsedHeader);
+    ASSERT_TRUE(status) << "Encountered error while Parsing Opus Header.";
+
+    ASSERT_EQ(writtenHeader.channels, parsedHeader.channels)
+            << "Invalid header generated. Mismatch between channel counts";
+
+    ASSERT_EQ(writtenHeader.skip_samples, parsedHeader.skip_samples)
+            << "Mismatch between no of skipSamples written "
+               "and no of skipSamples got after parsing";
+
+    ASSERT_EQ(writtenHeader.channel_mapping, parsedHeader.channel_mapping)
+            << "Mismatch between channelMapping written "
+               "and channelMapping got after parsing";
+
+    if (parsedHeader.channel_mapping) {
+        ASSERT_GT(parsedHeader.channels, 2);
+        ASSERT_EQ(writtenHeader.num_streams, parsedHeader.num_streams)
+                << "Invalid header generated. Mismatch between channel counts";
+
+        ASSERT_EQ(writtenHeader.num_coupled, parsedHeader.num_coupled)
+                << "Invalid header generated. Mismatch between channel counts";
+
+        ASSERT_EQ(parsedHeader.num_coupled + parsedHeader.num_streams, parsedHeader.channels);
+
+        ASSERT_LE(parsedHeader.num_coupled, parsedHeader.num_streams)
+                << "Invalid header generated. Number of coupled streams cannot be greater than "
+                   "number "
+                   "of streams.";
+
+        ASSERT_EQ(headerSize, kOpusHeaderChannelMapOffset + writtenHeader.channels)
+                << "Invalid header written. Header size should be equal to 86 + "
+                   "writtenHeader.channels";
+
+        uint8_t mappedChannelNumber;
+        for (int32_t channelNumber = 0; channelNumber < channels; channelNumber++) {
+            mappedChannelNumber = *(reinterpret_cast<uint8_t *>(opusHeadBuf) +
+                                    kOpusHeaderStreamMapOffset + channelNumber);
+            ASSERT_LT(mappedChannelNumber, channels) << "Invalid header generated. Channel mapping "
+                                                        "cannot be greater than channel count.";
+
+            ASSERT_EQ(mappedChannelNumber, kOpusChannelMap[channels - 1][channelNumber])
+                    << "Invalid header generated. Channel mapping is not as per specification.";
+        }
+    } else {
+        ASSERT_LE(parsedHeader.channels, 2);
+    }
+}
+
+TEST_P(OpusHeaderParseTest, ParseTest) {
+    tuple<string, int32_t, bool, bool, bool, bool> params = GetParam();
+    string inputFileName = gEnv->getRes() + get<0>(params);
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << get<0>(params);
+    bool isHeaderValid = get<2>(params);
+    bool isCodecDelayValid = get<3>(params);
+    bool isSeekPreRollValid = get<4>(params);
+    bool isInputValid = get<5>(params);
+
+    struct stat buf;
+    stat(inputFileName.c_str(), &buf);
+    size_t fileSize = buf.st_size;
+    mInputBuffer = (uint8_t *)malloc(fileSize);
+    ASSERT_NE(mInputBuffer, nullptr) << "Insufficient memory. Malloc failed for size " << fileSize;
+
+    mEleStream.read(reinterpret_cast<char *>(mInputBuffer), fileSize);
+    ASSERT_EQ(mEleStream.gcount(), fileSize) << "mEleStream.gcount() != bytesCount";
+
+    OpusHeader header;
+    size_t opusHeadSize = 0;
+    size_t codecDelayBufSize = 0;
+    size_t seekPreRollBufSize = 0;
+    void *opusHeadBuf = nullptr;
+    void *codecDelayBuf = nullptr;
+    void *seekPreRollBuf = nullptr;
+    bool status = GetOpusHeaderBuffers(mInputBuffer, fileSize, &opusHeadBuf, &opusHeadSize,
+                                       &codecDelayBuf, &codecDelayBufSize, &seekPreRollBuf,
+                                       &seekPreRollBufSize);
+    if (!isHeaderValid) {
+        ASSERT_EQ(opusHeadBuf, nullptr);
+    } else {
+        ASSERT_NE(opusHeadBuf, nullptr);
+    }
+    if (!isCodecDelayValid) {
+        ASSERT_EQ(codecDelayBuf, nullptr);
+    } else {
+        ASSERT_NE(codecDelayBuf, nullptr);
+    }
+    if (!isSeekPreRollValid) {
+        ASSERT_EQ(seekPreRollBuf, nullptr);
+    } else {
+        ASSERT_NE(seekPreRollBuf, nullptr);
+    }
+    if (!status) {
+        ASSERT_FALSE(isInputValid) << "GetOpusHeaderBuffers failed";
+        return;
+    }
+
+    status = ParseOpusHeader((uint8_t *)opusHeadBuf, opusHeadSize, &header);
+
+    if (status) {
+        ASSERT_TRUE(isInputValid) << "Parse opus header didn't fail for invalid input";
+    } else {
+        ASSERT_FALSE(isInputValid);
+        return;
+    }
+
+    int32_t channels = get<1>(params);
+    ASSERT_EQ(header.channels, channels) << "Parser returned invalid channel count";
+    ASSERT_LE(header.channels, kMaxChannels);
+
+    ASSERT_LE(header.num_coupled, header.num_streams)
+            << "Invalid header generated. Number of coupled streams cannot be greater than number "
+               "of streams.";
+
+    ASSERT_EQ(header.num_coupled + header.num_streams, header.channels);
+
+    if (header.channel_mapping) {
+        uint8_t mappedChannelNumber;
+        for (int32_t channelNumber = 0; channelNumber < channels; channelNumber++) {
+            mappedChannelNumber = *(reinterpret_cast<uint8_t *>(opusHeadBuf) +
+                                    kOpusHeaderStreamMapOffset + channelNumber);
+            ASSERT_LT(mappedChannelNumber, channels)
+                    << "Invalid header. Channel mapping cannot be greater than channel count.";
+
+            ASSERT_EQ(mappedChannelNumber, kOpusChannelMap[channels - 1][channelNumber])
+                    << "Invalid header generated. Channel mapping "
+                       "is not as per specification.";
+        }
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        OpusHeaderTestAll, OpusHeaderWriteTest,
+        ::testing::Values(make_tuple(1, 312, "output_channels_1skipSamples_312.opus"),
+                          make_tuple(2, 312, "output_channels_2skipSamples_312.opus"),
+                          make_tuple(5, 312, "output_channels_5skipSamples_312.opus"),
+                          make_tuple(6, 312, "output_channels_6skipSamples_312.opus"),
+                          make_tuple(1, 0, "output_channels_1skipSamples_0.opus"),
+                          make_tuple(2, 0, "output_channels_2skipSamples_0.opus"),
+                          make_tuple(5, 0, "output_channels_5skipSamples_0.opus"),
+                          make_tuple(6, 0, "output_channels_6skipSamples_0.opus"),
+                          make_tuple(1, 624, "output_channels_1skipSamples_624.opus"),
+                          make_tuple(2, 624, "output_channels_2skipSamples_624.opus"),
+                          make_tuple(5, 624, "output_channels_5skipSamples_624.opus"),
+                          make_tuple(6, 624, "output_channels_6skipSamples_624.opus")));
+
+INSTANTIATE_TEST_SUITE_P(
+        OpusHeaderTestAll, OpusHeaderParseTest,
+        ::testing::Values(
+                make_tuple("2ch_valid_size83B.opus", 2, true, true, true, true),
+                make_tuple("3ch_valid_size88B.opus", 3, true, true, true, true),
+                make_tuple("5ch_valid.opus", 5, true, false, false, true),
+                make_tuple("6ch_valid.opus", 6, true, false, false, true),
+                make_tuple("1ch_valid.opus", 1, true, false, false, true),
+                make_tuple("2ch_valid.opus", 2, true, false, false, true),
+                make_tuple("3ch_invalid_size.opus", 3, true, true, true, false),
+                make_tuple("3ch_invalid_streams.opus", 3, true, true, true, false),
+                make_tuple("5ch_invalid_channelmapping.opus", 5, true, false, false, false),
+                make_tuple("5ch_invalid_coupledstreams.opus", 5, true, false, false, false),
+                make_tuple("6ch_invalid_channelmapping.opus", 6, true, false, false, false),
+                make_tuple("9ch_invalid_channels.opus", 9, true, true, true, false),
+                make_tuple("2ch_invalid_header.opus", 2, false, false, false, false),
+                make_tuple("2ch_invalid_headerlength_16.opus", 2, false, false, false, false),
+                make_tuple("2ch_invalid_headerlength_256.opus", 2, false, false, false, false),
+                make_tuple("2ch_invalid_size.opus", 2, false, false, false, false),
+                make_tuple("3ch_invalid_channelmapping_0.opus", 3, true, true, true, false),
+                make_tuple("3ch_invalid_coupledstreams.opus", 3, true, true, true, false),
+                make_tuple("3ch_invalid_headerlength.opus", 3, true, true, true, false),
+                make_tuple("3ch_invalid_headerSize1.opus", 3, false, false, false, false),
+                make_tuple("3ch_invalid_headerSize2.opus", 3, false, false, false, false),
+                make_tuple("3ch_invalid_headerSize3.opus", 3, false, false, false, false),
+                make_tuple("3ch_invalid_nodelay.opus", 3, false, false, false, false),
+                make_tuple("3ch_invalid_nopreroll.opus", 3, false, false, false, false)));
+
+int main(int argc, char **argv) {
+    gEnv = new OpusHeaderTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("Opus Header Test Result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
new file mode 100644
index 0000000..d0163c3
--- /dev/null
+++ b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __OPUS_HEADER_TEST_ENVIRONMENT_H__
+#define __OPUS_HEADER_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class OpusHeaderTestEnvironment : public ::testing::Environment {
+  public:
+    OpusHeaderTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int OpusHeaderTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __OPUS_HEADER_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/foundation/tests/OpusHeader/README.md b/media/libstagefright/foundation/tests/OpusHeader/README.md
new file mode 100644
index 0000000..860c827
--- /dev/null
+++ b/media/libstagefright/foundation/tests/OpusHeader/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### Opus Header
+The OpusHeader Test Suite validates the OPUS header available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m OpusHeaderTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/OpusHeaderTest/OpusHeaderTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/OpusHeaderTest/OpusHeaderTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/OpusHeader/OpusHeader.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push OpusHeader /data/local/tmp/
+```
+
+usage: OpusHeaderTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/OpusHeaderTest -P /data/local/tmp/OpusHeader/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest OpusHeaderTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/foundation/tests/TypeTraits_test.cpp b/media/libstagefright/foundation/tests/TypeTraits_test.cpp
index 1e2049d..d5383d1 100644
--- a/media/libstagefright/foundation/tests/TypeTraits_test.cpp
+++ b/media/libstagefright/foundation/tests/TypeTraits_test.cpp
@@ -30,7 +30,7 @@
     enum IA : int32_t { };
 };
 
-// =========== basic sanity tests for type-support templates
+// =========== basic tests for type-support templates
 TEST_F(TypeTraitsTest, StaticTests) {
 
     // ============ is_integral_or_enum
diff --git a/media/libstagefright/foundation/tests/colorutils/Android.bp b/media/libstagefright/foundation/tests/colorutils/Android.bp
new file mode 100644
index 0000000..d77f405
--- /dev/null
+++ b/media/libstagefright/foundation/tests/colorutils/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "ColorUtilsTest",
+    gtest: true,
+
+    srcs: [
+        "ColorUtilsTest.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libmediandk",
+    ],
+
+    static_libs: [
+        "libstagefright_foundation",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp b/media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp
new file mode 100644
index 0000000..0d802b4
--- /dev/null
+++ b/media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp
@@ -0,0 +1,773 @@
+/*
+ * Copyright (C) 2020 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 "ColorUtilsTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <stdio.h>
+
+#include <media/NdkMediaFormat.h>
+#include <media/NdkMediaFormatPriv.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+
+const size_t kHDRBufferSize = 25;
+const uint16_t kHDRInfoTestValue1 = 420;
+const uint16_t kHDRInfoTestValue2 = 42069;
+
+using namespace android;
+
+typedef ColorAspects CA;
+
+class ColorRangeTest : public ::testing::TestWithParam</* ColorRange */ CA::Range> {
+  public:
+    ColorRangeTest() { mRange = GetParam(); };
+
+    CA::Range mRange;
+};
+
+class ColorTransferTest : public ::testing::TestWithParam</* ColorTransfer */ CA::Transfer> {
+  public:
+    ColorTransferTest() { mTransfer = GetParam(); };
+
+    CA::Transfer mTransfer;
+};
+
+class ColorStandardTest : public ::testing::TestWithParam<std::pair<
+                                  /* Primaries */ CA::Primaries,
+                                  /* MatrixCoeffs */ CA::MatrixCoeffs>> {
+  public:
+    ColorStandardTest() {
+        mPrimaries = GetParam().first;
+        mMatrixCoeffs = GetParam().second;
+    };
+
+    CA::Primaries mPrimaries;
+    CA::MatrixCoeffs mMatrixCoeffs;
+};
+
+class IsoToPlatformAspectsTest : public ::testing::TestWithParam<std::tuple<
+                                         /* Primaries */ CA::Primaries,
+                                         /* Transfer */ CA::Transfer,
+                                         /* MatrixCoeffs */ CA::MatrixCoeffs,
+                                         /* Standard */ int32_t,
+                                         /* Transfer */ int32_t>> {
+  public:
+    IsoToPlatformAspectsTest() {
+        mPrimaries = std::get<0>(GetParam());
+        mTransfer = std::get<1>(GetParam());
+        mMatrixCoeffs = std::get<2>(GetParam());
+        mPlatformStandard = std::get<3>(GetParam());
+        mPlatformTransfer = std::get<4>(GetParam());
+    };
+
+    CA::Primaries mPrimaries;
+    CA::Transfer mTransfer;
+    CA::MatrixCoeffs mMatrixCoeffs;
+    int32_t mPlatformStandard;
+    int32_t mPlatformTransfer;
+};
+
+class ColorAspectsTest : public ::testing::TestWithParam<std::tuple<
+                                 /* Primaries */ CA::Primaries,
+                                 /* ColorTransfer */ CA::Transfer,
+                                 /* MatrixCoeffs */ CA::MatrixCoeffs,
+                                 /* ColorRange */ CA::Range,
+                                 /* ColorStandard */ CA::Standard>> {
+  public:
+    ColorAspectsTest() {
+        mPrimaries = std::get<0>(GetParam());
+        mTransfer = std::get<1>(GetParam());
+        mMatrixCoeffs = std::get<2>(GetParam());
+        mRange = std::get<3>(GetParam());
+        mStandard = std::get<4>(GetParam());
+    };
+
+    CA::Primaries mPrimaries;
+    CA::Transfer mTransfer;
+    CA::MatrixCoeffs mMatrixCoeffs;
+    CA::Range mRange;
+    CA::Standard mStandard;
+};
+
+class DefaultColorAspectsTest : public ::testing::TestWithParam<std::tuple<
+                                        /* Width */ int32_t,
+                                        /* Height */ int32_t,
+                                        /* Primaries */ CA::Primaries,
+                                        /* MatrixCoeffs */ CA::MatrixCoeffs>> {
+  public:
+    DefaultColorAspectsTest() {
+        mWidth = std::get<0>(GetParam());
+        mHeight = std::get<1>(GetParam());
+        mPrimaries = std::get<2>(GetParam());
+        mMatrixCoeffs = std::get<3>(GetParam());
+    };
+
+    int32_t mWidth;
+    int32_t mHeight;
+    CA::Primaries mPrimaries;
+    CA::MatrixCoeffs mMatrixCoeffs;
+};
+
+class DataSpaceTest : public ::testing::TestWithParam<std::tuple<
+                              /* ColorRange */ CA::Range,
+                              /* Primaries */ CA::Primaries,
+                              /* ColorTransfer */ CA::Transfer,
+                              /* MatrixCoeffs */ CA::MatrixCoeffs,
+                              /* v0_android_dataspace */ android_dataspace,
+                              /* android_dataspace */ android_dataspace>> {
+  public:
+    DataSpaceTest() {
+        mRange = std::get<0>(GetParam());
+        mPrimaries = std::get<1>(GetParam());
+        mTransfer = std::get<2>(GetParam());
+        mMatrixCoeffs = std::get<3>(GetParam());
+        mDataSpaceV0 = std::get<4>(GetParam());
+        mDataSpace = std::get<5>(GetParam());
+    };
+
+    CA::Range mRange;
+    CA::Primaries mPrimaries;
+    CA::Transfer mTransfer;
+    CA::MatrixCoeffs mMatrixCoeffs;
+    android_dataspace mDataSpaceV0;
+    android_dataspace mDataSpace;
+};
+
+TEST_P(ColorRangeTest, WrapColorRangeTest) {
+    int32_t range = ColorUtils::wrapColorAspectsIntoColorRange(mRange);
+    CA::Range unwrappedRange;
+    status_t status = ColorUtils::unwrapColorAspectsFromColorRange(range, &unwrappedRange);
+    ASSERT_EQ(status, OK) << "unwrapping ColorAspects from ColorRange failed";
+    EXPECT_EQ(unwrappedRange, mRange) << "Returned ColorRange doesn't match";
+    ALOGV("toString test: Range: %s", asString(mRange, "default"));
+}
+
+TEST_P(ColorTransferTest, WrapColorTransferTest) {
+    int32_t transfer = ColorUtils::wrapColorAspectsIntoColorTransfer(mTransfer);
+    CA::Transfer unwrappedTransfer;
+    status_t status = ColorUtils::unwrapColorAspectsFromColorTransfer(transfer, &unwrappedTransfer);
+    ASSERT_EQ(status, OK) << "unwrapping ColorAspects from ColorTransfer failed";
+    EXPECT_EQ(unwrappedTransfer, mTransfer) << "Returned ColorTransfer doesn't match";
+    ALOGV("toString test: Transfer: %s", asString(mTransfer, "default"));
+}
+
+TEST_P(ColorStandardTest, WrapColorStandardTest) {
+    int32_t standard = ColorUtils::wrapColorAspectsIntoColorStandard(mPrimaries, mMatrixCoeffs);
+    CA::Primaries unwrappedPrimaries;
+    CA::MatrixCoeffs unwrappedMatrixCoeffs;
+    status_t status = ColorUtils::unwrapColorAspectsFromColorStandard(standard, &unwrappedPrimaries,
+                                                                      &unwrappedMatrixCoeffs);
+    ASSERT_EQ(status, OK) << "unwrapping ColorAspects from ColorStandard failed";
+    EXPECT_EQ(unwrappedPrimaries, mPrimaries) << "Returned primaries doesn't match";
+    EXPECT_EQ(unwrappedMatrixCoeffs, mMatrixCoeffs) << "Returned  matrixCoeffs doesn't match";
+}
+
+TEST_P(ColorAspectsTest, PlatformAspectsTest) {
+    CA aspects;
+    aspects.mRange = mRange;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+
+    int32_t range = -1;
+    int32_t standard = -1;
+    int32_t transfer = -1;
+    status_t status = ColorUtils::convertCodecColorAspectsToPlatformAspects(aspects, &range,
+                                                                            &standard, &transfer);
+    ASSERT_EQ(status, OK) << "Conversion of ColorAspects to PlatformAspects failed";
+
+    CA returnedAspects;
+    status = ColorUtils::convertPlatformColorAspectsToCodecAspects(range, standard, transfer,
+                                                                   returnedAspects);
+    ASSERT_EQ(status, OK) << "Conversion of PlatformAspects to ColorAspects failed";
+    EXPECT_EQ(returnedAspects.mRange, aspects.mRange)
+            << "range mismatch for conversion between PlatformAspects";
+    EXPECT_EQ(returnedAspects.mPrimaries, aspects.mPrimaries)
+            << "primaries mismatch for conversion between PlatformAspects";
+    EXPECT_EQ(returnedAspects.mTransfer, aspects.mTransfer)
+            << "transfer mismatch for conversion between PlatformAspects";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, aspects.mMatrixCoeffs)
+            << "matrixCoeffs mismatch for conversion between PlatformAspects";
+}
+
+TEST_P(ColorAspectsTest, IsoAspectsTest) {
+    CA aspects;
+    aspects.mRange = mRange;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+
+    int32_t primaries = -1;
+    int32_t colorTransfer = -1;
+    int32_t matrixCoeffs = -1;
+    bool fullRange = false;
+    ColorUtils::convertCodecColorAspectsToIsoAspects(aspects, &primaries, &colorTransfer,
+                                                     &matrixCoeffs, &fullRange);
+
+    CA returnedAspects;
+    ColorUtils::convertIsoColorAspectsToCodecAspects(primaries, colorTransfer, matrixCoeffs,
+                                                     fullRange, returnedAspects);
+    EXPECT_EQ(returnedAspects.mRange, aspects.mRange)
+            << "range mismatch for conversion between IsoAspects";
+    EXPECT_EQ(returnedAspects.mPrimaries, aspects.mPrimaries)
+            << "primaries mismatch for conversion between IsoAspects";
+    EXPECT_EQ(returnedAspects.mTransfer, aspects.mTransfer)
+            << "transfer mismatch for conversion between IsoAspects";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, aspects.mMatrixCoeffs)
+            << "matrixCoeffs mismatch for conversion between IsoAspects";
+}
+
+TEST_P(IsoToPlatformAspectsTest, IsoAspectsToPlatformAspectsTest) {
+    CA aspects;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+
+    int32_t isoPrimaries = -1;
+    int32_t isoTransfer = -1;
+    int32_t isoMatrixCoeffs = -1;
+    bool fullrange = false;
+    ColorUtils::convertCodecColorAspectsToIsoAspects(aspects, &isoPrimaries, &isoTransfer,
+                                                     &isoMatrixCoeffs, &fullrange);
+
+    int32_t range = -1;
+    int32_t standard = -1;
+    int32_t transfer = -1;
+    ColorUtils::convertIsoColorAspectsToPlatformAspects(isoPrimaries, isoTransfer, isoMatrixCoeffs,
+                                                        fullrange, &range, &standard, &transfer);
+    if (fullrange) {
+        EXPECT_EQ(range, ColorUtils::kColorRangeFull)
+                << "range incorrect converting to PlatformAspects";
+    }
+    EXPECT_EQ(standard, mPlatformStandard) << "standard incorrect converting to PlatformAspects";
+    EXPECT_EQ(transfer, mPlatformTransfer) << "transfer incorrect converting to PlatformAspects";
+}
+
+TEST_P(ColorAspectsTest, PackColorAspectsTest) {
+    CA aspects;
+    aspects.mRange = mRange;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+    uint32_t packedColorAspects = ColorUtils::packToU32(aspects);
+
+    CA unpackedAspects = ColorUtils::unpackToColorAspects(packedColorAspects);
+    EXPECT_EQ(unpackedAspects.mRange, mRange) << "range mismatch after unpacking";
+    EXPECT_EQ(unpackedAspects.mPrimaries, mPrimaries) << "primaries mismatch after unpacking";
+    EXPECT_EQ(unpackedAspects.mTransfer, mTransfer) << "transfer mismatch after unpacking";
+    EXPECT_EQ(unpackedAspects.mMatrixCoeffs, mMatrixCoeffs)
+            << "matrixCoeffs mismatch after unpacking";
+    ALOGV("toString test: Standard: %s", asString(mStandard, "default"));
+}
+
+TEST_P(DefaultColorAspectsTest, DefaultColorAspectsTest) {
+    CA aspects;
+    aspects.mRange = CA::RangeUnspecified;
+    aspects.mPrimaries = CA::PrimariesUnspecified;
+    aspects.mMatrixCoeffs = CA::MatrixUnspecified;
+    aspects.mTransfer = CA::TransferUnspecified;
+
+    ColorUtils::setDefaultCodecColorAspectsIfNeeded(aspects, mWidth, mHeight);
+    EXPECT_EQ(aspects.mRange, CA::RangeLimited) << "range not set to default";
+    EXPECT_EQ(aspects.mPrimaries, mPrimaries) << "primaries not set to default";
+    EXPECT_EQ(aspects.mMatrixCoeffs, mMatrixCoeffs) << "matrixCoeffs not set to default";
+    EXPECT_EQ(aspects.mTransfer, CA::TransferSMPTE170M) << "transfer not set to default";
+}
+
+TEST_P(DataSpaceTest, DataSpaceTest) {
+    CA aspects;
+    aspects.mRange = mRange;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+
+    android_dataspace dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, false);
+    EXPECT_EQ(dataSpace, mDataSpace) << "Returned incorrect dataspace";
+
+    bool status = ColorUtils::convertDataSpaceToV0(dataSpace);
+    ASSERT_TRUE(status) << "Returned v0 dataspace is not aspect-only";
+    EXPECT_EQ(dataSpace, mDataSpaceV0) << "Returned incorrect v0 dataspace";
+}
+
+TEST(ColorUtilsUnitTest, AspectsChangedTest) {
+    CA origAspects;
+    origAspects.mRange = CA::Range::RangeFull;
+    origAspects.mPrimaries = CA::Primaries::PrimariesBT709_5;
+    origAspects.mTransfer = CA::Transfer::TransferLinear;
+    origAspects.mMatrixCoeffs = CA::MatrixCoeffs::MatrixBT709_5;
+
+    CA aspects;
+    aspects.mRange = CA::Range::RangeFull;
+    aspects.mPrimaries = CA::Primaries::PrimariesBT709_5;
+    aspects.mTransfer = CA::Transfer::TransferLinear;
+    aspects.mMatrixCoeffs = CA::MatrixCoeffs::MatrixBT709_5;
+
+    bool status = ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects);
+    ASSERT_FALSE(status) << "ColorAspects comparison check failed";
+
+    aspects.mRange = CA::Range::RangeLimited;
+    status = ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects);
+    ASSERT_TRUE(status) << "ColorAspects comparison check failed";
+    EXPECT_EQ(aspects.mRange, CA::Range::RangeUnspecified) << "range should have been unspecified";
+    aspects.mRange = CA::Range::RangeFull;
+
+    aspects.mTransfer = CA::Transfer::TransferSRGB;
+    status = ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects);
+    ASSERT_TRUE(status) << "ColorAspects comparison check failed";
+    EXPECT_EQ(aspects.mTransfer, CA::Transfer::TransferUnspecified)
+            << "transfer should have been unspecified";
+    aspects.mTransfer = CA::Transfer::TransferLinear;
+
+    aspects.mPrimaries = CA::Primaries::PrimariesBT2020;
+    status = ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects, true);
+    ASSERT_TRUE(status) << "ColorAspects comparison check failed";
+    EXPECT_EQ(aspects.mPrimaries, CA::Primaries::PrimariesUnspecified)
+            << "primaries should have been unspecified";
+    EXPECT_EQ(aspects.mMatrixCoeffs, CA::MatrixCoeffs::MatrixUnspecified)
+            << "matrixCoeffs should have been unspecified";
+
+    aspects.mMatrixCoeffs = CA::MatrixCoeffs::MatrixSMPTE240M;
+    status = ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects, true);
+    ASSERT_TRUE(status) << "ColorAspects comparison check failed";
+    EXPECT_EQ(aspects.mPrimaries, CA::Primaries::PrimariesUnspecified)
+            << "primaries should have been unspecified";
+    EXPECT_EQ(aspects.mMatrixCoeffs, CA::MatrixCoeffs::MatrixUnspecified)
+            << "matrixCoeffs should have been unspecified";
+}
+
+TEST(ColorUtilsUnitTest, ColorConfigFromFormatTest) {
+    int range = -1;
+    int standard = -1;
+    int transfer = -1;
+    sp<AMessage> format = new AMessage();
+    ASSERT_NE(format, nullptr) << "failed to create AMessage";
+    ColorUtils::getColorConfigFromFormat(format, &range, &standard, &transfer);
+    EXPECT_EQ(range | standard | transfer, 0) << "color config didn't default to 0";
+
+    format->setInt32(KEY_COLOR_RANGE, CA::Range::RangeFull);
+    format->setInt32(KEY_COLOR_STANDARD, CA::Standard::StandardBT709);
+    format->setInt32(KEY_COLOR_TRANSFER, CA::Transfer::TransferLinear);
+    ColorUtils::getColorConfigFromFormat(format, &range, &standard, &transfer);
+    EXPECT_EQ(range, CA::Range::RangeFull) << "range mismatch";
+    EXPECT_EQ(standard, CA::Standard::StandardBT709) << "standard mismatch";
+    EXPECT_EQ(transfer, CA::Transfer::TransferLinear) << "transfer mismatch";
+
+    range = standard = transfer = -1;
+    sp<AMessage> copyFormat = new AMessage();
+    ASSERT_NE(copyFormat, nullptr) << "failed to create AMessage";
+    ColorUtils::copyColorConfig(format, copyFormat);
+    bool status = copyFormat->findInt32(KEY_COLOR_RANGE, &range);
+    ASSERT_TRUE(status) << "ColorConfig range entry missing";
+    status = copyFormat->findInt32(KEY_COLOR_STANDARD, &standard);
+    ASSERT_TRUE(status) << "ColorConfig standard entry missing";
+    status = copyFormat->findInt32(KEY_COLOR_TRANSFER, &transfer);
+    ASSERT_TRUE(status) << "ColorConfig transfer entry missing";
+    EXPECT_EQ(range, CA::Range::RangeFull) << "range mismatch";
+    EXPECT_EQ(standard, CA::Standard::StandardBT709) << "standard mismatch";
+    EXPECT_EQ(transfer, CA::Transfer::TransferLinear) << "transfer mismatchd";
+
+    range = standard = transfer = -1;
+    ColorUtils::getColorConfigFromFormat(copyFormat, &range, &standard, &transfer);
+    EXPECT_EQ(range, CA::Range::RangeFull) << "range mismatch";
+    EXPECT_EQ(standard, CA::Standard::StandardBT709) << "standard mismatch";
+    EXPECT_EQ(transfer, CA::Transfer::TransferLinear) << "transfer mismatch";
+}
+
+TEST_P(ColorAspectsTest, FormatTest) {
+    CA aspects;
+    sp<AMessage> format = new AMessage();
+    ASSERT_NE(format, nullptr) << "failed to create AMessage";
+    ColorUtils::setColorAspectsIntoFormat(aspects, format, true);
+
+    CA returnedAspects;
+    ColorUtils::getColorAspectsFromFormat(format, returnedAspects);
+    EXPECT_EQ(returnedAspects.mRange, aspects.mRange) << "range mismatch";
+    EXPECT_EQ(returnedAspects.mPrimaries, aspects.mPrimaries) << "primaries mismatch";
+    EXPECT_EQ(returnedAspects.mTransfer, aspects.mTransfer) << "transfer mismatch";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, aspects.mMatrixCoeffs) << "matrixCoeffs mismatch";
+
+    aspects.mRange = mRange;
+    aspects.mPrimaries = mPrimaries;
+    aspects.mTransfer = mTransfer;
+    aspects.mMatrixCoeffs = mMatrixCoeffs;
+    ColorUtils::setColorAspectsIntoFormat(aspects, format);
+
+    memset(&returnedAspects, 0, sizeof(returnedAspects));
+    ColorUtils::getColorAspectsFromFormat(format, returnedAspects);
+    EXPECT_EQ(returnedAspects.mRange, aspects.mRange) << "range mismatch";
+    EXPECT_EQ(returnedAspects.mPrimaries, aspects.mPrimaries) << "primaries mismatch";
+    EXPECT_EQ(returnedAspects.mTransfer, aspects.mTransfer) << "transfer mismatch";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, aspects.mMatrixCoeffs) << "matrixCoeffs mismatch";
+}
+
+TEST(ColorUtilsUnitTest, HDRStaticInfoTest) {
+    sp<AMessage> format = new AMessage();
+    ASSERT_NE(format, nullptr) << "failed to create AMessage";
+
+    HDRStaticInfo returnedInfoHDR;
+    bool status = ColorUtils::getHDRStaticInfoFromFormat(format, &returnedInfoHDR);
+    ASSERT_FALSE(status) << "HDR info should be absent in empty format";
+
+    HDRStaticInfo infoHDR;
+    infoHDR.sType1.mMaxDisplayLuminance = kHDRInfoTestValue2;
+    infoHDR.sType1.mMinDisplayLuminance = kHDRInfoTestValue1;
+    infoHDR.sType1.mMaxContentLightLevel = kHDRInfoTestValue2;
+    infoHDR.sType1.mMaxFrameAverageLightLevel = kHDRInfoTestValue1;
+    infoHDR.sType1.mR.x = kHDRInfoTestValue1;
+    infoHDR.sType1.mR.y = kHDRInfoTestValue2;
+    infoHDR.sType1.mG.x = kHDRInfoTestValue1;
+    infoHDR.sType1.mG.y = kHDRInfoTestValue2;
+    infoHDR.sType1.mB.x = kHDRInfoTestValue1;
+    infoHDR.sType1.mB.y = kHDRInfoTestValue2;
+    infoHDR.sType1.mW.x = kHDRInfoTestValue1;
+    infoHDR.sType1.mW.y = kHDRInfoTestValue2;
+    ColorUtils::setHDRStaticInfoIntoFormat(infoHDR, format);
+
+    status = ColorUtils::getHDRStaticInfoFromFormat(format, &returnedInfoHDR);
+    ASSERT_TRUE(status) << "Failed to get HDR info from format";
+    ASSERT_EQ(0, memcmp(&returnedInfoHDR, &infoHDR, sizeof(infoHDR))) << " HDRStaticInfo mismatch";
+
+    AMediaFormat *mediaFormat = AMediaFormat_new();
+    ASSERT_NE(mediaFormat, nullptr) << "Unable to create AMediaFormat";
+    ColorUtils::setHDRStaticInfoIntoAMediaFormat(infoHDR, mediaFormat);
+    memset(&returnedInfoHDR, 0, sizeof(returnedInfoHDR));
+    status = ColorUtils::getHDRStaticInfoFromFormat(mediaFormat->mFormat, &returnedInfoHDR);
+    AMediaFormat_delete(mediaFormat);
+    ASSERT_TRUE(status) << "Failed to get HDR info from media format";
+    ASSERT_EQ(0, memcmp(&returnedInfoHDR, &infoHDR, sizeof(infoHDR))) << " HDRStaticInfo mismatch";
+}
+
+TEST(ColorUtilsUnitTest, SanityTest) {
+    CA::Primaries unmappedPrimaries = (CA::Primaries)(CA::Primaries::PrimariesOther + 1);
+    CA::MatrixCoeffs unmappedMatrixCoeffs = (CA::MatrixCoeffs)(CA::MatrixOther + 1);
+    int32_t colorStandard =
+            ColorUtils::wrapColorAspectsIntoColorStandard(unmappedPrimaries, CA::MatrixUnspecified);
+    EXPECT_EQ(colorStandard, ColorUtils::kColorStandardUnspecified)
+            << "Standard unspecified expected";
+    colorStandard =
+            ColorUtils::wrapColorAspectsIntoColorStandard(CA::PrimariesOther, unmappedMatrixCoeffs);
+    EXPECT_EQ(colorStandard, ColorUtils::kColorStandardUnspecified)
+            << "Standard unspecified expected";
+    colorStandard = ColorUtils::wrapColorAspectsIntoColorStandard(CA::PrimariesBT601_6_525,
+                                                                  CA::MatrixBT2020);
+    EXPECT_GE(colorStandard, ColorUtils::kColorStandardExtendedStart)
+            << "Standard greater than extended start expected";
+    unmappedPrimaries = (CA::Primaries)(CA::Primaries::PrimariesBT2020 + 1);
+    unmappedMatrixCoeffs = (CA::MatrixCoeffs)(CA::MatrixBT2020Constant + 1);
+    colorStandard =
+            ColorUtils::wrapColorAspectsIntoColorStandard(unmappedPrimaries, unmappedMatrixCoeffs);
+    EXPECT_GE(colorStandard, ColorUtils::kColorStandardExtendedStart)
+            << "Standard greater than extended start expected";
+
+    CA aspects;
+    int32_t colorRange = -1;
+    colorStandard = -1;
+    int32_t colorTransfer = -1;
+    aspects.mPrimaries = (CA::Primaries)(CA::Primaries::PrimariesOther + 1);
+    status_t status = ColorUtils::convertCodecColorAspectsToPlatformAspects(
+            aspects, &colorRange, &colorStandard, &colorTransfer);
+    EXPECT_NE(status, OK) << "invalid colorAspects value accepted";
+
+    int32_t colorPrimaries = -1;
+    colorTransfer = -1;
+    int32_t colorMatrixCoeffs = -1;
+    bool fullRange = false;
+    aspects.mPrimaries = CA::PrimariesOther;
+    aspects.mTransfer = CA::TransferOther;
+    aspects.mMatrixCoeffs = CA::MatrixOther;
+    ColorUtils::convertCodecColorAspectsToIsoAspects(aspects, &colorPrimaries, &colorTransfer,
+                                                     &colorMatrixCoeffs, &fullRange);
+    CA returnedAspects;
+    ColorUtils::convertIsoColorAspectsToCodecAspects(colorPrimaries, colorTransfer,
+                                                     colorMatrixCoeffs, fullRange, returnedAspects);
+    EXPECT_EQ(returnedAspects.mPrimaries, CA::PrimariesUnspecified)
+            << "expected unspecified Primaries";
+    EXPECT_EQ(returnedAspects.mTransfer, CA::TransferUnspecified)
+            << "expected unspecified Transfer";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, CA::MatrixUnspecified)
+            << "expected unspecified MatrixCoeffs";
+
+    // invalid values, other value equals 0xFF
+    colorPrimaries = CA::PrimariesOther;
+    colorTransfer = CA::TransferOther;
+    colorMatrixCoeffs = CA::MatrixOther;
+    fullRange = false;
+    memset(&returnedAspects, 0, sizeof(returnedAspects));
+    ColorUtils::convertIsoColorAspectsToCodecAspects(colorPrimaries, colorTransfer,
+                                                     colorMatrixCoeffs, fullRange, returnedAspects);
+    EXPECT_EQ(returnedAspects.mPrimaries, CA::PrimariesUnspecified)
+            << "expected unspecified Primaries";
+    EXPECT_EQ(returnedAspects.mTransfer, CA::TransferUnspecified)
+            << "expected unspecified Transfer";
+    EXPECT_EQ(returnedAspects.mMatrixCoeffs, CA::MatrixUnspecified)
+            << "expected unspecified MatrixCoeffs";
+
+    CA::Primaries primaries = CA::PrimariesUnspecified;
+    CA::MatrixCoeffs matrixCoeffs = CA::MatrixUnspecified;
+    status = ColorUtils::unwrapColorAspectsFromColorStandard(ColorUtils::kColorStandardVendorStart,
+                                                             &primaries, &matrixCoeffs);
+    EXPECT_EQ(status, OK) << "unwrapping aspects from color standard failed";
+
+    primaries = CA::PrimariesUnspecified;
+    matrixCoeffs = CA::MatrixUnspecified;
+    status = ColorUtils::unwrapColorAspectsFromColorStandard(
+            ColorUtils::kColorStandardVendorStart * 4, &primaries, &matrixCoeffs);
+    EXPECT_NE(status, OK) << "unwrapping aspects from color standard failed";
+
+    colorRange = ColorUtils::wrapColorAspectsIntoColorRange((CA::Range)(CA::RangeOther + 1));
+    EXPECT_EQ(colorRange, ColorUtils::kColorRangeUnspecified) << "expected unspecified color range";
+
+    CA::Range range;
+    status = ColorUtils::unwrapColorAspectsFromColorRange(
+            ColorUtils::kColorRangeVendorStart + CA::RangeOther + 1, &range);
+    EXPECT_NE(status, OK) << "invalid range value accepted";
+    EXPECT_EQ(range, CA::RangeOther) << "returned unexpected range value";
+
+    colorTransfer =
+            ColorUtils::wrapColorAspectsIntoColorTransfer((CA::Transfer)(CA::TransferOther + 1));
+    EXPECT_EQ(colorTransfer, ColorUtils::kColorTransferUnspecified)
+            << "expected unspecified color transfer";
+
+    CA::Transfer transfer;
+    status = ColorUtils::unwrapColorAspectsFromColorTransfer(
+            ColorUtils::kColorTransferVendorStart + CA::TransferOther + 1, &transfer);
+    EXPECT_NE(status, OK) << "invalid transfer value accepted";
+    EXPECT_EQ(transfer, CA::TransferOther) << "expected other color transfer";
+}
+
+TEST(ColorUtilsUnitTest, HDRInfoSanityTest) {
+    HDRStaticInfo hdrInfo;
+    sp<AMessage> format = new AMessage();
+    ASSERT_NE(format, nullptr) << "failed to create AMessage";
+
+    bool boolStatus = ColorUtils::getHDRStaticInfoFromFormat(format, &hdrInfo);
+    EXPECT_FALSE(boolStatus) << "HDRStaticInfo should not be present";
+
+    sp<ABuffer> invalidSizeHDRInfoBuffer = new ABuffer(kHDRBufferSize - 1);
+    ASSERT_NE(invalidSizeHDRInfoBuffer, nullptr) << "failed to create ABuffer";
+    format->setBuffer(KEY_HDR_STATIC_INFO, invalidSizeHDRInfoBuffer);
+    memset(&hdrInfo, 0, sizeof(hdrInfo));
+    boolStatus = ColorUtils::getHDRStaticInfoFromFormat(format, &hdrInfo);
+    EXPECT_FALSE(boolStatus) << "incorrect HDRStaticInfo buffer accepted";
+
+    sp<ABuffer> invalidHDRInfoBuffer = new ABuffer(kHDRBufferSize);
+    ASSERT_NE(invalidHDRInfoBuffer, nullptr) << "failed to create ABuffer";
+    uint8_t *data = invalidHDRInfoBuffer->data();
+    *data = HDRStaticInfo::kType1 + 1;
+    format->setBuffer(KEY_HDR_STATIC_INFO, invalidHDRInfoBuffer);
+    memset(&hdrInfo, 0, sizeof(hdrInfo));
+    boolStatus = ColorUtils::getHDRStaticInfoFromFormat(format, &hdrInfo);
+    EXPECT_FALSE(boolStatus) << "incorrect HDRStaticInfo buffer accepted";
+
+    CA aspects;
+    format->setInt32(KEY_COLOR_RANGE, ColorUtils::kColorRangeVendorStart + CA::RangeOther + 1);
+    format->setInt32(KEY_COLOR_STANDARD, CA::Standard::StandardBT709);
+    format->setInt32(KEY_COLOR_TRANSFER, CA::Transfer::TransferLinear);
+    ColorUtils::getColorAspectsFromFormat(format, aspects);
+    EXPECT_EQ(aspects.mRange, CA::RangeOther) << "unexpected range";
+}
+
+TEST(ColorUtilsUnitTest, DataSpaceSanityTest) {
+    CA aspects;
+    aspects.mRange = CA::RangeUnspecified;
+    aspects.mPrimaries = CA::PrimariesUnspecified;
+    aspects.mMatrixCoeffs = CA::MatrixUnspecified;
+    aspects.mTransfer = CA::TransferUnspecified;
+    android_dataspace dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true);
+    EXPECT_EQ(dataSpace, 0) << "expected invalid dataspace";
+    aspects.mPrimaries = CA::PrimariesUnspecified;
+    aspects.mMatrixCoeffs = CA::MatrixBT2020Constant;
+    dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true);
+    EXPECT_NE(dataSpace, 0) << "unexpected value";
+}
+
+INSTANTIATE_TEST_SUITE_P(ColorUtilsUnitTest, ColorRangeTest,
+                         ::testing::Values(
+                                 // ColorRange
+                                 CA::Range::RangeLimited, CA::Range::RangeFull,
+                                 CA::Range::RangeUnspecified, CA::Range::RangeOther));
+
+INSTANTIATE_TEST_SUITE_P(ColorUtilsUnitTest, ColorTransferTest,
+                         ::testing::Values(
+                                 // ColorTransfer
+                                 CA::Transfer::TransferUnspecified, CA::Transfer::TransferLinear,
+                                 CA::Transfer::TransferSRGB, CA::Transfer::TransferSMPTE170M,
+                                 CA::Transfer::TransferGamma22, CA::Transfer::TransferGamma28,
+                                 CA::Transfer::TransferST2084, CA::Transfer::TransferHLG,
+                                 CA::Transfer::TransferSMPTE240M, CA::Transfer::TransferXvYCC,
+                                 CA::Transfer::TransferBT1361, CA::Transfer::TransferST428,
+                                 CA::Transfer::TransferOther));
+
+INSTANTIATE_TEST_SUITE_P(
+        ColorUtilsUnitTest, ColorStandardTest,
+        ::testing::Values(
+                // Primaries, MatrixCoeffs
+                std::make_pair(CA::Primaries::PrimariesUnspecified,
+                               CA::MatrixCoeffs::MatrixUnspecified),
+                std::make_pair(CA::Primaries::PrimariesBT709_5,
+                               CA::MatrixCoeffs::MatrixBT709_5),
+                std::make_pair(CA::Primaries::PrimariesBT601_6_625,
+                               CA::MatrixCoeffs::MatrixBT601_6),
+                std::make_pair(CA::Primaries::PrimariesBT601_6_625,
+                               CA::MatrixCoeffs::MatrixBT709_5),
+                std::make_pair(CA::Primaries::PrimariesBT601_6_525,
+                               CA::MatrixCoeffs::MatrixBT601_6),
+                std::make_pair(CA::Primaries::PrimariesBT601_6_525,
+                               CA::MatrixCoeffs::MatrixSMPTE240M),
+                std::make_pair(CA::Primaries::PrimariesBT2020,
+                               CA::MatrixCoeffs::MatrixBT2020),
+                std::make_pair(CA::Primaries::PrimariesBT2020,
+                               CA::MatrixCoeffs::MatrixBT2020Constant),
+                std::make_pair(CA::Primaries::PrimariesBT470_6M,
+                               CA::MatrixCoeffs::MatrixBT470_6M),
+                std::make_pair(CA::Primaries::PrimariesGenericFilm,
+                               CA::MatrixCoeffs::MatrixBT2020)));
+
+INSTANTIATE_TEST_SUITE_P(
+        ColorUtilsUnitTest, ColorAspectsTest,
+        ::testing::Values(
+                // Primaries, ColorTransfer, MatrixCoeffs, ColorRange, ColorStandard
+                std::make_tuple(CA::Primaries::PrimariesUnspecified,
+                                CA::Transfer::TransferUnspecified,
+                                CA::MatrixCoeffs::MatrixUnspecified, CA::Range::RangeFull,
+                                CA::Standard::StandardUnspecified),
+                std::make_tuple(CA::Primaries::PrimariesBT709_5, CA::Transfer::TransferLinear,
+                                CA::MatrixCoeffs::MatrixBT709_5, CA::Range::RangeFull,
+                                CA::Standard::StandardBT709),
+                std::make_tuple(CA::Primaries::PrimariesBT601_6_625, CA::Transfer::TransferSRGB,
+                                CA::MatrixCoeffs::MatrixBT601_6, CA::Range::RangeFull,
+                                CA::Standard::StandardUnspecified),
+                std::make_tuple(CA::Primaries::PrimariesBT601_6_625,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT709_5,
+                                CA::Range::RangeFull, CA::Standard::StandardUnspecified),
+                std::make_tuple(CA::Primaries::PrimariesBT601_6_525, CA::Transfer::TransferGamma22,
+                                CA::MatrixCoeffs::MatrixBT601_6, CA::Range::RangeFull,
+                                CA::Standard::StandardUnspecified),
+                std::make_tuple(CA::Primaries::PrimariesBT601_6_525, CA::Transfer::TransferGamma28,
+                                CA::MatrixCoeffs::MatrixSMPTE240M, CA::Range::RangeFull,
+                                CA::Standard::StandardBT470M),
+                std::make_tuple(CA::Primaries::PrimariesBT2020, CA::Transfer::TransferST2084,
+                                CA::MatrixCoeffs::MatrixBT2020, CA::Range::RangeFull,
+                                CA::Standard::StandardBT601_525),
+                std::make_tuple(CA::Primaries::PrimariesBT2020, CA::Transfer::TransferHLG,
+                                CA::MatrixCoeffs::MatrixBT2020Constant, CA::Range::RangeFull,
+                                CA::Standard::StandardBT601_525),
+                std::make_tuple(CA::Primaries::PrimariesBT470_6M, CA::Transfer::TransferLinear,
+                                CA::MatrixCoeffs::MatrixBT470_6M, CA::Range::RangeFull,
+                                CA::Standard::StandardUnspecified),
+                std::make_tuple(CA::Primaries::PrimariesGenericFilm, CA::Transfer::TransferLinear,
+                                CA::MatrixCoeffs::MatrixBT2020, CA::Range::RangeFull,
+                                CA::Standard::StandardBT601_625)));
+
+INSTANTIATE_TEST_SUITE_P(
+        ColorUtilsUnitTest, IsoToPlatformAspectsTest,
+        ::testing::Values(
+                // Primaries, Transfer, MatrixCoeffs, Standard, Transfer
+                std::make_tuple(CA::PrimariesUnspecified, CA::TransferUnspecified,
+                                CA::MatrixUnspecified, ColorUtils::kColorStandardUnspecified,
+                                ColorUtils::kColorTransferUnspecified),
+                std::make_tuple(CA::PrimariesBT709_5, CA::TransferLinear, CA::MatrixBT709_5,
+                                ColorUtils::kColorStandardBT709, ColorUtils::kColorTransferLinear),
+                std::make_tuple(CA::PrimariesBT601_6_625, CA::TransferSRGB, CA::MatrixBT601_6,
+                                ColorUtils::kColorStandardBT601_625,
+                                ColorUtils::kColorTransferSRGB),
+                std::make_tuple(CA::PrimariesBT601_6_625, CA::TransferSMPTE170M, CA::MatrixBT709_5,
+                                ColorUtils::kColorStandardBT601_625_Unadjusted,
+                                ColorUtils::kColorTransferSMPTE_170M),
+                std::make_tuple(CA::PrimariesBT601_6_525, CA::TransferGamma22, CA::MatrixBT601_6,
+                                ColorUtils::kColorStandardBT601_525,
+                                ColorUtils::kColorTransferGamma22),
+                std::make_tuple(CA::PrimariesBT601_6_525, CA::TransferGamma28, CA::MatrixSMPTE240M,
+                                ColorUtils::kColorStandardBT601_525_Unadjusted,
+                                ColorUtils::kColorTransferGamma28),
+                std::make_tuple(CA::PrimariesBT2020, CA::TransferST2084, CA::MatrixBT2020,
+                                ColorUtils::kColorStandardBT2020, ColorUtils::kColorTransferST2084),
+                std::make_tuple(CA::PrimariesBT2020, CA::TransferHLG, CA::MatrixBT2020Constant,
+                                ColorUtils::kColorStandardBT2020Constant,
+                                ColorUtils::kColorTransferHLG),
+                std::make_tuple(CA::PrimariesBT470_6M, CA::TransferUnspecified, CA::MatrixBT470_6M,
+                                ColorUtils::kColorStandardBT470M,
+                                ColorUtils::kColorTransferUnspecified),
+                std::make_tuple(CA::PrimariesGenericFilm, CA::TransferLinear, CA::MatrixBT2020,
+                                ColorUtils::kColorStandardFilm, ColorUtils::kColorTransferLinear)));
+
+INSTANTIATE_TEST_SUITE_P(
+        ColorUtilsUnitTest, DefaultColorAspectsTest,
+        ::testing::Values(
+                // Width, Height, Primaries, MatrixCoeffs
+                std::make_tuple(3840, 3840, CA::PrimariesBT2020, CA::MatrixBT2020),
+                std::make_tuple(720, 576, CA::PrimariesBT601_6_625, CA::MatrixBT601_6),
+                std::make_tuple(480, 360, CA::PrimariesBT601_6_525, CA::MatrixBT601_6),
+                std::make_tuple(480, 1920, CA::PrimariesBT709_5, CA::MatrixBT709_5)));
+
+INSTANTIATE_TEST_SUITE_P(
+        ColorUtilsUnitTest, DataSpaceTest,
+        ::testing::Values(
+                // ColorRange, Primaries, ColorTransfer, MatrixCoeffs, v0_android_dataspace,
+                // android_dataspace
+                std::make_tuple(CA::Range::RangeFull, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSRGB, CA::MatrixCoeffs::MatrixBT709_5,
+                                HAL_DATASPACE_V0_SRGB, HAL_DATASPACE_SRGB),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT709_5,
+                                HAL_DATASPACE_V0_BT709, HAL_DATASPACE_BT709),
+                std::make_tuple(CA::Range::RangeFull, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferLinear, CA::MatrixCoeffs::MatrixBT709_5,
+                                HAL_DATASPACE_V0_SRGB_LINEAR, HAL_DATASPACE_SRGB_LINEAR),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_525,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT601_6,
+                                HAL_DATASPACE_V0_BT601_525, HAL_DATASPACE_BT601_525),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_625,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT601_6,
+                                HAL_DATASPACE_V0_BT601_625, HAL_DATASPACE_BT601_625),
+                std::make_tuple(CA::Range::RangeFull, CA::Primaries::PrimariesBT601_6_625,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT601_6,
+                                HAL_DATASPACE_V0_JFIF, HAL_DATASPACE_JFIF),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT470_6M,
+                                HAL_DATASPACE_V0_BT601_625, HAL_DATASPACE_BT601_625),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT601_6,
+                                HAL_DATASPACE_V0_BT601_625, HAL_DATASPACE_BT601_625),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixSMPTE240M,
+                                HAL_DATASPACE_V0_BT709, HAL_DATASPACE_BT709),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT2020,
+                                HAL_DATASPACE_V0_BT709, HAL_DATASPACE_BT709),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT709_5,
+                                CA::Transfer::TransferSMPTE170M,
+                                CA::MatrixCoeffs::MatrixBT2020Constant, HAL_DATASPACE_V0_BT601_525,
+                                HAL_DATASPACE_BT601_525),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_625,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT470_6M,
+                                HAL_DATASPACE_V0_BT601_625, HAL_DATASPACE_BT601_625),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_625,
+                                CA::Transfer::TransferSMPTE170M,
+                                CA::MatrixCoeffs::MatrixBT2020Constant, HAL_DATASPACE_V0_BT601_525,
+                                HAL_DATASPACE_BT601_525),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_525,
+                                CA::Transfer::TransferSMPTE170M, CA::MatrixCoeffs::MatrixBT470_6M,
+                                HAL_DATASPACE_V0_BT601_525, HAL_DATASPACE_BT601_525),
+                std::make_tuple(CA::Range::RangeLimited, CA::Primaries::PrimariesBT601_6_525,
+                                CA::Transfer::TransferSMPTE170M,
+                                CA::MatrixCoeffs::MatrixBT2020Constant, HAL_DATASPACE_V0_BT601_525,
+                                HAL_DATASPACE_BT601_525)));
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index db37fe9..e34504d 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -5,7 +5,9 @@
     srcs: ["ID3.cpp"],
 
     header_libs: [
-        "libmedia_headers",
+        "libmedia_datasource_headers",
+        "libstagefright_foundation_headers",
+        "libstagefright_headers",
         "media_ndk_headers",
     ],
 
@@ -19,6 +21,12 @@
         ],
         cfi: true,
     },
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 //###############################################################################
diff --git a/media/libstagefright/id3/test/AndroidTest.xml b/media/libstagefright/id3/test/AndroidTest.xml
index 6c6697d..d6ea470 100644
--- a/media/libstagefright/id3/test/AndroidTest.xml
+++ b/media/libstagefright/id3/test/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="ID3Test->/data/local/tmp/ID3Test" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test-1.1.zip?unzip=true"
             value="/data/local/tmp/ID3TestRes/" />
     </target_preparer>
 
diff --git a/media/libstagefright/id3/test/ID3Test.cpp b/media/libstagefright/id3/test/ID3Test.cpp
index cd5cd9e..8db83cb 100644
--- a/media/libstagefright/id3/test/ID3Test.cpp
+++ b/media/libstagefright/id3/test/ID3Test.cpp
@@ -51,7 +51,7 @@
     while (!it.done()) {
         String8 id;
         it.getID(&id);
-        ASSERT_GT(id.length(), 0) << "No ID tag found! \n";
+        ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
         ALOGV("Found ID tag: %s\n", String8(id).c_str());
         it.next();
     }
@@ -66,8 +66,8 @@
     DataSourceHelper helper(file->wrap());
     ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
-    ASSERT_TRUE(tag.version() >= versionNumber)
-            << "Expected version: " << tag.version() << " Found version: " << versionNumber;
+    ASSERT_EQ(tag.version(), versionNumber)
+            << "Found version: " << tag.version() << " Expected version: " << versionNumber;
 }
 
 TEST_P(ID3textTagTest, TextTagTest) {
@@ -81,17 +81,34 @@
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
     int countTextFrames = 0;
     ID3::Iterator it(tag, nullptr);
-    while (!it.done()) {
-        String8 id;
-        it.getID(&id);
-        ASSERT_GT(id.length(), 0);
-        if (id[0] == 'T') {
-            String8 text;
-            countTextFrames++;
-            it.getString(&text);
-            ALOGV("Found text frame %s : %s \n", id.string(), text.string());
+    if (tag.version() != ID3::ID3_V1 && tag.version() != ID3::ID3_V1_1) {
+        while (!it.done()) {
+            String8 id;
+            it.getID(&id);
+            ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
+            if (id[0] == 'T') {
+                String8 text;
+                countTextFrames++;
+                it.getString(&text);
+                ALOGV("Found text frame %s : %s \n", id.string(), text.string());
+            }
+            it.next();
         }
-        it.next();
+    } else {
+        while (!it.done()) {
+            String8 id;
+            String8 text;
+            it.getID(&id);
+            ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
+            it.getString(&text);
+            // if the tag has a value
+            if (strcmp(text.string(), "")) {
+                countTextFrames++;
+                ALOGV("ID: %s\n", id.c_str());
+                ALOGV("Text string: %s\n", text.string());
+            }
+            it.next();
+        }
     }
     ASSERT_EQ(countTextFrames, numTextFrames)
             << "Expected " << numTextFrames << " text frames, found " << countTextFrames;
@@ -114,7 +131,7 @@
         if (data) {
             ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
         }
-        ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
+        ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
     } else {
         ASSERT_EQ(data, nullptr) << "Found album art when expected none!";
     }
@@ -137,7 +154,7 @@
     while (!it.done()) {
         String8 id;
         it.getID(&id);
-        ASSERT_GT(id.length(), 0);
+        ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
         // Check if the tag is an "APIC/PIC" tag.
         if (String8(id) == "APIC" || String8(id) == "PIC") {
             count++;
@@ -150,7 +167,7 @@
                 hexdump(data, dataSize > 128 ? 128 : dataSize);
 #endif
             }
-            ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
+            ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
         }
         it.next();
     }
@@ -159,56 +176,67 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest,
-                         ::testing::Values("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_5mins.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3",
-                                           "bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3"));
+                         ::testing::Values("bbb_1sec_v23.mp3",
+                                           "bbb_1sec_1_image.mp3",
+                                           "bbb_1sec_2_image.mp3",
+                                           "bbb_2sec_v24.mp3",
+                                           "bbb_2sec_1_image.mp3",
+                                           "bbb_2sec_2_image.mp3",
+                                           "bbb_2sec_largeSize.mp3",
+                                           "bbb_1sec_v23_3tags.mp3",
+                                           "bbb_1sec_v1_5tags.mp3",
+                                           "bbb_2sec_v24_unsynchronizedOneFrame.mp3",
+                                           "bbb_2sec_v24_unsynchronizedAllFrames.mp3"));
 
 INSTANTIATE_TEST_SUITE_P(
         id3TestAll, ID3versionTest,
-        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 4),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 4)));
+        ::testing::Values(make_pair("bbb_1sec_v23.mp3", ID3::ID3_V2_3),
+                          make_pair("bbb_1sec_1_image.mp3", ID3::ID3_V2_3),
+                          make_pair("bbb_1sec_2_image.mp3", ID3::ID3_V2_3),
+                          make_pair("bbb_2sec_v24.mp3", ID3::ID3_V2_4),
+                          make_pair("bbb_2sec_1_image.mp3", ID3::ID3_V2_4),
+                          make_pair("bbb_2sec_2_image.mp3", ID3::ID3_V2_4),
+                          make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4),
+                          make_pair("bbb_1sec_v23_3tags.mp3", ID3::ID3_V2_3),
+                          make_pair("bbb_1sec_v1_5tags.mp3", ID3::ID3_V1_1),
+                          make_pair("bbb_1sec_v1_3tags.mp3", ID3::ID3_V1_1),
+                          make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", ID3::ID3_V2_4),
+                          make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", ID3::ID3_V2_4)));
 
 INSTANTIATE_TEST_SUITE_P(
         id3TestAll, ID3textTagTest,
-        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 5)));
+        ::testing::Values(
+                make_pair("bbb_1sec_v23.mp3", 1),
+                make_pair("bbb_1sec_1_image.mp3", 1),
+                make_pair("bbb_1sec_2_image.mp3", 1),
+                make_pair("bbb_2sec_v24.mp3", 1),
+                make_pair("bbb_2sec_1_image.mp3", 1),
+                make_pair("bbb_2sec_2_image.mp3", 1),
+                make_pair("bbb_2sec_largeSize.mp3", 1),
+                make_pair("bbb_1sec_v23_3tags.mp3", 3),
+                make_pair("bbb_1sec_v1_5tags.mp3", 5),
+                make_pair("bbb_1sec_v1_3tags.mp3", 3),
+                make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3),
+                make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", 3)));
 
-INSTANTIATE_TEST_SUITE_P(
-        id3TestAll, ID3albumArtTest,
-        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", false),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", true),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", true),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", false),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", true),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", true),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", true)));
+INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest,
+                         ::testing::Values(make_pair("bbb_1sec_v23.mp3", false),
+                                           make_pair("bbb_1sec_1_image.mp3", true),
+                                           make_pair("bbb_1sec_2_image.mp3", true),
+                                           make_pair("bbb_2sec_v24.mp3", false),
+                                           make_pair("bbb_2sec_1_image.mp3", true),
+                                           make_pair("bbb_2sec_2_image.mp3", true),
+                                           make_pair("bbb_2sec_largeSize.mp3", true),
+                                           make_pair("bbb_1sec_v1_5tags.mp3", false)));
 
-INSTANTIATE_TEST_SUITE_P(
-        id3TestAll, ID3multiAlbumArtTest,
-        ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 0),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 2),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 2),
-                          make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 3)));
+INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3multiAlbumArtTest,
+                         ::testing::Values(make_pair("bbb_1sec_v23.mp3", 0),
+                                           make_pair("bbb_2sec_v24.mp3", 0),
+                                           make_pair("bbb_1sec_1_image.mp3", 1),
+                                           make_pair("bbb_2sec_1_image.mp3", 1),
+                                           make_pair("bbb_1sec_2_image.mp3", 2),
+                                           make_pair("bbb_2sec_2_image.mp3", 2),
+                                           make_pair("bbb_2sec_largeSize.mp3", 3)));
 
 int main(int argc, char **argv) {
     gEnv = new ID3TestEnvironment();
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 83e92b9..105e7f7 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -499,6 +499,7 @@
     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
     status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels);
 
+    status_t setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels);
     status_t setupFlacCodec(
             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
             AudioEncoding encoding);
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index fbb2d0c..5d697f7 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -1,12 +1,11 @@
-cc_library_static {
-    name: "libstagefright_mpeg2support",
+cc_defaults {
+    name: "libstagefright_mpeg2support_defaults",
 
     srcs: [
         "AnotherPacketSource.cpp",
         "ATSParser.cpp",
         "CasManager.cpp",
         "ESQueue.cpp",
-        "HlsSampleDecryptor.cpp",
     ],
 
     include_dirs: [
@@ -28,7 +27,6 @@
     },
 
     shared_libs: [
-        "libcrypto",
         "libhidlmemory",
         "android.hardware.cas.native@1.0",
         "android.hidl.memory@1.0",
@@ -36,9 +34,10 @@
     ],
 
     header_libs: [
-        "libmedia_headers",
+        "libmedia_datasource_headers",
         "libaudioclient_headers",
         "media_ndk_headers",
+        "libstagefright_foundation_headers",
     ],
 
     export_include_dirs: ["."],
@@ -48,4 +47,39 @@
     ],
 
     min_sdk_version: "29",
+
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+
+cc_library_static {
+    name: "libstagefright_mpeg2support",
+    defaults: [
+        "libstagefright_mpeg2support_defaults",
+    ],
+    cflags: [
+        "-DENABLE_CRYPTO",
+    ],
+    shared_libs: [
+        "libcrypto",
+    ],
+    srcs: [
+        "HlsSampleDecryptor.cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libstagefright_mpeg2support_nocrypto",
+    defaults: [
+        "libstagefright_mpeg2support_defaults",
+    ],
+    apex_available: [
+        "com.android.media",
+    ],
 }
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 4bb21fa..801dba1 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -36,7 +36,7 @@
 #include <inttypes.h>
 #include <netinet/in.h>
 
-#ifndef __ANDROID_APEX__
+#ifdef ENABLE_CRYPTO
 #include "HlsSampleDecryptor.h"
 #endif
 
@@ -55,10 +55,10 @@
     // Create the decryptor anyway since we don't know the use-case unless key is provided
     // Won't decrypt if key info not available (e.g., scanner/extractor just parsing ts files)
     mSampleDecryptor = isSampleEncrypted() ?
-#ifdef __ANDROID_APEX__
-        new SampleDecryptor
-#else
+#ifdef ENABLE_CRYPTO
         new HlsSampleDecryptor
+#else
+        new SampleDecryptor
 #endif
         : NULL;
 }
@@ -172,29 +172,26 @@
         return 0;
     }
 
-    unsigned bsmod __unused = bits.getBits(3);
+    bits.skipBits(3); // bsmod
     unsigned acmod = bits.getBits(3);
-    unsigned cmixlev __unused = 0;
-    unsigned surmixlev __unused = 0;
-    unsigned dsurmod __unused = 0;
 
     if ((acmod & 1) > 0 && acmod != 1) {
         if (bits.numBitsLeft() < 2) {
             return 0;
         }
-        cmixlev = bits.getBits(2);
+        bits.skipBits(2); //cmixlev
     }
     if ((acmod & 4) > 0) {
         if (bits.numBitsLeft() < 2) {
             return 0;
         }
-        surmixlev = bits.getBits(2);
+        bits.skipBits(2); //surmixlev
     }
     if (acmod == 2) {
         if (bits.numBitsLeft() < 2) {
             return 0;
         }
-        dsurmod = bits.getBits(2);
+        bits.skipBits(2); //dsurmod
     }
 
     if (bits.numBitsLeft() < 1) {
@@ -269,7 +266,7 @@
         samplingRate = samplingRateTable2[fscod2];
     } else {
         samplingRate = samplingRateTable[fscod];
-        unsigned numblkscod __unused = bits.getBits(2);
+        bits.skipBits(2); // numblkscod
     }
 
     unsigned acmod = bits.getBits(3);
@@ -1087,7 +1084,7 @@
     }
     unsigned numAUs = bits.getBits(8);
     bits.skipBits(8);
-    unsigned quantization_word_length __unused = bits.getBits(2);
+    bits.skipBits(2); // quantization_word_length
     unsigned audio_sampling_frequency = bits.getBits(3);
     unsigned num_channels = bits.getBits(3);
 
diff --git a/media/libstagefright/mpeg2ts/test/Android.bp b/media/libstagefright/mpeg2ts/test/Android.bp
new file mode 100644
index 0000000..4e4832a
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Android.bp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test{
+    name: "Mpeg2tsUnitTest",
+    gtest: true,
+
+    srcs: [
+        "Mpeg2tsUnitTest.cpp"
+    ],
+
+    shared_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.token@1.0-utils",
+        "android.hidl.allocator@1.0",
+        "libcrypto",
+        "libhidlbase",
+        "libhidlmemory",
+        "liblog",
+        "libmedia",
+        "libbinder",
+        "libbinder_ndk",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libdatasource",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libstagefright_metadatautils",
+        "libstagefright_mpeg2support",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/",
+        "frameworks/av/media/libstagefright/",
+    ],
+
+    header_libs: [
+        "libmedia_headers",
+        "libaudioclient_headers",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/mpeg2ts/test/AndroidTest.xml b/media/libstagefright/mpeg2ts/test/AndroidTest.xml
new file mode 100644
index 0000000..ac1294d
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for Mpeg2ts unit tests">
+    <option name="test-suite-tag" value="Mpeg2tsUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="Mpeg2tsUnitTest->/data/local/tmp/Mpeg2tsUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.zip?unzip=true"
+            value="/data/local/tmp/Mpeg2tsUnitTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="Mpeg2tsUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/Mpeg2tsUnitTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
new file mode 100644
index 0000000..79c233b
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 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 "Mpeg2tsUnitTest"
+
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/stat.h>
+
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include "mpeg2ts/ATSParser.h"
+#include "mpeg2ts/AnotherPacketSource.h"
+
+#include "Mpeg2tsUnitTestEnvironment.h"
+
+constexpr size_t kTSPacketSize = 188;
+constexpr uint16_t kPIDMask = 0x1FFF;
+// Max value of PID which is also used for Null packets
+constexpr uint16_t kPIDMaxValue = 8191;
+constexpr uint8_t kTSSyncByte = 0x47;
+constexpr uint8_t kVideoPresent = 0x01;
+constexpr uint8_t kAudioPresent = 0x02;
+constexpr uint8_t kMetaDataPresent = 0x04;
+
+static Mpeg2tsUnitTestEnvironment *gEnv = nullptr;
+
+using namespace android;
+
+class Mpeg2tsUnitTest
+    : public ::testing ::TestWithParam<
+              tuple</*fileName*/ string, /*sourceType*/ char, /*numSource*/ uint16_t>> {
+  public:
+    Mpeg2tsUnitTest()
+        : mInputBuffer(nullptr), mSource(nullptr), mFpInput(nullptr), mParser(nullptr) {}
+
+    ~Mpeg2tsUnitTest() {
+        if (mInputBuffer) free(mInputBuffer);
+        if (mFpInput) fclose(mFpInput);
+        mSource.clear();
+    }
+
+    void SetUp() override {
+        mOffset = 0;
+        mNumDataSource = 0;
+        tuple<string, char, uint16_t> params = GetParam();
+        char sourceType = get<1>(params);
+        /* mSourceType = 0b x x x x x M A V
+                                     /  |  \
+                            metaData  audio  video */
+        mMediaType = (sourceType & 0x07);
+        mNumDataSource = get<2>(params);
+        string inputFile = gEnv->getRes() + get<0>(params);
+        mFpInput = fopen(inputFile.c_str(), "rb");
+        ASSERT_NE(mFpInput, nullptr) << "Failed to open file: " << inputFile;
+
+        struct stat buf;
+        int8_t err = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+        long fileSize = buf.st_size;
+        mTotalPackets = fileSize / kTSPacketSize;
+        int32_t fd = fileno(mFpInput);
+        ASSERT_GE(fd, 0) << "Failed to get the integer file descriptor";
+
+        mSource = new FileSource(dup(fd), 0, buf.st_size);
+        ASSERT_NE(mSource, nullptr) << "Failed to get the data source!";
+
+        mParser = new ATSParser();
+        ASSERT_NE(mParser, nullptr) << "Unable to create ATS parser!";
+        mInputBuffer = (uint8_t *)malloc(kTSPacketSize);
+        ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate memory for TS packet!";
+    }
+
+    uint64_t mOffset;
+    uint64_t mTotalPackets;
+    uint16_t mNumDataSource;
+
+    int8_t mMediaType;
+
+    uint8_t *mInputBuffer;
+    string mInputFile;
+    sp<DataSource> mSource;
+    FILE *mFpInput;
+    ATSParser *mParser;
+};
+
+TEST_P(Mpeg2tsUnitTest, MediaInfoTest) {
+    bool videoFound = false;
+    bool audioFound = false;
+    bool metaDataFound = false;
+    bool syncPointPresent = false;
+
+    int16_t totalDataSource = 0;
+    int32_t val32 = 0;
+    uint8_t numDataSource = 0;
+    uint8_t packet[kTSPacketSize];
+    ssize_t numBytesRead = -1;
+
+    ATSParser::SyncEvent event(mOffset);
+    static const ATSParser::SourceType mediaType[] = {ATSParser::VIDEO, ATSParser::AUDIO,
+                                                      ATSParser::META, ATSParser::NUM_SOURCE_TYPES};
+    const uint32_t nMediaTypes = sizeof(mediaType) / sizeof(mediaType[0]);
+
+    while ((numBytesRead = mSource->readAt(mOffset, packet, kTSPacketSize)) == kTSPacketSize) {
+        ASSERT_TRUE(packet[0] == kTSSyncByte) << "Sync byte error!";
+
+        // pid is 13 bits
+        uint16_t pid = (packet[1] + (packet[2] << 8)) & kPIDMask;
+        ASSERT_TRUE(pid <= kPIDMaxValue) << "Invalid PID: " << pid;
+
+        status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
+        ASSERT_EQ(err, (status_t)OK) << "Unable to feed TS packet!";
+
+        mOffset += numBytesRead;
+        for (int i = 0; i < nMediaTypes; i++) {
+            if (mParser->hasSource(mediaType[i])) {
+                switch (mediaType[i]) {
+                    case ATSParser::VIDEO:
+                        videoFound = true;
+                        break;
+                    case ATSParser::AUDIO:
+                        audioFound = true;
+                        break;
+                    case ATSParser::META:
+                        metaDataFound = true;
+                        break;
+                    case ATSParser::NUM_SOURCE_TYPES:
+                        numDataSource = 3;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        if (videoFound && audioFound && metaDataFound && (numDataSource == 3)) break;
+    }
+
+    for (int i = 0; i < nMediaTypes; i++) {
+        ATSParser::SourceType currentMediaType = mediaType[i];
+        if (mParser->hasSource(currentMediaType)) {
+            if (event.hasReturnedData()) {
+                syncPointPresent = true;
+                sp<AnotherPacketSource> syncPacketSource = event.getMediaSource();
+                ASSERT_NE(syncPacketSource, nullptr)
+                        << "Cannot get sync source for media type: " << currentMediaType;
+
+                status_t err = syncPacketSource->start();
+                ASSERT_EQ(err, (status_t)OK) << "Error returned while starting!";
+
+                sp<MetaData> format = syncPacketSource->getFormat();
+                ASSERT_NE(format, nullptr) << "Unable to get the format of the source packet!";
+
+                MediaBufferBase *buf;
+                syncPacketSource->read(&buf, nullptr);
+                ASSERT_NE(buf, nullptr) << "Failed to read sync packet source data";
+
+                MetaDataBase &inMeta = buf->meta_data();
+                bool status = inMeta.findInt32(kKeyIsSyncFrame, &val32);
+                ASSERT_EQ(status, true) << "Sync frame key is not set";
+
+                status = inMeta.findInt32(kKeyCryptoMode, &val32);
+                ASSERT_EQ(status, false) << "Invalid packet, found scrambled packets!";
+
+                err = syncPacketSource->stop();
+                ASSERT_EQ(err, (status_t)OK) << "Error returned while stopping!";
+            }
+            sp<AnotherPacketSource> packetSource = mParser->getSource(currentMediaType);
+            ASSERT_NE(packetSource, nullptr)
+                    << "Cannot get source for media type: " << currentMediaType;
+
+            status_t err = packetSource->start();
+            ASSERT_EQ(err, (status_t)OK) << "Error returned while starting!";
+            sp<MetaData> format = packetSource->getFormat();
+            ASSERT_NE(format, nullptr) << "Unable to get the format of the packet!";
+
+            err = packetSource->stop();
+            ASSERT_EQ(err, (status_t)OK) << "Error returned while stopping!";
+        }
+    }
+
+    ASSERT_EQ(videoFound, bool(mMediaType & kVideoPresent)) << "No Video packets found!";
+    ASSERT_EQ(audioFound, bool(mMediaType & kAudioPresent)) << "No Audio packets found!";
+    ASSERT_EQ(metaDataFound, bool(mMediaType & kMetaDataPresent)) << "No meta data found!";
+
+    if (videoFound || audioFound) {
+        ASSERT_TRUE(syncPointPresent) << "No sync points found for audio/video";
+    }
+
+    if (videoFound) totalDataSource += 1;
+    if (audioFound) totalDataSource += 1;
+    if (metaDataFound) totalDataSource += 1;
+
+    ASSERT_TRUE(totalDataSource == mNumDataSource)
+            << "Expected " << mNumDataSource << " data sources, found " << totalDataSource;
+    if (numDataSource == 3) {
+        ASSERT_EQ(numDataSource, mNumDataSource)
+                << "Expected " << mNumDataSource << " data sources, found " << totalDataSource;
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        infoTest, Mpeg2tsUnitTest,
+        ::testing::Values(make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", 0x01, 1),
+                          make_tuple("segment000001.ts", 0x03, 2),
+                          make_tuple("bbb_44100hz_2ch_128kbps_mp3_5mins.ts", 0x02, 1)));
+
+int32_t main(int argc, char **argv) {
+    gEnv = new Mpeg2tsUnitTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    uint8_t status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Mpeg2tsUnit Test Result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
new file mode 100644
index 0000000..9e41db7
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
+#define __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class Mpeg2tsUnitTestEnvironment : public::testing::Environment {
+  public:
+    Mpeg2tsUnitTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int Mpeg2tsUnitTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/mpeg2ts/test/README.md b/media/libstagefright/mpeg2ts/test/README.md
new file mode 100644
index 0000000..237ce72
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/README.md
@@ -0,0 +1,38 @@
+## Media Testing ##
+---
+#### Mpeg2TS Unit Test :
+The Mpeg2TS Unit Test Suite validates the functionality of the libraries present in Mpeg2TS.
+
+Run the following steps to build the test suite:
+```
+mmm frameworks/av/media/libstagefright/mpeg2ts/test/
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+
+adb push ${OUT}/data/nativetest64/Mpeg2tsUnitTest/Mpeg2tsUnitTest /data/local/tmp/
+
+To test 32-bit binary push binaries from nativetest.
+
+adb push ${OUT}/data/nativetest/Mpeg2tsUnitTest/Mpeg2tsUnitTest /data/local/tmp/
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.zip ).
+Download, unzip and push these files into device for testing.
+
+```
+adb push Mpeg2tsUnitTestRes/. /data/local/tmp/
+```
+
+usage: Mpeg2tsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/Mpeg2tsUnitTest -P /data/local/tmp/Mpeg2tsUnitTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest Mpeg2tsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index eef9ce3..eb15039 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -22,7 +22,7 @@
 #include <media/openmax/OMX_AsString.h>
 
 #include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
 #include <media/stagefright/omx/OmxGraphicBufferSource.h>
 
 #include <media/stagefright/omx/1.0/WOmxNode.h>
@@ -41,21 +41,21 @@
 constexpr size_t kMaxNodeInstances = (1 << 16);
 
 Omx::Omx() :
-    mMaster(new OMXMaster()),
+    mStore(new OMXStore()),
     mParser() {
     (void)mParser.parseXmlFilesInSearchDirs();
     (void)mParser.parseXmlPath(mParser.defaultProfilingResultsXmlPath);
 }
 
 Omx::~Omx() {
-    delete mMaster;
+    delete mStore;
 }
 
 Return<void> Omx::listNodes(listNodes_cb _hidl_cb) {
     std::list<::android::IOMX::ComponentInfo> list;
     char componentName[256];
     for (OMX_U32 index = 0;
-            mMaster->enumerateComponents(
+            mStore->enumerateComponents(
             componentName, sizeof(componentName), index) == OMX_ErrorNone;
             ++index) {
         list.push_back(::android::IOMX::ComponentInfo());
@@ -63,7 +63,7 @@
         info.mName = componentName;
         ::android::Vector<::android::String8> roles;
         OMX_ERRORTYPE err =
-                mMaster->getRolesOfComponent(componentName, &roles);
+                mStore->getRolesOfComponent(componentName, &roles);
         if (err == OMX_ErrorNone) {
             for (OMX_U32 i = 0; i < roles.size(); ++i) {
                 info.mRoles.push_back(roles[i]);
@@ -101,7 +101,7 @@
                 this, new LWOmxObserver(observer), name.c_str());
 
         OMX_COMPONENTTYPE *handle;
-        OMX_ERRORTYPE err = mMaster->makeComponentInstance(
+        OMX_ERRORTYPE err = mStore->makeComponentInstance(
                 name.c_str(), &OMXNodeInstance::kCallbacks,
                 instance.get(), &handle);
 
@@ -208,7 +208,7 @@
 
     OMX_ERRORTYPE err = OMX_ErrorNone;
     if (instance->handle() != NULL) {
-        err = mMaster->destroyComponentInstance(
+        err = mStore->destroyComponentInstance(
                 static_cast<OMX_COMPONENTTYPE*>(instance->handle()));
     }
     return StatusFromOMXError(err);
diff --git a/media/libstagefright/omx/1.0/OmxStore.cpp b/media/libstagefright/omx/1.0/OmxStore.cpp
index 67f478e..b5c1166 100644
--- a/media/libstagefright/omx/1.0/OmxStore.cpp
+++ b/media/libstagefright/omx/1.0/OmxStore.cpp
@@ -54,6 +54,24 @@
         });
     }
 
+    if (!nodes.empty()) {
+        auto anyNode = nodes.cbegin();
+        std::string::const_iterator first = anyNode->cbegin();
+        std::string::const_iterator last = anyNode->cend();
+        for (const std::string &name : nodes) {
+            std::string::const_iterator it1 = first;
+            for (std::string::const_iterator it2 = name.cbegin();
+                    it1 != last && it2 != name.cend() && tolower(*it1) == tolower(*it2);
+                    ++it1, ++it2) {
+            }
+            last = it1;
+        }
+        mPrefix = std::string(first, last);
+        LOG(INFO) << "omx common prefix: '" << mPrefix.c_str() << "'";
+    } else {
+        LOG(INFO) << "omx common prefix: no nodes";
+    }
+
     MediaCodecsXmlParser parser;
     parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
     if (profilingResultsXmlPath != nullptr) {
@@ -112,8 +130,6 @@
         mRoleList[i] = std::move(role);
         ++i;
     }
-
-    mPrefix = parser.getCommonPrefix();
 }
 
 OmxStore::~OmxStore() {
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 78b4f19..7c372cd 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -7,7 +7,7 @@
     double_loadable: true,
 
     srcs: [
-        "OMXMaster.cpp",
+        "OMXStore.cpp",
         "OMXNodeInstance.cpp",
         "OMXUtils.cpp",
         "OmxGraphicBufferSource.cpp",
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index ac42373..bebd516 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -22,7 +22,7 @@
 #include <inttypes.h>
 
 #include <media/stagefright/omx/OMXNodeInstance.h>
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
 #include <media/stagefright/omx/OMXUtils.h>
 #include <android/IOMXBufferSource.h>
 
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXStore.cpp
similarity index 91%
rename from media/libstagefright/omx/OMXMaster.cpp
rename to media/libstagefright/omx/OMXStore.cpp
index 094b1f5..e8fee42 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -15,11 +15,11 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "OMXMaster"
+#define LOG_TAG "OMXStore"
 #include <android-base/properties.h>
 #include <utils/Log.h>
 
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
 #include <media/stagefright/omx/SoftOMXPlugin.h>
 #include <media/stagefright/foundation/ADebug.h>
 
@@ -30,7 +30,7 @@
 
 namespace android {
 
-OMXMaster::OMXMaster() {
+OMXStore::OMXStore() {
 
     pid_t pid = getpid();
     char filename[20];
@@ -55,19 +55,19 @@
     addPlatformPlugin();
 }
 
-OMXMaster::~OMXMaster() {
+OMXStore::~OMXStore() {
     clearPlugins();
 }
 
-void OMXMaster::addVendorPlugin() {
+void OMXStore::addVendorPlugin() {
     addPlugin("libstagefrighthw.so");
 }
 
-void OMXMaster::addPlatformPlugin() {
+void OMXStore::addPlatformPlugin() {
     addPlugin("libstagefright_softomx_plugin.so");
 }
 
-void OMXMaster::addPlugin(const char *libname) {
+void OMXStore::addPlugin(const char *libname) {
     if (::android::base::GetIntProperty("vendor.media.omx", int64_t(1)) == 0) {
         return;
     }
@@ -99,7 +99,7 @@
     }
 }
 
-void OMXMaster::addPlugin(OMXPluginBase *plugin) {
+void OMXStore::addPlugin(OMXPluginBase *plugin) {
     Mutex::Autolock autoLock(mLock);
 
     OMX_U32 index = 0;
@@ -126,7 +126,7 @@
     }
 }
 
-void OMXMaster::clearPlugins() {
+void OMXStore::clearPlugins() {
     Mutex::Autolock autoLock(mLock);
 
     mPluginByComponentName.clear();
@@ -148,7 +148,7 @@
     mPlugins.clear();
 }
 
-OMX_ERRORTYPE OMXMaster::makeComponentInstance(
+OMX_ERRORTYPE OMXStore::makeComponentInstance(
         const char *name,
         const OMX_CALLBACKTYPE *callbacks,
         OMX_PTR appData,
@@ -177,7 +177,7 @@
     return err;
 }
 
-OMX_ERRORTYPE OMXMaster::destroyComponentInstance(
+OMX_ERRORTYPE OMXStore::destroyComponentInstance(
         OMX_COMPONENTTYPE *component) {
     Mutex::Autolock autoLock(mLock);
 
@@ -193,7 +193,7 @@
     return plugin->destroyComponentInstance(component);
 }
 
-OMX_ERRORTYPE OMXMaster::enumerateComponents(
+OMX_ERRORTYPE OMXStore::enumerateComponents(
         OMX_STRING name,
         size_t size,
         OMX_U32 index) {
@@ -213,7 +213,7 @@
     return OMX_ErrorNone;
 }
 
-OMX_ERRORTYPE OMXMaster::getRolesOfComponent(
+OMX_ERRORTYPE OMXStore::getRolesOfComponent(
         const char *name,
         Vector<String8> *roles) {
     Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index 1b8493a..d6d280f 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -354,7 +354,7 @@
     DescribeColorFormat2Params describeParams;
     InitOMXParams(&describeParams);
     describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
-    // reasonable dummy values
+    // reasonable initial values (that will be overwritten)
     describeParams.nFrameWidth = 128;
     describeParams.nFrameHeight = 128;
     describeParams.nStride = 128;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
index 5a46b26..84ae511 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
@@ -27,7 +27,7 @@
 
 namespace android {
 
-struct OMXMaster;
+struct OMXStore;
 struct OMXNodeInstance;
 
 namespace hardware {
@@ -51,7 +51,7 @@
 using ::android::sp;
 using ::android::wp;
 
-using ::android::OMXMaster;
+using ::android::OMXStore;
 using ::android::OMXNodeInstance;
 
 struct Omx : public IOmx, public hidl_death_recipient {
@@ -73,7 +73,7 @@
     status_t freeNode(sp<OMXNodeInstance> const& instance);
 
 protected:
-    OMXMaster* mMaster;
+    OMXStore* mStore;
     Mutex mLock;
     KeyedVector<wp<IBase>, sp<OMXNodeInstance> > mLiveNodes;
     KeyedVector<OMXNodeInstance*, wp<IBase> > mNode2Observer;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
index a761ef6..5f32c9e 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
@@ -33,7 +33,7 @@
 class GraphicBuffer;
 class IOMXBufferSource;
 class IOMXObserver;
-struct OMXMaster;
+struct OMXStore;
 class OMXBuffer;
 using IHidlMemory = hidl::memory::V1_0::IMemory;
 using hardware::media::omx::V1_0::implementation::Omx;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
similarity index 88%
rename from media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
index 93eaef1..5d6c3ed 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef OMX_MASTER_H_
+#ifndef OMX_STORE_H_
 
-#define OMX_MASTER_H_
+#define OMX_STORE_H_
 
 #include <media/hardware/OMXPluginBase.h>
 
@@ -27,9 +27,9 @@
 
 namespace android {
 
-struct OMXMaster : public OMXPluginBase {
-    OMXMaster();
-    virtual ~OMXMaster();
+struct OMXStore : public OMXPluginBase {
+    OMXStore();
+    virtual ~OMXStore();
 
     virtual OMX_ERRORTYPE makeComponentInstance(
             const char *name,
@@ -66,10 +66,10 @@
     void addPlugin(OMXPluginBase *plugin);
     void clearPlugins();
 
-    OMXMaster(const OMXMaster &);
-    OMXMaster &operator=(const OMXMaster &);
+    OMXStore(const OMXStore &);
+    OMXStore &operator=(const OMXStore &);
 };
 
 }  // namespace android
 
-#endif  // OMX_MASTER_H_
+#endif  // OMX_STORE_H_
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index bb66f4c..c33bf3f 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -329,6 +329,7 @@
     mPass.clear();
     mAuthType = NONE;
     mNonce.clear();
+    mRealm.clear();
 
     mState = DISCONNECTED;
 }
@@ -911,6 +912,14 @@
         CHECK_GE(j, 0);
 
         mNonce.setTo(value, i + 7, j - i - 7);
+
+        i = value.find("realm=");
+        CHECK_GE(i, 0);
+        CHECK_EQ(value.c_str()[i + 6], '\"');
+        j = value.find("\"", i + 7);
+        CHECK_GE(j, 0);
+
+        mRealm.setTo(value, i + 7, j - i - 7);
     }
 
     return true;
@@ -993,7 +1002,7 @@
     AString A1;
     A1.append(mUser);
     A1.append(":");
-    A1.append("Streaming Server");
+    A1.append(mRealm);
     A1.append(":");
     A1.append(mPass);
 
@@ -1029,6 +1038,9 @@
     fragment.append("\", ");
     fragment.append("response=\"");
     fragment.append(digest);
+    fragment.append("\", ");
+    fragment.append("realm=\"");
+    fragment.append(mRealm);
     fragment.append("\"");
     fragment.append("\r\n");
 
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 56b604d..7cdd4c0 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -84,6 +84,7 @@
     AString mUser, mPass;
     AuthType mAuthType;
     AString mNonce;
+    AString mRealm;
     int mSocket;
     int32_t mConnectionID;
     int32_t mNextCSeq;
diff --git a/media/libstagefright/rtsp/NetworkUtils.cpp b/media/libstagefright/rtsp/NetworkUtils.cpp
index cc36b78..c053be8 100644
--- a/media/libstagefright/rtsp/NetworkUtils.cpp
+++ b/media/libstagefright/rtsp/NetworkUtils.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <unistd.h>
+
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NetworkUtils"
 #include <utils/Log.h>
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/libstagefright/tests/ESDS/Android.bp
new file mode 100644
index 0000000..1ad1a64
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "ESDSTest",
+    gtest: true,
+
+    srcs: [
+        "ESDSTest.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libdatasource",
+        "liblog",
+        "libmedia",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libstagefright_esds",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/libstagefright/tests/ESDS/AndroidTest.xml
new file mode 100644
index 0000000..a4fbc7f
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for ESDS unit test">
+    <option name="test-suite-tag" value="ESDSTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ESDSTest->/data/local/tmp/ESDSTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip?unzip=true"
+            value="/data/local/tmp/ESDSTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ESDSTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/ESDSTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/libstagefright/tests/ESDS/ESDSTest.cpp
new file mode 100644
index 0000000..101e00c
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 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 "ESDSTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+#include <ESDS.h>
+#include <binder/ProcessState.h>
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MetaData.h>
+
+#include "ESDSTestEnvironment.h"
+
+using namespace android;
+
+static ESDSTestEnvironment *gEnv = nullptr;
+
+struct ESDSParams {
+    const char *inputFile;
+    int32_t objectTypeIndication;
+    const char *codecSpecificInfoData;
+    int32_t codecSpecificInfoDataSize;
+    int32_t bitrateMax;
+    int32_t bitrateAvg;
+};
+
+class ESDSUnitTest : public ::testing::TestWithParam<tuple<
+                             /* InputFile */ const char *,
+                             /* ObjectTypeIndication */ int32_t,
+                             /* CodecSpecificInfoData */ const char *,
+                             /* CodecSpecificInfoDataSize */ int32_t,
+                             /* BitrateMax */ int32_t,
+                             /* BitrateAvg */ int32_t>> {
+  public:
+    ESDSUnitTest() : mESDSData(nullptr) {
+        mESDSParams.inputFile = get<0>(GetParam());
+        mESDSParams.objectTypeIndication = get<1>(GetParam());
+        mESDSParams.codecSpecificInfoData = get<2>(GetParam());
+        mESDSParams.codecSpecificInfoDataSize = get<3>(GetParam());
+        mESDSParams.bitrateMax = get<4>(GetParam());
+        mESDSParams.bitrateAvg = get<5>(GetParam());
+    };
+
+    virtual void TearDown() override {
+        if (mDataSource) mDataSource.clear();
+        if (mInputFp) {
+            fclose(mInputFp);
+            mInputFp = nullptr;
+        }
+    }
+
+    virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(readESDSData()); }
+    const void *mESDSData;
+    size_t mESDSSize;
+    ESDSParams mESDSParams;
+
+  private:
+    void readESDSData() {
+        string inputFile = gEnv->getRes() + mESDSParams.inputFile;
+        mInputFp = fopen(inputFile.c_str(), "rb");
+        ASSERT_NE(mInputFp, nullptr) << "File open failed for file: " << inputFile;
+        int32_t fd = fileno(mInputFp);
+        ASSERT_GE(fd, 0) << "File descriptor invalid for file: " << inputFile;
+
+        struct stat buf;
+        status_t status = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(status, 0) << "Failed to get properties of input file: " << mESDSParams.inputFile;
+        size_t fileSize = buf.st_size;
+
+        mDataSource = new FileSource(dup(fd), 0, fileSize);
+        ASSERT_NE(mDataSource, nullptr) << "Unable to create data source for file: " << inputFile;
+
+        sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(mDataSource);
+        if (extractor == nullptr) {
+            mDataSource.clear();
+            ASSERT_TRUE(false) << "Unable to create extractor for file: " << inputFile;
+        }
+
+        size_t numTracks = extractor->countTracks();
+        ASSERT_GT(numTracks, 0) << "No tracks in file: " << inputFile;
+        ASSERT_TRUE(esdsDataPresent(numTracks, extractor))
+                << "Unable to find esds in any track in file: " << inputFile;
+    }
+
+    bool esdsDataPresent(size_t numTracks, sp<IMediaExtractor> extractor) {
+        bool foundESDS = false;
+        uint32_t type;
+        for (size_t i = 0; i < numTracks; ++i) {
+            sp<MetaData> trackMeta = extractor->getTrackMetaData(i);
+            if (trackMeta != nullptr &&
+                trackMeta->findData(kKeyESDS, &type, &mESDSData, &mESDSSize)) {
+                trackMeta->clear();
+                foundESDS = true;
+                break;
+            }
+        }
+        return foundESDS;
+    }
+
+    FILE *mInputFp;
+    sp<DataSource> mDataSource;
+};
+
+TEST_P(ESDSUnitTest, InvalidDataTest) {
+    void *invalidData = calloc(mESDSSize, 1);
+    ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+    ESDS esds(invalidData, mESDSSize);
+    free(invalidData);
+    ASSERT_NE(esds.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST(ESDSSanityUnitTest, ConstructorSanityTest) {
+    void *invalidData = malloc(1);
+    ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+    ESDS esds_zero(invalidData, 0);
+    free(invalidData);
+    ASSERT_NE(esds_zero.InitCheck(), OK) << "invalid ESDS data accepted";
+
+    ESDS esds_null(NULL, 0);
+    ASSERT_NE(esds_null.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST_P(ESDSUnitTest, CreateAndDestroyTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+}
+
+TEST_P(ESDSUnitTest, ObjectTypeIndicationTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    uint8_t objectTypeIndication;
+    status_t status = esds.getObjectTypeIndication(&objectTypeIndication);
+    ASSERT_EQ(status, OK) << "ESDS objectTypeIndication data invalid";
+    ASSERT_EQ(objectTypeIndication, mESDSParams.objectTypeIndication)
+            << "ESDS objectTypeIndication data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, CodecSpecificInfoTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    status_t status;
+    const void *codecSpecificInfo;
+    size_t codecSpecificInfoSize;
+    status = esds.getCodecSpecificInfo(&codecSpecificInfo, &codecSpecificInfoSize);
+    ASSERT_EQ(status, OK) << "ESDS getCodecSpecificInfo data invalid";
+    ASSERT_EQ(mESDSParams.codecSpecificInfoDataSize, codecSpecificInfoSize)
+            << "CodecSpecificInfo data doesn't match";
+    status = memcmp(codecSpecificInfo, mESDSParams.codecSpecificInfoData, codecSpecificInfoSize);
+    ASSERT_EQ(status, 0) << "CodecSpecificInfo data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, GetBitrateTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    uint32_t bitrateMax;
+    uint32_t bitrateAvg;
+    status_t status = esds.getBitRate(&bitrateMax, &bitrateAvg);
+    ASSERT_EQ(status, OK) << "ESDS bitRate data invalid";
+    ASSERT_EQ(bitrateMax, mESDSParams.bitrateMax) << "ESDS bitrateMax doesn't match";
+    ASSERT_EQ(bitrateAvg, mESDSParams.bitrateAvg) << "ESDS bitrateAvg doesn't match";
+    ASSERT_LE(bitrateAvg, bitrateMax) << "ESDS bitrateMax is less than bitrateAvg";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        ESDSUnitTestAll, ESDSUnitTest,
+        ::testing::Values(
+                // InputFile, ObjectTypeIndication, CodecSpecificInfoData,
+                // CodecSpecificInfoDataSize, BitrateMax, BitrateAvg
+                make_tuple("video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_22050hz.3gp", 64,
+                           "\x13\x90", 2, 131072, 0),
+                make_tuple("video_1280x720_mp4_mpeg2_3000kbps_30fps_aac_stereo_128kbps_48000hz.mp4",
+                           97,
+                           "\x00\x00\x01\xB3\x50\x02\xD0\x35\xFF\xFF\xE1\xA0\x00\x00\x01\xB5\x15"
+                           "\x6A\x00\x01\x00\x00",
+                           22, 3415452, 3415452),
+                make_tuple("video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_11025hz.3gp", 64,
+                           "\x15\x08", 2, 24576, 0)));
+
+int main(int argc, char **argv) {
+    // MediaExtractor needs binder thread pool
+    ProcessState::self()->startThreadPool();
+    gEnv = new ESDSTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
new file mode 100644
index 0000000..4ca2303
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 __ESDS_TEST_ENVIRONMENT_H__
+#define __ESDS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ESDSTestEnvironment : public ::testing::Environment {
+  public:
+    ESDSTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int ESDSTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P':
+                setRes(optarg);
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __ESDS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/libstagefright/tests/ESDS/README.md
new file mode 100644
index 0000000..100fb86
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/README.md
@@ -0,0 +1,40 @@
+## Media Testing ##
+---
+#### ESDS Unit Test :
+The ESDS Unit Test Suite validates the ESDS class available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m ESDSTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip)
+Download, unzip and push these files into device for testing.
+
+```
+adb push ESDSTestRes /data/local/tmp/
+```
+
+usage: ESDSTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/ESDSTest -P /data/local/tmp/ESDSTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ESDSTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/tests/HEVC/Android.bp b/media/libstagefright/tests/HEVC/Android.bp
new file mode 100644
index 0000000..7a6b959
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "HEVCUtilsUnitTest",
+    gtest: true,
+
+    srcs: [
+        "HEVCUtilsUnitTest.cpp",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+    static_libs: [
+        "libstagefright",
+        "libstagefright_foundation",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/tests/HEVC/AndroidTest.xml b/media/libstagefright/tests/HEVC/AndroidTest.xml
new file mode 100644
index 0000000..ff850a2
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for HEVC Utils unit tests">
+    <option name="test-suite-tag" value="HEVCUtilsUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="false" />
+        <option name="push" value="HEVCUtilsUnitTest->/data/local/tmp/HEVCUtilsUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest.zip?unzip=true"
+            value="/data/local/tmp/HEVCUtilsUnitTest/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="HEVCUtilsUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/HEVCUtilsUnitTest/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.h b/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.h
new file mode 100644
index 0000000..e4481e1
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __HEVC_UTILS_TEST_ENVIRONMENT_H__
+#define __HEVC_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class HEVCUtilsTestEnvironment : public::testing::Environment {
+  public:
+    HEVCUtilsTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int HEVCUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __HEVC_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
new file mode 100644
index 0000000..324a042
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2020 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 "HevcUtilityTest"
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include <media/stagefright/foundation/ABitReader.h>
+#include "include/HevcUtils.h"
+
+#include "HEVCUtilsTestEnvironment.h"
+
+using namespace android;
+
+// max size of hvcc box is 2 KB
+constexpr uint32_t kHvccBoxMaxSize = 2048;
+constexpr uint32_t kHvccBoxMinSize = 20;
+constexpr uint32_t kVPSCode = 32;
+constexpr uint32_t kSPSCode = 33;
+constexpr uint32_t kPPSCode = 34;
+constexpr uint32_t kNALSizeLength = 2;
+
+static HEVCUtilsTestEnvironment *gEnv = nullptr;
+
+class HEVCUtilsUnitTest
+    : public ::testing::TestWithParam<
+              tuple</*fileName*/ string, /*infoFileName*/ string, /*numVPSNals*/ size_t,
+                    /*numSPSNals*/ size_t, /*numPPSNals*/ size_t, /*frameRate*/ int16_t,
+                    /*isHdr*/ bool>> {
+  public:
+    ~HEVCUtilsUnitTest() {
+        if (mMediaFileStream.is_open()) mMediaFileStream.close();
+        if (mInfoFileStream.is_open()) mInfoFileStream.close();
+    }
+
+    virtual void SetUp() override {
+        tuple<string, string, size_t, size_t, size_t, int16_t, bool> params = GetParam();
+        string inputMediaFile = gEnv->getRes() + get<0>(params);
+        mMediaFileStream.open(inputMediaFile, ifstream::in);
+        ASSERT_TRUE(mMediaFileStream.is_open()) << "Failed to open media file: " << inputMediaFile;
+
+        string inputInfoFile = gEnv->getRes() + get<1>(params);
+        mInfoFileStream.open(inputInfoFile, ifstream::in);
+        ASSERT_TRUE(mInfoFileStream.is_open()) << "Failed to open info file: " << inputInfoFile;
+
+        mNumVPSNals = get<2>(params);
+        mNumSPSNals = get<3>(params);
+        mNumPPSNals = get<4>(params);
+        mFrameRate = get<5>(params);
+        mIsHDR = get<6>(params);
+    }
+
+    size_t mNumVPSNals;
+    size_t mNumSPSNals;
+    size_t mNumPPSNals;
+    int16_t mFrameRate;
+    bool mIsHDR;
+    ifstream mMediaFileStream;
+    ifstream mInfoFileStream;
+};
+
+TEST_P(HEVCUtilsUnitTest, NALUnitTest) {
+    HevcParameterSets hevcParams;
+
+    string line;
+    int32_t index = 0;
+    status_t err;
+    while (getline(mInfoFileStream, line)) {
+        string type;
+        int32_t chunkLength;
+
+        istringstream stringLine(line);
+        stringLine >> type >> chunkLength;
+        ASSERT_GT(chunkLength, 0) << "Length of data chunk must be greater than 0";
+
+        char *data = (char *)malloc(chunkLength);
+        ASSERT_NE(data, nullptr) << "Failed to allocate data buffer of size: " << chunkLength;
+
+        mMediaFileStream.read(data, chunkLength);
+        ASSERT_EQ(mMediaFileStream.gcount(), chunkLength)
+                << "Failed to read complete file, bytes read: " << mMediaFileStream.gcount();
+
+        // A valid startcode consists of at least two 0x00 bytes followed by 0x01.
+        int32_t offset = 0;
+        for (; offset + 2 < chunkLength; ++offset) {
+            if (data[offset + 2] == 0x01 && data[offset + 1] == 0x00 && data[offset] == 0x00) {
+                break;
+            }
+        }
+        offset += 3;
+        ASSERT_LE(offset, chunkLength) << "NAL unit offset must not exceed the chunk length";
+
+        uint8_t *nalUnit = (uint8_t *)(data + offset);
+        size_t nalUnitLength = chunkLength - offset;
+
+        // Add NAL units only if they're of type: VPS/SPS/PPS/SEI
+        if (!((type.compare("VPS") && type.compare("SPS") && type.compare("PPS") &&
+               type.compare("SEI")))) {
+            err = hevcParams.addNalUnit(nalUnit, nalUnitLength);
+            ASSERT_EQ(err, (status_t)OK)
+                    << "Failed to add NAL Unit type: " << type << " Size: " << nalUnitLength;
+
+            size_t sizeNalUnit = hevcParams.getSize(index);
+            ASSERT_EQ(sizeNalUnit, nalUnitLength) << "Invalid size returned for NAL: " << type;
+
+            uint8_t *destination = (uint8_t *)malloc(nalUnitLength);
+            ASSERT_NE(destination, nullptr)
+                    << "Failed to allocate buffer of size: " << nalUnitLength;
+
+            bool status = hevcParams.write(index, destination, nalUnitLength);
+            ASSERT_TRUE(status) << "Unable to write NAL Unit data";
+
+            free(destination);
+            index++;
+        } else {
+            err = hevcParams.addNalUnit(nalUnit, nalUnitLength);
+            ASSERT_NE(err, (status_t)OK) << "Invalid NAL Unit added, type: " << type;
+        }
+        free(data);
+    }
+
+    size_t numNalUnits = hevcParams.getNumNalUnitsOfType(kVPSCode);
+    ASSERT_EQ(numNalUnits, mNumVPSNals) << "Wrong number of VPS NAL Units";
+
+    numNalUnits = hevcParams.getNumNalUnitsOfType(kSPSCode);
+    ASSERT_EQ(numNalUnits, mNumSPSNals) << "Wrong number of SPS NAL Units";
+
+    numNalUnits = hevcParams.getNumNalUnitsOfType(kPPSCode);
+    ASSERT_EQ(numNalUnits, mNumPPSNals) << "Wrong number of PPS NAL Units";
+
+    HevcParameterSets::Info info = hevcParams.getInfo();
+    ASSERT_EQ(info & HevcParameterSets::kInfoIsHdr,
+              (mIsHDR ? HevcParameterSets::kInfoIsHdr : HevcParameterSets::kInfoNone))
+            << "Wrong info about HDR";
+
+    ASSERT_EQ(info & HevcParameterSets::kInfoHasColorDescription,
+              (mIsHDR ? HevcParameterSets::kInfoHasColorDescription : HevcParameterSets::kInfoNone))
+            << "Wrong info about color description";
+
+    // an HEVC file starts with VPS, SPS and PPS NAL units in sequence.
+    uint8_t typeNalUnit = hevcParams.getType(0);
+    ASSERT_EQ(typeNalUnit, kHevcNalUnitTypeVps)
+            << "Expected NAL type: 32(VPS), found: " << typeNalUnit;
+
+    typeNalUnit = hevcParams.getType(1);
+    ASSERT_EQ(typeNalUnit, kHevcNalUnitTypeSps)
+            << "Expected NAL type: 33(SPS), found: " << typeNalUnit;
+
+    typeNalUnit = hevcParams.getType(2);
+    ASSERT_EQ(typeNalUnit, kHevcNalUnitTypePps)
+            << "Expected NAL type: 34(PPS), found: " << typeNalUnit;
+
+    size_t hvccBoxSize = kHvccBoxMaxSize;
+    uint8_t *hvcc = (uint8_t *)malloc(kHvccBoxMaxSize);
+    ASSERT_NE(hvcc, nullptr) << "Failed to allocate a hvcc buffer of size: " << kHvccBoxMaxSize;
+
+    err = hevcParams.makeHvcc(hvcc, &hvccBoxSize, kNALSizeLength);
+    ASSERT_EQ(err, (status_t)OK) << "Unable to create hvcc box";
+
+    ASSERT_GT(hvccBoxSize, kHvccBoxMinSize)
+            << "Hvcc box size must be greater than " << kHvccBoxMinSize;
+
+    int16_t frameRate = hvcc[kHvccBoxMinSize - 1] | (hvcc[kHvccBoxMinSize] << 8);
+    if (frameRate != mFrameRate)
+        cout << "[   WARN   ] Expected frame rate: " << mFrameRate << " Found: " << frameRate
+             << endl;
+
+    free(hvcc);
+}
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+        HEVCUtilsUnitTestAll, HEVCUtilsUnitTest,
+        ::testing::Values(make_tuple("crowd_3840x2160p50f300_32500kbps.hevc",
+                                     "crowd_3840x2160p50f300_32500kbps.info", 1, 1, 1, 50, false),
+                          make_tuple("crowd_1920x1080p24f300_4500kbps.hevc",
+                                     "crowd_1920x1080p24f300_4500kbps.info", 1, 1, 1, 24, false),
+                          make_tuple("crowd_1280x720p24f300_3000kbps.hevc",
+                                     "crowd_1280x720p24f300_3000kbps.info", 1, 1, 1, 24, false),
+                          make_tuple("crowd_640x360p24f300_500kbps.hevc",
+                                     "crowd_640x360p24f300_500kbps.info", 1, 1, 1, 24, false)));
+
+int main(int argc, char **argv) {
+    gEnv = new HEVCUtilsTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/tests/HEVC/README.md b/media/libstagefright/tests/HEVC/README.md
new file mode 100644
index 0000000..fa0e99c
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### HEVC Utils Test
+The HEVC Utility Unit Test Suite validates the HevcUtils library available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m HEVCUtilsUnitTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/HEVCUtilsUnitTest/HEVCUtilsUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/HEVCUtilsUnitTest/HEVCUtilsUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push HEVCUtilsUnitTest /data/local/tmp/
+```
+
+usage: HEVCUtilsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/HEVCUtilsUnitTest -P /data/local/tmp/HEVCUtilsUnitTest/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest HEVCUtilsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/tests/metadatautils/Android.bp b/media/libstagefright/tests/metadatautils/Android.bp
new file mode 100644
index 0000000..69830fc
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/Android.bp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "MetaDataUtilsTest",
+    gtest: true,
+
+    srcs: [
+        "MetaDataUtilsTest.cpp",
+    ],
+
+    static_libs: [
+        "libstagefright_metadatautils",
+        "libstagefright_esds",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libmediandk",
+        "libstagefright",
+        "libstagefright_foundation",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/tests/metadatautils/AndroidTest.xml b/media/libstagefright/tests/metadatautils/AndroidTest.xml
new file mode 100644
index 0000000..d6497f3
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for MetaDataUtils unit test">
+    <option name="test-suite-tag" value="MetaDataUtilsTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="false" />
+        <option name="push" value="MetaDataUtilsTest->/data/local/tmp/MetaDataUtilsTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip?unzip=true"
+            value="/data/local/tmp/MetaDataUtilsTestRes/" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="MetaDataUtilsTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/MetaDataUtilsTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp b/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
new file mode 100644
index 0000000..9fd5fdb
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2020 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 "MetaDataUtilsTest"
+#include <utils/Log.h>
+
+#include <fstream>
+#include <string>
+
+#include <ESDS.h>
+#include <media/NdkMediaFormat.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/MetaDataUtils.h>
+#include <media/stagefright/foundation/ABitReader.h>
+
+#include "MetaDataUtilsTestEnvironment.h"
+
+constexpr uint8_t kAdtsCsdSize = 7;
+// from AAC specs: https://www.iso.org/standard/43345.html
+constexpr int32_t kSamplingFreq[] = {96000, 88200, 64000, 48000, 44100, 32000,
+                                     24000, 22050, 16000, 12000, 11025, 8000};
+constexpr uint8_t kMaxSamplingFreqIndex = sizeof(kSamplingFreq) / sizeof(kSamplingFreq[0]);
+
+static MetaDataUtilsTestEnvironment *gEnv = nullptr;
+
+using namespace android;
+
+class MetaDataValidate {
+  public:
+    MetaDataValidate() : mInputBuffer(nullptr) {}
+
+    ~MetaDataValidate() {
+        if (mInputBuffer) {
+            delete[] mInputBuffer;
+            mInputBuffer = nullptr;
+        }
+    }
+
+    void SetUpMetaDataValidate(string fileName) {
+        struct stat buf;
+        int8_t err = stat(fileName.c_str(), &buf);
+        ASSERT_EQ(err, 0) << "Failed to get file information for file: " << fileName;
+
+        mInputBufferSize = buf.st_size;
+        FILE *inputFilePtr = fopen(fileName.c_str(), "rb+");
+        ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << fileName;
+
+        mInputBuffer = new uint8_t[mInputBufferSize];
+        ASSERT_NE(mInputBuffer, nullptr)
+                << "Failed to allocate memory of size: " << mInputBufferSize;
+
+        int32_t numBytes =
+                fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
+        ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
+
+        fclose(inputFilePtr);
+    }
+
+    size_t mInputBufferSize;
+    const uint8_t *mInputBuffer;
+};
+
+class AvcCSDTest : public ::testing::TestWithParam<
+                           tuple<string /*inputFile*/, size_t /*avcWidth*/, size_t /*avcHeight*/>> {
+  public:
+    AvcCSDTest() : mInputBuffer(nullptr) {}
+
+    ~AvcCSDTest() {
+        if (mInputBuffer) {
+            delete[] mInputBuffer;
+            mInputBuffer = nullptr;
+        }
+    }
+    virtual void SetUp() override {
+        tuple<string, size_t, size_t> params = GetParam();
+        string inputFile = gEnv->getRes() + get<0>(params);
+        mFrameWidth = get<1>(params);
+        mFrameHeight = get<2>(params);
+
+        struct stat buf;
+        int8_t err = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+        mInputBufferSize = buf.st_size;
+        FILE *inputFilePtr = fopen(inputFile.c_str(), "rb+");
+        ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << inputFile;
+
+        mInputBuffer = new uint8_t[mInputBufferSize];
+        ASSERT_NE(mInputBuffer, nullptr)
+                << "Failed to create a buffer of size: " << mInputBufferSize;
+
+        int32_t numBytes =
+                fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
+        ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
+
+        fclose(inputFilePtr);
+    }
+
+    size_t mFrameWidth;
+    size_t mFrameHeight;
+    size_t mInputBufferSize;
+    const uint8_t *mInputBuffer;
+};
+
+class AvcCSDValidateTest : public MetaDataValidate,
+                           public ::testing::TestWithParam<string /*inputFile*/> {
+  public:
+    virtual void SetUp() override {
+        string inputFile = gEnv->getRes() + GetParam();
+
+        ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
+    }
+};
+
+class AacCSDTest
+    : public ::testing::TestWithParam<tuple<uint32_t /*profile*/, uint32_t /*samplingFreqIndex*/,
+                                            uint32_t /*channelConfig*/>> {
+  public:
+    virtual void SetUp() override {
+        tuple<uint32_t, uint32_t, uint32_t> params = GetParam();
+        mAacProfile = get<0>(params);
+        mAacSamplingFreqIndex = get<1>(params);
+        mAacChannelConfig = get<2>(params);
+    }
+
+    uint32_t mAacProfile;
+    uint32_t mAacSamplingFreqIndex;
+    uint32_t mAacChannelConfig;
+};
+
+class AacADTSTest
+    : public ::testing::TestWithParam<
+              tuple<string /*adtsFile*/, uint32_t /*channelCount*/, uint32_t /*sampleRate*/>> {
+  public:
+    AacADTSTest() : mInputBuffer(nullptr) {}
+
+    virtual void SetUp() override {
+        tuple<string, uint32_t, uint32_t> params = GetParam();
+        string fileName = gEnv->getRes() + get<0>(params);
+        mAacChannelCount = get<1>(params);
+        mAacSampleRate = get<2>(params);
+
+        FILE *filePtr = fopen(fileName.c_str(), "r");
+        ASSERT_NE(filePtr, nullptr) << "Failed to open file: " << fileName;
+
+        mInputBuffer = new uint8_t[kAdtsCsdSize];
+        ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate a memory of size: " << kAdtsCsdSize;
+
+        int32_t numBytes = fread((void *)mInputBuffer, sizeof(uint8_t), kAdtsCsdSize, filePtr);
+        ASSERT_EQ(numBytes, kAdtsCsdSize)
+                << "Failed to read complete file, bytes read: " << numBytes;
+
+        fclose(filePtr);
+    }
+    int32_t mAacChannelCount;
+    int32_t mAacSampleRate;
+    const uint8_t *mInputBuffer;
+};
+
+class AacCSDValidateTest : public MetaDataValidate,
+                           public ::testing::TestWithParam<string /*inputFile*/> {
+  public:
+    virtual void SetUp() override {
+        string inputFile = gEnv->getRes() + GetParam();
+
+        ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
+    }
+};
+
+class VorbisTest : public ::testing::TestWithParam<pair<string /*fileName*/, string /*infoFile*/>> {
+  public:
+    virtual void SetUp() override {
+        pair<string, string> params = GetParam();
+        string inputMediaFile = gEnv->getRes() + params.first;
+        mInputFileStream.open(inputMediaFile, ifstream::in);
+        ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputMediaFile;
+
+        string inputInfoFile = gEnv->getRes() + params.second;
+        mInfoFileStream.open(inputInfoFile, ifstream::in);
+        ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputInfoFile;
+        ASSERT_FALSE(inputInfoFile.empty()) << "Empty info file: " << inputInfoFile;
+    }
+
+    ~VorbisTest() {
+        if (mInputFileStream.is_open()) mInputFileStream.close();
+        if (mInfoFileStream.is_open()) mInfoFileStream.close();
+    }
+
+    ifstream mInputFileStream;
+    ifstream mInfoFileStream;
+};
+
+TEST_P(AvcCSDTest, AvcCSDValidationTest) {
+    AMediaFormat *csdData = AMediaFormat_new();
+    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+    bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
+    ASSERT_TRUE(status) << "Failed to make AVC CSD from AMediaFormat";
+
+    int32_t avcWidth = -1;
+    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_WIDTH, &avcWidth);
+    ASSERT_TRUE(status) << "Failed to get avc width";
+    ASSERT_EQ(avcWidth, mFrameWidth);
+
+    int32_t avcHeight = -1;
+    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_HEIGHT, &avcHeight);
+    ASSERT_TRUE(status) << "Failed to get avc height";
+    ASSERT_EQ(avcHeight, mFrameHeight);
+
+    const char *mimeType = "";
+    status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
+    ASSERT_TRUE(status) << "Failed to get the mime type";
+    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_VIDEO_AVC);
+
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+    status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
+    ASSERT_TRUE(status) << "Failed to make AVC CSD from MetaDataBase";
+
+    avcWidth = -1;
+    status = metaData->findInt32(kKeyWidth, &avcWidth);
+    ASSERT_TRUE(status) << "Failed to find the width";
+    ASSERT_EQ(avcWidth, mFrameWidth);
+
+    avcHeight = -1;
+    status = metaData->findInt32(kKeyHeight, &avcHeight);
+    ASSERT_TRUE(status) << "Failed to find the height";
+    ASSERT_EQ(avcHeight, mFrameHeight);
+
+    void *csdAMediaFormatBuffer = nullptr;
+    size_t csdAMediaFormatSize;
+    status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_AVC, &csdAMediaFormatBuffer,
+                                    &csdAMediaFormatSize);
+    ASSERT_TRUE(status) << "Failed to get the CSD from AMediaFormat";
+    ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD from AMediaFormat";
+
+    const void *csdMetaDataBaseBuffer = nullptr;
+    size_t csdMetaDataBaseSize = 0;
+    uint32_t mediaType;
+    status = metaData->findData(kKeyAVCC, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+    ASSERT_TRUE(status) << "Failed to get the CSD from MetaDataBase";
+    ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD from MetaDataBase";
+    ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
+    ASSERT_EQ(csdMetaDataBaseSize, csdAMediaFormatSize)
+            << "CSD size of MetaData type and AMediaFormat type must be same";
+
+    int32_t result = memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
+    ASSERT_EQ(result, 0) << "CSD from AMediaFormat and MetaDataBase do not match";
+
+    delete metaData;
+    AMediaFormat_delete(csdData);
+}
+
+TEST_P(AvcCSDValidateTest, AvcValidateTest) {
+    AMediaFormat *csdData = AMediaFormat_new();
+    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+    bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
+    ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with AMediaFormat succeeds with invalid data";
+
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+    status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
+    ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with MetaDataBase succeeds with invalid data";
+}
+
+TEST_P(AacCSDTest, AacCSDValidationTest) {
+    AMediaFormat *csdData = AMediaFormat_new();
+    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+    ASSERT_GE(mAacSamplingFreqIndex, 0);
+    ASSERT_LT(mAacSamplingFreqIndex, kMaxSamplingFreqIndex);
+    bool status = MakeAACCodecSpecificData(csdData, mAacProfile, mAacSamplingFreqIndex,
+                                           mAacChannelConfig);
+    ASSERT_TRUE(status) << "Failed to make AAC CSD from AMediaFormat";
+
+    int32_t sampleRate = -1;
+    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
+    ASSERT_TRUE(status) << "Failed to get sample rate";
+    ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
+
+    int32_t channelCount = -1;
+    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
+    ASSERT_TRUE(status) << "Failed to get channel count";
+    ASSERT_EQ(channelCount, mAacChannelConfig);
+
+    const char *mimeType = "";
+    status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
+    ASSERT_TRUE(status) << "Failed to get the mime type";
+    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+    status = MakeAACCodecSpecificData(*metaData, mAacProfile, mAacSamplingFreqIndex,
+                                      mAacChannelConfig);
+    ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
+
+    sampleRate = -1;
+    status = metaData->findInt32(kKeySampleRate, &sampleRate);
+    ASSERT_TRUE(status) << "Failed to get sampling rate";
+    ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
+
+    channelCount = -1;
+    status = metaData->findInt32(kKeyChannelCount, &channelCount);
+    ASSERT_TRUE(status) << "Failed to get channel count";
+    ASSERT_EQ(channelCount, mAacChannelConfig);
+
+    mimeType = "";
+    status = metaData->findCString(kKeyMIMEType, &mimeType);
+    ASSERT_TRUE(status) << "Failed to get mime type";
+    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+    void *csdAMediaFormatBuffer = nullptr;
+    size_t csdAMediaFormatSize = 0;
+    status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_0, &csdAMediaFormatBuffer,
+                                    &csdAMediaFormatSize);
+    ASSERT_TRUE(status) << "Failed to get the AMediaFormat CSD";
+    ASSERT_GT(csdAMediaFormatSize, 0) << "CSD size must be greater than 0";
+    ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD found";
+
+    const void *csdMetaDataBaseBuffer;
+    size_t csdMetaDataBaseSize = 0;
+    uint32_t mediaType;
+    status = metaData->findData(kKeyESDS, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+    ASSERT_TRUE(status) << "Failed to get the ESDS data from MetaDataBase";
+    ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
+
+    ESDS esds(csdMetaDataBaseBuffer, csdMetaDataBaseSize);
+    status_t result = esds.getCodecSpecificInfo(&csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+    ASSERT_EQ(result, (status_t)OK) << "Failed to get CSD from ESDS data";
+    ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD found";
+    ASSERT_EQ(csdAMediaFormatSize, csdMetaDataBaseSize)
+            << "CSD size do not match between AMediaFormat type and MetaDataBase type";
+
+    int32_t memcmpResult =
+            memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
+    ASSERT_EQ(memcmpResult, 0) << "AMediaFormat and MetaDataBase CSDs do not match";
+
+    AMediaFormat_delete(csdData);
+    delete metaData;
+}
+
+TEST_P(AacADTSTest, AacADTSValidationTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
+    ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
+
+    int32_t sampleRate = -1;
+    status = metaData->findInt32(kKeySampleRate, &sampleRate);
+    ASSERT_TRUE(status) << "Failed to get sampling rate";
+    ASSERT_EQ(sampleRate, mAacSampleRate);
+
+    int32_t channelCount = -1;
+    status = metaData->findInt32(kKeyChannelCount, &channelCount);
+    ASSERT_TRUE(status) << "Failed to get channel count";
+    ASSERT_EQ(channelCount, mAacChannelCount);
+
+    const char *mimeType = "";
+    status = metaData->findCString(kKeyMIMEType, &mimeType);
+    ASSERT_TRUE(status) << "Failed to get mime type";
+    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+    delete metaData;
+}
+
+TEST_P(AacCSDValidateTest, AacInvalidInputTest) {
+    MetaDataBase *metaData = new MetaDataBase();
+    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+    bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
+    ASSERT_FALSE(status) << "MakeAACCodecSpecificData succeeds with invalid data";
+}
+
+TEST_P(VorbisTest, VorbisCommentTest) {
+    string line;
+    string tag;
+    string key;
+    string value;
+    size_t commentLength;
+    bool status;
+
+    while (getline(mInfoFileStream, line)) {
+        istringstream stringLine(line);
+        stringLine >> tag >> key >> value >> commentLength;
+        ASSERT_GT(commentLength, 0) << "Vorbis comment size must be greater than 0";
+
+        string comment;
+        string dataLine;
+
+        getline(mInputFileStream, dataLine);
+        istringstream dataStringLine(dataLine);
+        dataStringLine >> comment;
+
+        char *buffer = strndup(comment.c_str(), commentLength);
+        ASSERT_NE(buffer, nullptr) << "Failed to allocate buffer of size: " << commentLength;
+
+        AMediaFormat *fileMeta = AMediaFormat_new();
+        ASSERT_NE(fileMeta, nullptr) << "Failed to create AMedia format";
+
+        parseVorbisComment(fileMeta, buffer, commentLength);
+        free(buffer);
+
+        if (!strncasecmp(tag.c_str(), "ANDROID_HAPTIC", sizeof(tag))) {
+            int32_t numChannelExpected = stoi(value);
+            int32_t numChannelFound = -1;
+            status = AMediaFormat_getInt32(fileMeta, key.c_str(), &numChannelFound);
+            ASSERT_TRUE(status) << "Failed to get the channel count";
+            ASSERT_EQ(numChannelExpected, numChannelFound);
+        } else if (!strncasecmp(tag.c_str(), "ANDROID_LOOP", sizeof(tag))) {
+            int32_t loopExpected = !value.compare("true");
+            int32_t loopFound = -1;
+
+            status = AMediaFormat_getInt32(fileMeta, "loop", &loopFound);
+            ASSERT_TRUE(status) << "Failed to get the loop count";
+            ASSERT_EQ(loopExpected, loopFound);
+        } else {
+            const char *tagValue = "";
+            status = AMediaFormat_getString(fileMeta, key.c_str(), &tagValue);
+            ASSERT_TRUE(status) << "Failed to get the tag value";
+            ASSERT_STREQ(value.c_str(), tagValue);
+        }
+        AMediaFormat_delete(fileMeta);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDTest,
+                         ::testing::Values(make_tuple("sps_pps_userdata.h264", 8, 8),
+                                           make_tuple("sps_userdata_pps.h264", 8, 8),
+                                           make_tuple("sps_pps_sps_pps.h264", 8, 8)));
+
+// TODO(b/158067691): Add invalid test vectors with incomplete PPS or no PPS
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDValidateTest,
+                         ::testing::Values("sps_pps_only_startcode.h264",
+                                           "sps_incomplete_pps.h264",
+                                           // TODO(b/158067691) "sps_pps_incomplete.h264",
+                                           "randomdata.h264",
+                                           // TODO(b/158067691) "sps.h264",
+                                           "pps.h264"));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDTest,
+                         ::testing::Values(make_tuple(AACObjectMain, 1, 1)));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacADTSTest,
+                         ::testing::Values(make_tuple("loudsoftaacadts", 1, 44100)));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDValidateTest,
+                         ::testing::Values("loudsoftaacadts_invalidheader",
+                                           "loudsoftaacadts_invalidprofile",
+                                           "loudsoftaacadts_invalidchannelconfig"));
+
+// TODO(b/157974508) Add test vector for vorbis thumbnail tag
+// Info file contains TAG, Key, Value and size of the vorbis comment
+INSTANTIATE_TEST_SUITE_P(
+        MetaDataUtilsTestAll, VorbisTest,
+        ::testing::Values(make_pair("vorbiscomment_sintel.dat", "vorbiscomment_sintel.info"),
+                          make_pair("vorbiscomment_album.dat", "vorbiscomment_album.info"),
+                          make_pair("vorbiscomment_loop.dat", "vorbiscomment_loop.info")));
+
+int main(int argc, char **argv) {
+    gEnv = new MetaDataUtilsTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h b/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
new file mode 100644
index 0000000..4d642bc
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __METADATA_UTILS_TEST_ENVIRONMENT_H__
+#define __METADATA_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class MetaDataUtilsTestEnvironment : public::testing::Environment {
+  public:
+    MetaDataUtilsTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int MetaDataUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __METADATA_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/metadatautils/README.md b/media/libstagefright/tests/metadatautils/README.md
new file mode 100644
index 0000000..0862a07
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### MetaDataUtils Test
+The MetaDataUtils Unit Test Suite validates the libstagefright_metadatautils library available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m MetaDataUtilsTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/MetaDataUtilsTest/MetaDataUtilsTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/MetaDataUtilsTest/MetaDataUtilsTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push MetaDataUtilsTestRes-1.0 /data/local/tmp/
+```
+
+usage: MetaDataUtilsTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/MetaDataUtilsTest -P /data/local/tmp/MetaDataUtilsTestRes-1.0/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest MetaDataUtilsTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/tests/writer/Android.bp b/media/libstagefright/tests/writer/Android.bp
index 7e169cb..b5d453e 100644
--- a/media/libstagefright/tests/writer/Android.bp
+++ b/media/libstagefright/tests/writer/Android.bp
@@ -28,13 +28,15 @@
         "libcutils",
         "liblog",
         "libutils",
+        "libmedia",
+        "libmediandk",
+        "libstagefright",
     ],
 
     static_libs: [
         "libstagefright_webm",
-        "libdatasource",
-        "libstagefright",
         "libstagefright_foundation",
+        "libdatasource",
         "libstagefright_esds",
         "libogg",
     ],
diff --git a/media/libstagefright/tests/writer/AndroidTest.xml b/media/libstagefright/tests/writer/AndroidTest.xml
index d831555..cc890fe 100644
--- a/media/libstagefright/tests/writer/AndroidTest.xml
+++ b/media/libstagefright/tests/writer/AndroidTest.xml
@@ -19,12 +19,13 @@
         <option name="cleanup" value="true" />
         <option name="push" value="writerTest->/data/local/tmp/writerTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/Writer.zip?unzip=true"
-            value="/data/local/tmp/writerTestRes/" />
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes-1.1.zip?unzip=true"
+            value="/data/local/tmp/WriterTestRes/" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="writerTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/writerTestRes/" />
+        <option name="native-test-flag" value="-P /data/local/tmp/WriterTestRes/" />
+        <option name="native-test-flag" value="-C true" />
     </test>
 </configuration>
diff --git a/media/libstagefright/tests/writer/README.md b/media/libstagefright/tests/writer/README.md
index ae07917..0e54ca7 100644
--- a/media/libstagefright/tests/writer/README.md
+++ b/media/libstagefright/tests/writer/README.md
@@ -19,13 +19,18 @@
 
 adb push ${OUT}/data/nativetest/writerTest/writerTest /data/local/tmp/
 
-The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/writerTestRes.zip).
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes-1.1.zip).
 Download and extract the folder. Push all the files in this folder to /data/local/tmp/ on the device.
 ```
-adb push writerTestRes /data/local/tmp/
+adb push WriterTestRes-1.1/. /data/local/tmp/WriterTestRes/
 ```
 
-usage: writerTest -P \<path_to_res_folder\>
+usage: writerTest -P \<path_to_res_folder\> -C <remove_output_file>
 ```
-adb shell /data/local/tmp/writerTest -P /data/local/tmp/
+adb shell /data/local/tmp/writerTest -P /data/local/tmp/WriterTestRes/ -C true
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest writerTest -- --enable-module-dynamic-download=true
 ```
diff --git a/media/libstagefright/tests/writer/WriterListener.h b/media/libstagefright/tests/writer/WriterListener.h
new file mode 100644
index 0000000..81f0a7c
--- /dev/null
+++ b/media/libstagefright/tests/writer/WriterListener.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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 WRITER_LISTENER_H_
+#define WRITER_LISTENER_H_
+
+#include <mutex>
+
+#include <media/IMediaRecorderClient.h>
+#include <media/mediarecorder.h>
+
+using namespace android;
+using namespace std;
+
+class WriterListener : public BnMediaRecorderClient {
+  public:
+    WriterListener() : mSignaledSize(false), mSignaledDuration(false) {}
+
+    virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
+        ALOGV("msg : %d, ext1 : %d, ext2 : %d", msg, ext1, ext2);
+        if (ext1 == MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
+            mSignaledSize = true;
+        } else if (ext1 == MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
+            mSignaledDuration = true;
+        }
+    }
+
+    volatile bool mSignaledSize;
+    volatile bool mSignaledDuration;
+};
+
+#endif  // WRITER_LISTENER_H_
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
index ff063e3..d170e7c 100644
--- a/media/libstagefright/tests/writer/WriterTest.cpp
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -18,9 +18,13 @@
 #define LOG_TAG "WriterTest"
 #include <utils/Log.h>
 
+#include <binder/ProcessState.h>
+
+#include <inttypes.h>
 #include <fstream>
 #include <iostream>
 
+#include <media/NdkMediaExtractor.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
@@ -39,18 +43,40 @@
 
 #define OUTPUT_FILE_NAME "/data/local/tmp/writer.out"
 
+// Stts values within 0.1ms(100us) difference are fudged to save too
+// many stts entries in MPEG4Writer.
+constexpr int32_t kMpeg4MuxToleranceTimeUs = 100;
+// Tolerance value for other writers
+constexpr int32_t kMuxToleranceTimeUs = 1;
+
 static WriterTestEnvironment *gEnv = nullptr;
 
-struct configFormat {
-    char mime[128];
-    int32_t width;
-    int32_t height;
-    int32_t sampleRate;
-    int32_t channelCount;
+enum inputId {
+    // audio streams
+    AAC_1,
+    AAC_ADTS_1,
+    AMR_NB_1,
+    AMR_WB_1,
+    FLAC_1,
+    OPUS_1,
+    VORBIS_1,
+    // video streams
+    AV1_1,
+    AVC_1,
+    H263_1,
+    HEVC_1,
+    MPEG4_1,
+    VP8_1,
+    VP9_1,
+    // heif stream
+    HEIC_1,
+    UNUSED_ID,
+    UNKNOWN_ID,
 };
 
 // LookUpTable of clips and metadata for component testing
 static const struct InputData {
+    inputId inpId;
     const char *mime;
     string inputFile;
     string info;
@@ -58,65 +84,73 @@
     int32_t secondParam;
     bool isAudio;
 } kInputData[] = {
-        {MEDIA_MIMETYPE_AUDIO_OPUS, "bbb_opus_stereo_128kbps_48000hz.opus",
-         "bbb_opus_stereo_128kbps_48000hz.info", 48000, 2, true},
-        {MEDIA_MIMETYPE_AUDIO_AAC, "bbb_aac_stereo_128kbps_48000hz.aac",
-         "bbb_aac_stereo_128kbps_48000hz.info", 48000, 2, true},
-        {MEDIA_MIMETYPE_AUDIO_AAC_ADTS, "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.adts",
+        {AAC_1, MEDIA_MIMETYPE_AUDIO_AAC, "audio_aac_stereo_8kbps_11025hz.aac",
+         "audio_aac_stereo_8kbps_11025hz.info", 11025, 2, true},
+        {AAC_ADTS_1, MEDIA_MIMETYPE_AUDIO_AAC_ADTS, "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.adts",
          "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.info", 48000, 2, true},
-        {MEDIA_MIMETYPE_AUDIO_AMR_NB, "sine_amrnb_1ch_12kbps_8000hz.amrnb",
+        {AMR_NB_1, MEDIA_MIMETYPE_AUDIO_AMR_NB, "sine_amrnb_1ch_12kbps_8000hz.amrnb",
          "sine_amrnb_1ch_12kbps_8000hz.info", 8000, 1, true},
-        {MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
+        {AMR_WB_1, MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
          "bbb_amrwb_1ch_14kbps_16000hz.info", 16000, 1, true},
-        {MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_vorbis_stereo_128kbps_48000hz.vorbis",
-         "bbb_vorbis_stereo_128kbps_48000hz.info", 48000, 2, true},
-        {MEDIA_MIMETYPE_AUDIO_FLAC, "bbb_flac_stereo_680kbps_48000hz.flac",
+        {FLAC_1, MEDIA_MIMETYPE_AUDIO_FLAC, "bbb_flac_stereo_680kbps_48000hz.flac",
          "bbb_flac_stereo_680kbps_48000hz.info", 48000, 2, true},
-        {MEDIA_MIMETYPE_VIDEO_VP9, "bbb_vp9_176x144_285kbps_60fps.vp9",
-         "bbb_vp9_176x144_285kbps_60fps.info", 176, 144, false},
-        {MEDIA_MIMETYPE_VIDEO_VP8, "bbb_vp8_176x144_240kbps_60fps.vp8",
-         "bbb_vp8_176x144_240kbps_60fps.info", 176, 144, false},
-        {MEDIA_MIMETYPE_VIDEO_AVC, "bbb_avc_176x144_300kbps_60fps.h264",
-         "bbb_avc_176x144_300kbps_60fps.info", 176, 144, false},
-        {MEDIA_MIMETYPE_VIDEO_HEVC, "bbb_hevc_176x144_176kbps_60fps.hevc",
-         "bbb_hevc_176x144_176kbps_60fps.info", 176, 144, false},
-        {MEDIA_MIMETYPE_VIDEO_AV1, "bbb_av1_176_144.av1", "bbb_av1_176_144.info", 176, 144, false},
-        {MEDIA_MIMETYPE_VIDEO_H263, "bbb_h263_352x288_300kbps_12fps.h263",
+        {OPUS_1, MEDIA_MIMETYPE_AUDIO_OPUS, "bbb_opus_stereo_128kbps_48000hz.opus",
+         "bbb_opus_stereo_128kbps_48000hz.info", 48000, 2, true},
+        {VORBIS_1, MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_vorbis_1ch_64kbps_16kHz.vorbis",
+         "bbb_vorbis_1ch_64kbps_16kHz.info", 16000, 1, true},
+
+        {AV1_1, MEDIA_MIMETYPE_VIDEO_AV1, "bbb_av1_176_144.av1", "bbb_av1_176_144.info", 176, 144,
+         false},
+        {AVC_1, MEDIA_MIMETYPE_VIDEO_AVC, "bbb_avc_352x288_768kbps_30fps.avc",
+         "bbb_avc_352x288_768kbps_30fps.info", 352, 288, false},
+        {H263_1, MEDIA_MIMETYPE_VIDEO_H263, "bbb_h263_352x288_300kbps_12fps.h263",
          "bbb_h263_352x288_300kbps_12fps.info", 352, 288, false},
-        {MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_mpeg4_352x288_512kbps_30fps.m4v",
+        {HEVC_1, MEDIA_MIMETYPE_VIDEO_HEVC, "bbb_hevc_340x280_768kbps_30fps.hevc",
+         "bbb_hevc_340x280_768kbps_30fps.info", 340, 280, false},
+        {MPEG4_1, MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_mpeg4_352x288_512kbps_30fps.m4v",
          "bbb_mpeg4_352x288_512kbps_30fps.info", 352, 288, false},
+        {VP8_1, MEDIA_MIMETYPE_VIDEO_VP8, "bbb_vp8_176x144_240kbps_60fps.vp8",
+         "bbb_vp8_176x144_240kbps_60fps.info", 176, 144, false},
+        {VP9_1, MEDIA_MIMETYPE_VIDEO_VP9, "bbb_vp9_176x144_285kbps_60fps.vp9",
+         "bbb_vp9_176x144_285kbps_60fps.info", 176, 144, false},
+
+        {HEIC_1, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, "bbb_hevc_176x144_176kbps_60fps.hevc",
+         "bbb_heic_176x144_176kbps_60fps.info", 176, 144, false},
 };
 
-class WriterTest : public ::testing::TestWithParam<pair<string, int32_t>> {
+class WriterTest {
   public:
-    WriterTest() : mWriter(nullptr), mFileMeta(nullptr), mCurrentTrack(nullptr) {}
+    WriterTest() : mWriter(nullptr), mFileMeta(nullptr) {}
 
     ~WriterTest() {
-        if (mWriter) {
-            mWriter.clear();
-            mWriter = nullptr;
-        }
         if (mFileMeta) {
             mFileMeta.clear();
             mFileMeta = nullptr;
         }
-        if (mCurrentTrack) {
-            mCurrentTrack.clear();
-            mCurrentTrack = nullptr;
+        if (mWriter) {
+            mWriter.clear();
+            mWriter = nullptr;
+        }
+        if (gEnv->cleanUp()) remove(OUTPUT_FILE_NAME);
+
+        for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+            mBufferInfo[idx].clear();
+            if (mCurrentTrack[idx]) {
+                mCurrentTrack[idx]->stop();
+                mCurrentTrack[idx].clear();
+                mCurrentTrack[idx] = nullptr;
+            }
+            if (mInputStream[idx].is_open()) mInputStream[idx].close();
         }
     }
 
-    virtual void SetUp() override {
-        mNumCsds = 0;
-        mInputFrameId = 0;
+    void setupWriterType(string writerFormat) {
         mWriterName = unknown_comp;
         mDisableTest = false;
-
         static const std::map<std::string, standardWriters> mapWriter = {
                 {"ogg", OGG},     {"aac", AAC},      {"aac_adts", AAC_ADTS}, {"webm", WEBM},
                 {"mpeg4", MPEG4}, {"amrnb", AMR_NB}, {"amrwb", AMR_WB},      {"mpeg2Ts", MPEG2TS}};
         // Find the component type
-        string writerFormat = GetParam().first;
         if (mapWriter.find(writerFormat) != mapWriter.end()) {
             mWriterName = mapWriter.at(writerFormat);
         }
@@ -126,16 +160,19 @@
         }
     }
 
-    virtual void TearDown() override {
-        mBufferInfo.clear();
-        if (mInputStream.is_open()) mInputStream.close();
-    }
-
-    void getInputBufferInfo(string inputFileName, string inputInfo);
+    void getInputBufferInfo(string inputFileName, string inputInfo, int32_t idx = 0);
 
     int32_t createWriter(int32_t fd);
 
-    int32_t addWriterSource(bool isAudio, configFormat params);
+    int32_t addWriterSource(bool isAudio, configFormat params, int32_t idx = 0);
+
+    void setupExtractor(AMediaExtractor *extractor, string inputFileName, int32_t &trackCount);
+
+    void extract(AMediaExtractor *extractor, configFormat &params, vector<BufferInfo> &bufferInfo,
+                 uint8_t *buffer, size_t bufSize, size_t *bytesExtracted, int32_t idx);
+
+    void compareParams(configFormat srcParam, configFormat dstParam, vector<BufferInfo> dstBufInfo,
+                       int32_t index);
 
     enum standardWriters {
         OGG,
@@ -152,32 +189,42 @@
     standardWriters mWriterName;
     sp<MediaWriter> mWriter;
     sp<MetaData> mFileMeta;
-    sp<MediaAdapter> mCurrentTrack;
+    sp<MediaAdapter> mCurrentTrack[kMaxTrackCount]{};
 
     bool mDisableTest;
-    int32_t mNumCsds;
-    int32_t mInputFrameId;
-    ifstream mInputStream;
-    vector<BufferInfo> mBufferInfo;
+    int32_t mNumCsds[kMaxTrackCount]{};
+    int32_t mInputFrameId[kMaxTrackCount]{};
+    ifstream mInputStream[kMaxTrackCount]{};
+    vector<BufferInfo> mBufferInfo[kMaxTrackCount];
 };
 
-void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo) {
+class WriteFunctionalityTest
+    : public WriterTest,
+      public ::testing::TestWithParam<tuple<string /* writerFormat*/, inputId /* inputId0*/,
+                                            inputId /* inputId1*/, float /* BufferInterval*/>> {
+  public:
+    virtual void SetUp() override { setupWriterType(get<0>(GetParam())); }
+};
+
+void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo, int32_t idx) {
     std::ifstream eleInfo;
     eleInfo.open(inputInfo.c_str());
     ASSERT_EQ(eleInfo.is_open(), true);
     int32_t bytesCount = 0;
     uint32_t flags = 0;
     int64_t timestamp = 0;
+    int32_t numCsds = 0;
     while (1) {
         if (!(eleInfo >> bytesCount)) break;
         eleInfo >> flags;
         eleInfo >> timestamp;
-        mBufferInfo.push_back({bytesCount, flags, timestamp});
-        if (flags == CODEC_CONFIG_FLAG) mNumCsds++;
+        mBufferInfo[idx].push_back({bytesCount, flags, timestamp});
+        if (flags == CODEC_CONFIG_FLAG) numCsds++;
     }
     eleInfo.close();
-    mInputStream.open(inputFileName.c_str(), std::ifstream::binary);
-    ASSERT_EQ(mInputStream.is_open(), true);
+    mNumCsds[idx] = numCsds;
+    mInputStream[idx].open(inputFileName.c_str(), std::ifstream::binary);
+    ASSERT_EQ(mInputStream[idx].is_open(), true);
 }
 
 int32_t WriterTest::createWriter(int32_t fd) {
@@ -223,10 +270,10 @@
     return 0;
 }
 
-int32_t WriterTest::addWriterSource(bool isAudio, configFormat params) {
-    if (mInputFrameId) return -1;
+int32_t WriterTest::addWriterSource(bool isAudio, configFormat params, int32_t idx) {
+    if (mInputFrameId[idx]) return -1;
     sp<AMessage> format = new AMessage;
-    if (mInputStream.is_open()) {
+    if (mInputStream[idx].is_open()) {
         format->setString("mime", params.mime);
         if (isAudio) {
             format->setInt32("channel-count", params.channelCount);
@@ -235,25 +282,34 @@
             format->setInt32("width", params.width);
             format->setInt32("height", params.height);
         }
-
-        int32_t status =
-                writeHeaderBuffers(mInputStream, mBufferInfo, mInputFrameId, format, mNumCsds);
-        if (status != 0) return -1;
+        if (mNumCsds[idx]) {
+            int32_t status = writeHeaderBuffers(mInputStream[idx], mBufferInfo[idx],
+                                                mInputFrameId[idx], format, mNumCsds[idx]);
+            if (status != 0) return -1;
+        }
     }
+
     sp<MetaData> trackMeta = new MetaData;
     convertMessageToMetaData(format, trackMeta);
-    mCurrentTrack = new MediaAdapter(trackMeta);
-    if (mCurrentTrack == nullptr) {
+    mCurrentTrack[idx] = new MediaAdapter(trackMeta);
+    if (mCurrentTrack[idx] == nullptr) {
         ALOGE("MediaAdapter returned nullptr");
         return -1;
     }
-    status_t result = mWriter->addSource(mCurrentTrack);
+    status_t result = mWriter->addSource(mCurrentTrack[idx]);
     return result;
 }
 
 void getFileDetails(string &inputFilePath, string &info, configFormat &params, bool &isAudio,
-                    int32_t streamIndex = 0) {
-    if (streamIndex >= sizeof(kInputData) / sizeof(kInputData[0])) {
+                    inputId inpId) {
+    int32_t inputDataSize = sizeof(kInputData) / sizeof(kInputData[0]);
+    int32_t streamIndex = 0;
+    for (; streamIndex < inputDataSize; streamIndex++) {
+        if (inpId == kInputData[streamIndex].inpId) {
+            break;
+        }
+    }
+    if (streamIndex == inputDataSize) {
         return;
     }
     inputFilePath += kInputData[streamIndex].inputFile;
@@ -270,7 +326,147 @@
     return;
 }
 
-TEST_P(WriterTest, CreateWriterTest) {
+void WriterTest::setupExtractor(AMediaExtractor *extractor, string inputFileName,
+                                int32_t &trackCount) {
+    ALOGV("Input file for extractor: %s", inputFileName.c_str());
+
+    int32_t fd = open(inputFileName.c_str(), O_RDONLY);
+    ASSERT_GE(fd, 0) << "Failed to open writer's output file to validate";
+
+    struct stat buf;
+    int32_t status = fstat(fd, &buf);
+    ASSERT_EQ(status, 0) << "Failed to get properties of input file for extractor";
+
+    size_t fileSize = buf.st_size;
+    ALOGV("Size of input file to extractor: %zu", fileSize);
+
+    status = AMediaExtractor_setDataSourceFd(extractor, fd, 0, fileSize);
+    ASSERT_EQ(status, AMEDIA_OK) << "Failed to set data source for extractor";
+
+    trackCount = AMediaExtractor_getTrackCount(extractor);
+    ASSERT_GT(trackCount, 0) << "No tracks reported by extractor";
+    ALOGV("Number of tracks reported by extractor : %d", trackCount);
+    return;
+}
+
+void WriterTest::extract(AMediaExtractor *extractor, configFormat &params,
+                         vector<BufferInfo> &bufferInfo, uint8_t *buffer, size_t bufSize,
+                         size_t *bytesExtracted, int32_t idx) {
+    AMediaExtractor_selectTrack(extractor, idx);
+    AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, idx);
+    ASSERT_NE(format, nullptr) << "Track format is NULL";
+    ALOGI("Track format = %s", AMediaFormat_toString(format));
+
+    const char *mime = nullptr;
+    AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+    ASSERT_NE(mime, nullptr) << "Track mime is NULL";
+    ALOGI("Track mime = %s", mime);
+    strlcpy(params.mime, mime, kMimeSize);
+
+    if (!strncmp(mime, "audio/", 6)) {
+        ASSERT_TRUE(
+                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &params.channelCount))
+                << "Extractor did not report channel count";
+        ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &params.sampleRate))
+                << "Extractor did not report sample rate";
+    } else if (!strncmp(mime, "video/", 6) || !strncmp(mime, "image/", 6)) {
+        ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &params.width))
+                << "Extractor did not report width";
+        ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &params.height))
+                << "Extractor did not report height";
+    } else {
+        ASSERT_TRUE(false) << "Invalid mime " << mime;
+    }
+
+    int32_t bufferOffset = 0;
+    // Get CSD data
+    int index = 0;
+    void *csdBuf;
+    while (1) {
+        csdBuf = nullptr;
+        char csdName[16];
+        snprintf(csdName, 16, "csd-%d", index);
+        size_t csdSize = 0;
+        bool csdFound = AMediaFormat_getBuffer(format, csdName, &csdBuf, &csdSize);
+        if (!csdFound || !csdBuf || !csdSize) break;
+
+        bufferInfo.push_back({static_cast<int32_t>(csdSize), CODEC_CONFIG_FLAG, 0});
+        memcpy(buffer + bufferOffset, csdBuf, csdSize);
+        bufferOffset += csdSize;
+        index++;
+    }
+
+    // Get frame data
+    while (1) {
+        ssize_t sampleSize = AMediaExtractor_getSampleSize(extractor);
+        if (sampleSize < 0) break;
+
+        uint8_t *sampleBuffer = (uint8_t *)malloc(sampleSize);
+        ASSERT_NE(sampleBuffer, nullptr) << "Failed to allocate the buffer of size " << sampleSize;
+
+        int bytesRead = AMediaExtractor_readSampleData(extractor, sampleBuffer, sampleSize);
+        ASSERT_EQ(bytesRead, sampleSize)
+                << "Number of bytes extracted does not match with sample size";
+        int64_t pts = AMediaExtractor_getSampleTime(extractor);
+        uint32_t flag = AMediaExtractor_getSampleFlags(extractor);
+
+        if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
+            // Removing 4 bytes of AMEDIAFORMAT_KEY_VALID_SAMPLES from sample size
+            bytesRead = bytesRead - 4;
+        }
+
+        ASSERT_LE(bufferOffset + bytesRead, bufSize)
+                << "Size of the buffer is insufficient to store the extracted data";
+        bufferInfo.push_back({bytesRead, flag, pts});
+        memcpy(buffer + bufferOffset, sampleBuffer, bytesRead);
+        bufferOffset += bytesRead;
+
+        AMediaExtractor_advance(extractor);
+        free(sampleBuffer);
+    }
+    *bytesExtracted = bufferOffset;
+    return;
+}
+
+void WriterTest::compareParams(configFormat srcParam, configFormat dstParam,
+                               vector<BufferInfo> dstBufInfo, int32_t index) {
+    ASSERT_STREQ(srcParam.mime, dstParam.mime)
+            << "Extracted mime type does not match with input mime type";
+
+    if (!strncmp(srcParam.mime, "audio/", 6)) {
+        ASSERT_EQ(srcParam.channelCount, dstParam.channelCount)
+                << "Extracted channel count does not match with input channel count";
+        ASSERT_EQ(srcParam.sampleRate, dstParam.sampleRate)
+                << "Extracted sample rate does not match with input sample rate";
+    } else if (!strncmp(srcParam.mime, "video/", 6) || !strncmp(srcParam.mime, "image/", 6)) {
+        ASSERT_EQ(srcParam.width, dstParam.width)
+                << "Extracted width does not match with input width";
+        ASSERT_EQ(srcParam.height, dstParam.height)
+                << "Extracted height does not match with input height";
+    } else {
+        ASSERT_TRUE(false) << "Invalid mime type" << srcParam.mime;
+    }
+
+    int32_t toleranceValueUs = kMuxToleranceTimeUs;
+    if (mWriterName == MPEG4) {
+        toleranceValueUs = kMpeg4MuxToleranceTimeUs;
+    }
+    for (int32_t i = 0; i < dstBufInfo.size(); i++) {
+        ASSERT_EQ(mBufferInfo[index][i].size, dstBufInfo[i].size)
+                << "Input size " << mBufferInfo[index][i].size << " mismatched with extracted size "
+                << dstBufInfo[i].size;
+        ASSERT_EQ(mBufferInfo[index][i].flags, dstBufInfo[i].flags)
+                << "Input flag " << mBufferInfo[index][i].flags
+                << " mismatched with extracted size " << dstBufInfo[i].flags;
+        ASSERT_LE(abs(mBufferInfo[index][i].timeUs - dstBufInfo[i].timeUs), toleranceValueUs)
+                << "Difference between original timestamp " << mBufferInfo[index][i].timeUs
+                << " and extracted timestamp " << dstBufInfo[i].timeUs
+                << "is greater than tolerance value = " << toleranceValueUs << " micro seconds";
+    }
+    return;
+}
+
+TEST_P(WriteFunctionalityTest, CreateWriterTest) {
     if (mDisableTest) return;
     ALOGV("Tests the creation of writers");
 
@@ -281,14 +477,14 @@
 
     // Creating writer within a test scope. Destructor should be called when the test ends
     ASSERT_EQ((status_t)OK, createWriter(fd))
-            << "Failed to create writer for output format:" << GetParam().first;
+            << "Failed to create writer for output format:" << get<0>(GetParam());
 }
 
-TEST_P(WriterTest, WriterTest) {
+TEST_P(WriteFunctionalityTest, WriterTest) {
     if (mDisableTest) return;
     ALOGV("Checks if for a given input, a valid muxed file has been created or not");
 
-    string writerFormat = GetParam().first;
+    string writerFormat = get<0>(GetParam());
     string outputFile = OUTPUT_FILE_NAME;
     int32_t fd =
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
@@ -297,35 +493,110 @@
     int32_t status = createWriter(fd);
     ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
 
-    string inputFile = gEnv->getRes();
-    string inputInfo = gEnv->getRes();
-    configFormat param;
-    bool isAudio;
-    int32_t inputFileIdx = GetParam().second;
-    getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
-    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+    inputId inpId[] = {get<1>(GetParam()), get<2>(GetParam())};
+    ASSERT_NE(inpId[0], UNUSED_ID) << "Test expects first inputId to be a valid id";
 
-    ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
-    status = addWriterSource(isAudio, param);
-    ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+    int32_t numTracks = 1;
+    if (inpId[1] != UNUSED_ID) {
+        numTracks++;
+    }
+
+    size_t fileSize[numTracks];
+    configFormat param[numTracks];
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        string inputFile = gEnv->getRes();
+        string inputInfo = gEnv->getRes();
+        bool isAudio;
+        getFileDetails(inputFile, inputInfo, param[idx], isAudio, inpId[idx]);
+        ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+        struct stat buf;
+        status = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(status, 0) << "Failed to get properties of input file:" << inputFile;
+        fileSize[idx] = buf.st_size;
+
+        ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo, idx));
+        status = addWriterSource(isAudio, param[idx], idx);
+        ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+    }
 
     status = mWriter->start(mFileMeta.get());
     ASSERT_EQ((status_t)OK, status);
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
-                                 mBufferInfo.size());
-    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
-    mCurrentTrack->stop();
+    float interval = get<3>(GetParam());
+    ASSERT_LE(interval, 1.0f) << "Buffer interval invalid. Should be less than or equal to 1.0";
 
+    size_t range = 0;
+    int32_t loopCount = 0;
+    int32_t offset[kMaxTrackCount]{};
+    while (loopCount < ceil(1.0 / interval)) {
+        for (int32_t idx = 0; idx < numTracks; idx++) {
+            range = mBufferInfo[idx].size() * interval;
+            status = sendBuffersToWriter(mInputStream[idx], mBufferInfo[idx], mInputFrameId[idx],
+                                         mCurrentTrack[idx], offset[idx], range);
+            ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+            offset[idx] += range;
+        }
+        loopCount++;
+    }
+    for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+        if (mCurrentTrack[idx]) {
+            mCurrentTrack[idx]->stop();
+        }
+    }
     status = mWriter->stop();
     ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
     close(fd);
+
+    // Validate the output muxed file created by writer
+    // TODO(b/146423022): Skip validating output for webm writer
+    // TODO(b/146421018): Skip validating output for ogg writer
+    if (mWriterName != OGG && mWriterName != WEBM) {
+        configFormat extractorParams[numTracks];
+        vector<BufferInfo> extractorBufferInfo[numTracks];
+        int32_t trackCount = -1;
+
+        AMediaExtractor *extractor = AMediaExtractor_new();
+        ASSERT_NE(extractor, nullptr) << "Failed to create extractor";
+        ASSERT_NO_FATAL_FAILURE(setupExtractor(extractor, outputFile, trackCount));
+        ASSERT_EQ(trackCount, numTracks)
+                << "Tracks reported by extractor does not match with input number of tracks";
+
+        for (int32_t idx = 0; idx < numTracks; idx++) {
+            char *inputBuffer = (char *)malloc(fileSize[idx]);
+            ASSERT_NE(inputBuffer, nullptr)
+                    << "Failed to allocate the buffer of size " << fileSize[idx];
+            mInputStream[idx].seekg(0, mInputStream[idx].beg);
+            mInputStream[idx].read(inputBuffer, fileSize[idx]);
+            ASSERT_EQ(mInputStream[idx].gcount(), fileSize[idx]);
+
+            uint8_t *extractedBuffer = (uint8_t *)malloc(fileSize[idx]);
+            ASSERT_NE(extractedBuffer, nullptr)
+                    << "Failed to allocate the buffer of size " << fileSize[idx];
+            size_t bytesExtracted = 0;
+
+            ASSERT_NO_FATAL_FAILURE(extract(extractor, extractorParams[idx],
+                                            extractorBufferInfo[idx], extractedBuffer,
+                                            fileSize[idx], &bytesExtracted, idx));
+            ASSERT_GT(bytesExtracted, 0) << "Total bytes extracted by extractor cannot be zero";
+
+            ASSERT_NO_FATAL_FAILURE(
+                    compareParams(param[idx], extractorParams[idx], extractorBufferInfo[idx], idx));
+
+            ASSERT_EQ(memcmp(extractedBuffer, (uint8_t *)inputBuffer, bytesExtracted), 0)
+                    << "Extracted bit stream does not match with input bit stream";
+
+            free(inputBuffer);
+            free(extractedBuffer);
+        }
+        AMediaExtractor_delete(extractor);
+    }
 }
 
-TEST_P(WriterTest, PauseWriterTest) {
+TEST_P(WriteFunctionalityTest, PauseWriterTest) {
     if (mDisableTest) return;
     ALOGV("Validates the pause() api of writers");
 
-    string writerFormat = GetParam().first;
+    string writerFormat = get<0>(GetParam());
     string outputFile = OUTPUT_FILE_NAME;
     int32_t fd =
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
@@ -338,8 +609,10 @@
     string inputInfo = gEnv->getRes();
     configFormat param;
     bool isAudio;
-    int32_t inputFileIdx = GetParam().second;
-    getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+    inputId inpId = get<1>(GetParam());
+    ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
     ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
 
     ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
@@ -348,8 +621,8 @@
 
     status = mWriter->start(mFileMeta.get());
     ASSERT_EQ((status_t)OK, status);
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
-                                 mBufferInfo.size() / 4);
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], 0, mBufferInfo[0].size() / 4);
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
     bool isPaused = false;
@@ -359,26 +632,26 @@
         isPaused = true;
     }
     // In the pause state, writers shouldn't write anything. Testing the writers for the same
-    int32_t numFramesPaused = mBufferInfo.size() / 4;
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
-                                  mInputFrameId, numFramesPaused, isPaused);
+    int32_t numFramesPaused = mBufferInfo[0].size() / 4;
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], mInputFrameId[0], numFramesPaused, isPaused);
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
     if (isPaused) {
         status = mWriter->start(mFileMeta.get());
         ASSERT_EQ((status_t)OK, status);
     }
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
-                                  mInputFrameId, mBufferInfo.size());
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], mInputFrameId[0], mBufferInfo[0].size());
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
-    mCurrentTrack->stop();
+    mCurrentTrack[0]->stop();
 
     status = mWriter->stop();
     ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
     close(fd);
 }
 
-TEST_P(WriterTest, MultiStartStopPauseTest) {
+TEST_P(WriteFunctionalityTest, MultiStartStopPauseTest) {
     // TODO: (b/144821804)
     // Enable the test for MPE2TS writer
     if (mDisableTest || mWriterName == standardWriters::MPEG2TS) return;
@@ -389,7 +662,7 @@
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
     ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
 
-    string writerFormat = GetParam().first;
+    string writerFormat = get<0>(GetParam());
     int32_t status = createWriter(fd);
     ASSERT_EQ(status, (status_t)OK) << "Failed to create writer for output format:" << writerFormat;
 
@@ -397,8 +670,10 @@
     string inputInfo = gEnv->getRes();
     configFormat param;
     bool isAudio;
-    int32_t inputFileIdx = GetParam().second;
-    getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+    inputId inpId = get<1>(GetParam());
+    ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
     ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
 
     ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
@@ -415,8 +690,8 @@
         mWriter->start(mFileMeta.get());
     }
 
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
-                              mBufferInfo.size() / 4);
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], 0, mBufferInfo[0].size() / 4);
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
     for (int32_t count = 0; count < kMaxCount; count++) {
@@ -425,20 +700,20 @@
     }
 
     mWriter->pause();
-    int32_t numFramesPaused = mBufferInfo.size() / 4;
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
-                              mInputFrameId, numFramesPaused, true);
+    int32_t numFramesPaused = mBufferInfo[0].size() / 4;
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], mInputFrameId[0], numFramesPaused, true);
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
     for (int32_t count = 0; count < kMaxCount; count++) {
         mWriter->start(mFileMeta.get());
     }
 
-    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
-                              mInputFrameId, mBufferInfo.size());
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], mInputFrameId[0], mBufferInfo[0].size());
     ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
-    mCurrentTrack->stop();
+    mCurrentTrack[0]->stop();
 
     // first stop should succeed.
     status = mWriter->stop();
@@ -451,19 +726,380 @@
     close(fd);
 }
 
+class WriterValidityTest
+    : public WriterTest,
+      public ::testing::TestWithParam<
+              tuple<string /* writerFormat*/, inputId /* inputId0*/, bool /* addSourceFail*/>> {
+  public:
+    virtual void SetUp() override { setupWriterType(get<0>(GetParam())); }
+};
+
+TEST_P(WriterValidityTest, InvalidInputTest) {
+    if (mDisableTest) return;
+    ALOGV("Validates writer's behavior for invalid inputs");
+
+    string writerFormat = get<0>(GetParam());
+    inputId inpId = get<1>(GetParam());
+    bool addSourceFailExpected = get<2>(GetParam());
+
+    // Test writers for invalid FD value
+    int32_t fd = -1;
+    int32_t status = createWriter(fd);
+    if (status != OK) {
+        ALOGV("createWriter failed for invalid FD, this is expected behavior");
+        return;
+    }
+
+    // If writer was created for invalid fd, test it further.
+    string inputFile = gEnv->getRes();
+    string inputInfo = gEnv->getRes();
+    configFormat param;
+    bool isAudio;
+    ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+    ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
+    status = addWriterSource(isAudio, param);
+    if (status != OK) {
+        ASSERT_TRUE(addSourceFailExpected)
+                << "Failed to add source for " << writerFormat << " writer";
+        ALOGV("addWriterSource failed for invalid FD, this is expected behavior");
+        return;
+    }
+
+    // start the writer with valid argument but invalid FD
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_NE((status_t)OK, status) << "Writer did not fail for invalid FD";
+
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], 0, mBufferInfo[0].size());
+    ASSERT_NE((status_t)OK, status) << "Writer did not report error for invalid FD";
+
+    status = mCurrentTrack[0]->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the track";
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop " << writerFormat << " writer";
+}
+
+TEST_P(WriterValidityTest, MalFormedDataTest) {
+    if (mDisableTest) return;
+    // Enable test for Ogg writer
+    ASSERT_NE(mWriterName, OGG) << "TODO(b/160105646)";
+    ALOGV("Test writer for malformed inputs");
+
+    string writerFormat = get<0>(GetParam());
+    inputId inpId = get<1>(GetParam());
+    bool addSourceFailExpected = get<2>(GetParam());
+    int32_t fd =
+            open(OUTPUT_FILE_NAME, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
+    int32_t status = createWriter(fd);
+    ASSERT_EQ(status, (status_t)OK)
+            << "Failed to create writer for " << writerFormat << " output format";
+
+    string inputFile = gEnv->getRes();
+    string inputInfo = gEnv->getRes();
+    configFormat param;
+    bool isAudio;
+    ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+    ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
+    // Remove CSD data from input
+    mNumCsds[0] = 0;
+    status = addWriterSource(isAudio, param);
+    if (status != OK) {
+        ASSERT_TRUE(addSourceFailExpected)
+                << "Failed to add source for " << writerFormat << " writer";
+        ALOGV("%s writer failed to addSource after removing CSD from input", writerFormat.c_str());
+        return;
+    }
+
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status) << "Could not start " << writerFormat << "writer";
+
+    // Skip first few frames. These may contain sync frames also.
+    int32_t frameID = mInputFrameId[0] + mBufferInfo[0].size() / 4;
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], frameID, mCurrentTrack[0], 0,
+                                 mBufferInfo[0].size());
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+    status = mCurrentTrack[0]->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the track";
+
+    Vector<String16> args;
+    status = mWriter->dump(fd, args);
+    ASSERT_EQ((status_t)OK, status) << "Failed to dump statistics from writer";
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop " << writerFormat << " writer";
+    close(fd);
+}
+
+// This test is specific to MPEG4Writer to test more APIs
+TEST_P(WriteFunctionalityTest, Mpeg4WriterTest) {
+    if (mDisableTest) return;
+    if (mWriterName != standardWriters::MPEG4) return;
+    ALOGV("Test MPEG4 writer specific APIs");
+
+    inputId inpId = get<1>(GetParam());
+    int32_t fd =
+            open(OUTPUT_FILE_NAME, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
+    int32_t status = createWriter(fd);
+    ASSERT_EQ(status, (status_t)OK) << "Failed to create writer for mpeg4 output format";
+
+    string inputFile = gEnv->getRes();
+    string inputInfo = gEnv->getRes();
+    configFormat param;
+    bool isAudio;
+    ASSERT_NE(inpId, UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    getFileDetails(inputFile, inputInfo, param, isAudio, inpId);
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+    ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo));
+    status = addWriterSource(isAudio, param);
+    ASSERT_EQ((status_t)OK, status) << "Failed to add source for mpeg4 Writer";
+
+    // signal meta data for the writer
+    sp<MPEG4Writer> mp4writer = static_cast<MPEG4Writer *>(mWriter.get());
+    status = mp4writer->setInterleaveDuration(kDefaultInterleaveDuration);
+    ASSERT_EQ((status_t)OK, status) << "setInterleaveDuration failed";
+
+    status = mp4writer->setGeoData(kDefaultLatitudex10000, kDefaultLongitudex10000);
+    ASSERT_EQ((status_t)OK, status) << "setGeoData failed";
+
+    status = mp4writer->setCaptureRate(kDefaultFPS);
+    ASSERT_EQ((status_t)OK, status) << "setCaptureRate failed";
+
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status) << "Could not start the writer";
+
+    status = sendBuffersToWriter(mInputStream[0], mBufferInfo[0], mInputFrameId[0],
+                                 mCurrentTrack[0], 0, mBufferInfo[0].size());
+    ASSERT_EQ((status_t)OK, status) << "mpeg4 writer failed";
+
+    status = mCurrentTrack[0]->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the track";
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+    mp4writer.clear();
+    close(fd);
+}
+
+class ListenerTest
+    : public WriterTest,
+      public ::testing::TestWithParam<tuple<
+              string /* writerFormat*/, inputId /* inputId0*/, inputId /* inputId1*/,
+              float /* FileSizeLimit*/, float /* FileDurationLimit*/, float /* BufferInterval*/>> {
+  public:
+    virtual void SetUp() override { setupWriterType(get<0>(GetParam())); }
+};
+
+TEST_P(ListenerTest, SetMaxFileLimitsTest) {
+    // TODO(b/151892414): Enable test for other writers
+    if (mDisableTest || mWriterName != MPEG4) return;
+    ALOGV("Validates writer when max file limits are set");
+
+    string writerFormat = get<0>(GetParam());
+    string outputFile = OUTPUT_FILE_NAME;
+    int32_t fd =
+            open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
+    int32_t status = createWriter(fd);
+    ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
+
+    inputId inpId[] = {get<1>(GetParam()), get<2>(GetParam())};
+    ASSERT_NE(inpId[0], UNUSED_ID) << "Test expects first inputId to be a valid id";
+
+    size_t inputFileSize = 0;
+    int64_t lastFrameTimeStampUs = INT_MAX;
+    int32_t numTracks = 1;
+    if (inpId[1] != UNUSED_ID) {
+        numTracks++;
+    }
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        string inputFile = gEnv->getRes();
+        string inputInfo = gEnv->getRes();
+        configFormat param;
+        bool isAudio;
+        getFileDetails(inputFile, inputInfo, param, isAudio, inpId[idx]);
+        ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+        ASSERT_NO_FATAL_FAILURE(getInputBufferInfo(inputFile, inputInfo, idx));
+        status = addWriterSource(isAudio, param, idx);
+        ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+        // Read file properties
+        struct stat buf;
+        status = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(0, status);
+
+        inputFileSize += buf.st_size;
+        if (lastFrameTimeStampUs > mBufferInfo[idx][mBufferInfo[idx].size() - 1].timeUs) {
+            lastFrameTimeStampUs = mBufferInfo[idx][mBufferInfo[idx].size() - 1].timeUs;
+        }
+    }
+
+    float fileSizeLimit = get<3>(GetParam());
+    float fileDurationLimit = get<4>(GetParam());
+    int64_t maxFileSize = 0;
+    int64_t maxFileDuration = 0;
+    if (fileSizeLimit > 0) {
+        maxFileSize = (int64_t)(fileSizeLimit * inputFileSize);
+        mWriter->setMaxFileSize(maxFileSize);
+    }
+    if (fileDurationLimit > 0) {
+        maxFileDuration = (int64_t)(fileDurationLimit * lastFrameTimeStampUs);
+        mWriter->setMaxFileDuration(maxFileDuration);
+    }
+
+    sp<WriterListener> listener = new WriterListener();
+    ASSERT_NE(listener, nullptr) << "unable to allocate listener";
+
+    mWriter->setListener(listener);
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status);
+
+    float interval = get<5>(GetParam());
+    ASSERT_LE(interval, 1.0f) << "Buffer interval invalid. Should be less than or equal to 1.0";
+
+    size_t range = 0;
+    int32_t loopCount = 0;
+    int32_t offset[kMaxTrackCount]{};
+    while (loopCount < ceil(1.0 / interval)) {
+        for (int32_t idx = 0; idx < numTracks; idx++) {
+            range = mBufferInfo[idx].size() * interval;
+            status = sendBuffersToWriter(mInputStream[idx], mBufferInfo[idx], mInputFrameId[idx],
+                                         mCurrentTrack[idx], offset[idx], range, false, listener);
+            ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+            offset[idx] += range;
+        }
+        loopCount++;
+    }
+
+    ASSERT_TRUE(mWriter->reachedEOS()) << "EOS not signalled.";
+
+    for (int32_t idx = 0; idx < kMaxTrackCount; idx++) {
+        if (mCurrentTrack[idx]) {
+            mCurrentTrack[idx]->stop();
+        }
+    }
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+    close(fd);
+
+    if (maxFileSize <= 0) {
+        ASSERT_FALSE(listener->mSignaledSize);
+    } else if (maxFileDuration <= 0) {
+        ASSERT_FALSE(listener->mSignaledDuration);
+    } else if (maxFileSize > 0 && maxFileDuration <= 0) {
+        ASSERT_TRUE(listener->mSignaledSize);
+    } else if (maxFileDuration > 0 && maxFileSize <= 0) {
+        ASSERT_TRUE(listener->mSignaledDuration);
+    } else {
+        ASSERT_TRUE(listener->mSignaledSize || listener->mSignaledDuration);
+    }
+
+    if (maxFileSize > 0) {
+        struct stat buf;
+        status = stat(outputFile.c_str(), &buf);
+        ASSERT_EQ(0, status);
+        ASSERT_LE(buf.st_size, maxFileSize);
+    }
+}
+
+// TODO: (b/150923387)
+// Add WEBM input
+INSTANTIATE_TEST_SUITE_P(ListenerTestAll, ListenerTest,
+                         ::testing::Values(make_tuple("aac", AAC_1, UNUSED_ID, 0.6, 0.7, 1),
+                                           make_tuple("amrnb", AMR_NB_1, UNUSED_ID, 0.2, 0.6, 1),
+                                           make_tuple("amrwb", AMR_WB_1, UNUSED_ID, 0.5, 0.5, 1),
+                                           make_tuple("mpeg2Ts", AAC_1, UNUSED_ID, 0.2, 1, 1),
+                                           make_tuple("mpeg4", AAC_1, UNUSED_ID, 0.4, 0.3, 0.25),
+                                           make_tuple("mpeg4", AAC_1, UNUSED_ID, 0.3, 1, 0.5),
+                                           make_tuple("ogg", OPUS_1, UNUSED_ID, 0.7, 0.3, 1)));
+
 // TODO: (b/144476164)
 // Add AAC_ADTS, FLAC, AV1 input
-INSTANTIATE_TEST_SUITE_P(WriterTestAll, WriterTest,
-                         ::testing::Values(make_pair("ogg", 0), make_pair("webm", 0),
-                                           make_pair("aac", 1), make_pair("mpeg4", 1),
-                                           make_pair("amrnb", 3), make_pair("amrwb", 4),
-                                           make_pair("webm", 5), make_pair("webm", 7),
-                                           make_pair("webm", 8), make_pair("mpeg4", 9),
-                                           make_pair("mpeg4", 10), make_pair("mpeg4", 12),
-                                           make_pair("mpeg4", 13), make_pair("mpeg2Ts", 1),
-                                           make_pair("mpeg2Ts", 9)));
+INSTANTIATE_TEST_SUITE_P(
+        WriterTestAll, WriteFunctionalityTest,
+        ::testing::Values(
+                make_tuple("aac", AAC_1, UNUSED_ID, 1),
+
+                make_tuple("amrnb", AMR_NB_1, UNUSED_ID, 1),
+                make_tuple("amrwb", AMR_WB_1, UNUSED_ID, 1),
+
+                // TODO(b/144902018): Enable test for mpeg2ts
+                // make_tuple("mpeg2Ts", AAC_1, UNUSED_ID, 1),
+                // make_tuple("mpeg2Ts", AVC_1, UNUSED_ID, 1),
+                // TODO(b/156355857): Add multitrack for mpeg2ts
+                // make_tuple("mpeg2Ts", AAC_1, AVC_1, 0.50),
+                // make_tuple("mpeg2Ts", AVC_1, AAC_1, 0.25),
+
+                make_tuple("mpeg4", AAC_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", AMR_NB_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", AMR_WB_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", AVC_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", H263_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", HEIC_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", HEVC_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", MPEG4_1, UNUSED_ID, 1),
+                make_tuple("mpeg4", AAC_1, AVC_1, 0.25),
+                make_tuple("mpeg4", AVC_1, AAC_1, 0.75),
+                make_tuple("mpeg4", AMR_WB_1, AAC_1, 0.75),
+                make_tuple("mpeg4", HEVC_1, AMR_WB_1, 0.25),
+                make_tuple("mpeg4", H263_1, AMR_NB_1, 0.50),
+                make_tuple("mpeg4", MPEG4_1, AAC_1, 0.75),
+                make_tuple("mpeg4", AMR_NB_1, AMR_WB_1, 0.25),
+                make_tuple("mpeg4", H263_1, AMR_NB_1, 0.50),
+                make_tuple("mpeg4", MPEG4_1, HEVC_1, 0.75),
+
+                make_tuple("ogg", OPUS_1, UNUSED_ID, 1),
+
+                make_tuple("webm", OPUS_1, UNUSED_ID, 1),
+                make_tuple("webm", VORBIS_1, UNUSED_ID, 1),
+                make_tuple("webm", VP8_1, UNUSED_ID, 1),
+                make_tuple("webm", VP9_1, UNUSED_ID, 1),
+                make_tuple("webm", VP8_1, OPUS_1, 0.50),
+                make_tuple("webm", VORBIS_1, VP8_1, 0.25)));
+
+INSTANTIATE_TEST_SUITE_P(
+        WriterValidityTest, WriterValidityTest,
+        ::testing::Values(
+                make_tuple("aac", AAC_1, true),
+
+                make_tuple("amrnb", AMR_NB_1, true),
+                make_tuple("amrwb", AMR_WB_1, true),
+
+                make_tuple("mpeg4", AAC_1, false),
+                make_tuple("mpeg4", AMR_NB_1, false),
+                make_tuple("mpeg4", AVC_1, false),
+                make_tuple("mpeg4", H263_1, false),
+                make_tuple("mpeg4", HEIC_1, false),
+                make_tuple("mpeg4", HEVC_1, false),
+                make_tuple("mpeg4", MPEG4_1, false),
+
+                make_tuple("ogg", OPUS_1, true),
+
+                make_tuple("webm", OPUS_1, false),
+                make_tuple("webm", VORBIS_1, true),
+                make_tuple("webm", VP8_1, false),
+                make_tuple("webm", VP9_1, false)));
 
 int main(int argc, char **argv) {
+    ProcessState::self()->startThreadPool();
     gEnv = new WriterTestEnvironment();
     ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/media/libstagefright/tests/writer/WriterTestEnvironment.h b/media/libstagefright/tests/writer/WriterTestEnvironment.h
index 99e686f..7da0a62 100644
--- a/media/libstagefright/tests/writer/WriterTestEnvironment.h
+++ b/media/libstagefright/tests/writer/WriterTestEnvironment.h
@@ -25,7 +25,7 @@
 
 class WriterTestEnvironment : public ::testing::Environment {
   public:
-    WriterTestEnvironment() : res("/data/local/tmp/") {}
+    WriterTestEnvironment() : res("/data/local/tmp/"), deleteOutput(true) {}
 
     // Parses the command line arguments
     int initFromOptions(int argc, char **argv);
@@ -34,16 +34,21 @@
 
     const string getRes() const { return res; }
 
+    bool cleanUp() const { return deleteOutput; }
+
   private:
     string res;
+    bool deleteOutput;
 };
 
 int WriterTestEnvironment::initFromOptions(int argc, char **argv) {
-    static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+    static struct option options[] = {{"res", required_argument, 0, 'P'},
+                                      {"cleanUp", optional_argument, 0, 'C'},
+                                      {0, 0, 0, 0}};
 
     while (true) {
         int index = 0;
-        int c = getopt_long(argc, argv, "P:", options, &index);
+        int c = getopt_long(argc, argv, "P:C:", options, &index);
         if (c == -1) {
             break;
         }
@@ -52,6 +57,11 @@
             case 'P':
                 setRes(optarg);
                 break;
+            case 'C':
+                if (!strcmp(optarg, "false")) {
+                    deleteOutput = false;
+                }
+                break;
             default:
                 break;
         }
@@ -62,7 +72,8 @@
                 "unrecognized option: %s\n\n"
                 "usage: %s <gtest options> <test options>\n\n"
                 "test options are:\n\n"
-                "-P, --path: Resource files directory location\n",
+                "-P, --path: Resource files directory location\n"
+                "-C, default:true. Delete output file after test completes\n",
                 argv[optind ?: 1], argv[0]);
         return 2;
     }
diff --git a/media/libstagefright/tests/writer/WriterUtility.cpp b/media/libstagefright/tests/writer/WriterUtility.cpp
index f24ccb6..a3043fe 100644
--- a/media/libstagefright/tests/writer/WriterUtility.cpp
+++ b/media/libstagefright/tests/writer/WriterUtility.cpp
@@ -24,9 +24,16 @@
 
 int32_t sendBuffersToWriter(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
                             int32_t &inputFrameId, sp<MediaAdapter> &currentTrack, int32_t offset,
-                            int32_t range, bool isPaused) {
+                            int32_t range, bool isPaused, sp<WriterListener> listener) {
     while (1) {
         if (inputFrameId >= (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
+        if (listener != nullptr) {
+            if (listener->mSignaledDuration || listener->mSignaledSize) {
+                ALOGV("Max File limit reached. No more buffers will be sent to the writer");
+                break;
+            }
+        }
+
         int32_t size = bufferInfo[inputFrameId].size;
         char *data = (char *)malloc(size);
         if (!data) {
diff --git a/media/libstagefright/tests/writer/WriterUtility.h b/media/libstagefright/tests/writer/WriterUtility.h
index cdd6246..6b456fb 100644
--- a/media/libstagefright/tests/writer/WriterUtility.h
+++ b/media/libstagefright/tests/writer/WriterUtility.h
@@ -27,13 +27,19 @@
 
 #include <media/stagefright/MediaAdapter.h>
 
-using namespace android;
-using namespace std;
+#include "WriterListener.h"
 
 #define CODEC_CONFIG_FLAG 32
 
+constexpr uint32_t kMaxTrackCount = 2;
 constexpr uint32_t kMaxCSDStrlen = 16;
 constexpr uint32_t kMaxCount = 20;
+constexpr int32_t kMimeSize = 128;
+constexpr int32_t kDefaultInterleaveDuration = 0;
+// Geodata is set according to ISO-6709 standard.
+constexpr int32_t kDefaultLatitudex10000 = 500000;
+constexpr int32_t kDefaultLongitudex10000 = 1000000;
+constexpr float kDefaultFPS = 30.0f;
 
 struct BufferInfo {
     int32_t size;
@@ -41,9 +47,18 @@
     int64_t timeUs;
 };
 
+struct configFormat {
+    char mime[kMimeSize];
+    int32_t width;
+    int32_t height;
+    int32_t sampleRate;
+    int32_t channelCount;
+};
+
 int32_t sendBuffersToWriter(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
                             int32_t &inputFrameId, sp<MediaAdapter> &currentTrack, int32_t offset,
-                            int32_t range, bool isPaused = false);
+                            int32_t range, bool isPaused = false,
+                            sp<WriterListener> listener = nullptr);
 
 int32_t writeHeaderBuffers(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
                            int32_t &inputFrameId, sp<AMessage> &format, int32_t numCsds);
diff --git a/media/libstagefright/timedtext/test/Android.bp b/media/libstagefright/timedtext/test/Android.bp
new file mode 100644
index 0000000..36f8891
--- /dev/null
+++ b/media/libstagefright/timedtext/test/Android.bp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "TimedTextUnitTest",
+    gtest: true,
+
+    srcs: [
+        "TimedTextUnitTest.cpp",
+    ],
+
+    static_libs: [
+        "libstagefright_timedtext",
+        "libstagefright_foundation",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libmedia",
+        "libbinder",
+    ],
+
+    cflags: [
+        "-Wno-multichar",
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/timedtext/test/AndroidTest.xml b/media/libstagefright/timedtext/test/AndroidTest.xml
new file mode 100644
index 0000000..3654e23
--- /dev/null
+++ b/media/libstagefright/timedtext/test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for TimedText unit test">
+    <option name="test-suite-tag" value="TimedTextUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="TimedTextUnitTest->/data/local/tmp/TimedTextUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/timedtext/test/TimedTextUnitTest.zip?unzip=true"
+            value="/data/local/tmp/TimedTextUnitTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="TimedTextUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/TimedTextUnitTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/timedtext/test/README.md b/media/libstagefright/timedtext/test/README.md
new file mode 100644
index 0000000..3a774bd
--- /dev/null
+++ b/media/libstagefright/timedtext/test/README.md
@@ -0,0 +1,40 @@
+## Media Testing ##
+---
+#### TimedText Unit Test :
+The TimedText Unit Test Suite validates the TextDescription class available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m TimedTextUnitTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/TimedTextUnitTest/TimedTextUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/TimedTextUnitTest/TimedTextUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/timedtext/test/TimedTextUnitTest.zip).
+Download, unzip and push these files into device for testing.
+
+```
+adb push TimedTextUnitTestRes/. /data/local/tmp/
+```
+
+usage: TimedTextUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/TimedTextUnitTest -P /data/local/tmp/TimedTextUnitTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest TimedTextUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/timedtext/test/TimedTextTestEnvironment.h b/media/libstagefright/timedtext/test/TimedTextTestEnvironment.h
new file mode 100644
index 0000000..52280c1
--- /dev/null
+++ b/media/libstagefright/timedtext/test/TimedTextTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 __TIMEDTEXT_TEST_ENVIRONMENT_H__
+#define __TIMEDTEXT_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class TimedTextTestEnvironment : public ::testing::Environment {
+  public:
+    TimedTextTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int TimedTextTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P':
+                setRes(optarg);
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __TIMEDTEXT_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
new file mode 100644
index 0000000..d85ae39
--- /dev/null
+++ b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2020 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 "TimedTextUnitTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fstream>
+
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/ByteUtils.h>
+
+#include "timedtext/TextDescriptions.h"
+
+#include "TimedTextTestEnvironment.h"
+
+constexpr int32_t kStartTimeMs = 10000;
+
+enum {
+    // These keys must be in sync with the keys in
+    // frameworks/av/media/libstagefright/timedtext/TextDescriptions.h
+    KEY_DISPLAY_FLAGS = 1,
+    KEY_STYLE_FLAGS = 2,
+    KEY_BACKGROUND_COLOR_RGBA = 3,
+    KEY_HIGHLIGHT_COLOR_RGBA = 4,
+    KEY_SCROLL_DELAY = 5,
+    KEY_WRAP_TEXT = 6,
+    KEY_START_TIME = 7,
+    KEY_STRUCT_BLINKING_TEXT_LIST = 8,
+    KEY_STRUCT_FONT_LIST = 9,
+    KEY_STRUCT_HIGHLIGHT_LIST = 10,
+    KEY_STRUCT_HYPER_TEXT_LIST = 11,
+    KEY_STRUCT_KARAOKE_LIST = 12,
+    KEY_STRUCT_STYLE_LIST = 13,
+    KEY_STRUCT_TEXT_POS = 14,
+    KEY_STRUCT_JUSTIFICATION = 15,
+    KEY_STRUCT_TEXT = 16,
+
+    KEY_GLOBAL_SETTING = 101,
+    KEY_LOCAL_SETTING = 102,
+    KEY_START_CHAR = 103,
+    KEY_END_CHAR = 104,
+    KEY_FONT_ID = 105,
+    KEY_FONT_SIZE = 106,
+    KEY_TEXT_COLOR_RGBA = 107,
+};
+
+struct FontInfo {
+    int32_t displayFlag = -1;
+    int32_t horizontalJustification = -1;
+    int32_t verticalJustification = -1;
+    int32_t rgbaBackground = -1;
+    int32_t leftPos = -1;
+    int32_t topPos = -1;
+    int32_t bottomPos = -1;
+    int32_t rightPos = -1;
+    int32_t startchar = -1;
+    int32_t endChar = -1;
+    int32_t fontId = -1;
+    int32_t faceStyle = -1;
+    int32_t fontSize = -1;
+    int32_t rgbaText = -1;
+    int32_t entryCount = -1;
+};
+
+struct FontRecord {
+    int32_t fontID = -1;
+    int32_t fontNameLength = -1;
+    const uint8_t *font = nullptr;
+};
+
+using namespace android;
+
+static TimedTextTestEnvironment *gEnv = nullptr;
+
+class TimedTextUnitTest : public ::testing::TestWithParam</*filename*/ string> {
+  public:
+    TimedTextUnitTest(){};
+
+    ~TimedTextUnitTest() {
+        if (mEleStream) mEleStream.close();
+    }
+
+    virtual void SetUp() override {
+        mInputFileName = gEnv->getRes() + GetParam();
+        mEleStream.open(mInputFileName, ifstream::binary);
+        ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open " << GetParam();
+
+        struct stat buf;
+        status_t status = stat(mInputFileName.c_str(), &buf);
+        ASSERT_EQ(status, 0) << "Failed to get properties of input file: " << GetParam();
+        mFileSize = buf.st_size;
+        ALOGI("Size of the input file %s = %zu", GetParam().c_str(), mFileSize);
+    }
+
+    string mInputFileName;
+    size_t mFileSize;
+    ifstream mEleStream;
+};
+
+class SRTDescriptionTest : public TimedTextUnitTest {
+  public:
+    virtual void SetUp() override { TimedTextUnitTest::SetUp(); }
+};
+
+class Text3GPPDescriptionTest : public TimedTextUnitTest {
+  public:
+    virtual void SetUp() override { TimedTextUnitTest::SetUp(); }
+};
+
+TEST_P(SRTDescriptionTest, extractSRTDescriptionTest) {
+    char data[mFileSize];
+    mEleStream.read(data, sizeof(data));
+    ASSERT_EQ(mEleStream.gcount(), mFileSize);
+
+    Parcel parcel;
+    int32_t flag = TextDescriptions::OUT_OF_BAND_TEXT_SRT | TextDescriptions::LOCAL_DESCRIPTIONS;
+    status_t status = TextDescriptions::getParcelOfDescriptions((const uint8_t *)data, mFileSize,
+                                                                flag, kStartTimeMs, &parcel);
+    ASSERT_EQ(status, 0) << "getParcelOfDescriptions returned error";
+    ALOGI("Size of the Parcel: %zu", parcel.dataSize());
+    ASSERT_GT(parcel.dataSize(), 0) << "Parcel is empty";
+
+    parcel.setDataPosition(0);
+    int32_t key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_LOCAL_SETTING) << "Parcel has invalid key";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_START_TIME) << "Parcel has invalid start time key";
+    ASSERT_EQ(parcel.readInt32(), kStartTimeMs) << "Parcel has invalid timings";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STRUCT_TEXT) << "Parcel has invalid struct text key";
+    ASSERT_EQ(parcel.readInt32(), mFileSize) << "Parcel has invalid text data";
+    int32_t fileSize = parcel.readInt32();
+    ASSERT_EQ(fileSize, mFileSize) << "Parcel has invalid file size value";
+    uint8_t tmpData[fileSize];
+    status = parcel.read((void *)tmpData, fileSize);
+    ASSERT_EQ(status, 0) << "Failed to read the data from parcel";
+    // To make sure end of parcel is reached
+    ASSERT_EQ(parcel.dataAvail(), 0) << "Parcel has some data left to read";
+}
+
+// This test uses the properties of tx3g box mentioned in 3GPP Timed Text Format
+// Specification#: 26.245 / Section: 5.16(Sample Description Format)
+// https://www.3gpp.org/ftp/Specs/archive/26_series/26.245/
+
+TEST_P(Text3GPPDescriptionTest, Text3GPPGlobalDescriptionTest) {
+    char data[mFileSize];
+    mEleStream.read(data, sizeof(data));
+    ASSERT_EQ(mEleStream.gcount(), mFileSize);
+
+    const uint8_t *tmpData = (const uint8_t *)data;
+    int32_t remaining = mFileSize;
+    FontInfo fontInfo;
+    vector<FontRecord> fontRecordEntries;
+
+    // Skipping the bytes containing information about the type of subbox(tx3g)
+    tmpData += 16;
+    remaining -= 16;
+
+    fontInfo.displayFlag = U32_AT(tmpData);
+    ALOGI("Display flag: %d", fontInfo.displayFlag);
+    fontInfo.horizontalJustification = tmpData[4];
+    ALOGI("Horizontal Justification: %d", fontInfo.horizontalJustification);
+    fontInfo.verticalJustification = tmpData[5];
+    ALOGI("Vertical Justification: %d", fontInfo.verticalJustification);
+    fontInfo.rgbaBackground =
+            *(tmpData + 6) << 24 | *(tmpData + 7) << 16 | *(tmpData + 8) << 8 | *(tmpData + 9);
+    ALOGI("rgba value of background: %d", fontInfo.rgbaBackground);
+
+    tmpData += 10;
+    remaining -= 10;
+
+    if (remaining >= 8) {
+        fontInfo.leftPos = U16_AT(tmpData);
+        ALOGI("Left: %d", fontInfo.leftPos);
+        fontInfo.topPos = U16_AT(tmpData + 2);
+        ALOGI("Top: %d", fontInfo.topPos);
+        fontInfo.bottomPos = U16_AT(tmpData + 4);
+        ALOGI("Bottom: %d", fontInfo.bottomPos);
+        fontInfo.rightPos = U16_AT(tmpData + 6);
+        ALOGI("Right: %d", fontInfo.rightPos);
+
+        tmpData += 8;
+        remaining -= 8;
+
+        if (remaining >= 12) {
+            fontInfo.startchar = U16_AT(tmpData);
+            ALOGI("Start character: %d", fontInfo.startchar);
+            fontInfo.endChar = U16_AT(tmpData + 2);
+            ALOGI("End character: %d", fontInfo.endChar);
+            fontInfo.fontId = U16_AT(tmpData + 4);
+            ALOGI("Value of font Identifier: %d", fontInfo.fontId);
+            fontInfo.faceStyle = *(tmpData + 6);
+            ALOGI("Face style flag : %d", fontInfo.faceStyle);
+            fontInfo.fontSize = *(tmpData + 7);
+            ALOGI("Size of the font: %d", fontInfo.fontSize);
+            fontInfo.rgbaText = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 | *(tmpData + 10) << 8 |
+                                *(tmpData + 11);
+            ALOGI("rgba value of the text: %d", fontInfo.rgbaText);
+
+            tmpData += 12;
+            remaining -= 12;
+
+            if (remaining >= 10) {
+                // Skipping the bytes containing information about the type of subbox(ftab)
+                fontInfo.entryCount = U16_AT(tmpData + 8);
+                ALOGI("Value of entry count: %d", fontInfo.entryCount);
+
+                tmpData += 10;
+                remaining -= 10;
+
+                for (int32_t i = 0; i < fontInfo.entryCount; i++) {
+                    if (remaining < 3) break;
+                    int32_t tempFontID = U16_AT(tmpData);
+                    ALOGI("Font Id: %d", tempFontID);
+                    int32_t tempFontNameLength = *(tmpData + 2);
+                    ALOGI("Length of font name: %d", tempFontNameLength);
+
+                    tmpData += 3;
+                    remaining -= 3;
+
+                    if (remaining < tempFontNameLength) break;
+                    const uint8_t *tmpFont = tmpData;
+                    char *tmpFontName = strndup((const char *)tmpFont, tempFontNameLength);
+                    ASSERT_NE(tmpFontName, nullptr) << "Font Name is null";
+                    ALOGI("FontName = %s", tmpFontName);
+                    free(tmpFontName);
+                    tmpData += tempFontNameLength;
+                    remaining -= tempFontNameLength;
+                    fontRecordEntries.push_back({tempFontID, tempFontNameLength, tmpFont});
+                }
+            }
+        }
+    }
+
+    Parcel parcel;
+    int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP | TextDescriptions::GLOBAL_DESCRIPTIONS;
+    status_t status = TextDescriptions::getParcelOfDescriptions((const uint8_t *)data, mFileSize,
+                                                                flag, kStartTimeMs, &parcel);
+    ASSERT_EQ(status, 0) << "getParcelOfDescriptions returned error";
+    ALOGI("Size of the Parcel: %zu", parcel.dataSize());
+    ASSERT_GT(parcel.dataSize(), 0) << "Parcel is empty";
+
+    parcel.setDataPosition(0);
+    int32_t key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_GLOBAL_SETTING) << "Parcel has invalid key";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_DISPLAY_FLAGS) << "Parcel has invalid DISPLAY FLAGS Key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.displayFlag)
+            << "Parcel has invalid value of display flag";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STRUCT_JUSTIFICATION) << "Parcel has invalid STRUCT JUSTIFICATION key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.horizontalJustification)
+            << "Parcel has invalid value of Horizontal justification";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.verticalJustification)
+            << "Parcel has invalid value of Vertical justification";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_BACKGROUND_COLOR_RGBA) << "Parcel has invalid BACKGROUND COLOR key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.rgbaBackground)
+            << "Parcel has invalid rgba background color value";
+
+    if (parcel.dataAvail() == 0) {
+        ALOGV("Completed reading the parcel");
+        return;
+    }
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STRUCT_TEXT_POS) << "Parcel has invalid STRUCT TEXT POSITION key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.leftPos)
+            << "Parcel has invalid rgba background color value";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.topPos)
+            << "Parcel has invalid rgba background color value";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.bottomPos)
+            << "Parcel has invalid rgba background color value";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.rightPos)
+            << "Parcel has invalid rgba background color value";
+
+    if (parcel.dataAvail() == 0) {
+        ALOGV("Completed reading the parcel");
+        return;
+    }
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STRUCT_STYLE_LIST) << "Parcel has invalid STRUCT STYLE LIST key";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_START_CHAR) << "Parcel has invalid START CHAR key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.startchar)
+            << "Parcel has invalid value of start character";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_END_CHAR) << "Parcel has invalid END CHAR key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.endChar) << "Parcel has invalid value of end character";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_FONT_ID) << "Parcel has invalid FONT ID key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.fontId) << "Parcel has invalid value of font Id";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STYLE_FLAGS) << "Parcel has invalid STYLE FLAGS key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.faceStyle) << "Parcel has invalid value of style flags";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_FONT_SIZE) << "Parcel has invalid FONT SIZE key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.fontSize) << "Parcel has invalid value of font size";
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_TEXT_COLOR_RGBA) << "Parcel has invalid TEXT COLOR RGBA key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.rgbaText) << "Parcel has invalid rgba text color value";
+
+    if (parcel.dataAvail() == 0) {
+        ALOGV("Completed reading the parcel");
+        return;
+    }
+
+    key = parcel.readInt32();
+    ASSERT_EQ(key, KEY_STRUCT_FONT_LIST) << "Parcel has invalid STRUCT FONT LIST key";
+    ASSERT_EQ(parcel.readInt32(), fontInfo.entryCount) << "Parcel has invalid value of entry count";
+    ASSERT_EQ(fontInfo.entryCount, fontRecordEntries.size())
+            << "Array size does not match expected number of entries";
+    for (int32_t i = 0; i < fontInfo.entryCount; i++) {
+        ASSERT_EQ(parcel.readInt32(), fontRecordEntries[i].fontID)
+                << "Parcel has invalid value of font Id";
+        ASSERT_EQ(parcel.readInt32(), fontRecordEntries[i].fontNameLength)
+                << "Parcel has invalid value of font name length";
+        uint8_t fontName[fontRecordEntries[i].fontNameLength];
+        // written with writeByteArray() writes count, then the actual data
+        ASSERT_EQ(parcel.readInt32(), fontRecordEntries[i].fontNameLength);
+        status = parcel.read((void *)fontName, fontRecordEntries[i].fontNameLength);
+        ASSERT_EQ(status, 0) << "Failed to read the font name from parcel";
+        ASSERT_EQ(memcmp(fontName, fontRecordEntries[i].font, fontRecordEntries[i].fontNameLength),
+                  0)
+                << "Parcel has invalid font";
+    }
+    // To make sure end of parcel is reached
+    ASSERT_EQ(parcel.dataAvail(), 0) << "Parcel has some data left to read";
+}
+
+INSTANTIATE_TEST_SUITE_P(TimedTextUnitTestAll, SRTDescriptionTest,
+                         ::testing::Values(("sampleTest1.srt"),
+                                           ("sampleTest2.srt")));
+
+INSTANTIATE_TEST_SUITE_P(TimedTextUnitTestAll, Text3GPPDescriptionTest,
+                         ::testing::Values(("tx3gBox1"),
+                                           ("tx3gBox2")));
+
+int main(int argc, char **argv) {
+    gEnv = new TimedTextTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index a232150..3be5e74 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -1525,7 +1525,7 @@
                 nodeInfo.attributeList.push_back(Attribute{"rank", rank});
             }
             nodeList->insert(std::make_pair(
-                    std::move(order), std::move(nodeInfo)));
+                    order, std::move(nodeInfo)));
         }
     }
 }
diff --git a/media/libstagefright/xmlparser/test/Android.bp b/media/libstagefright/xmlparser/test/Android.bp
new file mode 100644
index 0000000..6d97c96
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/Android.bp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "XMLParserTest",
+    gtest: true,
+
+    srcs: [
+        "XMLParserTest.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libstagefright_xmlparser",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    data: [":xmlparsertest_test_files",],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+filegroup {
+    name: "xmlparsertest_test_files",
+    srcs: [
+        "testdata/media_codecs_unit_test.xml",
+        "testdata/media_codecs_unit_test_caller.xml",
+    ],
+}
diff --git a/media/libstagefright/xmlparser/test/AndroidTest.xml b/media/libstagefright/xmlparser/test/AndroidTest.xml
new file mode 100644
index 0000000..2e11b1b
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for xml parser unit test">
+    <option name="test-suite-tag" value="XMLParserTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="media_codecs_unit_test.xml->/data/local/tmp/media_codecs_unit_test.xml" />
+        <option name="push" value="media_codecs_unit_test_caller.xml->/data/local/tmp/media_codecs_unit_test_caller.xml" />
+        <option name="push" value="XMLParserTest->/data/local/tmp/XMLParserTest" />
+    </target_preparer>
+   <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="XMLParserTest" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/xmlparser/test/README.md b/media/libstagefright/xmlparser/test/README.md
new file mode 100644
index 0000000..e9363fd
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/README.md
@@ -0,0 +1,33 @@
+## Media Testing ##
+---
+#### XML Parser
+The XMLParser Test Suite validates the XMLParser available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m XMLParserTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/XMLParserTest/XMLParserTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/XMLParserTest/XMLParserTest /data/local/tmp/
+```
+
+usage: XMLParserTest
+```
+adb shell /data/local/tmp/XMLParserTest
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest XMLParserTest
+```
diff --git a/media/libstagefright/xmlparser/test/XMLParserTest.cpp b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
new file mode 100644
index 0000000..9ddd374
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2020 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 "XMLParserTest"
+
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include "XMLParserTestEnvironment.h"
+
+#define XML_FILE_NAME "media_codecs_unit_test_caller.xml"
+
+using namespace android;
+
+static XMLParserTestEnvironment *gEnv = nullptr;
+
+struct CodecProperties {
+    string codecName;
+    MediaCodecsXmlParser::CodecProperties codecProp;
+};
+
+struct RoleProperties {
+    string roleName;
+    string typeName;
+    string codecName;
+    bool isEncoder;
+    size_t order;
+    vector<pair<string, string>> attributeMap;
+};
+
+class XMLParseTest : public ::testing::Test {
+  public:
+    ~XMLParseTest() {
+        if (mEleStream.is_open()) mEleStream.close();
+        mInputDataVector.clear();
+        mInputRoleVector.clear();
+    }
+
+    virtual void SetUp() override { setUpDatabase(); }
+
+    void setUpDatabase();
+
+    void setCodecProperties(string codecName, bool isEncoder, int32_t order, set<string> quirkSet,
+                            set<string> domainSet, set<string> variantSet, string typeName,
+                            vector<pair<string, string>> domain, vector<string> aliases,
+                            string rank);
+
+    void setRoleProperties(string roleName, bool isEncoder, int32_t order, string typeName,
+                           string codecName, vector<pair<string, string>> domain);
+
+    void setServiceAttribute(map<string, string> serviceAttributeNameValuePair);
+
+    void printCodecMap(const MediaCodecsXmlParser::Codec mcodec);
+
+    void checkRoleMap(int32_t index, bool isEncoder, string typeName, string codecName,
+                      vector<pair<string, string>> attrMap);
+
+    bool compareMap(const map<string, string> &lhs, const map<string, string> &rhs);
+
+    ifstream mEleStream;
+    MediaCodecsXmlParser mParser;
+    vector<CodecProperties> mInputDataVector;
+    vector<RoleProperties> mInputRoleVector;
+    map<string, string> mInputServiceAttributeMap;
+};
+
+void XMLParseTest::setUpDatabase() {
+    // The values set below are specific to test vector testdata/media_codecs_unit_test.xml
+    setCodecProperties("test1.decoder", false, 1, {"attribute::disabled", "quirk::quirk1"},
+                       {"telephony"}, {}, "audio/mpeg", {}, {"alias1.decoder"}, "4");
+
+    setCodecProperties("test2.decoder", false, 2, {"quirk::quirk1"}, {}, {}, "audio/3gpp", {}, {},
+                       "");
+
+    setCodecProperties("test3.decoder", false, 3, {}, {}, {}, "audio/amr-wb",
+                       {
+                               pair<string, string>("feature-feature1", "feature1Val"),
+                               pair<string, string>("feature-feature2", "0"),
+                               pair<string, string>("feature-feature3", "0"),
+                       },
+                       {}, "");
+
+    setCodecProperties("test4.decoder", false, 4, {}, {}, {}, "audio/flac",
+                       {pair<string, string>("feature-feature1", "feature1Val")}, {}, "");
+
+    setCodecProperties("test5.decoder", false, 5, {"attribute::attributeQuirk1"}, {}, {},
+                       "audio/g711-mlaw", {}, {}, "");
+
+    setCodecProperties("test6.decoder", false, 6, {}, {}, {"variant1", "variant2"},
+                       "audio/mp4a-latm",
+                       {pair<string, string>("variant1:::variant1Limit1-range",
+                                             "variant1Limit1Min-variant1Limit1Max"),
+                        pair<string, string>("variant1:::variant1Limit2-range",
+                                             "variant1Limit2Low-variant1Limit2High"),
+                        pair<string, string>("variant2:::variant2Limit1", "variant2Limit1Value")},
+                       {}, "");
+
+    setCodecProperties(
+            "test7.decoder", false, 7, {}, {}, {}, "audio/vorbis",
+            {
+                    pair<string, string>("-min-limit1", "limit1Min"),
+                    /*pair<string, string>("limit1-in", "limit1In"),*/
+                    pair<string, string>("limit2-range", "limit2Min-limit2Max"),
+                    pair<string, string>("limit2-scale", "limit2Scale"),
+                    pair<string, string>("limit3-default", "limit3Val3"),
+                    pair<string, string>("limit3-ranges", "limit3Val1,limit3Val2,limit3Val3"),
+            },
+            {}, "");
+
+    setCodecProperties("test8.encoder", true, 8, {}, {}, {}, "audio/opus",
+                       {pair<string, string>("max-limit1", "limit1Max")}, {}, "");
+
+    setRoleProperties("audio_decoder.mp3", false, 1, "audio/mpeg", "test1.decoder",
+                      {pair<string, string>("attribute::disabled", "present"),
+                       pair<string, string>("rank", "4")});
+
+    setRoleProperties("audio_decoder.amrnb", false, 2, "audio/3gpp", "test2.decoder", {});
+
+    setRoleProperties("audio_decoder.amrwb", false, 3, "audio/amr-wb", "test3.decoder",
+                      {pair<string, string>("feature-feature1", "feature1Val"),
+                       pair<string, string>("feature-feature2", "0"),
+                       pair<string, string>("feature-feature3", "0")});
+
+    setRoleProperties("audio/flac", false, 4, "audio/flac", "test4.decoder",
+                      {pair<string, string>("feature-feature1", "feature1Val")});
+
+    setRoleProperties("audio_decoder.g711mlaw", false, 5, "audio/g711-mlaw", "test5.decoder",
+                      {pair<string, string>("attribute::attributeQuirk1", "present")});
+
+    setRoleProperties("audio_decoder.aac", false, 6, "audio/mp4a-latm", "test6.decoder",
+                      {pair<string, string>("variant1:::variant1Limit1-range",
+                                            "variant1Limit1Min-variant1Limit1Max"),
+                       pair<string, string>("variant1:::variant1Limit2-range",
+                                            "variant1Limit2Low-variant1Limit2High"),
+                       pair<string, string>("variant2:::variant2Limit1", "variant2Limit1Value")});
+
+    setRoleProperties("audio_decoder.vorbis", false, 7, "audio/vorbis", "test7.decoder",
+                      {pair<string, string>("-min-limit1", "limit1Min"),
+                       /*pair<string, string>("limit1-in", "limit1In"),*/
+                       pair<string, string>("limit2-range", "limit2Min-limit2Max"),
+                       pair<string, string>("limit2-scale", "limit2Scale"),
+                       pair<string, string>("limit3-default", "limit3Val3"),
+                       pair<string, string>("limit3-ranges", "limit3Val1,limit3Val2,limit3Val3")});
+
+    setRoleProperties("audio_encoder.opus", true, 8, "audio/opus", "test8.encoder",
+                      {pair<string, string>("max-limit1", "limit1Max")});
+
+    setServiceAttribute(
+            {pair<string, string>("domain-telephony", "0"), pair<string, string>("domain-tv", "0"),
+             pair<string, string>("setting2", "0"), pair<string, string>("variant-variant1", "0")});
+}
+
+bool XMLParseTest::compareMap(const map<string, string> &lhs, const map<string, string> &rhs) {
+    return lhs.size() == rhs.size() && equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+void XMLParseTest::setCodecProperties(string codecName, bool isEncoder, int32_t order,
+                                      set<string> quirkSet, set<string> domainSet,
+                                      set<string> variantSet, string typeName,
+                                      vector<pair<string, string>> domain, vector<string> aliases,
+                                      string rank) {
+    map<string, string> AttributeMapDB;
+    for (const auto &AttrStr : domain) {
+        AttributeMapDB.insert(AttrStr);
+    }
+    map<string, MediaCodecsXmlParser::AttributeMap> TypeMapDataBase;
+    TypeMapDataBase.insert(
+            pair<string, MediaCodecsXmlParser::AttributeMap>(typeName, AttributeMapDB));
+    CodecProperties codecProperty;
+    codecProperty.codecName = codecName;
+    codecProperty.codecProp.isEncoder = isEncoder;
+    codecProperty.codecProp.order = order;
+    codecProperty.codecProp.quirkSet = quirkSet;
+    codecProperty.codecProp.domainSet = domainSet;
+    codecProperty.codecProp.variantSet = variantSet;
+    codecProperty.codecProp.typeMap = TypeMapDataBase;
+    codecProperty.codecProp.aliases = aliases;
+    codecProperty.codecProp.rank = rank;
+    mInputDataVector.push_back(codecProperty);
+}
+
+void XMLParseTest::setRoleProperties(string roleName, bool isEncoder, int32_t order,
+                                     string typeName, string codecName,
+                                     vector<pair<string, string>> attributeNameValuePair) {
+    struct RoleProperties roleProperty;
+    roleProperty.roleName = roleName;
+    roleProperty.typeName = typeName;
+    roleProperty.codecName = codecName;
+    roleProperty.isEncoder = isEncoder;
+    roleProperty.order = order;
+    roleProperty.attributeMap = attributeNameValuePair;
+    mInputRoleVector.push_back(roleProperty);
+}
+
+void XMLParseTest::setServiceAttribute(map<string, string> serviceAttributeNameValuePair) {
+    for (const auto &serviceAttrStr : serviceAttributeNameValuePair) {
+        mInputServiceAttributeMap.insert(serviceAttrStr);
+    }
+}
+
+void XMLParseTest::printCodecMap(const MediaCodecsXmlParser::Codec mcodec) {
+    const string &name = mcodec.first;
+    ALOGV("codec name = %s\n", name.c_str());
+    const MediaCodecsXmlParser::CodecProperties &properties = mcodec.second;
+    bool isEncoder = properties.isEncoder;
+    ALOGV("isEncoder = %d\n", isEncoder);
+    size_t order = properties.order;
+    ALOGV("order = %zu\n", order);
+    string rank = properties.rank;
+    ALOGV("rank = %s\n", rank.c_str());
+
+    for (auto &itrQuirkSet : properties.quirkSet) {
+        ALOGV("quirkSet= %s", itrQuirkSet.c_str());
+    }
+
+    for (auto &itrDomainSet : properties.domainSet) {
+        ALOGV("domainSet= %s", itrDomainSet.c_str());
+    }
+
+    for (auto &itrVariantSet : properties.variantSet) {
+        ALOGV("variantSet= %s", itrVariantSet.c_str());
+    }
+
+    map<string, MediaCodecsXmlParser::AttributeMap> TypeMap = properties.typeMap;
+    ALOGV("The TypeMap is :");
+
+    for (auto &itrTypeMap : TypeMap) {
+        ALOGV("itrTypeMap->first\t%s\t", itrTypeMap.first.c_str());
+
+        for (auto &itrAttributeMap : itrTypeMap.second) {
+            ALOGV("AttributeMap->first = %s", itrAttributeMap.first.c_str());
+            ALOGV("AttributeMap->second = %s", itrAttributeMap.second.c_str());
+        }
+    }
+}
+
+void XMLParseTest::checkRoleMap(int32_t index, bool isEncoder, string typeName, string codecName,
+                                vector<pair<string, string>> AttributePairMap) {
+    ASSERT_EQ(isEncoder, mInputRoleVector.at(index).isEncoder)
+            << "Invalid RoleMap data. IsEncoder mismatch";
+    ASSERT_EQ(typeName, mInputRoleVector.at(index).typeName)
+            << "Invalid RoleMap data. typeName mismatch";
+    ASSERT_EQ(codecName, mInputRoleVector.at(index).codecName)
+            << "Invalid RoleMap data. codecName mismatch";
+
+    vector<pair<string, string>>::iterator itr_attributeMapDB =
+            (mInputRoleVector.at(index).attributeMap).begin();
+    vector<pair<string, string>>::iterator itr_attributeMap = AttributePairMap.begin();
+    for (; itr_attributeMap != AttributePairMap.end() &&
+           itr_attributeMapDB != mInputRoleVector.at(index).attributeMap.end();
+         ++itr_attributeMap, ++itr_attributeMapDB) {
+        string attributeName = itr_attributeMap->first;
+        string attributeNameDB = itr_attributeMapDB->first;
+        string attributevalue = itr_attributeMap->second;
+        string attributeValueDB = itr_attributeMapDB->second;
+        ASSERT_EQ(attributeName, attributeNameDB)
+                << "Invalid RoleMap data. Attribute name mismatch\t" << attributeName << " != "
+                << "attributeNameDB";
+        ASSERT_EQ(attributevalue, attributeValueDB)
+                << "Invalid RoleMap data. Attribute value mismatch\t" << attributevalue << " != "
+                << "attributeValueDB";
+    }
+}
+
+TEST_F(XMLParseTest, CodecMapParseTest) {
+    string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+    mParser.parseXmlPath(inputFileName);
+    for (const MediaCodecsXmlParser::Codec &mcodec : mParser.getCodecMap()) {
+        printCodecMap(mcodec);
+        const MediaCodecsXmlParser::CodecProperties &properties = mcodec.second;
+        int32_t index = properties.order - 1;
+        ASSERT_GE(index, 0) << "Invalid order";
+        ASSERT_EQ(mInputDataVector.at(index).codecName, mcodec.first.c_str())
+                << "Invalid CodecMap data. codecName mismatch";
+        ASSERT_EQ(properties.isEncoder, mInputDataVector.at(index).codecProp.isEncoder)
+                << "Invalid CodecMap data. isEncoder mismatch";
+        ASSERT_EQ(properties.order, mInputDataVector.at(index).codecProp.order)
+                << "Invalid CodecMap data. order mismatch";
+
+        set<string> quirkSetDB = mInputDataVector.at(index).codecProp.quirkSet;
+        set<string> quirkSet = properties.quirkSet;
+        set<string> quirkDifference;
+        set_difference(quirkSetDB.begin(), quirkSetDB.end(), quirkSet.begin(), quirkSet.end(),
+                       inserter(quirkDifference, quirkDifference.end()));
+        ASSERT_EQ(quirkDifference.size(), 0) << "CodecMap:quirk mismatch";
+
+        map<string, MediaCodecsXmlParser::AttributeMap> TypeMapDB =
+                mInputDataVector.at(index).codecProp.typeMap;
+        map<string, MediaCodecsXmlParser::AttributeMap> TypeMap = properties.typeMap;
+        map<string, MediaCodecsXmlParser::AttributeMap>::iterator itr_TypeMapDB = TypeMapDB.begin();
+        map<string, MediaCodecsXmlParser::AttributeMap>::iterator itr_TypeMap = TypeMap.begin();
+
+        ASSERT_EQ(TypeMapDB.size(), TypeMap.size())
+                << "Invalid CodecMap data. Typemap size mismatch";
+
+        for (; itr_TypeMap != TypeMap.end() && itr_TypeMapDB != TypeMapDB.end();
+             ++itr_TypeMap, ++itr_TypeMapDB) {
+            ASSERT_EQ(itr_TypeMap->first, itr_TypeMapDB->first)
+                    << "Invalid CodecMap data. type mismatch";
+            bool flag = compareMap(itr_TypeMap->second, itr_TypeMapDB->second);
+            ASSERT_TRUE(flag) << "typeMap mismatch";
+        }
+        ASSERT_EQ(mInputDataVector.at(index).codecProp.rank, properties.rank)
+                << "Invalid CodecMap data. rank mismatch";
+    }
+}
+
+TEST_F(XMLParseTest, RoleMapParseTest) {
+    string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+    mParser.parseXmlPath(inputFileName);
+
+    for (auto &mRole : mParser.getRoleMap()) {
+        typedef pair<string, string> Attribute;
+        const string &roleName = mRole.first;
+        ALOGV("Role map:name = %s\n", roleName.c_str());
+        const MediaCodecsXmlParser::RoleProperties &properties = mRole.second;
+        string type = properties.type;
+        ALOGV("Role map: type = %s\n", type.c_str());
+
+        bool isEncoder = properties.isEncoder;
+        ALOGV("Role map: isEncoder = %d\n", isEncoder);
+
+        multimap<size_t, MediaCodecsXmlParser::NodeInfo> nodeList = properties.nodeList;
+        multimap<size_t, MediaCodecsXmlParser::NodeInfo>::iterator itr_Node;
+        ALOGV("\nThe multimap nodeList is : \n");
+        for (itr_Node = nodeList.begin(); itr_Node != nodeList.end(); ++itr_Node) {
+            ALOGV("itr_Node->first=ORDER=\t%zu\t", itr_Node->first);
+            int32_t index = itr_Node->first - 1;
+            MediaCodecsXmlParser::NodeInfo nodePtr = itr_Node->second;
+            ALOGV("Role map:itr_Node->second.name = %s\n", nodePtr.name.c_str());
+            vector<Attribute> attrList = nodePtr.attributeList;
+            for (auto attrNameValueList = attrList.begin(); attrNameValueList != attrList.end();
+                 ++attrNameValueList) {
+                ALOGV("Role map:nodePtr.attributeList->first = %s\n",
+                      attrNameValueList->first.c_str());
+                ALOGV("Role map:nodePtr.attributeList->second = %s\n",
+                      attrNameValueList->second.c_str());
+            }
+            checkRoleMap(index, isEncoder, properties.type, nodePtr.name.c_str(), attrList);
+        }
+    }
+}
+
+TEST_F(XMLParseTest, ServiceAttributeMapParseTest) {
+    string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+    mParser.parseXmlPath(inputFileName);
+    const auto serviceAttributeMap = mParser.getServiceAttributeMap();
+    for (const auto &attributePair : serviceAttributeMap) {
+        ALOGV("serviceAttribute.key = %s \t serviceAttribute.value = %s",
+              attributePair.first.c_str(), attributePair.second.c_str());
+    }
+    bool flag = compareMap(mInputServiceAttributeMap, serviceAttributeMap);
+    ASSERT_TRUE(flag) << "ServiceMapParseTest: typeMap mismatch";
+}
+
+int main(int argc, char **argv) {
+    gEnv = new XMLParserTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("XML Parser Test Result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.h b/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.h
new file mode 100644
index 0000000..61a09e6
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __XML_PARSER_TEST_ENVIRONMENT_H__
+#define __XML_PARSER_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class XMLParserTestEnvironment : public ::testing::Environment {
+  public:
+    XMLParserTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int XMLParserTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __XML_PARSER_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
new file mode 100644
index 0000000..a7299d3
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<!-- REFERENCE : frameworks/av/media/libstagefright/xmlparser/media_codecs.xsd -->
+<Included>
+    <Settings>
+        <Domain name="telephony" enabled="false" />
+        <Domain name="tv" enabled="false" />
+        <Variant name="variant1" enabled="false" />
+        <Setting name="setting1" value="settingValue1" update="true" />
+        <Setting name="setting2" enabled="false" />
+    </Settings>
+    <Decoders>
+        <!-- entry for enabled, domain, rank and update properties -->
+        <MediaCodec name="test1.decoder" type="audio/mpeg" update="false" domain="telephony" enabled="false" rank="4">
+            <Alias name="alias1.decoder" />
+            <Quirk name="quirk1" value="quirk1Value"/>
+        </MediaCodec>
+        <!-- entry for testing Quirk -->
+        <MediaCodec name="test2.decoder" type="audio/3gpp" enabled="true" >
+            <Quirk name="quirk1" value="quirk1Value"/>
+        </MediaCodec>
+        <!-- entry for testing Feature -->
+        <!-- feature2 takes value 0 (feature with same name takes lower feature's value) -->
+        <!-- feature3 gives value as 0 since it's optional -->
+        <!-- optional="true" required="true" is not a valid combination. -->
+        <!-- optional="false" required="false" is not a valid combination. -->
+        <MediaCodec name="test3.decoder" type="audio/amr-wb" >
+            <Feature name="feature1" value="feature1Val" />
+            <Feature name="feature2" value="feature2Val"/>
+            <Feature name="feature2" />
+            <Feature name="feature3" optional="true" required="false" />
+        </MediaCodec>
+        <!-- entry for testing Type -->
+        <MediaCodec name="test4.decoder">
+            <Type name="audio/flac">
+                <Feature name="feature1" value="feature1Val" />
+            </Type>
+        </MediaCodec>
+        <!-- entry for testing Attribute -->
+        <MediaCodec name="test5.decoder" type="audio/g711-mlaw" >
+            <Attribute name="attributeQuirk1" />
+        </MediaCodec>
+        <!-- entry for testing Variant -->
+        <MediaCodec name="test6.decoder" type="audio/mp4a-latm" variant="variant1,variant2" >
+            <Variant name="variant1">
+                <Limit name="variant1Limit1" min="variant1Limit1Min" max="variant1Limit1Max" />
+                <Limit name="variant1Limit2" range="variant1Limit2Low-variant1Limit2High" />
+            </Variant>
+            <Variant name="variant2">
+                <Limit name="variant2Limit1" value="variant2Limit1Value" />
+            </Variant>
+        </MediaCodec>
+        <!-- entry for testing Limit -->
+        <!-- 'in' is present in xsd file but not handled in MediaCodecsXmlParser -->
+        <MediaCodec name="test7.decoder" type="audio/vorbis" >
+            <Limit name="limit1" in="limit1In" min="limit1Min"/>
+            <Limit name="limit2" min="limit2Min" max="limit2Max" scale="limit2Scale" />
+            <Limit name="limit3" ranges="limit3Val1,limit3Val2,limit3Val3" default="limit3Val3" />
+        </MediaCodec>
+    </Decoders>
+    <Encoders>
+        <MediaCodec name="test8.encoder" type="audio/opus">
+            <Limit name="limit1" max="limit1Max" />
+        </MediaCodec>
+    </Encoders>
+</Included>
diff --git a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml
new file mode 100644
index 0000000..d864ce9
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml
@@ -0,0 +1,4 @@
+<!-- entry for testing Include -->
+<MediaCodecs>
+    <Include href="media_codecs_unit_test.xml" />
+</MediaCodecs>
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index afca7c4..8d5c77f 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -34,8 +34,10 @@
         "frameworks/av/services/mediaresourcemanager",
     ],
 
-    // back to 32-bit, b/126502613
-    compile_multilib: "32",
+    // mediaserver has only been verified on 32-bit, see b/126502613
+    // use "prefer32" to *only* enable 64-bit builds on 64-bit-only lunch
+    // targets, which allows them to reach 'boot_complete'.
+    compile_multilib: "prefer32",
 
     init_rc: ["mediaserver.rc"],
 
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index bd6a6c6..c8b4a03 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -114,11 +114,11 @@
 void MtpFfsHandle::advise(int fd) {
     for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
         if (posix_madvise(mIobuf[i].bufs.data(), MAX_FILE_CHUNK_SIZE,
-                POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) < 0)
+                POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) != 0)
             PLOG(ERROR) << "Failed to madvise";
     }
     if (posix_fadvise(fd, 0, 0,
-                POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) < 0)
+                POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) != 0)
         PLOG(ERROR) << "Failed to fadvise";
 }
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 43989bb..37598f8 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -43,7 +43,13 @@
         "com.android.media.swcodec",
     ],
     min_sdk_version: "29",
-    export_include_dirs: ["include"]
+    export_include_dirs: ["include"],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_shared {
@@ -79,6 +85,7 @@
     ],
 
     header_libs: [
+        "jni_headers",
         "libmediadrm_headers",
         "libmediametrics_headers",
     ],
@@ -106,6 +113,8 @@
         "libnativehelper",
     ],
 
+    export_header_lib_headers: ["jni_headers"],
+
     export_include_dirs: ["include"],
 
     export_shared_lib_headers: [
@@ -195,3 +204,41 @@
         "frameworks/av/media/ndk/",
     ],
 }
+
+cc_library_static {
+    name: "libmediandk_format",
+
+    host_supported: true,
+
+    srcs: [
+        "NdkMediaFormat.cpp",
+    ],
+
+    header_libs: [
+        "libstagefright_foundation_headers",
+    ],
+
+    cflags: [
+        "-DEXPORT=__attribute__((visibility(\"default\")))",
+        "-Werror",
+        "-Wall",
+    ],
+
+    export_include_dirs: ["include"],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
+    apex_available: ["com.android.media"],
+}
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index ab0cb63..8680641 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -26,9 +26,6 @@
 #include <utils/StrongPointer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <android_util_Binder.h>
-
-#include <jni.h>
 
 using namespace android;
 
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 8fb6a87..80d5d50 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -114,12 +114,12 @@
         int32_t actionCode,
         const char *detail);
 
-struct AMediaCodecOnAsyncNotifyCallback {
+typedef struct AMediaCodecOnAsyncNotifyCallback {
       AMediaCodecOnAsyncInputAvailable  onAsyncInputAvailable;
       AMediaCodecOnAsyncOutputAvailable onAsyncOutputAvailable;
       AMediaCodecOnAsyncFormatChanged   onAsyncFormatChanged;
       AMediaCodecOnAsyncError           onAsyncError;
-};
+} AMediaCodecOnAsyncNotifyCallback;
 
 #if __ANDROID_API__ >= 21
 
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index 14319c4..a1cd9e3 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -36,6 +36,7 @@
 #ifndef _NDK_MEDIA_EXTRACTOR_H
 #define _NDK_MEDIA_EXTRACTOR_H
 
+#include <stdbool.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 49d8b4a..6371de4 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -36,9 +36,24 @@
 #ifndef _NDK_MEDIA_FORMAT_H
 #define _NDK_MEDIA_FORMAT_H
 
+#include <stdbool.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
+#ifndef __ANDROID__
+// Value copied from 'bionic/libc/include/android/api-level.h' which is not available on
+// non Android systems. It is set to 10000 which is same as __ANDROID_API_FUTURE__ value.
+#ifndef __ANDROID_API__
+#define __ANDROID_API__ 10000
+#endif
+
+// Value copied from 'bionic/libc/include/android/versioning.h' which is not available on
+// non Android systems
+#ifndef __INTRODUCED_IN
+#define __INTRODUCED_IN(api_level)
+#endif
+#endif
+
 #include "NdkMediaError.h"
 
 __BEGIN_DECLS
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
index 48e1422..4202732 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
@@ -34,6 +34,7 @@
 import com.android.media.benchmark.library.Native;
 import com.android.media.benchmark.library.Stats;
 
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,40 +58,87 @@
 public class EncoderTest {
     private static final Context mContext =
             InstrumentationRegistry.getInstrumentation().getTargetContext();
+    private static final String mFileDirPath = mContext.getFilesDir() + "/";
     private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
     private static final String mOutputFilePath = mContext.getString(R.string.output_file_path);
     private static final String mStatsFile =
             mContext.getExternalFilesDir(null) + "/Encoder." + System.currentTimeMillis() + ".csv";
     private static final String TAG = "EncoderTest";
-    private static final long PER_TEST_TIMEOUT_MS = 120000;
     private static final boolean DEBUG = false;
     private static final boolean WRITE_OUTPUT = false;
+    private static final long PER_TEST_TIMEOUT_MS = 120000;
     private static final int ENCODE_DEFAULT_FRAME_RATE = 25;
-    private static final int ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
-    private static final int ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
+    private static final int ENCODE_DEFAULT_VIDEO_BIT_RATE = 8000000 /* 8 Mbps */;
+    private static final int ENCODE_MIN_VIDEO_BIT_RATE = 600000 /* 600 Kbps */;
     private static final int ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
+    private static int mColorFormat = COLOR_FormatYUV420Flexible;
+    private static File mDecodedFileQcif;
+    private static File mDecodedFileFullHd;
+    private static File mDecodedFileAudio;
     private String mInputFile;
+    private String mMime;
+    private int mBitRate;
+    private int mIFrameInterval;
+    private int mWidth;
+    private int mHeight;
+    private int mProfile;
+    private int mLevel;
+    private int mSampleRate;
+    private int mNumChannel;
+    private static final String DECODE_FULLHD_INPUT = "crowd_1920x1080_25fps_4000kbps_h265.mkv";
+    private static final String DECODE_QCIF_INPUT = "crowd_176x144_25fps_6000kbps_mpeg4.mp4";
+    private static final String DECODE_AUDIO_INPUT = "bbb_48000hz_2ch_100kbps_opus_30sec.webm";
+    private static final String DECODE_FULLHD_UNPACKED = "crowd_1920x1080_25fps_4000kbps_h265.yuv";
+    private static final String DECODE_QCIF_UNPACKED = "crowd_176x144_25fps_6000kbps_mpeg4.yuv";
+    private static final String DECODE_AUDIO_UNPACKED = "bbb_48000hz_2ch_100kbps_opus_30sec.raw";
 
     @Parameterized.Parameters
     public static Collection<Object[]> inputFiles() {
         return Arrays.asList(new Object[][]{
                 // Audio Test
-                {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4"},
-                {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp"},
-                {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp"},
-                {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4"},
-                {"bbb_48000hz_2ch_100kbps_opus_30sec.webm"},
+                // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+                // profile, level, sampleRate, channelCount
+                {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AAC,
+                        ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+                {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_NB,
+                        ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 8000, 1},
+                {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_WB,
+                        ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 16000, 1},
+                {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_FLAC,
+                        ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+                {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_OPUS,
+                        ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 48000, 2},
+
                 // Video Test
-                {"crowd_1920x1080_25fps_4000kbps_vp8.webm"},
-                {"crowd_1920x1080_25fps_6700kbps_h264.ts"},
-                {"crowd_1920x1080_25fps_4000kbps_h265.mkv"},
-                {"crowd_1920x1080_25fps_4000kbps_vp9.webm"},
-                {"crowd_176x144_25fps_6000kbps_mpeg4.mp4"},
-                {"crowd_176x144_25fps_6000kbps_h263.3gp"}});
+                // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+                // profile, level, sampleRate, channelCount
+                {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP8,
+                        ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+                {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_AVC,
+                        ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+                {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_HEVC,
+                        ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+                {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP9,
+                        ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+                {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_MPEG4, ENCODE_MIN_VIDEO_BIT_RATE,
+                        176, 144, 1, -1, -1, -1, -1},
+                {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_H263, ENCODE_MIN_VIDEO_BIT_RATE,
+                        176, 144, 1, -1, -1, -1, -1}});
     }
 
-    public EncoderTest(String inputFileName) {
-        this.mInputFile = inputFileName;
+    public EncoderTest(String filename, String mime, int bitrate, int width, int height,
+                       int frameInterval, int profile, int level, int samplerate,
+                       int channelCount) {
+        this.mInputFile = filename;
+        this.mMime = mime;
+        this.mBitRate = bitrate;
+        this.mIFrameInterval = frameInterval;
+        this.mWidth = width;
+        this.mHeight = height;
+        this.mProfile = profile;
+        this.mLevel = level;
+        this.mSampleRate = samplerate;
+        this.mNumChannel = channelCount;
     }
 
     @BeforeClass
@@ -101,33 +149,36 @@
         Log.d(TAG, "Saving Benchmark results in: " + mStatsFile);
     }
 
-    @Test(timeout = PER_TEST_TIMEOUT_MS)
-    public void testEncoder() throws Exception {
-        int status;
-        int frameSize;
-        //Parameters for video
-        int width = 0;
-        int height = 0;
-        int profile = 0;
-        int level = 0;
-        int frameRate = 0;
+    @BeforeClass
+    public static void prepareInput() throws IOException {
 
-        //Parameters for audio
-        int bitRate = 0;
-        int sampleRate = 0;
-        int numChannels = 0;
-        File inputFile = new File(mInputFilePath + mInputFile);
-        assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
-                inputFile.exists());
+        mDecodedFileFullHd = new File(mFileDirPath + DECODE_FULLHD_UNPACKED);
+        int status = decodeFile(mInputFilePath + DECODE_FULLHD_INPUT, mDecodedFileFullHd);
+        assertEquals("Decoder returned error " + status, 0, status);
+
+        mDecodedFileQcif = new File(mFileDirPath + DECODE_QCIF_UNPACKED);
+        status = decodeFile(mInputFilePath + DECODE_QCIF_INPUT, mDecodedFileQcif);
+        assertEquals("Decoder returned error " + status, 0, status);
+
+        mDecodedFileAudio = new File(mFileDirPath + DECODE_AUDIO_UNPACKED);
+        status = decodeFile(mInputFilePath + DECODE_AUDIO_INPUT, mDecodedFileAudio);
+        assertEquals("Decoder returned error " + status, 0, status);
+    }
+
+    private static int decodeFile(String inputFileName, File outputDecodeFile) throws IOException {
+        int status = -1;
+        File inputFile = new File(inputFileName);
+        assertTrue("Cannot open input file " + inputFileName, inputFile.exists());
         FileInputStream fileInput = new FileInputStream(inputFile);
         FileDescriptor fileDescriptor = fileInput.getFD();
+        FileOutputStream decodeOutputStream = new FileOutputStream(outputDecodeFile);
+
         Extractor extractor = new Extractor();
         int trackCount = extractor.setUpExtractor(fileDescriptor);
-        assertTrue("Extraction failed. No tracks for file: " + mInputFile, (trackCount > 0));
+        assertTrue("Extraction failed. No tracks for the given input file", (trackCount > 0));
         ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
         ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
         for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
-            int colorFormat = COLOR_FormatYUV420Flexible;
             extractor.selectExtractorTrack(currentTrack);
             MediaFormat format = extractor.getFormat(currentTrack);
             // Get samples from extractor
@@ -146,163 +197,135 @@
                             bufInfo.presentationTimeUs + " size = " + bufInfo.size);
                 }
             } while (sampleSize > 0);
-            int tid = android.os.Process.myTid();
-            File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
-            FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
             Decoder decoder = new Decoder();
             decoder.setupDecoder(decodeOutputStream);
             status = decoder.decode(inputBuffer, frameInfo, false, format, "");
-            assertEquals("Decoder returned error " + status + " for file: " + mInputFile, 0,
-                    status);
             MediaFormat decoderFormat = decoder.getFormat();
+            if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
+                mColorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
+            }
             decoder.deInitCodec();
             extractor.unselectExtractorTrack(currentTrack);
             inputBuffer.clear();
             frameInfo.clear();
-            if (decodeOutputStream != null) {
-                decodeOutputStream.close();
-            }
-            String mime = format.getString(MediaFormat.KEY_MIME);
-            ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
-            assertTrue("No suitable codecs found for file: " + mInputFile + " track : " +
-                    currentTrack + " mime: " + mime, (mediaCodecs.size() > 0));
-            Boolean[] encodeMode = {true, false};
-            /* Encoding the decoder's output */
-            for (Boolean asyncMode : encodeMode) {
-                for (String codecName : mediaCodecs) {
-                    FileOutputStream encodeOutputStream = null;
-                    if (WRITE_OUTPUT) {
-                        File outEncodeFile = new File(mOutputFilePath + "encoder.out");
-                        if (outEncodeFile.exists()) {
-                            assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
-                                    outEncodeFile.delete());
-                        }
-                        assertTrue("Unable to create file to write encoder output: " +
-                                outEncodeFile.toString(), outEncodeFile.createNewFile());
-                        encodeOutputStream = new FileOutputStream(outEncodeFile);
-                    }
-                    File rawFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
-                    assertTrue("Cannot open file to write decoded output", rawFile.exists());
-                    if (DEBUG) {
-                        Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
-                    }
-                    FileInputStream eleStream = new FileInputStream(rawFile);
-                    if (mime.startsWith("video/")) {
-                        width = format.getInteger(MediaFormat.KEY_WIDTH);
-                        height = format.getInteger(MediaFormat.KEY_HEIGHT);
-                        if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
-                            frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
-                        } else if (frameRate <= 0) {
-                            frameRate = ENCODE_DEFAULT_FRAME_RATE;
-                        }
-                        if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
-                            bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
-                        } else if (bitRate <= 0) {
-                            if (mime.contains("video/3gpp") || mime.contains("video/mp4v-es")) {
-                                bitRate = ENCODE_MIN_BIT_RATE;
-                            } else {
-                                bitRate = ENCODE_DEFAULT_BIT_RATE;
-                            }
-                        }
-                        if (format.containsKey(MediaFormat.KEY_PROFILE)) {
-                            profile = format.getInteger(MediaFormat.KEY_PROFILE);
-                        }
-                        if (format.containsKey(MediaFormat.KEY_PROFILE)) {
-                            level = format.getInteger(MediaFormat.KEY_LEVEL);
-                        }
-                        if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
-                            colorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
-                        }
-                    } else {
-                        sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
-                        numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-                        if (decoderFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
-                            bitRate = decoderFormat.getInteger(MediaFormat.KEY_BIT_RATE);
-                        } else {
-                            bitRate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
-                        }
-                    }
-                    /*Setup Encode Format*/
-                    MediaFormat encodeFormat;
-                    if (mime.startsWith("video/")) {
-                        frameSize = width * height * 3 / 2;
-                        encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
-                        encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
-                        encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
-                        encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
-                        encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
-                        encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
-                        encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
-                        encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
-                    } else {
-                        encodeFormat = MediaFormat.createAudioFormat(mime, sampleRate, numChannels);
-                        encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
-                        frameSize = 4096;
-                    }
-                    Encoder encoder = new Encoder();
-                    encoder.setupEncoder(encodeOutputStream, eleStream);
-                    status = encoder.encode(codecName, encodeFormat, mime, frameRate, sampleRate,
-                            frameSize, asyncMode);
-                    encoder.deInitEncoder();
-                    assertEquals(
-                            codecName + " encoder returned error " + status + " for " + "file:" +
-                                    " " + mInputFile, 0, status);
-                    encoder.dumpStatistics(mInputFile, codecName, (asyncMode ? "async" : "sync"),
-                            extractor.getClipDuration(), mStatsFile);
-                    Log.i(TAG, "Encoding complete for file: " + mInputFile + " with codec: " +
-                            codecName + " for aSyncMode = " + asyncMode);
-                    encoder.resetEncoder();
-                    eleStream.close();
-                    if (encodeOutputStream != null) {
-                        encodeOutputStream.close();
-                    }
-
-                }
-            }
-            //Cleanup temporary input file
-            if (decodedFile.exists()) {
-                assertTrue(" Unable to delete decoded file" + decodedFile.toString(),
-                        decodedFile.delete());
-                Log.i(TAG, "Successfully deleted decoded file");
-            }
         }
         extractor.deinitExtractor();
         fileInput.close();
+        decodeOutputStream.close();
+        return status;
     }
 
     @Test(timeout = PER_TEST_TIMEOUT_MS)
-    public void testNativeEncoder() throws Exception {
-        File inputFile = new File(mInputFilePath + mInputFile);
-        assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
-                inputFile.exists());
-        int tid = android.os.Process.myTid();
-        final String mDecodedFile = mContext.getFilesDir() + "/decoder_" + tid + ".out";
-        FileInputStream fileInput = new FileInputStream(inputFile);
-        FileDescriptor fileDescriptor = fileInput.getFD();
-        Extractor extractor = new Extractor();
-        int trackCount = extractor.setUpExtractor(fileDescriptor);
-        assertTrue("Extraction failed. No tracks for file: ", trackCount > 0);
-        for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
-            extractor.selectExtractorTrack(currentTrack);
-            MediaFormat format = extractor.getFormat(currentTrack);
-            String mime = format.getString(MediaFormat.KEY_MIME);
-            ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
-            // Encoding the decoder's output
+    public void testEncoder() throws Exception {
+        int status;
+        int frameSize;
+
+        ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+        assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+        Boolean[] encodeMode = {true, false};
+        // Encoding the decoded input file
+        for (Boolean asyncMode : encodeMode) {
             for (String codecName : mediaCodecs) {
-                Native nativeEncoder = new Native();
-                int status = nativeEncoder
-                        .Encode(mInputFilePath, mInputFile, mDecodedFile, mStatsFile, codecName);
+                FileOutputStream encodeOutputStream = null;
+                if (WRITE_OUTPUT) {
+                    File outEncodeFile = new File(mOutputFilePath + "encoder.out");
+                    if (outEncodeFile.exists()) {
+                        assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
+                                outEncodeFile.delete());
+                    }
+                    assertTrue("Unable to create file to write encoder output: " +
+                            outEncodeFile.toString(), outEncodeFile.createNewFile());
+                    encodeOutputStream = new FileOutputStream(outEncodeFile);
+                }
+                File rawFile = new File(mFileDirPath + mInputFile);
+                assertTrue("Cannot open decoded input file", rawFile.exists());
+                if (DEBUG) {
+                    Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
+                }
+                FileInputStream eleStream = new FileInputStream(rawFile);
+                // Setup Encode Format
+                MediaFormat encodeFormat;
+                if (mMime.startsWith("video/")) {
+                    frameSize = mWidth * mHeight * 3 / 2;
+                    encodeFormat = MediaFormat.createVideoFormat(mMime, mWidth, mHeight);
+                    encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODE_DEFAULT_FRAME_RATE);
+                    encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameInterval);
+                    encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+                    encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
+                    if (mProfile != -1 && mLevel != -1) {
+                        encodeFormat.setInteger(MediaFormat.KEY_PROFILE, mProfile);
+                        encodeFormat.setInteger(MediaFormat.KEY_LEVEL, mLevel);
+                    }
+                } else {
+                    frameSize = 4096;
+                    encodeFormat = MediaFormat.createAudioFormat(mMime, mSampleRate, mNumChannel);
+                    encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+                }
+                Encoder encoder = new Encoder();
+                encoder.setupEncoder(encodeOutputStream, eleStream);
+                status = encoder.encode(codecName, encodeFormat, mMime, ENCODE_DEFAULT_FRAME_RATE,
+                        mSampleRate, frameSize, asyncMode);
+                encoder.deInitEncoder();
                 assertEquals(
-                        codecName + " encoder returned error " + status + " for " + "file:" + " " +
-                                mInputFile, 0, status);
+                        codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+                                mMime, 0, status);
+                String inputReference;
+                long durationUs;
+                if (mMime.startsWith("video/")) {
+                    inputReference =
+                            mInputFile + "_" + mWidth + "x" + mHeight + "_" + mBitRate + "bps";
+                    durationUs = (((eleStream.getChannel().size() + frameSize - 1) / frameSize) /
+                            ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+                } else {
+                    inputReference = mInputFile + "_" + mSampleRate + "hz_" + mNumChannel + "ch_" +
+                            mBitRate + "bps";
+                    durationUs =
+                            (eleStream.getChannel().size() / (mSampleRate * mNumChannel)) * 1000000;
+                }
+                encoder.dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
+                        durationUs, mStatsFile);
+                Log.i(TAG, "Encoding complete for mime: " + mMime + " with codec: " + codecName +
+                        " for aSyncMode = " + asyncMode);
+                encoder.resetEncoder();
+                eleStream.close();
+                if (encodeOutputStream != null) {
+                    encodeOutputStream.close();
+                }
             }
         }
-        File decodedFile = new File(mDecodedFile);
-        // Cleanup temporary input file
-        if (decodedFile.exists()) {
-            assertTrue("Unable to delete - " + mDecodedFile, decodedFile.delete());
-            Log.i(TAG, "Successfully deleted - " + mDecodedFile);
+    }
+
+    @Test(timeout = PER_TEST_TIMEOUT_MS)
+    public void testNativeEncoder() {
+        ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+        assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+        for (String codecName : mediaCodecs) {
+            Native nativeEncoder = new Native();
+            int status = nativeEncoder
+                    .Encode(mFileDirPath, mInputFile, mStatsFile, codecName, mMime, mBitRate,
+                            mColorFormat, mIFrameInterval, mWidth, mHeight, mProfile, mLevel,
+                            mSampleRate, mNumChannel);
+            assertEquals(codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+                    mMime, 0, status);
         }
-        fileInput.close();
+    }
+
+    @AfterClass
+    public static void deleteDecodedFiles() {
+        if (mDecodedFileFullHd.exists()) {
+            assertTrue(" Unable to delete decoded file" + mDecodedFileFullHd.toString(),
+                    mDecodedFileFullHd.delete());
+            Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileFullHd.toString());
+        }
+        if (mDecodedFileQcif.exists()) {
+            assertTrue(" Unable to delete decoded file" + mDecodedFileQcif.toString(),
+                    mDecodedFileQcif.delete());
+            Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileQcif.toString());
+        }
+        if (mDecodedFileAudio.exists()) {
+            assertTrue(" Unable to delete decoded file" + mDecodedFileAudio.toString(),
+                    mDecodedFileAudio.delete());
+            Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileAudio.toString());
+        }
     }
 }
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
index 1277c8b..2f658e3 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
@@ -30,189 +30,81 @@
 #include <stdio.h>
 
 constexpr int32_t ENCODE_DEFAULT_FRAME_RATE = 25;
-constexpr int32_t ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
-constexpr int32_t ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
-constexpr int32_t ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
 
 extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Encode(
-        JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jOutFilePath,
-        jstring jStatsFile, jstring jCodecName) {
+        JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jStatsFile,
+        jstring jCodecName, jstring jMime, jint jBitRate, jint jColorFormat, jint jFrameInterval,
+        jint jWidth, jint jHeight, jint jProfile, jint jLevel, jint jSampleRate,
+        jint jNumChannels) {
+    UNUSED(thiz);
     const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
     const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
-    string sFilePath = string(filePath) + string(fileName);
-    UNUSED(thiz);
-    FILE *inputFp = fopen(sFilePath.c_str(), "rb");
-    env->ReleaseStringUTFChars(jFileName, fileName);
-    env->ReleaseStringUTFChars(jFilePath, filePath);
-    if (!inputFp) {
-        ALOGE("Unable to open input file for reading");
+    string inputFile = string(filePath) + string(fileName);
+    const char *codecName = env->GetStringUTFChars(jCodecName, nullptr);
+    string sCodecName = string(codecName);
+    const char *mime = env->GetStringUTFChars(jMime, nullptr);
+
+    ifstream eleStream;
+    eleStream.open(inputFile, ifstream::binary | ifstream::ate);
+    if (!eleStream.is_open()) {
+        ALOGE("%s - File failed to open for reading!", fileName);
+        env->ReleaseStringUTFChars(jFileName, fileName);
         return -1;
     }
 
-    Decoder *decoder = new Decoder();
-    Extractor *extractor = decoder->getExtractor();
-    if (!extractor) {
-        ALOGE("Extractor creation failed");
-        return -1;
-    }
+    bool asyncMode[2] = {true, false};
+    for (bool mode : asyncMode) {
+        size_t eleSize = eleStream.tellg();
+        eleStream.seekg(0, ifstream::beg);
 
-    // Read file properties
-    struct stat buf;
-    stat(sFilePath.c_str(), &buf);
-    size_t fileSize = buf.st_size;
-    if (fileSize > kMaxBufferSize) {
-        ALOGE("File size greater than maximum buffer size");
-        return -1;
-    }
-    int32_t fd = fileno(inputFp);
-    int32_t trackCount = extractor->initExtractor(fd, fileSize);
-    if (trackCount <= 0) {
-        ALOGE("initExtractor failed");
-        return -1;
-    }
+        // Set encoder params
+        encParameter encParams;
+        encParams.width = jWidth;
+        encParams.height = jHeight;
+        encParams.bitrate = jBitRate;
+        encParams.iFrameInterval = jFrameInterval;
+        encParams.sampleRate = jSampleRate;
+        encParams.numChannels = jNumChannels;
+        encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
+        encParams.colorFormat = jColorFormat;
+        encParams.profile = jProfile;
+        encParams.level = jLevel;
 
-    for (int curTrack = 0; curTrack < trackCount; curTrack++) {
-        int32_t status = extractor->setupTrackFormat(curTrack);
-        if (status != 0) {
-            ALOGE("Track Format invalid");
-            return -1;
-        }
-        uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
-        if (!inputBuffer) {
-            ALOGE("Insufficient memory");
-            return -1;
-        }
-        vector<AMediaCodecBufferInfo> frameInfo;
-        AMediaCodecBufferInfo info;
-        uint32_t inputBufferOffset = 0;
-
-        // Get frame data
-        while (1) {
-            status = extractor->getFrameSample(info);
-            if (status || !info.size) break;
-            // copy the meta data and buffer to be passed to decoder
-            if (inputBufferOffset + info.size > kMaxBufferSize) {
-                ALOGE("Memory allocated not sufficient");
-                free(inputBuffer);
-                return -1;
-            }
-            memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
-            frameInfo.push_back(info);
-            inputBufferOffset += info.size;
-        }
-        string decName = "";
-        const char *outputFilePath = env->GetStringUTFChars(jOutFilePath, nullptr);
-        FILE *outFp = fopen(outputFilePath, "wb");
-        if (outFp == nullptr) {
-            ALOGE("%s - File failed to open for writing!", outputFilePath);
-            free(inputBuffer);
-            return -1;
-        }
-        decoder->setupDecoder();
-        status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+        Encoder *encoder = new Encoder();
+        encoder->setupEncoder();
+        auto status = encoder->encode(sCodecName, eleStream, eleSize, mode, encParams,
+                                      const_cast<char *>(mime));
         if (status != AMEDIA_OK) {
-            ALOGE("Decode returned error");
-            free(inputBuffer);
+            ALOGE("Encoder returned error");
             return -1;
         }
-
-        AMediaFormat *decoderFormat = decoder->getFormat();
-        AMediaFormat *format = extractor->getFormat();
-        if (inputBuffer) {
-            free(inputBuffer);
-            inputBuffer = nullptr;
+        ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(), mode);
+        encoder->deInitCodec();
+        const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
+        string inputReference;
+        int64_t clipDurationUs;
+        if (!strncmp(mime, "video/", 6)) {
+            inputReference = string(fileName) + "_" + to_string(jWidth) + "x" + to_string(jHeight) +
+                             "_" + to_string(jBitRate) + "bps";
+            int32_t frameSize = jWidth * jHeight * 3 / 2;
+            clipDurationUs =
+                    (((eleSize + frameSize - 1) / frameSize) / ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+        } else {
+            inputReference = string(fileName) + "_" + to_string(jSampleRate) + "hz_" +
+                             to_string(jNumChannels) + "ch_" + to_string(jBitRate) + "bps";
+            clipDurationUs = (eleSize / (jSampleRate * jNumChannels)) * 1000000;
         }
-        const char *mime = nullptr;
-        AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
-        if (!mime) {
-            ALOGE("Error in AMediaFormat_getString");
-            return -1;
-        }
-        ifstream eleStream;
-        eleStream.open(outputFilePath, ifstream::binary | ifstream::ate);
-        if (!eleStream.is_open()) {
-            ALOGE("%s - File failed to open for reading!", outputFilePath);
-            env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
-            return -1;
-        }
-        const char *codecName = env->GetStringUTFChars(jCodecName, NULL);
-        const char *inputReference = env->GetStringUTFChars(jFileName, nullptr);
-        string sCodecName = string(codecName);
-        string sInputReference = string(inputReference);
-
-        bool asyncMode[2] = {true, false};
-        for (int i = 0; i < 2; i++) {
-            size_t eleSize = eleStream.tellg();
-            eleStream.seekg(0, ifstream::beg);
-
-            // Get encoder params
-            encParameter encParams;
-            if (!strncmp(mime, "video/", 6)) {
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &encParams.width);
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &encParams.height);
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &encParams.frameRate);
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &encParams.bitrate);
-                if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
-                    encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
-                    if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
-                        encParams.bitrate = ENCODE_MIN_BIT_RATE /* 600 Kbps */;
-                    } else {
-                        encParams.bitrate = ENCODE_DEFAULT_BIT_RATE /* 8 Mbps */;
-                    }
-                }
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
-                AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
-                                      &encParams.colorFormat);
-            } else {
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
-                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
-                                      &encParams.numChannels);
-                encParams.bitrate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
-            }
-            Encoder *encoder = new Encoder();
-            encoder->setupEncoder();
-            status = encoder->encode(sCodecName, eleStream, eleSize, asyncMode[i], encParams,
-                                     (char *)mime);
-            if (status != AMEDIA_OK) {
-                ALOGE("Encoder returned error");
-                return -1;
-            }
-            ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(),
-                  asyncMode[i]);
-            encoder->deInitCodec();
-            const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
-            encoder->dumpStatistics(sInputReference, extractor->getClipDuration(), sCodecName,
-                                    (asyncMode[i] ? "async" : "sync"), statsFile);
-            env->ReleaseStringUTFChars(jStatsFile, statsFile);
-            encoder->resetEncoder();
-            delete encoder;
-            encoder = nullptr;
-        }
-        eleStream.close();
-        if (outFp) {
-            fclose(outFp);
-            outFp = nullptr;
-        }
-        env->ReleaseStringUTFChars(jFileName, inputReference);
-        env->ReleaseStringUTFChars(jCodecName, codecName);
-        env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
-        if (format) {
-            AMediaFormat_delete(format);
-            format = nullptr;
-        }
-        if (decoderFormat) {
-            AMediaFormat_delete(decoderFormat);
-            decoderFormat = nullptr;
-        }
-        decoder->deInitCodec();
-        decoder->resetDecoder();
+        encoder->dumpStatistics(inputReference, clipDurationUs, sCodecName,
+                                (mode ? "async" : "sync"), statsFile);
+        env->ReleaseStringUTFChars(jStatsFile, statsFile);
+        encoder->resetEncoder();
+        delete encoder;
+        encoder = nullptr;
     }
-    if (inputFp) {
-        fclose(inputFp);
-        inputFp = nullptr;
-    }
-    extractor->deInitExtractor();
-    delete decoder;
+    eleStream.close();
+    env->ReleaseStringUTFChars(jFilePath, filePath);
+    env->ReleaseStringUTFChars(jFileName, fileName);
+    env->ReleaseStringUTFChars(jMime, mime);
+    env->ReleaseStringUTFChars(jCodecName, codecName);
     return 0;
 }
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java
index 45e5574..754cd8e 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java
@@ -175,10 +175,10 @@
 
                 @Override
                 public void onError(@NonNull MediaCodec mediaCodec, @NonNull CodecException e) {
-                    mediaCodec.stop();
-                    mediaCodec.release();
-                    Log.e(TAG, "CodecError: " + e.toString());
+                    mSignalledError = true;
+                    Log.e(TAG, "Codec Error: " + e.toString());
                     e.printStackTrace();
+                    synchronized (mLock) { mLock.notify(); }
                 }
 
                 @Override
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
index 38b608a..3e3969c 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
@@ -27,6 +27,7 @@
     public native int Decode(String inputFilePath, String inputFileName, String statsFile,
             String codecName, boolean asyncMode);
 
-    public native int Encode(String inputFilePath, String inputFileName, String outputFilePath,
-            String statsFile, String codecName);
+    public native int Encode(String inputFilePath, String inputFileName, String statsFile,
+            String codecName, String mime, int bitRate, int colorFormat, int frameInterval,
+            int width, int height, int profile, int level, int sampleRate, int numChannel);
 }
diff --git a/media/tests/benchmark/README.md b/media/tests/benchmark/README.md
index 05fbe6f..047c289 100644
--- a/media/tests/benchmark/README.md
+++ b/media/tests/benchmark/README.md
@@ -1,7 +1,7 @@
 # Benchmark tests
 
 Benchmark app analyses the time taken by MediaCodec, MediaExtractor and MediaMuxer for given set of inputs. It is used to benchmark these modules on android devices.
-Benchmark results are emitted to logcat.
+Benchmark results are published as a CSV report.
 
 This page describes steps to run the NDK and SDK layer test.
 
@@ -10,35 +10,49 @@
 mmm frameworks/av/media/tests/benchmark/
 ```
 
-# NDK
-
-To run the test suite for measuring performance of the native layer, follow the following steps:
-
-The binaries will be created in the following path : $OUT/data/nativetest64/
-
-adb push $OUT/data/nativetest64/* /data/local/tmp/
-
-Eg. adb push $OUT/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
-
-To run the binary, follow the commands mentioned below under each module.
-
-The resource file for the tests is taken from [here](https://drive.google.com/open?id=1ghMr17BBJ7n0pqbm7oREiTN_MNemJUqy)
+# Resources
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/tests/benchmark/MediaBenchmark.zip)
 
 Download the MediaBenchmark.zip file, unzip and push it to /data/local/tmp/ on the device.
 
 ```
 unzip MediaBenchmark.zip
-adb push MediaBenchmark /data/local/tmp
+adb push MediaBenchmark /data/local/tmp/MediaBenchmark/res/
 ```
 
+The resource files are assumed to be at /data/local/tmp/MediaBenchmark/res/. You can use a different location, but you have to modify the rest of the instructions to replace /data/local/tmp/MediaBenchmark/res/ with wherever you chose to put the files.
+
+# NDK CLI Tests
+Note: [Benchmark Application](#BenchmarkApplication) now supports profiling both SDK and NDK APIs and that is the preferred way to benchmark codecs
+
+To run the test suite for measuring performance of the native layer, follow the following steps:
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+
+adb push $OUT/data/nativetest64/* /data/local/tmp/. For example
+
+```
+adb push $OUT/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+To test 32-bit binary push binaries from nativetest.
+
+adb push $OUT/data/nativetest/* /data/local/tmp/. For example
+
+```
+adb push $OUT/data/nativetest/extractorTest/extractorTest /data/local/tmp/
+```
+
+To run the binary, follow the commands mentioned below under each module.
+
 ## Extractor
 
 The test extracts elementary stream and benchmarks the extractors available in NDK.
 
-The resource files are assumed to be at /data/local/tmp/MediaBenchmark/res/. You can use a different location, but you have to modify the rest of the instructions to replace /data/local/tmp/MediaBenchmark/res/ with wherever you chose to put the files.
-
-The path to these files on the device is required to be given for the test.
-
 ```
 adb shell /data/local/tmp/extractorTest -P /data/local/tmp/MediaBenchmark/res/
 ```
@@ -47,8 +61,6 @@
 
 The test decodes input stream and benchmarks the decoders available in NDK.
 
-Setup steps are same as extractor.
-
 ```
 adb shell /data/local/tmp/decoderTest -P /data/local/tmp/MediaBenchmark/res/
 ```
@@ -57,8 +69,6 @@
 
 The test muxes elementary stream and benchmarks the muxers available in NDK.
 
-Setup steps are same as extractor.
-
 ```
 adb shell /data/local/tmp/muxerTest -P /data/local/tmp/MediaBenchmark/res/
 ```
@@ -67,55 +77,82 @@
 
 The test encodes input stream and benchmarks the encoders available in NDK.
 
-Setup steps are same as extractor.
-
 ```
 adb shell /data/local/tmp/encoderTest -P /data/local/tmp/MediaBenchmark/res/
 ```
 
-# SDK
+# <a name="BenchmarkApplication"></a> Benchmark Application
+To run the test suite for measuring performance of the SDK and NDK APIs, follow the following steps:
+Benchmark Application can be run in two ways.
 
-To run the test suite for measuring performance of the SDK APIs, follow the following steps:
+## Steps to run with atest
+Note that atest command will install Benchmark application and push the required test files to the device as well.
+
+For running all the tests, run the following command
+```
+atest com.android.media.benchmark.tests -- --enable-module-dynamic-download=true
+```
+
+For running the tests individually, run the following atest commands:
+
+```
+atest com.android.media.benchmark.tests.ExtractorTest -- --enable-module-dynamic-download=true
+atest com.android.media.benchmark.tests.DecoderTest -- --enable-module-dynamic-download=true
+atest com.android.media.benchmark.tests.MuxerTest -- --enable-module-dynamic-download=true
+atest com.android.media.benchmark.tests.EncoderTest -- --enable-module-dynamic-download=true
+```
+
+## Steps to run without atest
 
 The apk will be created at the following path:
-$OUT/testcases/MediaBenchmarkTest/arm64/
 
-To get the resorce files for the test follow instructions given in [NDK](#NDK)
+The 64-bit apk will be created in the following path :
+$OUT/testcases/MediaBenchmarkTest/arm64/
 
 For installing the apk, run the command:
 ```
 adb install -f -r $OUT/testcases/MediaBenchmarkTest/arm64/MediaBenchmarkTest.apk
 ```
 
-For running all the tests, run the command:
+The 32-bit apk will be created in the following path :
+$OUT/testcases/MediaBenchmarkTest/arm/
+
+For installing the apk, run the command:
+```
+adb install -f -r $OUT/testcases/MediaBenchmarkTest/arm/MediaBenchmarkTest.apk
+```
+
+To get the resource files for the test follow instructions given in [Resources](#Resources)
+
+For running all the tests, run the following command
 ```
 adb shell am instrument -w -r -e package com.android.media.benchmark.tests com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
 ```
 
 ## Extractor
 
-The test extracts elementary stream and benchmarks the extractors available in SDK.
+The test extracts elementary stream and benchmarks the extractors available in SDK and NDK.
 ```
 adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.ExtractorTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
 ```
 
 ## Decoder
 
-The test decodes input stream and benchmarks the decoders available in SDK.
+The test decodes input stream and benchmarks the decoders available in SDK and NDK.
 ```
 adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.DecoderTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
 ```
 
 ## Muxer
 
-The test muxes elementary stream and benchmarks different writers available in SDK.
+The test muxes elementary stream and benchmarks different writers available in SDK and NDK.
 ```
 adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.MuxerTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
 ```
 
 ## Encoder
 
-The test encodes input stream and benchmarks the encoders available in SDK.
+The test encodes input stream and benchmarks the encoders available in SDK and NDK.
 ```
 adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.EncoderTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
 ```
@@ -124,24 +161,27 @@
 To run the test suite for measuring performance of the codec2 layer, follow the following steps:
 
 The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
 The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
 
 To test 64-bit binary push binaries from nativetest64.
 adb push $(OUT)/data/nativetest64/* /data/local/tmp/
-Eg. adb push $(OUT)/data/nativetest64/C2DecoderTest/C2DecoderTest /data/local/tmp/
+```
+adb push $(OUT)/data/nativetest64/C2DecoderTest/C2DecoderTest /data/local/tmp/
+```
 
 To test 32-bit binary push binaries from nativetest.
 adb push $(OUT)/data/nativetest/* /data/local/tmp/
-Eg. adb push $(OUT)/data/nativetest/C2DecoderTest/C2DecoderTest /data/local/tmp/
+```
+adb push $(OUT)/data/nativetest/C2DecoderTest/C2DecoderTest /data/local/tmp/
+```
 
-To get the resource files for the test follow instructions given in [NDK](#NDK)
+To get the resource files for the test follow instructions given in [Resources](#Resources)
 
 ## C2 Decoder
 
 The test decodes input stream and benchmarks the codec2 decoders available in device.
 
-Setup steps are same as [extractor](#extractor).
-
 ```
 adb shell /data/local/tmp/C2DecoderTest -P /data/local/tmp/MediaBenchmark/res/
 ```
@@ -149,8 +189,95 @@
 
 The test encodes input stream and benchmarks the codec2 encoders available in device.
 
-Setup steps are same as [extractor](#extractor).
-
 ```
 adb shell /data/local/tmp/C2EncoderTest -P /data/local/tmp/MediaBenchmark/res/
 ```
+
+# Analysis
+
+The benchmark results are stored in a CSV file which can be used for analysis. These results are stored in following format:
+<app directory>/<module_name>.<timestamp>.csv
+
+Note: This timestamp is in nano seconds and will change based on current system time.
+
+To find the location of the CSV file, look for the path in logs. Example log below -
+
+```
+com.android.media.benchmark D/DecoderTest: Saving Benchmark results in: /storage/emulated/0/Android/data/com.android.media.benchmark/files/Decoder.1587732395387.csv
+```
+
+This file can be pulled from the device using "adb pull" command.
+```
+adb pull /storage/emulated/0/Android/data/com.android.media.benchmark/files/Decoder.1587732395387.csv ./Decoder.1587732395387.csv
+```
+
+## CSV Columns
+
+Following columns are available in CSV.
+
+Note: All time values are in nano seconds
+
+1. **currentTime** : The time recorded at the creation of the stats. This may be used to estimate time between consecutive test clips.
+
+2. **fileName**: The file being used as an input for the benchmark test.
+
+3. **operation**: The current operation on the input test vector i.e. Extract/Mux/Encode/Decode.
+
+4. **NDK/SDK**: The target APIs i.e. AMedia vs Media calls for the operation being performed.
+
+5. **sync/async**: This is specific to MediaCodec objects (i.e. Encoder and Decoder). It specifies the mode in which MediaCodec APIs are working. For async mode, callbacks are set. For sync mode, we have to poll the dequeueBuffer APIs to queue and dequeue input output buffers respectively.
+
+6. **setupTime**: The time taken to set up the MediaExtractor/Muxer/Codec instance.
+
+    * MediaCodec: includes setting async/sync mode, configuring with a format and codec.start
+
+    * MediaExtractor: includes AMediaExtractor_new and setDataSource.
+
+    * MediaMuxer: includes creating the object, adding track, and starting the muxer.
+
+7. **destroyTime**: The time taken to stop and close MediaExtractor/Muxer/Codec instance.
+
+8. **minimumTime**: The minimum time taken to extract/mux/encode/decode a frame.
+
+9. **maximumTime**: The maximum time taken to extract/mux/encode/decode a frame.
+
+10. **averageTime**: Average time taken to extract/mux/encode/decode per frame.
+
+    * MediaCodec: computed as the total time taken to encode/decode all frames divided by the number of frames encoded/decoded.
+
+    * MediaExtractor: computed as the total time taken to extract all frames divided by the number of frames extracted.
+
+    * MediaMuxer: computed as the total time taken to mux all frames divided by the number of frames muxed.
+
+11. **timeToProcess1SecContent**: The time required to process one second worth input data.
+
+12. **totalBytesProcessedPerSec**: The number of bytes extracted/muxed/decoded/encoded per second.
+
+13. **timeToFirstFrame**: The time taken to receive the first output frame.
+
+14. **totalSizeInBytes**: The total output size of the operation (in bytes).
+
+15. **totalTime**: The time taken to perform the complete operation (i.e. Extract/Mux/Decode/Encode) for respective test vector.
+
+
+## Muxer
+1. **componentName**: The format of the output Media file. Following muxers are currently supported:
+     * Ogg, Webm, 3gpp, and mp4.
+
+## Decoder
+1. **componentName**: Includes all supported codecs on the device. Aliased components are skipped.
+    *   Video: H263, H264, H265, VPx, Mpeg4, Mpeg2, AV1
+    *   Audio: AAC, Flac, Opus, MP3, Vorbis, GSM, AMR-NB/WB
+
+## Encoder
+1. **componentName**: Includes all supported codecs on the device. Aliased components are skipped.
+    *   Video: H263, H264, H265, VPx, Mpeg4
+    *   Audio: AAC, Flac, Opus, AMR-NB/WB
+
+## Common Failures
+On some devices, if a codec isn't supported some tests may report a failure like "codec not found for"
+
+For example: On mobile devices without support for mpeg2 decoder, following failure is observed:
+```
+Unable to create codec by mime: video/mpeg2
+```
diff --git a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
index 20a1468..46c4a7c 100644
--- a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
@@ -156,9 +156,11 @@
     mStats->setDeInitTime(timeTaken);
 }
 
-void C2Decoder::dumpStatistics(string inputReference, int64_t durationUs) {
+void C2Decoder::dumpStatistics(string inputReference, int64_t durationUs, string componentName,
+                               string statsFile) {
     string operation = "c2decode";
-    mStats->dumpStatistics(operation, inputReference, durationUs);
+    string mode = "async";
+    mStats->dumpStatistics(operation, inputReference, durationUs, componentName, mode, statsFile);
 }
 
 void C2Decoder::resetDecoder() {
diff --git a/media/tests/benchmark/src/native/decoder/C2Decoder.h b/media/tests/benchmark/src/native/decoder/C2Decoder.h
index 4a3eb96..fb35a66 100644
--- a/media/tests/benchmark/src/native/decoder/C2Decoder.h
+++ b/media/tests/benchmark/src/native/decoder/C2Decoder.h
@@ -31,7 +31,8 @@
 
     void deInitCodec();
 
-    void dumpStatistics(string inputReference, int64_t durationUs);
+    void dumpStatistics(string inputReference, int64_t durationUs, string componentName,
+                        string statsFile);
 
     void resetDecoder();
 
diff --git a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
index 33429ef..6a50d40 100644
--- a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
@@ -251,9 +251,11 @@
     mStats->setDeInitTime(timeTaken);
 }
 
-void C2Encoder::dumpStatistics(string inputReference, int64_t durationUs) {
+void C2Encoder::dumpStatistics(string inputReference, int64_t durationUs, string componentName,
+                               string statsFile) {
     string operation = "c2encode";
-    mStats->dumpStatistics(operation, inputReference, durationUs);
+    string mode = "async";
+    mStats->dumpStatistics(operation, inputReference, durationUs, componentName, mode, statsFile);
 }
 
 void C2Encoder::resetEncoder() {
diff --git a/media/tests/benchmark/src/native/encoder/C2Encoder.h b/media/tests/benchmark/src/native/encoder/C2Encoder.h
index a4ca097..7a021f4 100644
--- a/media/tests/benchmark/src/native/encoder/C2Encoder.h
+++ b/media/tests/benchmark/src/native/encoder/C2Encoder.h
@@ -44,7 +44,8 @@
 
     void deInitCodec();
 
-    void dumpStatistics(string inputReference, int64_t durationUs);
+    void dumpStatistics(string inputReference, int64_t durationUs, string componentName,
+                        string statsFile);
 
     void resetEncoder();
 
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
index 26fb1b9..15c479d 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -203,13 +203,13 @@
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mParams.width);
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mParams.height);
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_FRAME_RATE, mParams.frameRate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, mParams.iFrameInterval);
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
-        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
-        if (mParams.profile && mParams.level) {
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
+        if (mParams.profile != -1 && mParams.level != -1) {
             AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
             AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
         }
-        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
     } else {
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
         AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
index 5ad142b..324317c 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.h
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -23,10 +23,11 @@
 #include <queue>
 #include <thread>
 
-#include "media/NdkImage.h"
 #include "BenchmarkCommon.h"
 #include "Stats.h"
 
+// constant not defined in NDK api
+constexpr int32_t COLOR_FormatYUV420Flexible = 0x7F420888;
 
 struct encParameter {
     int32_t bitrate = -1;
@@ -38,9 +39,10 @@
     int32_t width = 0;
     int32_t height = 0;
     int32_t frameRate = -1;
-    int32_t profile = 0;
-    int32_t level = 0;
-    int32_t colorFormat = AIMAGE_FORMAT_YUV_420_888;
+    int32_t iFrameInterval = 0;
+    int32_t profile = -1;
+    int32_t level = -1;
+    int32_t colorFormat = COLOR_FormatYUV420Flexible;
 };
 
 class Encoder : public CallBackHandle {
diff --git a/media/tests/benchmark/tests/BenchmarkTestEnvironment.h b/media/tests/benchmark/tests/BenchmarkTestEnvironment.h
index ae2eee1..4edb048 100644
--- a/media/tests/benchmark/tests/BenchmarkTestEnvironment.h
+++ b/media/tests/benchmark/tests/BenchmarkTestEnvironment.h
@@ -25,7 +25,9 @@
 
 class BenchmarkTestEnvironment : public ::testing::Environment {
   public:
-    BenchmarkTestEnvironment() : res("/sdcard/media/") {}
+    BenchmarkTestEnvironment()
+        : res("/data/local/tmp/MediaBenchmark/res/"),
+          statsFile("/data/local/tmp/MediaBenchmark/res/stats.csv") {}
 
     // Parses the command line argument
     int initFromOptions(int argc, char **argv);
@@ -34,8 +36,15 @@
 
     const string getRes() const { return res; }
 
+    void setStatsFile(const string module) { statsFile = getRes() + module; }
+
+    const string getStatsFile() const { return statsFile; }
+
+    bool writeStatsHeader();
+
   private:
     string res;
+    string statsFile;
 };
 
 int BenchmarkTestEnvironment::initFromOptions(int argc, char **argv) {
@@ -70,4 +79,26 @@
     return 0;
 }
 
+/**
+ * Writes the stats header to a file
+ * <p>
+ * \param statsFile    file where the stats data is to be written
+ **/
+bool BenchmarkTestEnvironment::writeStatsHeader() {
+    char statsHeader[] =
+        "currentTime, fileName, operation, componentName, NDK/SDK, sync/async, setupTime, "
+        "destroyTime, minimumTime, maximumTime, averageTime, timeToProcess1SecContent, "
+        "totalBytesProcessedPerSec, timeToFirstFrame, totalSizeInBytes, totalTime\n";
+    FILE *fpStats = fopen(statsFile.c_str(), "w");
+    if(!fpStats) {
+        return false;
+    }
+    int32_t numBytes = fwrite(statsHeader, sizeof(char), sizeof(statsHeader), fpStats);
+    fclose(fpStats);
+    if(numBytes != sizeof(statsHeader)) {
+        return false;
+    }
+    return true;
+}
+
 #endif  // __BENCHMARK_TEST_ENVIRONMENT_H__
diff --git a/media/tests/benchmark/tests/C2DecoderTest.cpp b/media/tests/benchmark/tests/C2DecoderTest.cpp
index dedc743..85dcbc1 100644
--- a/media/tests/benchmark/tests/C2DecoderTest.cpp
+++ b/media/tests/benchmark/tests/C2DecoderTest.cpp
@@ -136,7 +136,8 @@
                 mDecoder->deInitCodec();
                 int64_t durationUs = extractor->getClipDuration();
                 ALOGV("codec : %s", codecName.c_str());
-                mDecoder->dumpStatistics(GetParam().first, durationUs);
+                mDecoder->dumpStatistics(GetParam().first, durationUs, codecName,
+                                         gEnv->getStatsFile());
                 mDecoder->resetDecoder();
             }
         }
@@ -178,6 +179,9 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("C2Decoder.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
         ALOGV("C2 Decoder Test result = %d\n", status);
     }
diff --git a/media/tests/benchmark/tests/C2EncoderTest.cpp b/media/tests/benchmark/tests/C2EncoderTest.cpp
index 98eb17a..b18d856 100644
--- a/media/tests/benchmark/tests/C2EncoderTest.cpp
+++ b/media/tests/benchmark/tests/C2EncoderTest.cpp
@@ -108,7 +108,7 @@
         }
 
         string decName = "";
-        string outputFileName = "decode.out";
+        string outputFileName = "/data/local/tmp/decode.out";
         FILE *outFp = fopen(outputFileName.c_str(), "wb");
         ASSERT_NE(outFp, nullptr) << "Unable to open output file" << outputFileName
                                   << " for dumping decoder's output";
@@ -140,7 +140,8 @@
                 mEncoder->deInitCodec();
                 int64_t durationUs = extractor->getClipDuration();
                 ALOGV("codec : %s", codecName.c_str());
-                mEncoder->dumpStatistics(GetParam().first, durationUs);
+                mEncoder->dumpStatistics(GetParam().first, durationUs, codecName,
+                                         gEnv->getStatsFile());
                 mEncoder->resetEncoder();
             }
         }
@@ -180,6 +181,9 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("C2Encoder.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
         ALOGV("C2 Encoder Test result = %d\n", status);
     }
diff --git a/media/tests/benchmark/tests/DecoderTest.cpp b/media/tests/benchmark/tests/DecoderTest.cpp
index 9f96d3b..81ef02a 100644
--- a/media/tests/benchmark/tests/DecoderTest.cpp
+++ b/media/tests/benchmark/tests/DecoderTest.cpp
@@ -84,7 +84,8 @@
         decoder->deInitCodec();
         ALOGV("codec : %s", codecName.c_str());
         string inputReference = get<0>(params);
-        decoder->dumpStatistics(inputReference);
+        decoder->dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
+                                gEnv->getStatsFile());
         free(inputBuffer);
         decoder->resetDecoder();
     }
@@ -179,8 +180,11 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("Decoder.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
-        ALOGD("Decoder Test result = %d\n", status);
+        ALOGV("Decoder Test result = %d\n", status);
     }
     return status;
 }
\ No newline at end of file
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
index dc2a2dd..7e1681d 100644
--- a/media/tests/benchmark/tests/EncoderTest.cpp
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -23,6 +23,10 @@
 #include "Decoder.h"
 #include "Encoder.h"
 
+constexpr int32_t kEncodeDefaultVideoBitRate = 8000000 /* 8 Mbps */;
+constexpr int32_t kEncodeMinVideoBitRate = 600000 /* 600 Kbps */;
+constexpr int32_t kEncodeDefaultAudioBitRate = 128000 /* 128 Kbps */;
+
 static BenchmarkTestEnvironment *gEnv = nullptr;
 
 class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
@@ -78,7 +82,7 @@
         }
 
         string decName = "";
-        string outputFileName = "decode.out";
+        string outputFileName = "/data/local/tmp/decode.out";
         FILE *outFp = fopen(outputFileName.c_str(), "wb");
         ASSERT_NE(outFp, nullptr) << "Unable to open output file" << outputFileName
                                   << " for dumping decoder's output";
@@ -86,6 +90,7 @@
         decoder->setupDecoder();
         status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
         ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
+        AMediaFormat *decoderFormat = decoder->getFormat();
 
         ifstream eleStream;
         eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
@@ -108,11 +113,13 @@
             if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
                 encParams.frameRate = 25;
                 if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
-                    encParams.bitrate = 600000 /* 600 Kbps */;
+                    encParams.bitrate = kEncodeMinVideoBitRate;
                 } else {
-                    encParams.bitrate = 8000000 /* 8 Mbps */;
+                    encParams.bitrate = kEncodeDefaultVideoBitRate;
                 }
             }
+            AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
+                                  &encParams.colorFormat);
             AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
             AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
         } else {
@@ -120,8 +127,7 @@
                                               &encParams.sampleRate));
             ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
                                               &encParams.numChannels));
-            encParams.bitrate =
-                    encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
+            encParams.bitrate = kEncodeDefaultAudioBitRate;
         }
 
         encoder->setupEncoder();
@@ -133,7 +139,8 @@
         encoder->deInitCodec();
         ALOGV("codec : %s", codecName.c_str());
         string inputReference = get<0>(params);
-        encoder->dumpStatistics(inputReference, extractor->getClipDuration());
+        encoder->dumpStatistics(inputReference, extractor->getClipDuration(), codecName,
+                                (asyncMode ? "async" : "sync"), gEnv->getStatsFile());
         eleStream.close();
         if (outFp) fclose(outFp);
 
@@ -141,6 +148,10 @@
             AMediaFormat_delete(format);
             format = nullptr;
         }
+        if (decoderFormat) {
+            AMediaFormat_delete(decoderFormat);
+            decoderFormat = nullptr;
+        }
         encoder->resetEncoder();
         decoder->deInitCodec();
         free(inputBuffer);
@@ -214,8 +225,11 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("Encoder.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
-        ALOGD("Encoder Test result = %d\n", status);
+        ALOGV("Encoder Test result = %d\n", status);
     }
     return status;
 }
diff --git a/media/tests/benchmark/tests/ExtractorTest.cpp b/media/tests/benchmark/tests/ExtractorTest.cpp
index ad8f1e6..d14d15b 100644
--- a/media/tests/benchmark/tests/ExtractorTest.cpp
+++ b/media/tests/benchmark/tests/ExtractorTest.cpp
@@ -48,8 +48,7 @@
     ASSERT_EQ(status, AMEDIA_OK) << "Extraction failed \n";
 
     extractObj->deInitExtractor();
-
-    extractObj->dumpStatistics(GetParam().first);
+    extractObj->dumpStatistics(GetParam().first, "", gEnv->getStatsFile());
 
     fclose(inputFp);
     delete extractObj;
@@ -79,8 +78,11 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("Extractor.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
-        ALOGD(" Extractor Test result = %d\n", status);
+        ALOGV("Extractor Test result = %d\n", status);
     }
     return status;
 }
diff --git a/media/tests/benchmark/tests/MuxerTest.cpp b/media/tests/benchmark/tests/MuxerTest.cpp
index fa2635d..991644b 100644
--- a/media/tests/benchmark/tests/MuxerTest.cpp
+++ b/media/tests/benchmark/tests/MuxerTest.cpp
@@ -113,7 +113,7 @@
         ASSERT_EQ(status, 0) << "Mux failed";
 
         muxerObj->deInitMuxer();
-        muxerObj->dumpStatistics(GetParam().first + "." + fmt.c_str());
+        muxerObj->dumpStatistics(GetParam().first + "." + fmt.c_str(), fmt, gEnv->getStatsFile());
         free(inputBuffer);
         fclose(outputFp);
         muxerObj->resetMuxer();
@@ -151,8 +151,11 @@
     ::testing::InitGoogleTest(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
+        gEnv->setStatsFile("Muxer.csv");
+        status = gEnv->writeStatsHeader();
+        ALOGV("Stats file = %d\n", status);
         status = RUN_ALL_TESTS();
-        ALOGV("Test result = %d\n", status);
+        ALOGV("Muxer Test result = %d\n", status);
     }
     return status;
 }
diff --git a/media/utils/EventLogTags.logtags b/media/utils/EventLogTags.logtags
index 67f0ea8..c397f34 100644
--- a/media/utils/EventLogTags.logtags
+++ b/media/utils/EventLogTags.logtags
@@ -31,7 +31,7 @@
 # 6: Percent
 # Default value for data of type int/long is 2 (bytes).
 #
-# See system/core/logcat/event.logtags for the master copy of the tags.
+# See system/core/logcat/event.logtags for the original definition of the tags.
 
 # 61000 - 61199 reserved for audioserver
 
diff --git a/media/utils/fuzzers/Android.bp b/media/utils/fuzzers/Android.bp
new file mode 100644
index 0000000..ca1123c
--- /dev/null
+++ b/media/utils/fuzzers/Android.bp
@@ -0,0 +1,51 @@
+cc_defaults {
+    name: "libmediautils_fuzzer_defaults",
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libmediautils",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-c++2a-extensions",
+    ],
+
+    header_libs: [
+        "bionic_libc_platform_headers",
+        "libmedia_headers",
+    ],
+
+    include_dirs: [
+        // For DEBUGGER_SIGNAL
+        "system/core/debuggerd/include",
+    ],
+}
+
+cc_fuzz {
+    name: "libmediautils_fuzzer_battery_notifier",
+    defaults: ["libmediautils_fuzzer_defaults"],
+    srcs: ["BatteryNotifierFuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libmediautils_fuzzer_scheduling_policy_service",
+    defaults: ["libmediautils_fuzzer_defaults"],
+    srcs: ["SchedulingPolicyServiceFuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libmediautils_fuzzer_service_utilities",
+    defaults: ["libmediautils_fuzzer_defaults"],
+    srcs: ["ServiceUtilitiesFuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libmediautils_fuzzer_time_check",
+    defaults: ["libmediautils_fuzzer_defaults"],
+    srcs: ["TimeCheckFuzz.cpp"],
+}
diff --git a/media/utils/fuzzers/BatteryNotifierFuzz.cpp b/media/utils/fuzzers/BatteryNotifierFuzz.cpp
new file mode 100644
index 0000000..00b3cce
--- /dev/null
+++ b/media/utils/fuzzers/BatteryNotifierFuzz.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2020 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 <functional>
+#include <string>
+#include <vector>
+
+#include <utils/String8.h>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/BatteryNotifier.h"
+
+static constexpr int kMaxOperations = 30;
+static constexpr int kMaxStringLength = 500;
+using android::BatteryNotifier;
+
+std::vector<std::function<void(std::string /*flashlight_name*/, std::string /*camera_name*/,
+                               uid_t /*video_id*/, uid_t /*audio_id*/, uid_t /*light_id*/,
+                               uid_t /*camera_id*/)>>
+    operations = {
+        [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteResetVideo();
+        },
+        [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteResetAudio();
+        },
+        [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteResetFlashlight();
+        },
+        [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteResetCamera();
+        },
+        [](std::string, std::string, uid_t video_id, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteStartVideo(video_id);
+        },
+        [](std::string, std::string, uid_t video_id, uid_t, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteStopVideo(video_id);
+        },
+        [](std::string, std::string, uid_t, uid_t audio_id, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteStartAudio(audio_id);
+        },
+        [](std::string, std::string, uid_t, uid_t audio_id, uid_t, uid_t) -> void {
+            BatteryNotifier::getInstance().noteStopAudio(audio_id);
+        },
+        [](std::string flashlight_name, std::string, uid_t, uid_t, uid_t light_id, uid_t) -> void {
+            android::String8 name(flashlight_name.c_str());
+            BatteryNotifier::getInstance().noteFlashlightOn(name, light_id);
+        },
+        [](std::string flashlight_name, std::string, uid_t, uid_t, uid_t light_id, uid_t) -> void {
+            android::String8 name(flashlight_name.c_str());
+            BatteryNotifier::getInstance().noteFlashlightOff(name, light_id);
+        },
+        [](std::string, std::string camera_name, uid_t, uid_t, uid_t, uid_t camera_id) -> void {
+            android::String8 name(camera_name.c_str());
+            BatteryNotifier::getInstance().noteStartCamera(name, camera_id);
+        },
+        [](std::string, std::string camera_name, uid_t, uid_t, uid_t, uid_t camera_id) -> void {
+            android::String8 name(camera_name.c_str());
+            BatteryNotifier::getInstance().noteStopCamera(name, camera_id);
+        },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider data_provider(data, size);
+    std::string camera_name = data_provider.ConsumeRandomLengthString(kMaxStringLength);
+    std::string flashlight_name = data_provider.ConsumeRandomLengthString(kMaxStringLength);
+    uid_t video_id = data_provider.ConsumeIntegral<uid_t>();
+    uid_t audio_id = data_provider.ConsumeIntegral<uid_t>();
+    uid_t light_id = data_provider.ConsumeIntegral<uid_t>();
+    uid_t camera_id = data_provider.ConsumeIntegral<uid_t>();
+    size_t ops_run = 0;
+    while (data_provider.remaining_bytes() > 0 && ops_run++ < kMaxOperations) {
+        uint8_t op = data_provider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+        operations[op](flashlight_name, camera_name, video_id, audio_id, light_id, camera_id);
+    }
+    return 0;
+}
diff --git a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
new file mode 100644
index 0000000..4521853
--- /dev/null
+++ b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 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_TAG "BatteryNotifierFuzzer"
+#include <binder/IBatteryStats.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+#include <android/log.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include "fuzzer/FuzzedDataProvider.h"
+using android::IBatteryStats;
+using android::IBinder;
+using android::IInterface;
+using android::IServiceManager;
+using android::sp;
+using android::String16;
+using android::defaultServiceManager;
+using android::requestCpusetBoost;
+using android::requestPriority;
+sp<IBatteryStats> getBatteryService() {
+    sp<IBatteryStats> batteryStatService;
+    const sp<IServiceManager> sm(defaultServiceManager());
+    if (sm != nullptr) {
+        const String16 name("batterystats");
+        batteryStatService = checked_interface_cast<IBatteryStats>(sm->checkService(name));
+        if (batteryStatService == nullptr) {
+            ALOGW("batterystats service unavailable!");
+            return nullptr;
+        }
+    }
+    return batteryStatService;
+}
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider data_provider(data, size);
+    sp<IBatteryStats> batteryStatService = getBatteryService();
+    // There is some state here, but it's mostly focused around thread-safety, so
+    // we won't worry about order.
+    int32_t priority = data_provider.ConsumeIntegral<int32_t>();
+    bool is_for_app = data_provider.ConsumeBool();
+    bool async = data_provider.ConsumeBool();
+    requestPriority(getpid(), gettid(), priority, is_for_app, async);
+    // TODO: Verify and re-enable in AOSP (R).
+    // bool enable = data_provider.ConsumeBool();
+    // We are just using batterystats to avoid the need
+    // to register a new service.
+    // requestCpusetBoost(enable, IInterface::asBinder(batteryStatService));
+    return 0;
+}
+
diff --git a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
new file mode 100644
index 0000000..3d141b5
--- /dev/null
+++ b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 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 <fcntl.h>
+
+#include <functional>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/ServiceUtilities.h"
+
+static constexpr int kMaxOperations = 50;
+static constexpr int kMaxStringLen = 256;
+
+const std::vector<std::function<void(FuzzedDataProvider*, android::MediaPackageManager)>>
+    operations = {
+        [](FuzzedDataProvider* data_provider, android::MediaPackageManager pm) -> void {
+            uid_t uid = data_provider->ConsumeIntegral<uid_t>();
+            pm.allowPlaybackCapture(uid);
+        },
+        [](FuzzedDataProvider* data_provider, android::MediaPackageManager pm) -> void {
+            int spaces = data_provider->ConsumeIntegral<int>();
+
+            // Dump everything into /dev/null
+            int fd = open("/dev/null", O_WRONLY);
+            pm.dump(fd, spaces);
+            close(fd);
+        },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider data_provider(data, size);
+    uid_t uid = data_provider.ConsumeIntegral<uid_t>();
+    pid_t pid = data_provider.ConsumeIntegral<pid_t>();
+
+    // There is not state here, and order is not significant,
+    // so we can simply call all of the target functions
+    android::isServiceUid(uid);
+    android::isAudioServerUid(uid);
+    android::isAudioServerOrSystemServerUid(uid);
+    android::isAudioServerOrMediaServerUid(uid);
+    std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen);
+    android::String16 opPackageName(packageNameStr.c_str());
+    android::recordingAllowed(opPackageName, pid, uid);
+    android::startRecording(opPackageName, pid, uid);
+    android::finishRecording(opPackageName, uid);
+    android::captureAudioOutputAllowed(pid, uid);
+    android::captureMediaOutputAllowed(pid, uid);
+    android::captureHotwordAllowed(opPackageName, pid, uid);
+    android::modifyPhoneStateAllowed(uid, pid);
+    android::bypassInterruptionPolicyAllowed(uid, pid);
+    android::settingsAllowed();
+    android::modifyAudioRoutingAllowed();
+    android::modifyDefaultAudioEffectsAllowed();
+    android::dumpAllowed();
+
+    // MediaPackageManager does have state, so we need the fuzzer to decide order
+    android::MediaPackageManager packageManager;
+    size_t ops_run = 0;
+    while (data_provider.remaining_bytes() > 0 && ops_run++ < kMaxOperations) {
+        uint8_t op = data_provider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+        operations[op](&data_provider, packageManager);
+    }
+
+    return 0;
+}
diff --git a/media/utils/fuzzers/TimeCheckFuzz.cpp b/media/utils/fuzzers/TimeCheckFuzz.cpp
new file mode 100644
index 0000000..eeb6ba6
--- /dev/null
+++ b/media/utils/fuzzers/TimeCheckFuzz.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020 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 <chrono>
+#include <thread>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/TimeCheck.h"
+
+static constexpr int kMaxStringLen = 256;
+
+// While it might be interesting to test long-running
+// jobs, it seems unlikely it'd lead to the types of crashes
+// we're looking for, and would mean a significant increase in fuzzer time.
+// Therefore, we are setting a low cap.
+static constexpr uint32_t kMaxTimeoutMs = 1000;
+static constexpr uint32_t kMinTimeoutMs = 200;
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider data_provider(data, size);
+
+    // There's essentially 5 operations that we can access in this class
+    // 1. The time it takes to run this operation. As mentioned above,
+    //    long-running tasks are not good for fuzzing, but there will be
+    //    some change in the run time.
+    uint32_t timeoutMs =
+        data_provider.ConsumeIntegralInRange<uint32_t>(kMinTimeoutMs, kMaxTimeoutMs);
+    uint8_t pid_size = data_provider.ConsumeIntegral<uint8_t>();
+    std::vector<pid_t> pids(pid_size);
+    for (auto& pid : pids) {
+        pid = data_provider.ConsumeIntegral<pid_t>();
+    }
+
+    // 2. We also have setAudioHalPids, which is populated with the pids set
+    // above.
+    android::TimeCheck::setAudioHalPids(pids);
+    std::string name = data_provider.ConsumeRandomLengthString(kMaxStringLen);
+
+    // 3. The constructor, which is fuzzed here:
+    android::TimeCheck timeCheck(name.c_str(), timeoutMs);
+    // We will leave some buffer to avoid sleeping too long
+    uint8_t sleep_amount_ms = data_provider.ConsumeIntegralInRange<uint8_t>(0, timeoutMs / 2);
+
+    // We want to make sure we can cover the time out functionality.
+    if (sleep_amount_ms) {
+        auto ms = std::chrono::milliseconds(sleep_amount_ms);
+        std::this_thread::sleep_for(ms);
+    }
+
+    // 4. Finally, the destructor on timecheck. These seem to be the only factors
+    // in play.
+    return 0;
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 764fdc3..ef746f4 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -684,8 +684,8 @@
 
 sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
 {
-    // If there is no memory allocated for logs, return a dummy writer that does nothing.
-    // Similarly if we can't contact the media.log service, also return a dummy writer.
+    // If there is no memory allocated for logs, return a no-op writer that does nothing.
+    // Similarly if we can't contact the media.log service, also return a no-op writer.
     if (mLogMemoryDealer == 0 || sMediaLogService == 0) {
         return new NBLog::Writer();
     }
@@ -711,7 +711,7 @@
             }
         }
         // Even after garbage-collecting all old writers, there is still not enough memory,
-        // so return a dummy writer
+        // so return a no-op writer
         return new NBLog::Writer();
     }
 success:
@@ -1284,9 +1284,9 @@
     }
 
     // Now set the master mute in each playback thread.  Playback threads
-    // assigned to HALs which do not have master mute support will apply master
-    // mute during the mix operation.  Threads with HALs which do support master
-    // mute will simply ignore the setting.
+    // assigned to HALs which do not have master mute support will apply master mute
+    // during the mix operation.  Threads with HALs which do support master mute
+    // will simply ignore the setting.
     Vector<VolumeInterface *> volumeInterfaces = getAllVolumeInterfaces_l();
     for (size_t i = 0; i < volumeInterfaces.size(); i++) {
         volumeInterfaces[i]->setMasterMute(muted);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 3dfeb83..529b87c 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -292,6 +292,9 @@
         }
     }
 
+    // Prevent calls to process() and other functions on effect interface from now on.
+    // The effect engine will be released by the destructor when the last strong reference on
+    // this object is released which can happen after next process is called.
     if (mHandles.size() == 0 && !mPinned) {
         mState = DESTROYED;
     }
@@ -565,20 +568,6 @@
 
 }
 
-ssize_t AudioFlinger::EffectModule::removeHandle_l(EffectHandle *handle)
-{
-    ssize_t status = EffectBase::removeHandle_l(handle);
-
-    // Prevent calls to process() and other functions on effect interface from now on.
-    // The effect engine will be released by the destructor when the last strong reference on
-    // this object is released which can happen after next process is called.
-    if (status == 0 && !mPinned) {
-        mEffectInterface->close();
-    }
-
-    return status;
-}
-
 bool AudioFlinger::EffectModule::updateState() {
     Mutex::Autolock _l(mLock);
 
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 2826297..2c79ac5 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -144,7 +144,7 @@
     status_t addHandle(EffectHandle *handle);
     ssize_t disconnectHandle(EffectHandle *handle, bool unpinIfLast);
     ssize_t removeHandle(EffectHandle *handle);
-    virtual ssize_t removeHandle_l(EffectHandle *handle);
+    ssize_t removeHandle_l(EffectHandle *handle);
     EffectHandle* controlHandle_l();
     bool purgeHandles();
 
@@ -240,8 +240,6 @@
         return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL;
     }
 
-    ssize_t removeHandle_l(EffectHandle *handle) override;
-
     status_t         setDevices(const AudioDeviceTypeAddrVector &devices);
     status_t         setInputDevice(const AudioDeviceTypeAddr &device);
     status_t         setVolume(uint32_t *left, uint32_t *right, bool controller);
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 3eacc8c..cd3c743 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -27,7 +27,6 @@
 
 #include "Configuration.h"
 #include <time.h>
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <system/audio.h>
@@ -40,6 +39,7 @@
 #include <audio_utils/channels.h>
 #include <audio_utils/format.h>
 #include <audio_utils/mono_blend.h>
+#include <cutils/bitops.h>
 #include <media/AudioMixer.h>
 #include "FastMixer.h"
 #include "TypedLogger.h"
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index a42e09c..3f20282 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -24,7 +24,6 @@
 #include <cpustats/ThreadCpuUsage.h>
 #endif
 #endif
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include "FastMixerDumpState.h"
 
diff --git a/services/audioflinger/OWNERS b/services/audioflinger/OWNERS
index d02d9e0..034d161 100644
--- a/services/audioflinger/OWNERS
+++ b/services/audioflinger/OWNERS
@@ -1,4 +1,4 @@
+gkasten@google.com
 hunga@google.com
 jmtrivi@google.com
 mnaganov@google.com
-gkasten@google.com
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1d0147d..c5d1cc7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -29,6 +29,7 @@
 #include <linux/futex.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
+#include <cutils/bitops.h>
 #include <cutils/properties.h>
 #include <media/AudioContainers.h>
 #include <media/AudioDeviceTypeAddr.h>
@@ -3487,7 +3488,7 @@
                     // latency of 5 seconds).
                     const double minLatency = 0., maxLatency = 5000.;
                     if (latencyMs >= minLatency && latencyMs <= maxLatency) {
-                        ALOGV("new downstream latency %lf ms", latencyMs);
+                        ALOGVV("new downstream latency %lf ms", latencyMs);
                     } else {
                         ALOGD("out of range downstream latency %lf ms", latencyMs);
                         if (latencyMs < minLatency) latencyMs = minLatency;
@@ -3536,7 +3537,7 @@
                         mSampleRate);
 
                 if (isTimestampCorrectionEnabled()) {
-                    ALOGV("TS_BEFORE: %d %lld %lld", id(),
+                    ALOGVV("TS_BEFORE: %d %lld %lld", id(),
                             (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                             (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
                     auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
@@ -3544,7 +3545,7 @@
                             = correctedTimestamp.mFrames;
                     timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]
                             = correctedTimestamp.mTimeNs;
-                    ALOGV("TS_AFTER: %d %lld %lld", id(),
+                    ALOGVV("TS_AFTER: %d %lld %lld", id(),
                             (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                             (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
 
@@ -6887,7 +6888,7 @@
     snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
     mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
 
-    if (mInput != nullptr && mInput->audioHwDev != nullptr) {
+    if (mInput->audioHwDev != nullptr) {
         mIsMsdDevice = strcmp(
                 mInput->audioHwDev->moduleName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0;
     }
@@ -7318,7 +7319,7 @@
 
             const ssize_t availableToRead = mPipeSource->availableToRead();
             if (availableToRead >= 0) {
-                // PipeSource is the master clock.  It is up to the AudioRecord client to keep up.
+                // PipeSource is the primary clock.  It is up to the AudioRecord client to keep up.
                 LOG_ALWAYS_FATAL_IF((size_t)availableToRead > mPipeFramesP2,
                         "more frames to read than fifo size, %zd > %zu",
                         availableToRead, mPipeFramesP2);
@@ -7379,12 +7380,12 @@
 
                 // Correct timestamps
                 if (isTimestampCorrectionEnabled()) {
-                    ALOGV("TS_BEFORE: %d %lld %lld",
+                    ALOGVV("TS_BEFORE: %d %lld %lld",
                             id(), (long long)time, (long long)position);
                     auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
                     position = correctedTimestamp.mFrames;
                     time = correctedTimestamp.mTimeNs;
-                    ALOGV("TS_AFTER: %d %lld %lld",
+                    ALOGVV("TS_AFTER: %d %lld %lld",
                             id(), (long long)time, (long long)position);
                 }
 
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index f286d8a..178809c 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1933,6 +1933,25 @@
 {
     mProxy->releaseBuffer(buffer);
     restartIfDisabled();
+
+    // Check if the PatchTrack has enough data to write once in releaseBuffer().
+    // If not, prevent an underrun from occurring by moving the track into FS_FILLING;
+    // this logic avoids glitches when suspending A2DP with AudioPlaybackCapture.
+    // TODO: perhaps underrun avoidance could be a track property checked in isReady() instead.
+    if (mFillingUpStatus == FS_ACTIVE
+            && audio_is_linear_pcm(mFormat)
+            && !isOffloadedOrDirect()) {
+        if (sp<ThreadBase> thread = mThread.promote();
+            thread != 0) {
+            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+            const size_t frameCount = playbackThread->frameCount() * sampleRate()
+                    / playbackThread->sampleRate();
+            if (framesReady() < frameCount) {
+                ALOGD("%s(%d) Not enough data, wait for buffer to fill", __func__, mId);
+                mFillingUpStatus = FS_FILLING;
+            }
+        }
+    }
 }
 
 void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 6ef19bf..feb71e3 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -80,7 +80,7 @@
 
 // TODO Permit disabling of logging at compile-time.
 
-// TODO A non-nullptr dummy implementation that is a nop would be faster than checking for nullptr
+// TODO A non-nullptr stub implementation that is a nop would be faster than checking for nullptr
 //      in the case when logging is enabled at compile-time and enabled at runtime, but it might be
 //      slower than nullptr check when logging is enabled at compile-time and disabled at runtime.
 
@@ -129,8 +129,8 @@
 
 namespace android {
 extern "C" {
-// TODO consider adding a thread_local NBLog::Writer tlDummyNBLogWriter and then
-// initialize below tlNBLogWriter to &tlDummyNBLogWriter to remove the need to
+// TODO consider adding a thread_local NBLog::Writer tlStubNBLogWriter and then
+// initialize below tlNBLogWriter to &tlStubNBLogWriter to remove the need to
 // check for nullptr every time. Also reduces the need to add a new logging macro above
 // each time we want to log a new type.
 extern thread_local NBLog::Writer *tlNBLogWriter;
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
index a8483fa..da9d32f 100644
--- a/services/audiopolicy/OWNERS
+++ b/services/audiopolicy/OWNERS
@@ -1,3 +1,2 @@
 jmtrivi@google.com
-krocard@google.com
 mnaganov@google.com
diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h
index 7c8ce83..736f8b2 100644
--- a/services/audiopolicy/common/include/Volume.h
+++ b/services/audiopolicy/common/include/Volume.h
@@ -126,6 +126,7 @@
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
         case AUDIO_DEVICE_OUT_USB_HEADSET:
+        case AUDIO_DEVICE_OUT_BLE_HEADSET:
             return DEVICE_CATEGORY_HEADSET;
         case AUDIO_DEVICE_OUT_HEARING_AID:
             return DEVICE_CATEGORY_HEARING_AID;
@@ -139,6 +140,7 @@
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
         case AUDIO_DEVICE_OUT_USB_ACCESSORY:
         case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+        case AUDIO_DEVICE_OUT_BLE_SPEAKER:
         default:
             return DEVICE_CATEGORY_SPEAKER;
         }
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index dd1499c..0f9bcc1 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -248,7 +248,9 @@
         return String8("");
     }
 
-    std::string toString() const;
+    // Return a string to describe the DeviceVector. The sensitive information will only be
+    // added to the string if `includeSensitiveInfo` is true.
+    std::string toString(bool includeSensitiveInfo = false) const;
 
     void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index b963121..4922ebe 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -516,7 +516,7 @@
     dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
     dst->appendFormat(" Format: %d\n", mFormat);
     dst->appendFormat(" Channels: %08x\n", mChannelMask);
-    dst->appendFormat(" Devices %s\n", mDevice->toString().c_str());
+    dst->appendFormat(" Devices %s\n", mDevice->toString(true /*includeSensitiveInfo*/).c_str());
     mEnabledEffects.dump(dst, 1 /*spaces*/, false /*verbose*/);
     dst->append(" AudioRecord Clients:\n");
     ClientMapHandler<RecordClientDescriptor>::dump(dst);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index d6d472b..a2e2eec 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -245,7 +245,7 @@
     dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
     dst->appendFormat(" Format: %08x\n", mFormat);
     dst->appendFormat(" Channels: %08x\n", mChannelMask);
-    dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
+    dst->appendFormat(" Devices: %s\n", devices().toString(true /*includeSensitiveInfo*/).c_str());
     dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
     for (const auto &iter : mRoutingActivities) {
         dst->appendFormat(" Product Strategy id: %d", iter.first);
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index a29e60e..68a32a2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -408,7 +408,7 @@
     }
 }
 
-std::string DeviceVector::toString() const
+std::string DeviceVector::toString(bool includeSensitiveInfo) const
 {
     if (isEmpty()) {
         return {"AUDIO_DEVICE_NONE"};
@@ -418,7 +418,7 @@
         if (device != *begin()) {
            result += ";";
         }
-        result += device->toString();
+        result += device->toString(includeSensitiveInfo);
     }
     return result + "}";
 }
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
old mode 100755
new mode 100644
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
old mode 100755
new mode 100644
diff --git a/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h b/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
old mode 100755
new mode 100644
diff --git a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
old mode 100755
new mode 100644
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
index a7388da..bc32416 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -65,6 +65,12 @@
     </ProductStrategy>
 
     <ProductStrategy name="STRATEGY_MEDIA">
+        <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
+            <Attributes>
+                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+                <Usage value="AUDIO_USAGE_ASSISTANT"/>
+            </Attributes>
+        </AttributesGroup>
          <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
             <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
             <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
@@ -72,12 +78,6 @@
             <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
             <Attributes></Attributes>
         </AttributesGroup>
-        <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
-            <Attributes>
-                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
-                <Usage value="AUDIO_USAGE_ASSISTANT"/>
-            </Attributes>
-        </AttributesGroup>
         <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
             <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
         </AttributesGroup>
diff --git a/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py b/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
index 9a7fa8f..f060d45 100755
--- a/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
+++ b/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
@@ -52,13 +52,19 @@
 def findBitPos(decimal):
     pos = 0
     i = 1
-    while i != decimal:
+    while i < decimal:
         i = i << 1
         pos = pos + 1
         if pos == 32:
             return -1
-    return pos
 
+    # TODO: b/168065706. This is just to fix the build. That the problem of devices with
+    # multiple bits set must be addressed more generally in the configurable audio policy
+    # and parameter framework.
+    if i > decimal:
+        logging.info("Device:{} which has multiple bits set is skipped. b/168065706".format(decimal))
+        return -2
+    return pos
 
 def generateXmlStructureFile(componentTypeDict, structureTypesFile, outputFile):
 
@@ -74,10 +80,12 @@
                 if bitparameters_node is not None:
                     ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
                     for key, value in ordered_values.items():
-                        value_node = ET.SubElement(bitparameters_node, "BitParameter")
-                        value_node.set('Name', key)
-                        value_node.set('Size', "1")
-                        value_node.set('Pos', str(findBitPos(value)))
+                        pos = findBitPos(value)
+                        if pos >= 0:
+                            value_node = ET.SubElement(bitparameters_node, "BitParameter")
+                            value_node.set('Name', key)
+                            value_node.set('Size', "1")
+                            value_node.set('Pos', str(pos))
 
                 enum_parameter_node = component_type.find("EnumParameter")
                 if enum_parameter_node is not None:
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
index a7388da..bc32416 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -65,6 +65,12 @@
     </ProductStrategy>
 
     <ProductStrategy name="STRATEGY_MEDIA">
+        <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
+            <Attributes>
+                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+                <Usage value="AUDIO_USAGE_ASSISTANT"/>
+            </Attributes>
+        </AttributesGroup>
          <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="music">
             <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
             <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
@@ -72,12 +78,6 @@
             <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
             <Attributes></Attributes>
         </AttributesGroup>
-        <AttributesGroup streamType="AUDIO_STREAM_ASSISTANT" volumeGroup="assistant">
-            <Attributes>
-                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
-                <Usage value="AUDIO_USAGE_ASSISTANT"/>
-            </Attributes>
-        </AttributesGroup>
         <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
             <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
         </AttributesGroup>
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
old mode 100755
new mode 100644
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 07e80d1..12c6ae5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -42,6 +42,7 @@
 #include <set>
 #include <unordered_set>
 #include <vector>
+#include <cutils/bitops.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
@@ -461,7 +462,16 @@
             }
         }
     }
-
+    auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+       sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+       // mute media strategies and delay device switch by the largest
+       // This avoid sending the music tail into the earpiece or headset.
+       setStrategyMute(musicStrategy, true, desc);
+       setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+          mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                              nullptr, true /*fromCache*/).types());
+    }
     // Toggle the device state: UNAVAILABLE -> AVAILABLE
     // This will force reading again the device configuration
     status = setDeviceConnectionState(device,
@@ -1765,7 +1775,8 @@
         checkAndSetVolume(curves, client->volumeSource(),
                           curves.getVolumeIndex(outputDesc->devices().types()),
                           outputDesc,
-                          outputDesc->devices().types());
+                          outputDesc->devices().types(), 0 /*delay*/,
+                          outputDesc->useHwGain() /*force*/);
 
         // update the outputs if starting an output with a stream that can affect notification
         // routing
@@ -5450,6 +5461,12 @@
         }
     }
 
+    // Do not retrieve engine device for outputs through MSD
+    // TODO: support explicit routing requests by resetting MSD patch to engine device.
+    if (outputDesc->devices() == getMsdAudioOutDevices()) {
+        return outputDesc->devices();
+    }
+
     // Honor explicit routing requests only if no client using default routing is active on this
     // input: a specific app can not force routing for other apps by setting a preferred device.
     bool active; // unused
@@ -6035,7 +6052,8 @@
     if (!Intersection(deviceTypes,
             {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
              AUDIO_DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
-             AUDIO_DEVICE_OUT_USB_HEADSET, AUDIO_DEVICE_OUT_HEARING_AID}).empty() &&
+             AUDIO_DEVICE_OUT_USB_HEADSET, AUDIO_DEVICE_OUT_HEARING_AID,
+             AUDIO_DEVICE_OUT_BLE_HEADSET}).empty() &&
             ((volumeSource == alarmVolumeSrc ||
               volumeSource == ringVolumeSrc) ||
              (volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION)) ||
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 1ec0c5e..b738633 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -121,8 +121,8 @@
         Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
         for (size_t i = 0; i < effects.size(); i++) {
             EffectDesc *effect = effects[i];
-            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0,
-                                                 0, audioSession, input);
+            sp<AudioEffect> fx = new AudioEffect(String16("android"));
+            fx->set(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
             status_t status = fx->initCheck();
             if (status != NO_ERROR && status != ALREADY_EXISTS) {
                 ALOGW("addInputEffects(): failed to create Fx %s on source %d",
@@ -270,8 +270,8 @@
         Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
         for (size_t i = 0; i < effects.size(); i++) {
             EffectDesc *effect = effects[i];
-            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,
-                                                 audioSession, output);
+            sp<AudioEffect> fx = new AudioEffect(String16("android"));
+            fx->set(NULL, &effect->mUuid, 0, 0, 0, audioSession, output);
             status_t status = fx->initCheck();
             if (status != NO_ERROR && status != ALREADY_EXISTS) {
                 ALOGE("addOutputSessionEffects(): failed to create Fx  %s on session %d",
@@ -970,11 +970,11 @@
     for (const auto& deviceEffectsIter : mDeviceEffects) {
         const auto& deviceEffects =  deviceEffectsIter.second;
         for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
-            auto fx = std::make_unique<AudioEffect>(
-                        EFFECT_UUID_NULL, String16("android"), &effectDesc->mUuid, 0, nullptr,
-                        nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
-                        AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
-                                            deviceEffects->getDeviceAddress()});
+            auto fx = std::make_unique<AudioEffect>(String16("android"));
+            fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0, nullptr,
+                    nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
+                    AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
+                                        deviceEffects->getDeviceAddress()});
             status_t status = fx->initCheck();
             if (status != NO_ERROR && status != ALREADY_EXISTS) {
                 ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index e1721ea..bdddf06 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -75,6 +75,10 @@
     status_t createAudioPatch(const struct audio_patch *patch,
                               audio_patch_handle_t *handle,
                               int /*delayMs*/) override {
+        auto iter = mActivePatches.find(*handle);
+        if (iter != mActivePatches.end()) {
+            mActivePatches.erase(*handle);
+        }
         *handle = mNextPatchHandle++;
         mActivePatches.insert(std::make_pair(*handle, *patch));
         return NO_ERROR;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 24288d6..3d9998a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -802,7 +802,7 @@
 
 Status CameraService::makeClient(const sp<CameraService>& cameraService,
         const sp<IInterface>& cameraCb, const String16& packageName,
-        const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
+        const std::optional<String16>& featureId, const String8& cameraId, int api1CameraId,
         int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
         int deviceVersion, apiLevel effectiveApiLevel,
         /*out*/sp<BasicClient>* client) {
@@ -958,7 +958,7 @@
     if (!(ret = connectHelper<ICameraClient,Client>(
             sp<ICameraClient>{nullptr}, id, cameraId,
             static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
-            internalPackageName, std::unique_ptr<String16>(), uid, USE_CALLING_PID,
+            internalPackageName, {}, uid, USE_CALLING_PID,
             API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
             ).isOk()) {
         ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
@@ -1476,7 +1476,7 @@
     String8 id = cameraIdIntToStr(api1CameraId);
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
-            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, std::unique_ptr<String16>(),
+            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, {},
             clientUid, clientPid, API_1, /*shimUpdateOnly*/ false, /*out*/client);
 
     if(!ret.isOk()) {
@@ -1503,7 +1503,7 @@
     Status ret = Status::ok();
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
-            clientPackageName, std::unique_ptr<String16>(), clientUid, USE_CALLING_PID, API_1,
+            clientPackageName, {}, clientUid, USE_CALLING_PID, API_1,
             /*shimUpdateOnly*/ false, /*out*/client);
 
     if(!ret.isOk()) {
@@ -1578,7 +1578,7 @@
         const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
         const String16& cameraId,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         int clientUid,
         /*out*/
         sp<hardware::camera2::ICameraDeviceUser>* device) {
@@ -1612,7 +1612,7 @@
 template<class CALLBACK, class CLIENT>
 Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
         int api1CameraId, int halVersion, const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
+        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
         apiLevel effectiveApiLevel, bool shimUpdateOnly,
         /*out*/sp<CLIENT>& device) {
     binder::Status ret = binder::Status::ok();
@@ -2714,7 +2714,7 @@
 CameraService::Client::Client(const sp<CameraService>& cameraService,
         const sp<ICameraClient>& cameraClient,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         const String8& cameraIdStr,
         int api1CameraId, int cameraFacing,
         int clientPid, uid_t clientUid,
@@ -2751,24 +2751,18 @@
 
 CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
         const sp<IBinder>& remoteCallback,
-        const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
+        const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
         const String8& cameraIdStr, int cameraFacing,
         int clientPid, uid_t clientUid,
         int servicePid):
         mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
-        mClientPackageName(clientPackageName),
+        mClientPackageName(clientPackageName), mClientFeatureId(clientFeatureId),
         mClientPid(clientPid), mClientUid(clientUid),
         mServicePid(servicePid),
         mDisconnected(false), mUidIsTrusted(false),
         mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
         mRemoteBinder(remoteCallback)
 {
-    if (clientFeatureId) {
-        mClientFeatureId = std::unique_ptr<String16>(new String16(*clientFeatureId));
-    } else {
-        mClientFeatureId = std::unique_ptr<String16>();
-    }
-
     if (sCameraService == nullptr) {
         sCameraService = cameraService;
     }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 685ed5e..6771718 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -52,6 +52,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <unordered_map>
 #include <unordered_set>
@@ -142,7 +143,7 @@
 
     virtual binder::Status     connectDevice(
             const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
-            const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
+            const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
             int32_t clientUid,
             /*out*/
             sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -299,7 +300,7 @@
         BasicClient(const sp<CameraService>& cameraService,
                 const sp<IBinder>& remoteCallback,
                 const String16& clientPackageName,
-                const std::unique_ptr<String16>& clientFeatureId,
+                const std::optional<String16>& clientFeatureId,
                 const String8& cameraIdStr,
                 int cameraFacing,
                 int clientPid,
@@ -319,7 +320,7 @@
         const String8                   mCameraIdStr;
         const int                       mCameraFacing;
         String16                        mClientPackageName;
-        std::unique_ptr<String16>       mClientFeatureId;
+        std::optional<String16>         mClientFeatureId;
         pid_t                           mClientPid;
         const uid_t                     mClientUid;
         const pid_t                     mServicePid;
@@ -391,7 +392,7 @@
         Client(const sp<CameraService>& cameraService,
                 const sp<hardware::ICameraClient>& cameraClient,
                 const String16& clientPackageName,
-                const std::unique_ptr<String16>& clientFeatureId,
+                const std::optional<String16>& clientFeatureId,
                 const String8& cameraIdStr,
                 int api1CameraId,
                 int cameraFacing,
@@ -729,7 +730,7 @@
     template<class CALLBACK, class CLIENT>
     binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
             int api1CameraId, int halVersion, const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
+            const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
             apiLevel effectiveApiLevel, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
 
     // Lock guarding camera service state
@@ -1063,7 +1064,7 @@
 
     static binder::Status makeClient(const sp<CameraService>& cameraService,
             const sp<IInterface>& cameraCb, const String16& packageName,
-            const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
+            const std::optional<String16>& featureId, const String8& cameraId, int api1CameraId,
             int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
             int deviceVersion, apiLevel effectiveApiLevel,
             /*out*/sp<BasicClient>* client);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index b043c0b..09e2c3f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -50,7 +50,7 @@
 Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
         const sp<hardware::ICameraClient>& cameraClient,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         const String8& cameraDeviceId,
         int api1CameraId,
         int cameraFacing,
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 03ca44a..f8da0b6 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -94,7 +94,7 @@
     Camera2Client(const sp<CameraService>& cameraService,
             const sp<hardware::ICameraClient>& cameraClient,
             const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId,
+            const std::optional<String16>& clientFeatureId,
             const String8& cameraDeviceId,
             int api1CameraId,
             int cameraFacing,
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 892996c..b860ceb 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -34,7 +34,7 @@
 
 CameraClient::CameraClient(const sp<CameraService>& cameraService,
         const sp<hardware::ICameraClient>& cameraClient,
-        const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
+        const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
         int cameraId, int cameraFacing,
         int clientPid, int clientUid,
         int servicePid):
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index a7eb960..aacb00e 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -68,7 +68,7 @@
     CameraClient(const sp<CameraService>& cameraService,
             const sp<hardware::ICameraClient>& cameraClient,
             const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId,
+            const std::optional<String16>& clientFeatureId,
             int cameraId,
             int cameraFacing,
             int clientPid,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index e35b436..022d686 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -54,7 +54,7 @@
         const sp<CameraService>& cameraService,
         const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         const String8& cameraId,
         int api1CameraId,
         int cameraFacing,
@@ -80,7 +80,7 @@
 CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
         const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         const String8& cameraId,
         int cameraFacing,
         int clientPid,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 9d3874f..5cd16ee 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,7 +50,7 @@
     CameraDeviceClientBase(const sp<CameraService>& cameraService,
             const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
             const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId,
+            const std::optional<String16>& clientFeatureId,
             const String8& cameraId,
             int api1CameraId,
             int cameraFacing,
@@ -175,7 +175,7 @@
     CameraDeviceClient(const sp<CameraService>& cameraService,
             const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
             const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId,
+            const std::optional<String16>& clientFeatureId,
             const String8& cameraId,
             int cameraFacing,
             int clientPid,
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index b67fcb3..03621c8 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -48,7 +48,7 @@
             const KeyedVector<sp<IBinder>, sp<CompositeStream>>& offlineCompositeStreamMap,
             const sp<ICameraDeviceCallbacks>& remoteCallback,
             const String16& clientPackageName,
-            const std::unique_ptr<String16>& clientFeatureId,
+            const std::optional<String16>& clientFeatureId,
             const String8& cameraIdStr, int cameraFacing,
             int clientPid, uid_t clientUid, int servicePid) :
             CameraService::BasicClient(
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 0a41776..609698c 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -44,7 +44,7 @@
         const sp<CameraService>& cameraService,
         const sp<TCamCallbacks>& remoteCallback,
         const String16& clientPackageName,
-        const std::unique_ptr<String16>& clientFeatureId,
+        const std::optional<String16>& clientFeatureId,
         const String8& cameraId,
         int api1CameraId,
         int cameraFacing,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 042f5aa..d7506af 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -48,7 +48,7 @@
     Camera2ClientBase(const sp<CameraService>& cameraService,
                       const sp<TCamCallbacks>& remoteCallback,
                       const String16& clientPackageName,
-                      const std::unique_ptr<String16>& clientFeatureId,
+                      const std::optional<String16>& clientFeatureId,
                       const String8& cameraId,
                       int api1CameraId,
                       int cameraFacing,
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index a46133e..9ea9526 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -103,7 +103,7 @@
     }
     sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
     binder::Status serviceRet = mAidlICameraService->connectDevice(
-            callbacks, String16(cameraId.c_str()), String16(""), std::unique_ptr<String16>(),
+            callbacks, String16(cameraId.c_str()), String16(""), {},
             hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
     HStatus status = HStatus::NO_ERROR;
     if (!serviceRet.isOk()) {
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index c4efbaa..05bbbc7 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -15,18 +15,6 @@
         "libmedia_codecserviceregistrant",
     ],
 
-    target: {
-        android: {
-            product_variables: {
-                malloc_not_svelte: {
-                    // Scudo increases memory footprint, so only enable on
-                    // non-svelte devices.
-                    shared_libs: ["libc_scudo"],
-                },
-            },
-        },
-    },
-
     header_libs: [
         "libmedia_headers",
     ],
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index 0b25d62..03e1e41 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -35,20 +35,6 @@
         "liblog",
         "libavservices_minijail",
     ],
-    header_libs: [
-        "bionic_libc_platform_headers",
-    ],
-    target: {
-        android: {
-            product_variables: {
-                malloc_not_svelte: {
-                    // Scudo increases memory footprint, so only enable on
-                    // non-svelte devices.
-                    shared_libs: ["libc_scudo"],
-                },
-            },
-        },
-    },
     init_rc: ["mediaextractor.rc"],
 
     cflags: [
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index 9992d1c..71a5bff 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -39,23 +39,23 @@
 
 ::android::binder::Status MediaExtractorService::makeExtractor(
         const ::android::sp<::android::IDataSource>& remoteSource,
-        const ::std::unique_ptr< ::std::string> &mime,
+        const ::std::optional< ::std::string> &mime,
         ::android::sp<::android::IMediaExtractor>* _aidl_return) {
-    ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime.get()->c_str());
+    ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime ? mime->c_str() : nullptr);
 
     sp<DataSource> localSource = CreateDataSourceFromIDataSource(remoteSource);
 
     MediaBuffer::useSharedMemory();
     sp<IMediaExtractor> extractor = MediaExtractorFactory::CreateFromService(
             localSource,
-            mime.get() ? mime.get()->c_str() : nullptr);
+            mime ? mime->c_str() : nullptr);
 
     ALOGV("extractor service created %p (%s)",
             extractor.get(),
             extractor == nullptr ? "" : extractor->name());
 
     if (extractor != nullptr) {
-        registerMediaExtractor(extractor, localSource, mime.get() ? mime.get()->c_str() : nullptr);
+        registerMediaExtractor(extractor, localSource, mime ? mime->c_str() : nullptr);
     }
     *_aidl_return = extractor;
     return binder::Status::ok();
diff --git a/services/mediaextractor/MediaExtractorService.h b/services/mediaextractor/MediaExtractorService.h
index 1b40bf9..0081e7e 100644
--- a/services/mediaextractor/MediaExtractorService.h
+++ b/services/mediaextractor/MediaExtractorService.h
@@ -33,7 +33,7 @@
 
     virtual ::android::binder::Status makeExtractor(
             const ::android::sp<::android::IDataSource>& source,
-            const ::std::unique_ptr< ::std::string> &mime,
+            const ::std::optional< ::std::string> &mime,
             ::android::sp<::android::IMediaExtractor>* _aidl_return);
 
     virtual ::android::binder::Status makeIDataSource(
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index f21574f..b7b51a6 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -28,8 +28,6 @@
 #include <android-base/properties.h>
 #include <utils/misc.h>
 
-#include <bionic/reserved_signals.h>
-
 // from LOCAL_C_INCLUDES
 #include "MediaExtractorService.h"
 #include "minijail.h"
@@ -50,10 +48,6 @@
 
     signal(SIGPIPE, SIG_IGN);
 
-    // Do not assist platform profilers (relevant only on debug builds).
-    // Otherwise, the signal handler can violate the seccomp policy.
-    signal(BIONIC_SIGNAL_PROFILER, SIG_IGN);
-
     //b/62255959: this forces libutis.so to dlopen vendor version of libutils.so
     //before minijail is on. This is dirty but required since some syscalls such
     //as pread64 are used by linker but aren't allowed in the minijail. By
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index a3519d5..0d53c5e 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -1,6 +1,4 @@
-
-
-cc_library_shared {
+cc_library {
     name: "libresourcemanagerservice",
 
     srcs: [
@@ -25,5 +23,4 @@
     ],
 
     export_include_dirs: ["."],
-
 }
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index ee982b7..49c247e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -43,7 +43,7 @@
 using ::aidl::android::media::MediaResourcePolicyParcel;
 
 typedef std::map<std::tuple<
-        MediaResource::Type, MediaResource::SubType, std::vector<int8_t>>,
+        MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
         MediaResourceParcel> ResourceList;
 
 struct ResourceInfo {
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index b6c548c..6b2ef69 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -3,12 +3,12 @@
     name: "ResourceManagerService_test",
     srcs: ["ResourceManagerService_test.cpp"],
     test_suites: ["device-tests"],
+    static_libs: ["libresourcemanagerservice"],
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
         "liblog",
         "libmedia",
-        "libresourcemanagerservice",
         "libutils",
     ],
     include_dirs: [
@@ -19,17 +19,16 @@
         "-Werror",
         "-Wall",
     ],
-    compile_multilib: "32",
 }
 
 cc_test {
     name: "ServiceLog_test",
     srcs: ["ServiceLog_test.cpp"],
     test_suites: ["device-tests"],
+    static_libs: ["libresourcemanagerservice"],
     shared_libs: [
         "liblog",
         "libmedia",
-        "libresourcemanagerservice",
         "libutils",
     ],
     include_dirs: [
@@ -40,5 +39,4 @@
         "-Werror",
         "-Wall",
     ],
-    compile_multilib: "32",
 }
diff --git a/services/mediatranscoding/Android.bp b/services/mediatranscoding/Android.bp
index 17347a9..8cf2d62 100644
--- a/services/mediatranscoding/Android.bp
+++ b/services/mediatranscoding/Android.bp
@@ -44,18 +44,6 @@
         "mediatranscoding_aidl_interface-ndk_platform",
     ],
 
-    target: {
-        android: {
-            product_variables: {
-                malloc_not_svelte: {
-                    // Scudo increases memory footprint, so only enable on
-                    // non-svelte devices.
-                    shared_libs: ["libc_scudo"],
-                },
-            },
-        },
-    },
-
     init_rc: ["mediatranscoding.rc"],
 
     cflags: [
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 01b1c2e..f2cf016 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -105,7 +105,7 @@
     }
     int32_t capacityInFrames = numBursts * framesPerBurst;
 
-    // Final sanity check.
+    // Final range check.
     if (capacityInFrames > MAX_FRAMES_PER_BUFFER) {
         ALOGE("calculateBufferCapacity() calc capacity %d > max %d",
               capacityInFrames, MAX_FRAMES_PER_BUFFER);
diff --git a/services/oboeservice/SharedMemoryProxy.cpp b/services/oboeservice/SharedMemoryProxy.cpp
index c43ed22..78d4884 100644
--- a/services/oboeservice/SharedMemoryProxy.cpp
+++ b/services/oboeservice/SharedMemoryProxy.cpp
@@ -20,6 +20,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <aaudio/AAudio.h>
 #include "SharedMemoryProxy.h"