[automerger] Merge changes from topic "am-1e7935a2-3929-4000-bb19-9e0ff0e29216" into cw-f-dev am: ae2d8ccc79 am: 02cf7d9038 am: dc41d373b4
am: 608b18dfc6

Change-Id: I34405c0b7c10cabac7565ff077266a1fce3942d3
diff --git a/Android.bp b/Android.bp
index b207a96..a3679b1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,6 +2,5 @@
     "camera",
     "drm/*",
     "media/*",
-    "radio",
     "soundtrigger",
 ]
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 5e4d81d..f3946f0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -78,6 +78,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/soundfx/libbundlewrapper.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/soundfx/libaudiopreprocessing.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libmediacodecservice.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libstagefright_xmlparser@1.0.so)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..8f405e9
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,4 @@
+elaurent@google.com
+etalvala@google.com
+lajos@google.com
+marcone@google.com
diff --git a/camera/OWNERS b/camera/OWNERS
new file mode 100644
index 0000000..18acfee
--- /dev/null
+++ b/camera/OWNERS
@@ -0,0 +1,6 @@
+cychen@google.com
+epeev@google.com
+etalvala@google.com
+shuzhenwang@google.com
+yinchiayeh@google.com
+zhijunhe@google.com
diff --git a/cmds/OWNERS b/cmds/OWNERS
new file mode 100644
index 0000000..0d32aac
--- /dev/null
+++ b/cmds/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+lajos@google.com
+marcone@google.com
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index de0167a..bc32bbe 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -78,7 +78,7 @@
 static bool gWantFrameTime = false;     // do we want times on each frame?
 static uint32_t gVideoWidth = 0;        // default width+height
 static uint32_t gVideoHeight = 0;
-static uint32_t gBitRate = 4000000;     // 4Mbps
+static uint32_t gBitRate = 20000000;     // 20Mbps
 static uint32_t gTimeLimitSec = kMaxTimeLimitSec;
 
 // Set by signal handler to stop recording.
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index d7c2e87..d70282b 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -870,7 +870,9 @@
 
             sp<IMemory> mem =
                     retriever->getFrameAtTime(-1,
-                                    MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+                            MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
+                            HAL_PIXEL_FORMAT_RGB_565,
+                            false /*metaOnly*/);
 
             if (mem != NULL) {
                 failed = false;
diff --git a/drm/OWNERS b/drm/OWNERS
new file mode 100644
index 0000000..e788754
--- /dev/null
+++ b/drm/OWNERS
@@ -0,0 +1 @@
+jtinker@google.com
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 66f5fc2..f906564 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -5,36 +5,31 @@
 cc_library_shared {
     name: "libmediadrm",
 
-    aidl: {
-        local_include_dirs: ["aidl"],
-        export_aidl_headers: true,
-    },
 
     srcs: [
-        "aidl/android/media/ICas.aidl",
-        "aidl/android/media/ICasListener.aidl",
-        "aidl/android/media/IDescrambler.aidl",
-        "aidl/android/media/IMediaCasService.aidl",
-
-        "CasImpl.cpp",
-        "DescramblerImpl.cpp",
         "DrmPluginPath.cpp",
         "DrmSessionManager.cpp",
         "ICrypto.cpp",
         "IDrm.cpp",
         "IDrmClient.cpp",
         "IMediaDrmService.cpp",
-        "MediaCasDefs.cpp",
+        "PluginMetricsReporting.cpp",
         "SharedLibrary.cpp",
         "DrmHal.cpp",
         "CryptoHal.cpp",
+        "protos/plugin_metrics.proto",
     ],
 
+    proto: {
+        type: "lite",
+    },
+
     shared_libs: [
         "libbinder",
         "libcutils",
         "libdl",
         "liblog",
+        "libmediametrics",
         "libmediautils",
         "libstagefright_foundation",
         "libutils",
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
deleted file mode 100644
index 1a33bb0..0000000
--- a/drm/libmediadrm/CasImpl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "CasImpl"
-
-#include <android/media/ICasListener.h>
-#include <media/cas/CasAPI.h>
-#include <media/CasImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
-    if (err == OK) {
-        return Status::ok();
-    }
-    if (err == BAD_VALUE) {
-        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
-    }
-    if (err == INVALID_OPERATION) {
-        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
-    }
-    return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
-    String8 result;
-    for (size_t i = 0; i < sessionId.size(); i++) {
-        result.appendFormat("%02x ", sessionId[i]);
-    }
-    if (result.isEmpty()) {
-        result.append("(null)");
-    }
-    return result;
-}
-
-struct CasImpl::PluginHolder : public RefBase {
-public:
-    explicit PluginHolder(CasPlugin *plugin) : mPlugin(plugin) {}
-    ~PluginHolder() { if (mPlugin != NULL) delete mPlugin; }
-    CasPlugin* get() { return mPlugin; }
-
-private:
-    CasPlugin *mPlugin;
-    DISALLOW_EVIL_CONSTRUCTORS(PluginHolder);
-};
-
-CasImpl::CasImpl(const sp<ICasListener> &listener)
-    : mPluginHolder(NULL), mListener(listener) {
-    ALOGV("CTOR");
-}
-
-CasImpl::~CasImpl() {
-    ALOGV("DTOR");
-    release();
-}
-
-//static
-void CasImpl::OnEvent(
-        void *appData,
-        int32_t event,
-        int32_t arg,
-        uint8_t *data,
-        size_t size) {
-    if (appData == NULL) {
-        ALOGE("Invalid appData!");
-        return;
-    }
-    CasImpl *casImpl = static_cast<CasImpl *>(appData);
-    casImpl->onEvent(event, arg, data, size);
-}
-
-void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin *plugin) {
-    mLibrary = library;
-    mPluginHolder = new PluginHolder(plugin);
-}
-
-void CasImpl::onEvent(
-        int32_t event, int32_t arg, uint8_t *data, size_t size) {
-    if (mListener == NULL) {
-        return;
-    }
-
-    std::unique_ptr<CasData> eventData;
-    if (data != NULL && size > 0) {
-        eventData.reset(new CasData(data, data + size));
-    }
-
-    mListener->onEvent(event, arg, eventData);
-}
-
-Status CasImpl::setPrivateData(const CasData& pvtData) {
-    ALOGV("setPrivateData");
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-    return getBinderStatus(holder->get()->setPrivateData(pvtData));
-}
-
-Status CasImpl::openSession(CasSessionId* sessionId) {
-    ALOGV("openSession");
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-    status_t err = holder->get()->openSession(sessionId);
-
-    ALOGV("openSession: session opened, sessionId=%s",
-            sessionIdToString(*sessionId).string());
-
-    return getBinderStatus(err);
-}
-
-Status CasImpl::setSessionPrivateData(
-        const CasSessionId &sessionId, const CasData& pvtData) {
-    ALOGV("setSessionPrivateData: sessionId=%s",
-            sessionIdToString(sessionId).string());
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-    return getBinderStatus(holder->get()->setSessionPrivateData(sessionId, pvtData));
-}
-
-Status CasImpl::closeSession(const CasSessionId &sessionId) {
-    ALOGV("closeSession: sessionId=%s",
-            sessionIdToString(sessionId).string());
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-    return getBinderStatus(holder->get()->closeSession(sessionId));
-}
-
-Status CasImpl::processEcm(const CasSessionId &sessionId, const ParcelableCasData& ecm) {
-    ALOGV("processEcm: sessionId=%s",
-            sessionIdToString(sessionId).string());
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-
-    return getBinderStatus(holder->get()->processEcm(sessionId, ecm));
-}
-
-Status CasImpl::processEmm(const ParcelableCasData& emm) {
-    ALOGV("processEmm");
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-
-    return getBinderStatus(holder->get()->processEmm(emm));
-}
-
-Status CasImpl::sendEvent(
-        int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) {
-    ALOGV("sendEvent");
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-
-    status_t err;
-    if (eventData == nullptr) {
-        err = holder->get()->sendEvent(event, arg, CasData());
-    } else {
-        err = holder->get()->sendEvent(event, arg, *eventData);
-    }
-    return getBinderStatus(err);
-}
-
-Status CasImpl::provision(const String16& provisionString) {
-    ALOGV("provision: provisionString=%s", String8(provisionString).string());
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-
-    return getBinderStatus(holder->get()->provision(String8(provisionString)));
-}
-
-Status CasImpl::refreshEntitlements(
-        int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) {
-    ALOGV("refreshEntitlements");
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-
-    status_t err;
-    if (refreshData == nullptr) {
-        err = holder->get()->refreshEntitlements(refreshType, CasData());
-    } else {
-        err = holder->get()->refreshEntitlements(refreshType, *refreshData);
-    }
-    return getBinderStatus(err);
-}
-
-Status CasImpl::release() {
-    ALOGV("release: plugin=%p",
-            mPluginHolder == NULL ? mPluginHolder->get() : NULL);
-    mPluginHolder.clear();
-    return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/DescramblerImpl.cpp b/drm/libmediadrm/DescramblerImpl.cpp
deleted file mode 100644
index 94e09e2..0000000
--- a/drm/libmediadrm/DescramblerImpl.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DescramblerImpl"
-
-#include <media/cas/DescramblerAPI.h>
-#include <media/DescramblerImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
-    if (err == OK) {
-        return Status::ok();
-    }
-    if (err == BAD_VALUE) {
-        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
-    }
-    if (err == INVALID_OPERATION) {
-        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
-    }
-    return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
-    String8 result;
-    for (size_t i = 0; i < sessionId.size(); i++) {
-        result.appendFormat("%02x ", sessionId[i]);
-    }
-    if (result.isEmpty()) {
-        result.append("(null)");
-    }
-    return result;
-}
-
-DescramblerImpl::DescramblerImpl(
-        const sp<SharedLibrary>& library, DescramblerPlugin *plugin) :
-        mLibrary(library), mPlugin(plugin) {
-    ALOGV("CTOR: mPlugin=%p", mPlugin);
-}
-
-DescramblerImpl::~DescramblerImpl() {
-    ALOGV("DTOR: mPlugin=%p", mPlugin);
-    release();
-}
-
-Status DescramblerImpl::setMediaCasSession(const CasSessionId& sessionId) {
-    ALOGV("setMediaCasSession: sessionId=%s",
-            sessionIdToString(sessionId).string());
-
-    return getBinderStatus(mPlugin->setMediaCasSession(sessionId));
-}
-
-Status DescramblerImpl::requiresSecureDecoderComponent(
-        const String16& mime, bool *result) {
-    *result = mPlugin->requiresSecureDecoderComponent(String8(mime));
-
-    return getBinderStatus(OK);
-}
-
-Status DescramblerImpl::descramble(
-        const DescrambleInfo& info, int32_t *result) {
-    ALOGV("descramble");
-
-    *result = mPlugin->descramble(
-            info.dstType != DescrambleInfo::kDestinationTypeVmPointer,
-            info.scramblingControl,
-            info.numSubSamples,
-            info.subSamples,
-            info.srcMem->pointer(),
-            info.srcOffset,
-            info.dstType == DescrambleInfo::kDestinationTypeVmPointer ?
-                    info.srcMem->pointer() : info.dstPtr,
-            info.dstOffset,
-            NULL);
-
-    return getBinderStatus(*result >= 0 ? OK : *result);
-}
-
-Status DescramblerImpl::release() {
-    ALOGV("release: mPlugin=%p", mPlugin);
-
-    if (mPlugin != NULL) {
-        delete mPlugin;
-        mPlugin = NULL;
-    }
-    return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 074489a..bc37557 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -30,6 +30,7 @@
 #include <media/DrmHal.h>
 #include <media/DrmSessionClientInterface.h>
 #include <media/DrmSessionManager.h>
+#include <media/PluginMetricsReporting.h>
 #include <media/drm/DrmAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
@@ -194,7 +195,18 @@
      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
 }
 
+void DrmHal::closeOpenSessions() {
+    if (mPlugin != NULL) {
+        for (size_t i = 0; i < mOpenSessions.size(); i++) {
+            mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
+            DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
+        }
+    }
+    mOpenSessions.clear();
+}
+
 DrmHal::~DrmHal() {
+    closeOpenSessions();
     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
 }
 
@@ -413,11 +425,12 @@
 
 status_t DrmHal::destroyPlugin() {
     Mutex::Autolock autoLock(mLock);
-
     if (mInitCheck != OK) {
         return mInitCheck;
     }
 
+    closeOpenSessions();
+    reportMetrics();
     setListener(NULL);
     mInitCheck = NO_INIT;
 
@@ -471,6 +484,7 @@
     if (err == OK) {
         DrmSessionManager::Instance()->addSession(getCallingPid(),
                 mDrmSessionClient, sessionId);
+        mOpenSessions.push(sessionId);
     }
     return err;
 }
@@ -486,7 +500,14 @@
     if (status.isOk()) {
         if (status == Status::OK) {
             DrmSessionManager::Instance()->removeSession(sessionId);
+            for (size_t i = 0; i < mOpenSessions.size(); i++) {
+                if (mOpenSessions[i] == sessionId) {
+                    mOpenSessions.removeAt(i);
+                    break;
+                }
+            }
         }
+        reportMetrics();
         return toStatusT(status);
     }
     return DEAD_OBJECT;
@@ -740,6 +761,12 @@
 
 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
     Mutex::Autolock autoLock(mLock);
+    return getPropertyStringInternal(name, value);
+}
+
+status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
+    // This function is internal to the class and should only be called while
+    // mLock is already held.
 
     if (mInitCheck != OK) {
         return mInitCheck;
@@ -761,6 +788,12 @@
 
 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
     Mutex::Autolock autoLock(mLock);
+    return getPropertyByteArrayInternal(name, value);
+}
+
+status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
+    // This function is internal to the class and should only be called while
+    // mLock is already held.
 
     if (mInitCheck != OK) {
         return mInitCheck;
@@ -975,7 +1008,7 @@
 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
 {
     Mutex::Autolock autoLock(mLock);
-
+    closeOpenSessions();
     setListener(NULL);
     mInitCheck = NO_INIT;
 
@@ -997,4 +1030,20 @@
     }
 }
 
+void DrmHal::reportMetrics() const
+{
+    Vector<uint8_t> metrics;
+    String8 vendor;
+    String8 description;
+    if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
+            getPropertyStringInternal(String8("description"), description) == OK &&
+            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
+        status_t res = android::reportDrmPluginMetrics(
+                metrics, vendor, description);
+        if (res != OK) {
+            ALOGE("Metrics were retrieved but could not be reported: %i", res);
+        }
+    }
+}
+
 }  // namespace android
diff --git a/drm/libmediadrm/MediaCasDefs.cpp b/drm/libmediadrm/MediaCasDefs.cpp
deleted file mode 100644
index 9c2ba38..0000000
--- a/drm/libmediadrm/MediaCasDefs.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCas"
-
-#include <media/MediaCasDefs.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-namespace media {
-
-///////////////////////////////////////////////////////////////////////////////
-namespace MediaCas {
-
-status_t ParcelableCasData::readFromParcel(const Parcel* parcel) {
-    return parcel->readByteVector(this);
-}
-
-status_t ParcelableCasData::writeToParcel(Parcel* parcel) const  {
-    return parcel->writeByteVector(*this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-status_t ParcelableCasPluginDescriptor::readFromParcel(const Parcel* /*parcel*/) {
-    ALOGE("CAPluginDescriptor::readFromParcel() shouldn't be called");
-    return INVALID_OPERATION;
-}
-
-status_t ParcelableCasPluginDescriptor::writeToParcel(Parcel* parcel) const {
-    status_t err = parcel->writeInt32(mCASystemId);
-    if (err != NO_ERROR) {
-        return err;
-    }
-    return parcel->writeString16(mName);
-}
-
-} // namespace MediaCas
-///////////////////////////////////////////////////////////////////////////////
-
-namespace MediaDescrambler {
-
-DescrambleInfo::DescrambleInfo() {}
-
-DescrambleInfo::~DescrambleInfo() {}
-
-status_t DescrambleInfo::readFromParcel(const Parcel* parcel) {
-    status_t err = parcel->readInt32((int32_t*)&dstType);
-    if (err != OK) {
-        return err;
-    }
-    if (dstType != kDestinationTypeNativeHandle
-            && dstType != kDestinationTypeVmPointer) {
-        return BAD_VALUE;
-    }
-
-    err = parcel->readInt32((int32_t*)&scramblingControl);
-    if (err != OK) {
-        return err;
-    }
-
-    err = parcel->readUint32((uint32_t*)&numSubSamples);
-    if (err != OK) {
-        return err;
-    }
-    if (numSubSamples > 0xffff) {
-        return BAD_VALUE;
-    }
-
-    subSamples = new DescramblerPlugin::SubSample[numSubSamples];
-    if (subSamples == NULL) {
-        return NO_MEMORY;
-    }
-
-    for (size_t i = 0; i < numSubSamples; i++) {
-        err = parcel->readUint32(&subSamples[i].mNumBytesOfClearData);
-        if (err != OK) {
-            return err;
-        }
-        err = parcel->readUint32(&subSamples[i].mNumBytesOfEncryptedData);
-        if (err != OK) {
-            return err;
-        }
-    }
-
-    srcMem = interface_cast<IMemory>(parcel->readStrongBinder());
-    if (srcMem == NULL) {
-        return BAD_VALUE;
-    }
-
-    err = parcel->readInt32(&srcOffset);
-    if (err != OK) {
-        return err;
-    }
-
-    native_handle_t *nativeHandle = NULL;
-    if (dstType == kDestinationTypeNativeHandle) {
-        nativeHandle = parcel->readNativeHandle();
-        dstPtr = static_cast<void *>(nativeHandle);
-    } else {
-        dstPtr = NULL;
-    }
-
-    err = parcel->readInt32(&dstOffset);
-    if (err != OK) {
-        return err;
-    }
-
-    return OK;
-}
-
-status_t DescrambleInfo::writeToParcel(Parcel* parcel) const {
-    if (dstType != kDestinationTypeNativeHandle
-            && dstType != kDestinationTypeVmPointer) {
-        return BAD_VALUE;
-    }
-
-    status_t err = parcel->writeInt32((int32_t)dstType);
-    if (err != OK) {
-        return err;
-    }
-
-    err = parcel->writeInt32(scramblingControl);
-    if (err != OK) {
-        return err;
-    }
-
-    err = parcel->writeUint32(numSubSamples);
-    if (err != OK) {
-        return err;
-    }
-
-    for (size_t i = 0; i < numSubSamples; i++) {
-        err = parcel->writeUint32(subSamples[i].mNumBytesOfClearData);
-        if (err != OK) {
-            return err;
-        }
-        err = parcel->writeUint32(subSamples[i].mNumBytesOfEncryptedData);
-        if (err != OK) {
-            return err;
-        }
-    }
-
-    err = parcel->writeStrongBinder(IInterface::asBinder(srcMem));
-    if (err != OK) {
-        return err;
-    }
-
-    err = parcel->writeInt32(srcOffset);
-    if (err != OK) {
-        return err;
-    }
-
-    if (dstType == kDestinationTypeNativeHandle) {
-        parcel->writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
-    }
-
-    err = parcel->writeInt32(dstOffset);
-    if (err != OK) {
-        return err;
-    }
-
-    return OK;
-}
-
-} // namespace MediaDescrambler
-
-} // namespace media
-} // namespace android
-
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
new file mode 100644
index 0000000..a9302ea
--- /dev/null
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PluginMetricsReporting"
+#include <utils/Log.h>
+
+#include <media/PluginMetricsReporting.h>
+
+#include <media/MediaAnalyticsItem.h>
+
+#include "protos/plugin_metrics.pb.h"
+
+namespace android {
+
+namespace {
+
+using android::drm_metrics::MetricsGroup;
+using android::drm_metrics::MetricsGroup_Metric;
+using android::drm_metrics::MetricsGroup_Metric_MetricValue;
+
+const char* const kParentAttribute = "/parent/external";
+
+status_t reportMetricsGroup(const MetricsGroup& metricsGroup,
+                            const String8& batchName,
+                            const int64_t* parentId) {
+    MediaAnalyticsItem analyticsItem(batchName.c_str());
+    analyticsItem.generateSessionID();
+    int64_t sessionId = analyticsItem.getSessionID();
+    if (parentId != NULL) {
+        analyticsItem.setInt64(kParentAttribute, *parentId);
+    }
+
+    for (int i = 0; i < metricsGroup.metric_size(); ++i) {
+        const MetricsGroup_Metric& metric = metricsGroup.metric(i);
+        if (!metric.has_name()) {
+            ALOGE("Metric with no name.");
+            return BAD_VALUE;
+        }
+
+        if (!metric.has_value()) {
+            ALOGE("Metric with no value.");
+            return BAD_VALUE;
+        }
+
+        const MetricsGroup_Metric_MetricValue& value = metric.value();
+        if (value.has_int_value()) {
+            analyticsItem.setInt64(metric.name().c_str(),
+                                   value.int_value());
+        } else if (value.has_double_value()) {
+            analyticsItem.setDouble(metric.name().c_str(),
+                                    value.double_value());
+        } else if (value.has_string_value()) {
+            analyticsItem.setCString(metric.name().c_str(),
+                                     value.string_value().c_str());
+        } else {
+            ALOGE("Metric Value with no actual value.");
+            return BAD_VALUE;
+        }
+    }
+
+    analyticsItem.setFinalized(true);
+    analyticsItem.selfrecord();
+
+    for (int i = 0; i < metricsGroup.metric_sub_group_size(); ++i) {
+        const MetricsGroup& subGroup = metricsGroup.metric_sub_group(i);
+        status_t res = reportMetricsGroup(subGroup, batchName, &sessionId);
+        if (res != OK) {
+            return res;
+        }
+    }
+
+    return OK;
+}
+
+String8 sanitize(const String8& input) {
+    // Filters the input string down to just alphanumeric characters.
+    String8 output;
+    for (size_t i = 0; i < input.size(); ++i) {
+        char candidate = input[i];
+        if ((candidate >= 'a' && candidate <= 'z') ||
+                (candidate >= 'A' && candidate <= 'Z') ||
+                (candidate >= '0' && candidate <= '9')) {
+            output.append(&candidate, 1);
+        }
+    }
+    return output;
+}
+
+}  // namespace
+
+status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics,
+                                const String8& vendor,
+                                const String8& description) {
+    MetricsGroup root_metrics_group;
+    if (!root_metrics_group.ParseFromArray(serializedMetrics.array(),
+                                           serializedMetrics.size())) {
+        ALOGE("Failure to parse.");
+        return BAD_VALUE;
+    }
+
+    String8 name = String8::format("drm.vendor.%s.%s",
+                                   sanitize(vendor).c_str(),
+                                   sanitize(description).c_str());
+
+    return reportMetricsGroup(root_metrics_group, name, NULL);
+}
+
+}  // namespace android
diff --git a/drm/libmediadrm/aidl/android/media/ICas.aidl b/drm/libmediadrm/aidl/android/media/ICas.aidl
deleted file mode 100644
index 9746593..0000000
--- a/drm/libmediadrm/aidl/android/media/ICas.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.MediaCas;
-
-/** @hide */
-interface ICas {
-    void setPrivateData(in byte[] pvtData);
-    byte[] openSession();
-    void closeSession(in byte[] sessionId);
-    void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
-    void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
-    void processEmm(in MediaCas.ParcelableCasData emm);
-    void sendEvent(int event, int arg, in @nullable byte[] eventData);
-    void provision(String provisionString);
-    void refreshEntitlements(int refreshType, in @nullable byte[] refreshData);
-    void release();
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/ICasListener.aidl b/drm/libmediadrm/aidl/android/media/ICasListener.aidl
deleted file mode 100644
index 01a5abc..0000000
--- a/drm/libmediadrm/aidl/android/media/ICasListener.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/** @hide */
-interface ICasListener {
-    void onEvent(int event, int arg, in @nullable byte[] data);
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl b/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
deleted file mode 100644
index 44f6825..0000000
--- a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.IDescrambler;
-import android.media.ICas;
-import android.media.ICasListener;
-import android.media.MediaCas;
-
-/** @hide */
-interface IMediaCasService {
-    MediaCas.ParcelableCasPluginDescriptor[] enumeratePlugins();
-    boolean isSystemIdSupported(int CA_system_id);
-    ICas createPlugin(int CA_system_id, ICasListener listener);
-    boolean isDescramblerSupported(int CA_system_id);
-    IDescrambler createDescrambler(int CA_system_id);
-}
-
diff --git a/drm/libmediadrm/aidl/android/media/MediaCas.aidl b/drm/libmediadrm/aidl/android/media/MediaCas.aidl
deleted file mode 100644
index cb8d0c6..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaCas.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaCas.ParcelableCasPluginDescriptor cpp_header "media/MediaCasDefs.h";
-
-/** @hide */
-parcelable MediaCas.ParcelableCasData cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl b/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
deleted file mode 100644
index e789244..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/libmediadrm/protos/plugin_metrics.proto b/drm/libmediadrm/protos/plugin_metrics.proto
new file mode 100644
index 0000000..2d26f14
--- /dev/null
+++ b/drm/libmediadrm/protos/plugin_metrics.proto
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.drm_metrics;
+
+// need this if we are using libprotobuf-cpp-2.3.0-lite
+option optimize_for = LITE_RUNTIME;
+
+// The MetricsGroup is a collection of metric name/value pair instances
+// that can be serialized and provided to a caller.
+message MetricsGroup {
+  message Metric {
+    message MetricValue {
+      // Exactly one of the following values must be set.
+      optional int64 int_value = 1;
+      optional double double_value = 2;
+      optional string string_value = 3;
+    }
+
+    // The name of the metric. Must be valid UTF-8. Required.
+    optional string name = 1;
+
+    // The value of the metric. Required.
+    optional MetricValue value = 2;
+  }
+
+  // The list of name/value pairs of metrics.
+  repeated Metric metric = 1;
+
+  // Allow multiple sub groups of metrics.
+  repeated MetricsGroup metric_sub_group = 2;
+}
diff --git a/drm/mediacas/plugins/clearkey/Android.mk b/drm/mediacas/plugins/clearkey/Android.mk
index 8fd866c..4b139a8 100644
--- a/drm/mediacas/plugins/clearkey/Android.mk
+++ b/drm/mediacas/plugins/clearkey/Android.mk
@@ -28,8 +28,7 @@
 
 LOCAL_MODULE := libclearkeycasplugin
 
-#TODO: move this back to /vendor/lib after conversion to treble
-#LOCAL_PROPRIETARY_MODULE := true
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := mediacas
 
 LOCAL_SHARED_LIBRARIES := \
@@ -39,6 +38,9 @@
     libstagefright_foundation \
     libprotobuf-cpp-lite \
 
+LOCAL_HEADER_LIBRARIES := \
+    media_plugin_headers
+
 LOCAL_STATIC_LIBRARIES := \
     libjsmn \
 
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 4ed5fce..e27631f 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -121,7 +121,7 @@
     sp<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session == NULL) {
-        return ERROR_DRM_SESSION_NOT_OPENED;
+        return ERROR_CAS_SESSION_NOT_OPENED;
     }
 
     ClearKeySessionLibrary::get()->destroySession(sessionId);
@@ -135,7 +135,7 @@
     sp<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session == NULL) {
-        return ERROR_DRM_SESSION_NOT_OPENED;
+        return ERROR_CAS_SESSION_NOT_OPENED;
     }
     return OK;
 }
@@ -146,7 +146,7 @@
     sp<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session == NULL) {
-        return ERROR_DRM_SESSION_NOT_OPENED;
+        return ERROR_CAS_SESSION_NOT_OPENED;
     }
 
     Mutex::Autolock lock(mKeyFetcherLock);
@@ -293,7 +293,7 @@
 status_t ClearKeyCasSession::updateECM(
         KeyFetcher *keyFetcher, void *ecm, size_t size) {
     if (keyFetcher == nullptr) {
-        return ERROR_DRM_NOT_PROVISIONED;
+        return ERROR_CAS_NOT_PROVISIONED;
     }
 
     if (size < kEcmHeaderLength) {
@@ -344,7 +344,7 @@
         size_t numSubSamples, const DescramblerPlugin::SubSample *subSamples,
         const void *srcPtr, void *dstPtr, AString * /* errorDetailMsg */) {
     if (secure) {
-        return ERROR_DRM_CANNOT_HANDLE;
+        return ERROR_CAS_CANNOT_HANDLE;
     }
 
     AES_KEY contentKey;
@@ -356,7 +356,7 @@
         int32_t keyIndex = (scramblingControl & 1);
         if (!mKeyInfo[keyIndex].valid) {
             ALOGE("decrypt: key %d is invalid", keyIndex);
-            return ERROR_DRM_DECRYPT;
+            return ERROR_CAS_DECRYPT;
         }
         contentKey = mKeyInfo[keyIndex].contentKey;
     }
@@ -420,7 +420,7 @@
 
     if (session == NULL) {
         ALOGE("ClearKeyDescramblerPlugin: session not found");
-        return ERROR_DRM_SESSION_NOT_OPENED;
+        return ERROR_CAS_SESSION_NOT_OPENED;
     }
 
     mCASSession = session;
@@ -446,7 +446,7 @@
 
     if (mCASSession == NULL) {
         ALOGE("Uninitialized CAS session!");
-        return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
+        return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
     }
 
     return mCASSession->decrypt(
diff --git a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
index 9cd77e9..6e1004c 100644
--- a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
+++ b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
@@ -48,24 +48,24 @@
  * Extract a clear key asset from a JSON string.
  *
  * Returns OK if a clear key asset is extracted successfully,
- * or ERROR_DRM_NO_LICENSE if the string doesn't contain a valid
+ * or ERROR_CAS_NO_LICENSE if the string doesn't contain a valid
  * clear key asset.
  */
 status_t JsonAssetLoader::extractAssetFromString(
         const String8& jsonAssetString, Asset *asset) {
     if (!parseJsonAssetString(jsonAssetString, &mJsonObjects)) {
-        return ERROR_DRM_NO_LICENSE;
+        return ERROR_CAS_NO_LICENSE;
     }
 
     if (mJsonObjects.size() < 1) {
-        return ERROR_DRM_NO_LICENSE;
+        return ERROR_CAS_NO_LICENSE;
     }
 
     if (!parseJsonObject(mJsonObjects[0], &mTokens))
-        return ERROR_DRM_NO_LICENSE;
+        return ERROR_CAS_NO_LICENSE;
 
     if (!findKey(mJsonObjects[0], asset)) {
-        return ERROR_DRM_NO_LICENSE;
+        return ERROR_CAS_NO_LICENSE;
     }
     return OK;
 }
diff --git a/drm/mediacas/plugins/clearkey/ecm_generator.h b/drm/mediacas/plugins/clearkey/ecm_generator.h
index 2ef06c4..5fbdea5 100644
--- a/drm/mediacas/plugins/clearkey/ecm_generator.h
+++ b/drm/mediacas/plugins/clearkey/ecm_generator.h
@@ -29,7 +29,7 @@
 namespace android {
 namespace clearkeycas {
 enum {
-    CLEARKEY_STATUS_BASE = ERROR_DRM_VENDOR_MAX,
+    CLEARKEY_STATUS_BASE = ERROR_CAS_VENDOR_MAX,
     CLEARKEY_STATUS_INVALIDASSETID = CLEARKEY_STATUS_BASE - 1,
     CLEARKEY_STATUS_INVALIDSYSTEMID = CLEARKEY_STATUS_BASE - 2,
     CLEARKEY_STATUS_INVALID_PARAMETER = CLEARKEY_STATUS_BASE - 3,
diff --git a/drm/mediacas/plugins/clearkey/tests/Android.mk b/drm/mediacas/plugins/clearkey/tests/Android.mk
index cbf7be7..e1545af 100644
--- a/drm/mediacas/plugins/clearkey/tests/Android.mk
+++ b/drm/mediacas/plugins/clearkey/tests/Android.mk
@@ -21,12 +21,13 @@
     ClearKeyFetcherTest.cpp
 
 LOCAL_MODULE := ClearKeyFetcherTest
+LOCAL_VENDOR_MODULE := true
 
 # LOCAL_LDFLAGS is needed here for the test to use the plugin, because
 # the plugin is not in standard library search path. Without this .so
 # loading fails at run-time (linking is okay).
 LOCAL_LDFLAGS := \
-    -Wl,--rpath,\$${ORIGIN}/../../../system/lib/mediacas -Wl,--enable-new-dtags
+    -Wl,--rpath,\$${ORIGIN}/../../../system/vendor/lib/mediacas -Wl,--enable-new-dtags
 
 LOCAL_SHARED_LIBRARIES := \
     libutils libclearkeycasplugin libstagefright_foundation libprotobuf-cpp-lite liblog
diff --git a/drm/mediacas/plugins/mock/Android.mk b/drm/mediacas/plugins/mock/Android.mk
index a97fac6..a1d61da 100644
--- a/drm/mediacas/plugins/mock/Android.mk
+++ b/drm/mediacas/plugins/mock/Android.mk
@@ -28,6 +28,8 @@
 LOCAL_SHARED_LIBRARIES := \
     libutils liblog
 
+LOCAL_HEADER_LIBRARIES := media_plugin_headers
+
 LOCAL_C_INCLUDES += \
     $(TOP)/frameworks/av/include \
     $(TOP)/frameworks/native/include/media \
diff --git a/drm/mediadrm/plugins/clearkey/tests/Android.bp b/drm/mediadrm/plugins/clearkey/tests/Android.bp
index ac57d65..0fcfc64 100644
--- a/drm/mediadrm/plugins/clearkey/tests/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/tests/Android.bp
@@ -34,4 +34,5 @@
         "libstagefright_foundation",
         "libutils",
     ],
+    header_libs: ["media_plugin_headers"],
 }
diff --git a/drm/mediadrm/plugins/mock/Android.bp b/drm/mediadrm/plugins/mock/Android.bp
index 7f44819..abd1884 100644
--- a/drm/mediadrm/plugins/mock/Android.bp
+++ b/drm/mediadrm/plugins/mock/Android.bp
@@ -22,6 +22,8 @@
     vendor: true,
     relative_install_path: "mediadrm",
 
+    header_libs: ["media_plugin_headers"],
+
     shared_libs: [
         "libutils",
         "liblog",
diff --git a/include/OWNERS b/include/OWNERS
new file mode 100644
index 0000000..3cb6d9c
--- /dev/null
+++ b/include/OWNERS
@@ -0,0 +1,6 @@
+elaurent@google.com
+gkasten@android.com
+hunga@google.com
+jtinker@google.com
+lajos@google.com
+marcone@google.com
diff --git a/include/media/AudioClient.h b/include/media/AudioClient.h
deleted file mode 120000
index a0530e4..0000000
--- a/include/media/AudioClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl b/include/media/AudioClient.h
similarity index 61%
rename from drm/libmediadrm/aidl/android/media/IDescrambler.aidl
rename to include/media/AudioClient.h
index fdf99eb..9efd76d 100644
--- a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl
+++ b/include/media/AudioClient.h
@@ -14,14 +14,25 @@
  * limitations under the License.
  */
 
-package android.media;
 
-import android.media.MediaDescrambler;
+#ifndef ANDROID_AUDIO_CLIENT_H
+#define ANDROID_AUDIO_CLIENT_H
 
-/** @hide */
-interface IDescrambler {
-    void setMediaCasSession(in byte[] sessionId);
-    boolean requiresSecureDecoderComponent(String mime);
-    int descramble(in MediaDescrambler.DescrambleInfo descrambleInfo);
-    void release();
-}
\ No newline at end of file
+#include <system/audio.h>
+#include <utils/String16.h>
+
+namespace android {
+
+class AudioClient {
+ public:
+    AudioClient() :
+        clientUid(-1), clientPid(-1), packageName("") {}
+
+    uid_t clientUid;
+    pid_t clientPid;
+    String16 packageName;
+};
+
+}; // namespace android
+
+#endif  // ANDROID_AUDIO_CLIENT_H
diff --git a/include/media/AudioResampler.h b/include/media/AudioResampler.h
index 50e12f4..771f1b8 120000
--- a/include/media/AudioResampler.h
+++ b/include/media/AudioResampler.h
@@ -1 +1 @@
-../../media/libaudioprocessing/include/AudioResampler.h
\ No newline at end of file
+../../media/libaudioprocessing/include/media/AudioResampler.h
\ No newline at end of file
diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h
index 309c23d..ce30a78 120000
--- a/include/media/AudioResamplerPublic.h
+++ b/include/media/AudioResamplerPublic.h
@@ -1 +1 @@
-../../media/libaudioprocessing/include/AudioResamplerPublic.h
\ No newline at end of file
+../../media/libaudioprocessing/include/media/AudioResamplerPublic.h
\ No newline at end of file
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
deleted file mode 100644
index 726f1ce..0000000
--- a/include/media/CasImpl.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAS_IMPL_H_
-#define CAS_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnCas.h>
-
-namespace android {
-namespace media {
-class ICasListener;
-}
-using namespace media;
-using namespace MediaCas;
-using binder::Status;
-struct CasPlugin;
-class SharedLibrary;
-
-class CasImpl : public BnCas {
-public:
-    CasImpl(const sp<ICasListener> &listener);
-    virtual ~CasImpl();
-
-    static void OnEvent(
-            void *appData,
-            int32_t event,
-            int32_t arg,
-            uint8_t *data,
-            size_t size);
-
-    void init(const sp<SharedLibrary>& library, CasPlugin *plugin);
-    void onEvent(
-            int32_t event,
-            int32_t arg,
-            uint8_t *data,
-            size_t size);
-
-    // ICas inherits
-
-    virtual Status setPrivateData(
-            const CasData& pvtData) override;
-
-    virtual Status openSession(CasSessionId* _aidl_return) override;
-
-    virtual Status closeSession(const CasSessionId& sessionId) override;
-
-    virtual Status setSessionPrivateData(
-            const CasSessionId& sessionId,
-            const CasData& pvtData) override;
-
-    virtual Status processEcm(
-            const CasSessionId& sessionId, const ParcelableCasData& ecm) override;
-
-    virtual Status processEmm(const ParcelableCasData& emm) override;
-
-    virtual Status sendEvent(
-            int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) override;
-
-    virtual Status provision(const String16& provisionString) override;
-
-    virtual Status refreshEntitlements(
-            int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) override;
-
-    virtual Status release() override;
-
-private:
-    struct PluginHolder;
-    sp<SharedLibrary> mLibrary;
-    sp<PluginHolder> mPluginHolder;
-    sp<ICasListener> mListener;
-
-    DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
-};
-
-} // namespace android
-
-#endif // CAS_IMPL_H_
diff --git a/include/media/DescramblerImpl.h b/include/media/DescramblerImpl.h
deleted file mode 100644
index 9f212ac..0000000
--- a/include/media/DescramblerImpl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DESCRAMBLER_IMPL_H_
-#define DESCRAMBLER_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnDescrambler.h>
-
-namespace android {
-using namespace media;
-using namespace MediaDescrambler;
-using binder::Status;
-struct DescramblerPlugin;
-class SharedLibrary;
-
-class DescramblerImpl : public BnDescrambler {
-public:
-    DescramblerImpl(const sp<SharedLibrary>& library, DescramblerPlugin *plugin);
-    virtual ~DescramblerImpl();
-
-    virtual Status setMediaCasSession(
-            const CasSessionId& sessionId) override;
-
-    virtual Status requiresSecureDecoderComponent(
-            const String16& mime, bool *result) override;
-
-    virtual Status descramble(
-            const DescrambleInfo& descrambleInfo, int32_t *result) override;
-
-    virtual Status release() override;
-
-private:
-    sp<SharedLibrary> mLibrary;
-    DescramblerPlugin *mPlugin;
-
-    DISALLOW_EVIL_CONSTRUCTORS(DescramblerImpl);
-};
-
-} // namespace android
-
-#endif // DESCRAMBLER_IMPL_H_
diff --git a/include/media/MediaCasDefs.h b/include/media/MediaCasDefs.h
deleted file mode 100644
index 8c5a967..0000000
--- a/include/media/MediaCasDefs.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_DEFS_H_
-#define MEDIA_CAS_DEFS_H_
-
-#include <binder/Parcel.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-class IMemory;
-namespace media {
-
-namespace MediaCas {
-class ParcelableCasData : public CasData,
-                          public Parcelable {
-public:
-    ParcelableCasData() {}
-    ParcelableCasData(const uint8_t *data, size_t size) :
-        CasData(data, data + size) {}
-    virtual ~ParcelableCasData() {}
-    status_t readFromParcel(const Parcel* parcel) override;
-    status_t writeToParcel(Parcel* parcel) const override;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasData);
-};
-
-class ParcelableCasPluginDescriptor : public Parcelable {
-public:
-    ParcelableCasPluginDescriptor(int32_t CA_system_id, const char *name)
-        : mCASystemId(CA_system_id), mName(name) {}
-
-    ParcelableCasPluginDescriptor() : mCASystemId(0) {}
-
-    ParcelableCasPluginDescriptor(ParcelableCasPluginDescriptor&& desc) = default;
-
-    virtual ~ParcelableCasPluginDescriptor() {}
-
-    status_t readFromParcel(const Parcel* parcel) override;
-    status_t writeToParcel(Parcel* parcel) const override;
-
-private:
-    int32_t mCASystemId;
-    String16 mName;
-    DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasPluginDescriptor);
-};
-}
-
-namespace MediaDescrambler {
-class DescrambleInfo : public Parcelable {
-public:
-    enum DestinationType {
-        kDestinationTypeVmPointer,    // non-secure
-        kDestinationTypeNativeHandle  // secure
-    };
-
-    DestinationType dstType;
-    DescramblerPlugin::ScramblingControl scramblingControl;
-    size_t numSubSamples;
-    DescramblerPlugin::SubSample *subSamples;
-    sp<IMemory> srcMem;
-    int32_t srcOffset;
-    void *dstPtr;
-    int32_t dstOffset;
-
-    DescrambleInfo();
-    virtual ~DescrambleInfo();
-    status_t readFromParcel(const Parcel* parcel) override;
-    status_t writeToParcel(Parcel* parcel) const override;
-
-private:
-
-    DISALLOW_EVIL_CONSTRUCTORS(DescrambleInfo);
-};
-}
-
-} // namespace media
-} // namespace android
-
-
-#endif // MEDIA_CAS_DEFS_H_
diff --git a/include/media/PluginMetricsReporting.h b/include/media/PluginMetricsReporting.h
new file mode 120000
index 0000000..7d9a7a0
--- /dev/null
+++ b/include/media/PluginMetricsReporting.h
@@ -0,0 +1 @@
+../../media/libmedia/include/media/PluginMetricsReporting.h
\ No newline at end of file
diff --git a/include/media/audiohal b/include/media/audiohal
index 37e2c39..f400582 120000
--- a/include/media/audiohal
+++ b/include/media/audiohal
@@ -1 +1 @@
-../../media/libaudiohal/include
\ No newline at end of file
+../../media/libaudiohal/include/media/audiohal/
\ No newline at end of file
diff --git a/include/media/nbaio b/include/media/nbaio
deleted file mode 120000
index 67d0ba6..0000000
--- a/include/media/nbaio
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libnbaio/include
\ No newline at end of file
diff --git a/include/media/nbaio/AudioBufferProviderSource.h b/include/media/nbaio/AudioBufferProviderSource.h
new file mode 120000
index 0000000..55841e7
--- /dev/null
+++ b/include/media/nbaio/AudioBufferProviderSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h
new file mode 120000
index 0000000..f5bcc76
--- /dev/null
+++ b/include/media/nbaio/AudioStreamInSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioStreamInSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h
new file mode 120000
index 0000000..43bfac5
--- /dev/null
+++ b/include/media/nbaio/AudioStreamOutSink.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSink.h b/include/media/nbaio/LibsndfileSink.h
new file mode 120000
index 0000000..8a13b6c
--- /dev/null
+++ b/include/media/nbaio/LibsndfileSink.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/LibsndfileSink.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSource.h b/include/media/nbaio/LibsndfileSource.h
new file mode 120000
index 0000000..2750fde
--- /dev/null
+++ b/include/media/nbaio/LibsndfileSource.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/LibsndfileSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h
new file mode 120000
index 0000000..4ea43be
--- /dev/null
+++ b/include/media/nbaio/MonoPipe.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/MonoPipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipeReader.h b/include/media/nbaio/MonoPipeReader.h
new file mode 120000
index 0000000..30f426c
--- /dev/null
+++ b/include/media/nbaio/MonoPipeReader.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h
new file mode 120000
index 0000000..ff6a151
--- /dev/null
+++ b/include/media/nbaio/NBAIO.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/NBAIO.h
\ No newline at end of file
diff --git a/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h
new file mode 120000
index 0000000..c35401e
--- /dev/null
+++ b/include/media/nbaio/NBLog.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/NBLog.h
\ No newline at end of file
diff --git a/include/media/nbaio/PerformanceAnalysis.h b/include/media/nbaio/PerformanceAnalysis.h
new file mode 120000
index 0000000..7acfc90
--- /dev/null
+++ b/include/media/nbaio/PerformanceAnalysis.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
\ No newline at end of file
diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h
new file mode 120000
index 0000000..a4bbbc9
--- /dev/null
+++ b/include/media/nbaio/Pipe.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/Pipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/PipeReader.h b/include/media/nbaio/PipeReader.h
new file mode 120000
index 0000000..64b21cf
--- /dev/null
+++ b/include/media/nbaio/PipeReader.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/PipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h
new file mode 120000
index 0000000..74a3b06
--- /dev/null
+++ b/include/media/nbaio/SourceAudioBufferProvider.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 9da5ef3..ff440bc 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -568,6 +568,9 @@
     // which may include non-contiguous frames
     virtual size_t      framesReady();
 
+    // Safe frames ready query used by dump() - this has no side effects.
+    virtual size_t      framesReadySafe() const;
+
     // Currently AudioFlinger will call framesReady() for a fast track from two threads:
     // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
     // to be called from at most one thread of server, and one thread of client.
@@ -620,6 +623,7 @@
 
 public:
     virtual size_t      framesReady();
+    virtual size_t      framesReadySafe() const override;
     virtual void        framesReadyIsCalledByMultipleThreads();
     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
     virtual void        releaseBuffer(Buffer* buffer);
diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h
index 51050cd..a9d4dd1 100644
--- a/include/private/media/VideoFrame.h
+++ b/include/private/media/VideoFrame.h
@@ -30,14 +30,41 @@
 class VideoFrame
 {
 public:
-    VideoFrame(): mWidth(0), mHeight(0), mDisplayWidth(0), mDisplayHeight(0), mSize(0),
-            mRotationAngle(0), mData(0) {}
+    // Construct a VideoFrame object with the specified parameters,
+    // will allocate frame buffer if |allocate| is set to true, will
+    // allocate buffer to hold ICC data if |iccData| and |iccSize|
+    // indicate its presence.
+    VideoFrame(uint32_t width, uint32_t height,
+            uint32_t displayWidth, uint32_t displayHeight,
+            uint32_t angle, uint32_t bpp, bool allocate,
+            const void *iccData, size_t iccSize):
+        mWidth(width), mHeight(height),
+        mDisplayWidth(displayWidth), mDisplayHeight(displayHeight),
+        mRotationAngle(angle), mBytesPerPixel(bpp), mRowBytes(bpp * width),
+        mSize(0), mIccSize(0), mReserved(0), mData(0), mIccData(0) {
+        if (allocate) {
+            mSize = mRowBytes * mHeight;
+            mData = new uint8_t[mSize];
+            if (mData == NULL) {
+                mSize = 0;
+            }
+        }
 
+        if (iccData != NULL && iccSize > 0) {
+            mIccSize = iccSize;
+            mIccData = new uint8_t[iccSize];
+            if (mIccData != NULL) {
+                memcpy(mIccData, iccData, iccSize);
+            } else {
+                mIccSize = 0;
+            }
+        }
+    }
+
+    // Deep copy of both the information fields and the frame data
     VideoFrame(const VideoFrame& copy) {
-        mWidth = copy.mWidth;
-        mHeight = copy.mHeight;
-        mDisplayWidth = copy.mDisplayWidth;
-        mDisplayHeight = copy.mDisplayHeight;
+        copyInfoOnly(copy);
+
         mSize = copy.mSize;
         mData = NULL;  // initialize it first
         if (mSize > 0 && copy.mData != NULL) {
@@ -48,26 +75,99 @@
                 mSize = 0;
             }
         }
-        mRotationAngle = copy.mRotationAngle;
+
+        mIccSize = copy.mIccSize;
+        mIccData = NULL;  // initialize it first
+        if (mIccSize > 0 && copy.mIccData != NULL) {
+            mIccData = new uint8_t[mIccSize];
+            if (mIccData != NULL) {
+                memcpy(mIccData, copy.mIccData, mIccSize);
+            } else {
+                mIccSize = 0;
+            }
+        }
     }
 
     ~VideoFrame() {
         if (mData != 0) {
             delete[] mData;
         }
+        if (mIccData != 0) {
+            delete[] mIccData;
+        }
+    }
+
+    // Copy |copy| to a flattened VideoFrame in IMemory, 'this' must point to
+    // a chunk of memory back by IMemory of size at least getFlattenedSize()
+    // of |copy|.
+    void copyFlattened(const VideoFrame& copy) {
+        copyInfoOnly(copy);
+
+        mSize = copy.mSize;
+        mData = NULL;  // initialize it first
+        if (copy.mSize > 0 && copy.mData != NULL) {
+            memcpy(getFlattenedData(), copy.mData, copy.mSize);
+        }
+
+        mIccSize = copy.mIccSize;
+        mIccData = NULL;  // initialize it first
+        if (copy.mIccSize > 0 && copy.mIccData != NULL) {
+            memcpy(getFlattenedIccData(), copy.mIccData, copy.mIccSize);
+        }
+    }
+
+    // Calculate the flattened size to put it in IMemory
+    size_t getFlattenedSize() const {
+        return sizeof(VideoFrame) + mSize + mIccSize;
+    }
+
+    // Get the pointer to the frame data in a flattened VideoFrame in IMemory
+    uint8_t* getFlattenedData() const {
+        return (uint8_t*)this + sizeof(VideoFrame);
+    }
+
+    // Get the pointer to the ICC data in a flattened VideoFrame in IMemory
+    uint8_t* getFlattenedIccData() const {
+        return (uint8_t*)this + sizeof(VideoFrame) + mSize;
     }
 
     // Intentional public access modifier:
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mDisplayWidth;
-    uint32_t mDisplayHeight;
+    uint32_t mWidth;           // Decoded image width before rotation
+    uint32_t mHeight;          // Decoded image height before rotation
+    uint32_t mDisplayWidth;    // Display width before rotation
+    uint32_t mDisplayHeight;   // Display height before rotation
+    int32_t  mRotationAngle;   // Rotation angle, clockwise, should be multiple of 90
+    uint32_t mBytesPerPixel;   // Number of bytes per pixel
+    uint32_t mRowBytes;        // Number of bytes per row before rotation
     uint32_t mSize;            // Number of bytes in mData
-    int32_t  mRotationAngle;   // rotation angle, clockwise, should be multiple of 90
-    // mData should be 64 bit aligned to prevent additional padding
+    uint32_t mIccSize;         // Number of bytes in mIccData
+    uint32_t mReserved;        // (padding to make mData 64-bit aligned)
+
+    // mData should be 64-bit aligned to prevent additional padding
     uint8_t* mData;            // Actual binary data
-    // pad structure so it's the same size on 64 bit and 32 bit
+    // pad structure so it's the same size on 64-bit and 32-bit
     char     mPadding[8 - sizeof(mData)];
+
+    // mIccData should be 64-bit aligned to prevent additional padding
+    uint8_t* mIccData;            // Actual binary data
+    // pad structure so it's the same size on 64-bit and 32-bit
+    char     mIccPadding[8 - sizeof(mIccData)];
+
+private:
+    //
+    // Utility methods used only within VideoFrame struct
+    //
+
+    // Copy the information fields only
+    void copyInfoOnly(const VideoFrame& copy) {
+        mWidth = copy.mWidth;
+        mHeight = copy.mHeight;
+        mDisplayWidth = copy.mDisplayWidth;
+        mDisplayHeight = copy.mDisplayHeight;
+        mRotationAngle = copy.mRotationAngle;
+        mBytesPerPixel = copy.mBytesPerPixel;
+        mRowBytes = copy.mRowBytes;
+    }
 };
 
 }; // namespace android
diff --git a/include/radio/IRadio.h b/include/radio/IRadio.h
deleted file mode 100644
index 1877f8f..0000000
--- a/include/radio/IRadio.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_H
-#define ANDROID_HARDWARE_IRADIO_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <system/radio.h>
-
-namespace android {
-
-class IRadio : public IInterface
-{
-public:
-
-    DECLARE_META_INTERFACE(Radio);
-
-    virtual void detach() = 0;
-
-    virtual status_t setConfiguration(const struct radio_band_config *config) = 0;
-
-    virtual status_t getConfiguration(struct radio_band_config *config) = 0;
-
-    virtual status_t setMute(bool mute) = 0;
-
-    virtual status_t getMute(bool *mute) = 0;
-
-    virtual status_t step(radio_direction_t direction, bool skipSubChannel) = 0;
-
-    virtual status_t scan(radio_direction_t direction, bool skipSubChannel) = 0;
-
-    virtual status_t tune(unsigned int channel, unsigned int subChannel) = 0;
-
-    virtual status_t cancel() = 0;
-
-    virtual status_t getProgramInformation(struct radio_program_info *info) = 0;
-
-    virtual status_t hasControl(bool *hasControl) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadio: public BnInterface<IRadio>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_H
diff --git a/include/radio/IRadioClient.h b/include/radio/IRadioClient.h
deleted file mode 100644
index 9062ad6..0000000
--- a/include/radio/IRadioClient.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_CLIENT_H
-#define ANDROID_HARDWARE_IRADIO_CLIENT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-class IRadioClient : public IInterface
-{
-public:
-
-    DECLARE_META_INTERFACE(RadioClient);
-
-    virtual void onEvent(const sp<IMemory>& eventMemory) = 0;
-
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadioClient : public BnInterface<IRadioClient>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_CLIENT_H
diff --git a/include/radio/IRadioService.h b/include/radio/IRadioService.h
deleted file mode 100644
index a946dd5..0000000
--- a/include/radio/IRadioService.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_IRADIO_SERVICE_H
-#define ANDROID_HARDWARE_IRADIO_SERVICE_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <system/radio.h>
-
-namespace android {
-
-class IRadio;
-class IRadioClient;
-
-class IRadioService : public IInterface
-{
-public:
-
-    DECLARE_META_INTERFACE(RadioService);
-
-    virtual status_t listModules(struct radio_properties *properties,
-                                 uint32_t *numModules) = 0;
-
-    virtual status_t attach(const radio_handle_t handle,
-                            const sp<IRadioClient>& client,
-                            const struct radio_band_config *config,
-                            bool withAudio,
-                            sp<IRadio>& radio) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnRadioService: public BnInterface<IRadioService>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_IRADIO_SERVICE_H
diff --git a/include/radio/Radio.h b/include/radio/Radio.h
deleted file mode 100644
index fb4dd2f..0000000
--- a/include/radio/Radio.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_H
-#define ANDROID_HARDWARE_RADIO_H
-
-#include <binder/IBinder.h>
-#include <utils/threads.h>
-#include <radio/RadioCallback.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-
-namespace android {
-
-class MemoryDealer;
-
-class Radio : public BnRadioClient,
-                        public IBinder::DeathRecipient
-{
-public:
-
-    virtual ~Radio();
-
-    static  status_t listModules(struct radio_properties *properties,
-                                 uint32_t *numModules);
-    static  sp<Radio> attach(radio_handle_t handle,
-                             const struct radio_band_config *config,
-                             bool withAudio,
-                             const sp<RadioCallback>& callback);
-
-
-            void detach();
-
-            status_t setConfiguration(const struct radio_band_config *config);
-
-            status_t getConfiguration(struct radio_band_config *config);
-
-            status_t setMute(bool mute);
-
-            status_t getMute(bool *mute);
-
-            status_t step(radio_direction_t direction, bool skipSubChannel);
-
-            status_t scan(radio_direction_t direction, bool skipSubChannel);
-
-            status_t tune(unsigned int channel, unsigned int subChannel);
-
-            status_t cancel();
-
-            status_t getProgramInformation(struct radio_program_info *info);
-
-            status_t hasControl(bool *hasControl);
-
-            // BpRadioClient
-            virtual void onEvent(const sp<IMemory>& eventMemory);
-
-            //IBinder::DeathRecipient
-            virtual void binderDied(const wp<IBinder>& who);
-
-private:
-            Radio(radio_handle_t handle,
-                            const sp<RadioCallback>&);
-            static const sp<IRadioService> getRadioService();
-
-            Mutex                   mLock;
-            sp<IRadio>              mIRadio;
-            sp<RadioCallback>       mCallback;
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_RADIO_H
diff --git a/include/radio/RadioCallback.h b/include/radio/RadioCallback.h
deleted file mode 100644
index 4a7f1a6..0000000
--- a/include/radio/RadioCallback.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_CALLBACK_H
-#define ANDROID_HARDWARE_RADIO_CALLBACK_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class RadioCallback : public RefBase
-{
-public:
-
-            RadioCallback() {}
-    virtual ~RadioCallback() {}
-
-    virtual void onEvent(struct radio_event *event) = 0;
-
-};
-
-}; // namespace android
-
-#endif //ANDROID_HARDWARE_RADIO_CALLBACK_H
diff --git a/media/OWNERS b/media/OWNERS
new file mode 100644
index 0000000..1605efd
--- /dev/null
+++ b/media/OWNERS
@@ -0,0 +1,18 @@
+chz@google.com
+dwkang@google.com
+elaurent@google.com
+essick@google.com
+hunga@google.com
+jmtrivi@google.com
+krocard@google.com
+lajos@google.com
+marcone@google.com
+mnaganov@google.com
+pawin@google.com
+philburk@google.com
+pmclean@google.com
+rachad@google.com
+rago@google.com
+robertshih@google.com
+wjia@google.com
+wonsik@google.com
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index afd1189..3ee7494 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -14,7 +14,6 @@
 	liblog \
 	libmedialogservice \
 	libnbaio \
-	libradioservice \
 	libsoundtriggerservice \
 	libutils \
 	libhwbinder
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index ee02d23..34c629b 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -36,7 +36,6 @@
 #include "AudioPolicyService.h"
 #include "AAudioService.h"
 #include "MediaLogService.h"
-#include "RadioService.h"
 #include "SoundTriggerHwService.h"
 
 using namespace android;
@@ -133,7 +132,6 @@
         AudioFlinger::instantiate();
         AudioPolicyService::instantiate();
         AAudioService::instantiate();
-        RadioService::instantiate();
         SoundTriggerHwService::instantiate();
         ProcessState::self()->startThreadPool();
 
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index f539ba9..6e60f24 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -16,12 +16,14 @@
     name: "libAAudio_headers",
     from: "include",
     to: "",
-    srcs: ["include/aaudio/*.h"],
+    // omit AAudioTesting.h; supplied separately to those who need it
+    srcs: ["include/aaudio/AAudio.h"],
     license: "include/aaudio/NOTICE",
 }
 
 ndk_library {
     name: "libaaudio",
+    // deliberately includes symbols from AAudioTesting.h
     symbol_file: "libaaudio.map.txt",
     first_version: "26",
     unversioned_until: "current",
diff --git a/media/libaaudio/OWNERS b/media/libaaudio/OWNERS
new file mode 100644
index 0000000..f4d51f9
--- /dev/null
+++ b/media/libaaudio/OWNERS
@@ -0,0 +1 @@
+philburk@google.com
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index 910b10c..2dfd0a7 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -27,9 +27,11 @@
 #include "AAudioSimpleRecorder.h"
 
 // TODO support FLOAT
-#define REQUIRED_FORMAT  AAUDIO_FORMAT_PCM_I16
+#define REQUIRED_FORMAT    AAUDIO_FORMAT_PCM_I16
 #define MIN_FRAMES_TO_READ 48  /* arbitrary, 1 msec at 48000 Hz */
 
+static const int FRAMES_PER_LINE = 20000;
+
 int main(int argc, const char **argv)
 {
     AAudioArgsParser   argParser;
@@ -46,7 +48,10 @@
     int32_t framesPerRead = 0;
     int32_t framesToRecord = 0;
     int32_t framesLeft = 0;
+    int32_t nextFrameCount = 0;
+    int32_t frameCount = 0;
     int32_t xRunCount = 0;
+    int64_t previousFramePosition = -1;
     int16_t *data = nullptr;
     float peakLevel = 0.0;
     int loopCounter = 0;
@@ -56,7 +61,7 @@
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Monitor input level using AAudio\n", argv[0]);
+    printf("%s - Monitor input level using AAudio V0.1.1\n", argv[0]);
 
     argParser.setFormat(REQUIRED_FORMAT);
     if (argParser.parseArgs(argc, argv)) {
@@ -74,7 +79,7 @@
     deviceId = AAudioStream_getDeviceId(aaudioStream);
     printf("deviceId = %d\n", deviceId);
 
-    actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream);
+    actualSamplesPerFrame = AAudioStream_getChannelCount(aaudioStream);
     printf("SamplesPerFrame = %d\n", actualSamplesPerFrame);
     actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
     printf("SamplesPerFrame = %d\n", actualSampleRate);
@@ -133,6 +138,7 @@
             goto finish;
         }
         framesLeft -= actual;
+        frameCount += actual;
 
         // Peak finder.
         for (int frameIndex = 0; frameIndex < actual; frameIndex++) {
@@ -143,9 +149,36 @@
         }
 
         // Display level as stars, eg. "******".
-        if ((loopCounter++ % 10) == 0) {
+        if (frameCount > nextFrameCount) {
             displayPeakLevel(peakLevel);
             peakLevel = 0.0;
+            nextFrameCount += FRAMES_PER_LINE;
+        }
+
+        // Print timestamps.
+        int64_t framePosition = 0;
+        int64_t frameTime = 0;
+        aaudio_result_t timeResult;
+        timeResult = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
+                                               &framePosition, &frameTime);
+
+        if (timeResult == AAUDIO_OK) {
+            if (framePosition > (previousFramePosition + FRAMES_PER_LINE)) {
+                int64_t realTime = getNanoseconds();
+                int64_t framesRead = AAudioStream_getFramesRead(aaudioStream);
+
+                double latencyMillis = calculateLatencyMillis(framesRead, realTime,
+                                                              framePosition, frameTime,
+                                                              actualSampleRate);
+
+                printf("--- timestamp: result = %4d, position = %lld, at %lld nanos"
+                               ", latency = %7.2f msec\n",
+                       timeResult,
+                       (long long) framePosition,
+                       (long long) frameTime,
+                       latencyMillis);
+                previousFramePosition = framePosition;
+            }
         }
     }
 
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index 144c941..df0df04 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -417,11 +417,18 @@
             sleep(1);
             printf("%4d: ", i);
             loopbackData.loopbackProcessor->printStatus();
-            int64_t framesWritten = AAudioStream_getFramesWritten(loopbackData.inputStream);
-            int64_t framesRead = AAudioStream_getFramesRead(loopbackData.inputStream);
-            printf(" input written = %lld, read %lld, xruns = %d\n",
-                   (long long) framesWritten,
-                   (long long) framesRead,
+
+            int64_t inputFramesWritten = AAudioStream_getFramesWritten(loopbackData.inputStream);
+            int64_t inputFramesRead = AAudioStream_getFramesRead(loopbackData.inputStream);
+            int64_t outputFramesWritten = AAudioStream_getFramesWritten(outputStream);
+            int64_t outputFramesRead = AAudioStream_getFramesRead(outputStream);
+            printf(" INPUT: wr %lld rd %lld state %s, OUTPUT: wr %lld rd %lld state %s, xruns %d\n",
+                   (long long) inputFramesWritten,
+                   (long long) inputFramesRead,
+                   AAudio_convertStreamStateToText(AAudioStream_getState(loopbackData.inputStream)),
+                   (long long) outputFramesWritten,
+                   (long long) outputFramesRead,
+                   AAudio_convertStreamStateToText(AAudioStream_getState(outputStream)),
                    AAudioStream_getXRunCount(outputStream)
             );
         }
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index 46bc99e..30c3ccd 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -24,7 +24,8 @@
 
 #include <aaudio/AAudio.h>
 #include <aaudio/AAudioTesting.h>
-#include <AAudioExampleUtils.h>
+
+#include "AAudioExampleUtils.h"
 
 // TODO use this as a base class within AAudio
 class AAudioParameters {
@@ -239,7 +240,7 @@
      * Print stream parameters in comparison with requested values.
      * @param stream
      */
-    void compareWithStream(AAudioStream *stream) {
+    void compareWithStream(AAudioStream *stream) const {
 
         printf("  DeviceId:     requested = %d, actual = %d\n",
                getDeviceId(), AAudioStream_getDeviceId(stream));
diff --git a/media/libaaudio/examples/utils/AAudioExampleUtils.h b/media/libaaudio/examples/utils/AAudioExampleUtils.h
index 66de25f..6cbcc58 100644
--- a/media/libaaudio/examples/utils/AAudioExampleUtils.h
+++ b/media/libaaudio/examples/utils/AAudioExampleUtils.h
@@ -25,7 +25,7 @@
 #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
 #define NANOS_PER_SECOND      (NANOS_PER_MILLISECOND * 1000)
 
-static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
+const char *getSharingModeText(aaudio_sharing_mode_t mode) {
     const char *modeText = "unknown";
     switch (mode) {
     case AAUDIO_SHARING_MODE_EXCLUSIVE:
@@ -49,7 +49,7 @@
     return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec;
 }
 
-void displayPeakLevel(float peakLevel) {
+static void displayPeakLevel(float peakLevel) {
     printf("%5.3f ", peakLevel);
     const int maxStars = 50; // arbitrary, fits on one line
     int numStars = (int) (peakLevel * maxStars);
@@ -59,4 +59,24 @@
     printf("\n");
 }
 
+/**
+ * @param position1 position of hardware frame
+ * @param nanoseconds1
+ * @param position2 position of client read/write
+ * @param nanoseconds2
+ * @param sampleRate
+ * @return latency in milliseconds
+ */
+static double calculateLatencyMillis(int64_t position1, int64_t nanoseconds1,
+                              int64_t position2, int64_t nanoseconds2,
+                              int64_t sampleRate) {
+    int64_t deltaFrames = position2 - position1;
+    int64_t deltaTime =
+            (NANOS_PER_SECOND * deltaFrames / sampleRate);
+    int64_t timeCurrentFramePlayed = nanoseconds1 + deltaTime;
+    int64_t latencyNanos = timeCurrentFramePlayed - nanoseconds2;
+    double latencyMillis = latencyNanos / 1000000.0;
+    return latencyMillis;
+}
+
 #endif // AAUDIO_EXAMPLE_UTILS_H
diff --git a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
index 5ecac04..1344273 100644
--- a/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
+++ b/media/libaaudio/examples/utils/AAudioSimpleRecorder.h
@@ -77,7 +77,7 @@
         if (mStream == nullptr) {
             return AAUDIO_ERROR_INVALID_STATE;
         }
-        return AAudioStream_getChannelCount(mStream);
+        return AAudioStream_getChannelCount(mStream);;
     }
 
     /**
@@ -187,7 +187,7 @@
 
     // Write zero data to fill up the buffer and prevent underruns.
     aaudio_result_t prime() {
-        int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(mStream);
+        int32_t samplesPerFrame = AAudioStream_getChannelCount(mStream);
         const int numFrames = 32; // arbitrary
         float zeros[numFrames * samplesPerFrame];
         memset(zeros, 0, sizeof(zeros));
@@ -260,7 +260,7 @@
     }
     PeakTrackerData_t *data = (PeakTrackerData_t *) userData;
     // printf("MyCallbackProc(): frameCount = %d\n", numFrames);
-    int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(stream);
+    int32_t samplesPerFrame = AAudioStream_getChannelCount(stream);
     float sample;
     // This code assume mono or stereo.
     switch (AAudioStream_getFormat(stream)) {
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index e1886ac..3c23736 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -234,10 +234,11 @@
                                                    int32_t channelCount);
 
 /**
+ * Identical to AAudioStreamBuilder_setChannelCount().
  *
- * @deprecated use AAudioStreamBuilder_setChannelCount()
+ * @param builder reference provided by AAudio_createStreamBuilder()
+ * @param samplesPerFrame Number of samples in a frame.
  */
-// TODO remove as soon as the NDK and OS are in sync, before RC1
 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
                                                        int32_t samplesPerFrame);
 
@@ -729,11 +730,10 @@
 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream);
 
 /**
- * The samplesPerFrame is also known as channelCount.
+ * Identical to AAudioStream_getChannelCount().
  *
- * @deprecated use AAudioStream_getChannelCount()
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual samples per frame
+ * @return actual number of samples frame
  */
 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream);
 
@@ -810,7 +810,7 @@
  * The position and time passed back are monotonically increasing.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @param clockid AAUDIO_CLOCK_MONOTONIC or AAUDIO_CLOCK_BOOTTIME
+ * @param clockid CLOCK_MONOTONIC or CLOCK_BOOTTIME
  * @param framePosition pointer to a variable to receive the position
  * @param timeNanoseconds pointer to a variable to receive the time
  * @return AAUDIO_OK or a negative error
diff --git a/media/libaaudio/src/binding/AAudioServiceMessage.h b/media/libaaudio/src/binding/AAudioServiceMessage.h
index b4377fb..54e8001 100644
--- a/media/libaaudio/src/binding/AAudioServiceMessage.h
+++ b/media/libaaudio/src/binding/AAudioServiceMessage.h
@@ -28,7 +28,6 @@
 // Used to send information about the HAL to the client.
 struct AAudioMessageTimestamp {
     int64_t position;     // number of frames transferred so far
-    int64_t deviceOffset; // add to client position to get device position
     int64_t timestamp;    // time when that position was reached
 };
 
@@ -51,7 +50,8 @@
 typedef struct AAudioServiceMessage_s {
     enum class code : uint32_t {
         NOTHING,
-        TIMESTAMP,
+        TIMESTAMP_SERVICE, // when frame is read or written by the service to the client
+        TIMESTAMP_HARDWARE, // when frame is at DAC or ADC
         EVENT,
     };
 
diff --git a/media/libaaudio/src/client/AudioEndpoint.cpp b/media/libaaudio/src/client/AudioEndpoint.cpp
index 6ec285f..3ee450a 100644
--- a/media/libaaudio/src/client/AudioEndpoint.cpp
+++ b/media/libaaudio/src/client/AudioEndpoint.cpp
@@ -32,14 +32,17 @@
 #define RIDICULOUSLY_LARGE_FRAME_SIZE        4096
 
 AudioEndpoint::AudioEndpoint()
-    : mFreeRunning(false)
+    : mUpCommandQueue(nullptr)
+    , mDataQueue(nullptr)
+    , mFreeRunning(false)
     , mDataReadCounter(0)
     , mDataWriteCounter(0)
 {
 }
 
-AudioEndpoint::~AudioEndpoint()
-{
+AudioEndpoint::~AudioEndpoint() {
+    delete mDataQueue;
+    delete mUpCommandQueue;
 }
 
 static aaudio_result_t AudioEndpoint_validateQueueDescriptor(const char *type,
@@ -254,3 +257,7 @@
     ALOGD("AudioEndpoint: data readCounter  = %lld", (long long) mDataQueue->getReadCounter());
     ALOGD("AudioEndpoint: data writeCounter = %lld", (long long) mDataQueue->getWriteCounter());
 }
+
+void AudioEndpoint::eraseDataMemory() {
+    mDataQueue->eraseMemory();
+}
diff --git a/media/libaaudio/src/client/AudioEndpoint.h b/media/libaaudio/src/client/AudioEndpoint.h
index 81a4f7b..f5b67e8 100644
--- a/media/libaaudio/src/client/AudioEndpoint.h
+++ b/media/libaaudio/src/client/AudioEndpoint.h
@@ -86,6 +86,11 @@
 
     int32_t getBufferCapacityInFrames() const;
 
+    /**
+     * Write zeros to the data queue memory.
+     */
+    void eraseDataMemory();
+
     void dump() const;
 
 private:
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 4c7d0f7..41d4909 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -68,6 +68,7 @@
         , mServiceInterface(serviceInterface)
         , mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
         , mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
+        , mAtomicTimestamp()
         {
     ALOGD("AudioStreamInternal(): mWakeupDelayNanos = %d, mMinimumSleepNanos = %d",
           mWakeupDelayNanos, mMinimumSleepNanos);
@@ -240,9 +241,11 @@
     int64_t startTime;
     ALOGD("AudioStreamInternal()::requestStart()");
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+        ALOGE("AudioStreamInternal::requestStart() mServiceStreamHandle invalid");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     if (isActive()) {
+        ALOGE("AudioStreamInternal::requestStart() already active");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     aaudio_stream_state_t originalState = getState();
@@ -319,6 +322,7 @@
 
 aaudio_result_t AudioStreamInternal::registerThread() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+        ALOGE("AudioStreamInternal::registerThread() mServiceStreamHandle invalid");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     return mServiceInterface.registerAudioThread(mServiceStreamHandle,
@@ -328,6 +332,7 @@
 
 aaudio_result_t AudioStreamInternal::unregisterThread() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+        ALOGE("AudioStreamInternal::unregisterThread() mServiceStreamHandle invalid");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     return mServiceInterface.unregisterAudioThread(mServiceStreamHandle, gettid());
@@ -351,15 +356,18 @@
 aaudio_result_t AudioStreamInternal::getTimestamp(clockid_t clockId,
                            int64_t *framePosition,
                            int64_t *timeNanoseconds) {
-    // TODO Generate in server and pass to client. Return latest.
-    int64_t time = AudioClock::getNanoseconds();
-    *framePosition = mClockModel.convertTimeToPosition(time) + mFramesOffsetFromService;
-    // TODO Get a more accurate timestamp from the service. This code just adds a fudge factor.
-    *timeNanoseconds = time + (6 * AAUDIO_NANOS_PER_MILLISECOND);
-    return AAUDIO_OK;
+    // Generated in server and passed to client. Return latest.
+    if (mAtomicTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicTimestamp.read();
+        *framePosition = timestamp.getPosition();
+        *timeNanoseconds = timestamp.getNanoseconds();
+        return AAUDIO_OK;
+    } else {
+        return AAUDIO_ERROR_UNAVAILABLE;
+    }
 }
 
-aaudio_result_t AudioStreamInternal::updateStateWhileWaiting() {
+aaudio_result_t AudioStreamInternal::updateStateMachine() {
     if (isDataCallbackActive()) {
         return AAUDIO_OK; // state is getting updated by the callback thread read/write call
     }
@@ -385,7 +393,7 @@
     oldTime = nanoTime;
 }
 
-aaudio_result_t AudioStreamInternal::onTimestampFromServer(AAudioServiceMessage *message) {
+aaudio_result_t AudioStreamInternal::onTimestampService(AAudioServiceMessage *message) {
 #if LOG_TIMESTAMPS
     logTimestamp(*message);
 #endif
@@ -393,23 +401,29 @@
     return AAUDIO_OK;
 }
 
+aaudio_result_t AudioStreamInternal::onTimestampHardware(AAudioServiceMessage *message) {
+    Timestamp timestamp(message->timestamp.position, message->timestamp.timestamp);
+    mAtomicTimestamp.write(timestamp);
+    return AAUDIO_OK;
+}
+
 aaudio_result_t AudioStreamInternal::onEventFromServer(AAudioServiceMessage *message) {
     aaudio_result_t result = AAUDIO_OK;
     switch (message->event.event) {
         case AAUDIO_SERVICE_EVENT_STARTED:
-            ALOGD("AudioStreamInternal::onEventFromServergot() AAUDIO_SERVICE_EVENT_STARTED");
+            ALOGD("AudioStreamInternal::onEventFromServer() got AAUDIO_SERVICE_EVENT_STARTED");
             if (getState() == AAUDIO_STREAM_STATE_STARTING) {
                 setState(AAUDIO_STREAM_STATE_STARTED);
             }
             break;
         case AAUDIO_SERVICE_EVENT_PAUSED:
-            ALOGD("AudioStreamInternal::onEventFromServergot() AAUDIO_SERVICE_EVENT_PAUSED");
+            ALOGD("AudioStreamInternal::onEventFromServer() got AAUDIO_SERVICE_EVENT_PAUSED");
             if (getState() == AAUDIO_STREAM_STATE_PAUSING) {
                 setState(AAUDIO_STREAM_STATE_PAUSED);
             }
             break;
         case AAUDIO_SERVICE_EVENT_STOPPED:
-            ALOGD("AudioStreamInternal::onEventFromServergot() AAUDIO_SERVICE_EVENT_STOPPED");
+            ALOGD("AudioStreamInternal::onEventFromServer() got AAUDIO_SERVICE_EVENT_STOPPED");
             if (getState() == AAUDIO_STREAM_STATE_STOPPING) {
                 setState(AAUDIO_STREAM_STATE_STOPPED);
             }
@@ -426,10 +440,14 @@
             setState(AAUDIO_STREAM_STATE_CLOSED);
             break;
         case AAUDIO_SERVICE_EVENT_DISCONNECTED:
+            // Prevent hardware from looping on old data and making buzzing sounds.
+            if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
+                mAudioEndpoint.eraseDataMemory();
+            }
             result = AAUDIO_ERROR_DISCONNECTED;
             setState(AAUDIO_STREAM_STATE_DISCONNECTED);
             ALOGW("WARNING - AudioStreamInternal::onEventFromServer()"
-                          " AAUDIO_SERVICE_EVENT_DISCONNECTED");
+                          " AAUDIO_SERVICE_EVENT_DISCONNECTED - FIFO cleared");
             break;
         case AAUDIO_SERVICE_EVENT_VOLUME:
             mStreamVolume = (float)message->event.dataDouble;
@@ -456,8 +474,12 @@
             break; // no command this time, no problem
         }
         switch (message.what) {
-        case AAudioServiceMessage::code::TIMESTAMP:
-            result = onTimestampFromServer(&message);
+        case AAudioServiceMessage::code::TIMESTAMP_SERVICE:
+            result = onTimestampService(&message);
+            break;
+
+        case AAudioServiceMessage::code::TIMESTAMP_HARDWARE:
+            result = onTimestampHardware(&message);
             break;
 
         case AAudioServiceMessage::code::EVENT:
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 1b991de..13cf16c 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -50,7 +50,7 @@
                                        int64_t *framePosition,
                                        int64_t *timeNanoseconds) override;
 
-    virtual aaudio_result_t updateStateWhileWaiting() override;
+    virtual aaudio_result_t updateStateMachine() override;
 
     aaudio_result_t open(const AudioStreamBuilder &builder) override;
 
@@ -122,7 +122,9 @@
 
     aaudio_result_t onEventFromServer(AAudioServiceMessage *message);
 
-    aaudio_result_t onTimestampFromServer(AAudioServiceMessage *message);
+    aaudio_result_t onTimestampService(AAudioServiceMessage *message);
+
+    aaudio_result_t onTimestampHardware(AAudioServiceMessage *message);
 
     void logTimestamp(AAudioServiceMessage &message);
 
@@ -181,6 +183,11 @@
 
     AudioEndpointParcelable  mEndPointParcelable; // description of the buffers filled by service
     EndpointDescriptor       mEndpointDescriptor; // buffer description with resolved addresses
+
+    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
+
+    int64_t                  mServiceLatencyNanos = 0;
+
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/client/IsochronousClockModel.cpp b/media/libaaudio/src/client/IsochronousClockModel.cpp
index 4d0a7b8..c06c8a9 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.cpp
+++ b/media/libaaudio/src/client/IsochronousClockModel.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "AAudio"
 //#define LOG_NDEBUG 0
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include <stdint.h>
 
@@ -25,7 +25,6 @@
 
 #define MIN_LATENESS_NANOS (10 * AAUDIO_NANOS_PER_MICROSECOND)
 
-using namespace android;
 using namespace aaudio;
 
 IsochronousClockModel::IsochronousClockModel()
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 3f5de77..5089b00 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -101,7 +101,6 @@
  */
 static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED;
 
-
 static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
 {
     return (AudioStream*) stream;
@@ -144,17 +143,16 @@
 }
 
 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
-                                                       int32_t channelCount)
+                                                    int32_t channelCount)
 {
     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
     streamBuilder->setSamplesPerFrame(channelCount);
 }
 
 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
-                                                       int32_t samplesPerFrame)
+                                                       int32_t channelCount)
 {
-    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
-    streamBuilder->setSamplesPerFrame(samplesPerFrame);
+    AAudioStreamBuilder_setChannelCount(builder, channelCount);
 }
 
 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
@@ -255,7 +253,7 @@
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
     ALOGD("AAudioStream_requestStart(%p) called --------------", stream);
     aaudio_result_t result = audioStream->requestStart();
-    ALOGD("AAudioStream_requestStart(%p) returned ------------", stream);
+    ALOGD("AAudioStream_requestStart(%p) returned %d ---------", stream, result);
     return result;
 }
 
@@ -359,8 +357,7 @@
 
 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
 {
-    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
-    return audioStream->getSamplesPerFrame();
+    return AAudioStream_getChannelCount(stream);
 }
 
 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 4859c69..4f1cc37 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -98,7 +98,7 @@
                                                 aaudio_stream_state_t *nextState,
                                                 int64_t timeoutNanoseconds)
 {
-    aaudio_result_t result = updateStateWhileWaiting();
+    aaudio_result_t result = updateStateMachine();
     if (result != AAUDIO_OK) {
         return result;
     }
@@ -112,7 +112,7 @@
         AudioClock::sleepForNanos(durationNanos);
         timeoutNanoseconds -= durationNanos;
 
-        aaudio_result_t result = updateStateWhileWaiting();
+        aaudio_result_t result = updateStateMachine();
         if (result != AAUDIO_OK) {
             return result;
         }
@@ -153,6 +153,7 @@
                                      void* threadArg)
 {
     if (mHasThread) {
+        ALOGE("AudioStream::createThread() - mHasThread already true");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     if (threadProc == nullptr) {
@@ -174,6 +175,7 @@
 aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds)
 {
     if (!mHasThread) {
+        ALOGE("AudioStream::joinThread() - but has no thread");
         return AAUDIO_ERROR_INVALID_STATE;
     }
 #if 0
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index e5fdcc6..ad18751 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -68,10 +68,10 @@
 
 
     /**
-     * Update state while in the middle of waitForStateChange()
+     * Update state machine.()
      * @return
      */
-    virtual aaudio_result_t updateStateWhileWaiting() = 0;
+    virtual aaudio_result_t updateStateMachine() = 0;
 
 
     // =========== End ABSTRACT methods ===========================
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index 8d2c62d..a869886 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -210,3 +210,9 @@
     return mFifo->getCapacity();
 }
 
+void FifoBuffer::eraseMemory() {
+    int32_t numBytes = convertFramesToBytes(getBufferCapacityInFrames());
+    if (numBytes > 0) {
+        memset(mStorage, 0, (size_t) numBytes);
+    }
+}
diff --git a/media/libaaudio/src/fifo/FifoBuffer.h b/media/libaaudio/src/fifo/FifoBuffer.h
index a94e9b0..f5a9e27 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.h
+++ b/media/libaaudio/src/fifo/FifoBuffer.h
@@ -111,6 +111,11 @@
         mFifo->setWriteCounter(n);
     }
 
+    /*
+     * This is generally only called before or after the buffer is used.
+     */
+    void eraseMemory();
+
 private:
 
     void fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index dd5e3c0..2816bac 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -94,12 +94,15 @@
                 } else {
                     audioBuffer->size = 0;
                 }
-                break;
+
+                if (updateStateMachine() == AAUDIO_OK) {
+                    break; // don't fall through
+                }
             }
         }
         /// FALL THROUGH
 
-            // Stream got rerouted so we disconnect.
+        // Stream got rerouted so we disconnect.
         case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: {
             setState(AAUDIO_STREAM_STATE_DISCONNECTED);
             ALOGD("processCallbackCommon() stream disconnected");
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 8e8070c..041280d 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -159,6 +159,9 @@
         actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
     }
     setPerformanceMode(actualPerformanceMode);
+
+    setSharingMode(AAUDIO_SHARING_MODE_SHARED); // EXCLUSIVE mode not supported in legacy
+
     // Log warning if we did not get what we asked for.
     ALOGW_IF(actualFlags != flags,
              "AudioStreamRecord::open() flags changed from 0x%08X to 0x%08X",
@@ -207,7 +210,7 @@
     if (mAudioRecord.get() == nullptr) {
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    // Get current position so we can detect when the track is playing.
+    // Get current position so we can detect when the track is recording.
     status_t err = mAudioRecord->getPosition(&mPositionWhenStarting);
     if (err != OK) {
         return AAudioConvert_androidToAAudioResult(err);
@@ -235,7 +238,7 @@
     return AAUDIO_OK;
 }
 
-aaudio_result_t AudioStreamRecord::updateStateWhileWaiting()
+aaudio_result_t AudioStreamRecord::updateStateMachine()
 {
     aaudio_result_t result = AAUDIO_OK;
     aaudio_wrapping_frames_t position;
@@ -292,6 +295,12 @@
     }
     int32_t framesRead = (int32_t)(bytesRead / bytesPerFrame);
     incrementFramesRead(framesRead);
+
+    result = updateStateMachine();
+    if (result != AAUDIO_OK) {
+        return result;
+    }
+
     return (aaudio_result_t) framesRead;
 }
 
@@ -330,3 +339,21 @@
     }
     return getBestTimestamp(clockId, framePosition, timeNanoseconds, &extendedTimestamp);
 }
+
+int64_t AudioStreamRecord::getFramesWritten() {
+    aaudio_wrapping_frames_t position;
+    status_t result;
+    switch (getState()) {
+        case AAUDIO_STREAM_STATE_STARTING:
+        case AAUDIO_STREAM_STATE_STARTED:
+        case AAUDIO_STREAM_STATE_STOPPING:
+            result = mAudioRecord->getPosition(&position);
+            if (result == OK) {
+                mFramesWritten.update32(position);
+            }
+            break;
+        default:
+            break;
+    }
+    return AudioStreamLegacy::getFramesWritten();
+}
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.h b/media/libaaudio/src/legacy/AudioStreamRecord.h
index 2c6a7eb..c1723ba 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.h
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.h
@@ -59,9 +59,11 @@
 
     int32_t getXRunCount() const override;
 
+    int64_t getFramesWritten() override;
+
     int32_t getFramesPerBurst() const override;
 
-    aaudio_result_t updateStateWhileWaiting() override;
+    aaudio_result_t updateStateMachine() override;
 
     aaudio_direction_t getDirection() const override {
         return AAUDIO_DIRECTION_INPUT;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 77f31e2..51440d6 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -183,6 +183,9 @@
         actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
     }
     setPerformanceMode(actualPerformanceMode);
+
+    setSharingMode(AAUDIO_SHARING_MODE_SHARED); // EXCLUSIVE mode not supported in legacy
+
     // Log warning if we did not get what we asked for.
     ALOGW_IF(actualFlags != flags,
              "AudioStreamTrack::open() flags changed from 0x%08X to 0x%08X",
@@ -227,6 +230,7 @@
     std::lock_guard<std::mutex> lock(mStreamMutex);
 
     if (mAudioTrack.get() == nullptr) {
+        ALOGE("AudioStreamTrack::requestStart() no AudioTrack");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     // Get current position so we can detect when the track is playing.
@@ -250,6 +254,7 @@
     std::lock_guard<std::mutex> lock(mStreamMutex);
 
     if (mAudioTrack.get() == nullptr) {
+        ALOGE("AudioStreamTrack::requestPause() no AudioTrack");
         return AAUDIO_ERROR_INVALID_STATE;
     } else if (getState() != AAUDIO_STREAM_STATE_STARTING
             && getState() != AAUDIO_STREAM_STATE_STARTED) {
@@ -271,8 +276,10 @@
     std::lock_guard<std::mutex> lock(mStreamMutex);
 
     if (mAudioTrack.get() == nullptr) {
+        ALOGE("AudioStreamTrack::requestFlush() no AudioTrack");
         return AAUDIO_ERROR_INVALID_STATE;
     } else if (getState() != AAUDIO_STREAM_STATE_PAUSED) {
+        ALOGE("AudioStreamTrack::requestFlush() not paused");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     setState(AAUDIO_STREAM_STATE_FLUSHING);
@@ -286,6 +293,7 @@
     std::lock_guard<std::mutex> lock(mStreamMutex);
 
     if (mAudioTrack.get() == nullptr) {
+        ALOGE("AudioStreamTrack::requestStop() no AudioTrack");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     onStop();
@@ -296,7 +304,7 @@
     return AAUDIO_OK;
 }
 
-aaudio_result_t AudioStreamTrack::updateStateWhileWaiting()
+aaudio_result_t AudioStreamTrack::updateStateMachine()
 {
     status_t err;
     aaudio_wrapping_frames_t position;
@@ -373,6 +381,12 @@
     }
     int32_t framesWritten = (int32_t)(bytesWritten / bytesPerFrame);
     incrementFramesWritten(framesWritten);
+
+    result = updateStateMachine();
+    if (result != AAUDIO_OK) {
+        return result;
+    }
+
     return framesWritten;
 }
 
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index ff429ea..3230ac8 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -67,7 +67,7 @@
         return AAUDIO_DIRECTION_OUTPUT;
     }
 
-    aaudio_result_t updateStateWhileWaiting() override;
+    aaudio_result_t updateStateMachine() override;
 
     // This is public so it can be called from the C callback function.
     void processCallback(int event, void *info) override;
@@ -81,8 +81,7 @@
     // adapts between variable sized blocks and fixed size blocks
     FixedBlockReader                 mFixedBlockReader;
 
-    // TODO add 64-bit position reporting to AudioRecord and use it.
-    aaudio_wrapping_frames_t         mPositionWhenStarting = 0;
+    // TODO add 64-bit position reporting to AudioTrack and use it.
     aaudio_wrapping_frames_t         mPositionWhenPausing = 0;
 };
 
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index acd319b..b0c6c94 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -258,4 +258,74 @@
     }
 }
 
+
+/**
+ * Simple double buffer for a structure that can be written occasionally and read occasionally.
+ * This allows a SINGLE writer with multiple readers.
+ *
+ * It is OK if the FIFO overflows and we lose old values.
+ * It is also OK if we read an old value.
+ * Thread may return a non-atomic result if the other thread is rapidly writing
+ * new values on another core.
+ */
+template <class T>
+class SimpleDoubleBuffer {
+public:
+    SimpleDoubleBuffer()
+            : mValues()
+            , mCounter(0) {}
+
+    __attribute__((no_sanitize("integer")))
+    void write(T value) {
+        int index = mCounter.load() & 1;
+        mValues[index] = value;
+        mCounter++; // Increment AFTER updating storage, OK if it wraps.
+    }
+
+    T read() const {
+        T result;
+        int before;
+        int after;
+        int timeout = 3;
+        do {
+            // Check to see if a write occurred while were reading.
+            before = mCounter.load();
+            int index = (before & 1) ^ 1;
+            result = mValues[index];
+            after = mCounter.load();
+        } while ((after != before) && --timeout > 0);
+        return result;
+    }
+
+    /**
+     * @return true if at least one value has been written
+     */
+    bool isValid() const {
+        return mCounter.load() > 0;
+    }
+
+private:
+    T                    mValues[2];
+    std::atomic<int>     mCounter;
+};
+
+class Timestamp {
+public:
+    Timestamp()
+            : mPosition(0)
+            , mNanoseconds(0) {}
+    Timestamp(int64_t position, int64_t nanoseconds)
+            : mPosition(position)
+            , mNanoseconds(nanoseconds) {}
+
+    int64_t getPosition() const { return mPosition; }
+
+    int64_t getNanoseconds() const { return mNanoseconds; }
+
+private:
+    // These cannot be const because we need to implement the copy assignment operator.
+    int64_t mPosition;
+    int64_t mNanoseconds;
+};
+
 #endif //UTILITY_AAUDIO_UTILITIES_H
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
index e4eef06..4402919 100644
--- a/media/libaaudio/tests/Android.mk
+++ b/media/libaaudio/tests/Android.mk
@@ -34,6 +34,17 @@
 LOCAL_C_INCLUDES := \
     $(call include-path-for, audio-utils) \
     frameworks/av/media/libaaudio/include \
+    frameworks/av/media/libaaudio/src \
+    frameworks/av/media/libaaudio/examples
+LOCAL_SRC_FILES:= test_timestamps.cpp
+LOCAL_SHARED_LIBRARIES := libaaudio
+LOCAL_MODULE := test_timestamps
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := \
+    $(call include-path-for, audio-utils) \
+    frameworks/av/media/libaaudio/include \
     frameworks/av/media/libaaudio/src
 LOCAL_SRC_FILES:= test_linear_ramp.cpp
 LOCAL_SHARED_LIBRARIES := libaaudio
diff --git a/media/libaaudio/tests/test_timestamps.cpp b/media/libaaudio/tests/test_timestamps.cpp
new file mode 100644
index 0000000..d9ca391
--- /dev/null
+++ b/media/libaaudio/tests/test_timestamps.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Play silence and recover from dead servers or disconnected devices.
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
+
+#include "utils/AAudioExampleUtils.h"
+
+#define DEFAULT_TIMEOUT_NANOS  ((int64_t)1000000000)
+
+int main(int argc, char **argv) {
+    (void) argc;
+    (void *)argv;
+
+    aaudio_result_t result = AAUDIO_OK;
+
+    int32_t triesLeft = 3;
+    int32_t bufferCapacity;
+    int32_t framesPerBurst = 0;
+    float *buffer = nullptr;
+
+    int32_t actualChannelCount = 0;
+    int32_t actualSampleRate = 0;
+    int32_t originalBufferSize = 0;
+    int32_t requestedBufferSize = 0;
+    int32_t finalBufferSize = 0;
+    aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
+    aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
+    int32_t framesMax;
+    int64_t framesTotal;
+    int64_t printAt;
+    int samplesPerBurst;
+    int64_t previousFramePosition = -1;
+
+    AAudioStreamBuilder *aaudioBuilder = nullptr;
+    AAudioStream *aaudioStream = nullptr;
+
+    // Make printf print immediately so that debug info is not stuck
+    // in a buffer if we hang or crash.
+    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+    printf("Test Timestamps V0.1.1\n");
+
+    AAudio_setMMapPolicy(AAUDIO_POLICY_AUTO);
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    result = AAudio_createStreamBuilder(&aaudioBuilder);
+    if (result != AAUDIO_OK) {
+        printf("AAudio_createStreamBuilder returned %s",
+               AAudio_convertResultToText(result));
+        goto finish;
+    }
+
+    // Request stream properties.
+    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
+    //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_NONE);
+    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+
+    // Create an AAudioStream using the Builder.
+    result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStreamBuilder_openStream returned %s",
+               AAudio_convertResultToText(result));
+        goto finish;
+    }
+
+    // Check to see what kind of stream we actually got.
+    actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
+    actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
+    actualDataFormat = AAudioStream_getFormat(aaudioStream);
+
+    printf("-------- chans = %3d, rate = %6d format = %d\n",
+            actualChannelCount, actualSampleRate, actualDataFormat);
+    printf("    Is MMAP used? %s\n", AAudioStream_isMMapUsed(aaudioStream)
+                                   ? "yes" : "no");
+
+    // This is the number of frames that are read in one chunk by a DMA controller
+    // or a DSP or a mixer.
+    framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
+    printf("    framesPerBurst = %3d\n", framesPerBurst);
+
+    originalBufferSize = AAudioStream_getBufferSizeInFrames(aaudioStream);
+    requestedBufferSize = 2 * framesPerBurst;
+    finalBufferSize = AAudioStream_setBufferSizeInFrames(aaudioStream, requestedBufferSize);
+
+    printf("    BufferSize: original = %4d, requested = %4d, final = %4d\n",
+           originalBufferSize, requestedBufferSize, finalBufferSize);
+
+    samplesPerBurst = framesPerBurst * actualChannelCount;
+    buffer = new float[samplesPerBurst];
+
+    result = AAudioStream_requestStart(aaudioStream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStream_requestStart returned %s",
+               AAudio_convertResultToText(result));
+        goto finish;
+    }
+
+    // Play silence very briefly.
+    framesMax = actualSampleRate * 4;
+    framesTotal = 0;
+    printAt = actualSampleRate;
+    while (result == AAUDIO_OK && framesTotal < framesMax) {
+        int32_t framesWritten = AAudioStream_write(aaudioStream,
+                                                   buffer, framesPerBurst,
+                                                   DEFAULT_TIMEOUT_NANOS);
+        if (framesWritten < 0) {
+            result = framesWritten;
+            printf("write() returned %s, frames = %d\n",
+                   AAudio_convertResultToText(result), (int)framesTotal);
+            printf("  frames = %d\n", (int)framesTotal);
+        } else if (framesWritten != framesPerBurst) {
+            printf("write() returned %d, frames = %d\n", framesWritten, (int)framesTotal);
+            result = AAUDIO_ERROR_TIMEOUT;
+        } else {
+            framesTotal += framesWritten;
+            if (framesTotal >= printAt) {
+                printf("frames = %d\n", (int)framesTotal);
+                printAt += actualSampleRate;
+            }
+        }
+
+        // Print timestamps.
+        int64_t framePosition = 0;
+        int64_t frameTime = 0;
+        aaudio_result_t timeResult;
+        timeResult = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
+                                           &framePosition, &frameTime);
+
+        if (timeResult == AAUDIO_OK) {
+            if (framePosition > (previousFramePosition + 5000)) {
+                int64_t realTime = getNanoseconds();
+                int64_t framesWritten = AAudioStream_getFramesWritten(aaudioStream);
+
+                double latencyMillis = calculateLatencyMillis(framePosition, frameTime,
+                                                              framesWritten, realTime,
+                                                              actualSampleRate);
+
+                printf("--- timestamp: result = %4d, position = %lld, at %lld nanos"
+                               ", latency = %7.2f msec\n",
+                       timeResult,
+                       (long long) framePosition,
+                       (long long) frameTime,
+                       latencyMillis);
+                previousFramePosition = framePosition;
+            }
+        }
+    }
+
+    result = AAudioStream_requestStop(aaudioStream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStream_requestStop returned %s\n",
+               AAudio_convertResultToText(result));
+    }
+    result = AAudioStream_close(aaudioStream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStream_close returned %s\n",
+               AAudio_convertResultToText(result));
+    }
+    aaudioStream = nullptr;
+
+
+finish:
+    if (aaudioStream != nullptr) {
+        AAudioStream_close(aaudioStream);
+    }
+    AAudioStreamBuilder_delete(aaudioBuilder);
+    delete[] buffer;
+    printf("result = %d = %s\n", result, AAudio_convertResultToText(result));
+}
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 2f710bd..211bd7d 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1297,7 +1297,7 @@
 }
 
 void AudioSystem::AudioPolicyServiceClient::onRecordingConfigurationUpdate(
-        int event, audio_session_t session, audio_source_t source,
+        int event, const record_client_info_t *clientInfo,
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle) {
     record_config_callback cb = NULL;
@@ -1307,7 +1307,7 @@
     }
 
     if (cb != NULL) {
-        cb(event, session, source, clientConfig, deviceConfig, patchHandle);
+        cb(event, clientInfo, clientConfig, deviceConfig, patchHandle);
     }
 }
 
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index b0b01db..31e1e2b 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -22,6 +22,7 @@
 #include <math.h>
 #include <sys/resource.h>
 
+#include <audio_utils/clock.h>
 #include <audio_utils/primitives.h>
 #include <binder/IPCThreadState.h>
 #include <media/AudioTrack.h>
@@ -62,11 +63,6 @@
     return tv.tv_sec * 1000000ll + tv.tv_nsec / 1000;
 }
 
-static inline nsecs_t convertTimespecToNs(const struct timespec &tv)
-{
-    return tv.tv_sec * (long long)NANOS_PER_SECOND + tv.tv_nsec;
-}
-
 // current monotonic time in microseconds.
 static int64_t getNowUs()
 {
@@ -2563,7 +2559,7 @@
                 // We update the timestamp time even when paused.
                 if (mState == STATE_PAUSED /* not needed: STATE_PAUSED_STOPPING */) {
                     const int64_t now = systemTime();
-                    const int64_t at = convertTimespecToNs(timestamp.mTime);
+                    const int64_t at = audio_utils_ns_from_timespec(&timestamp.mTime);
                     const int64_t lag =
                             (ets.mTimeNs[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] < 0 ||
                                 ets.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] < 0)
@@ -2695,8 +2691,9 @@
     // This is sometimes caused by erratic reports of the available space in the ALSA drivers.
     if (status == NO_ERROR) {
         if (previousTimestampValid) {
-            const int64_t previousTimeNanos = convertTimespecToNs(mPreviousTimestamp.mTime);
-            const int64_t currentTimeNanos = convertTimespecToNs(timestamp.mTime);
+            const int64_t previousTimeNanos =
+                    audio_utils_ns_from_timespec(&mPreviousTimestamp.mTime);
+            const int64_t currentTimeNanos = audio_utils_ns_from_timespec(&timestamp.mTime);
             if (currentTimeNanos < previousTimeNanos) {
                 ALOGW("retrograde timestamp time corrected, %lld < %lld",
                         (long long)currentTimeNanos, (long long)previousTimeNanos);
@@ -2726,7 +2723,7 @@
 #if 0
             // Uncomment this to verify audio timestamp rate.
             const int64_t deltaTime =
-                    convertTimespecToNs(timestamp.mTime) - previousTimeNanos;
+                    audio_utils_ns_from_timespec(&timestamp.mTime) - previousTimeNanos;
             if (deltaTime != 0) {
                 const int64_t computedSampleRate =
                         deltaPosition * (long long)NANOS_PER_SECOND / deltaTime;
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index 08c37f8..7bf4f99 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -36,7 +36,7 @@
 // a value between "other" + 1 and "other" + INT32_MAX, the choice of
 // which needs to be the "least recently used" sequence value for "self".
 // In general, this means (new_self) returned is max(self, other) + 1.
-
+__attribute__((no_sanitize("integer")))
 static uint32_t incrementSequence(uint32_t self, uint32_t other) {
     int32_t diff = (int32_t) self - (int32_t) other;
     if (diff >= 0 && diff < INT32_MAX) {
@@ -393,6 +393,7 @@
 
 // ---------------------------------------------------------------------------
 
+__attribute__((no_sanitize("integer")))
 void AudioTrackClientProxy::flush()
 {
     // This works for mFrameCountP2 <= 2^30
@@ -840,6 +841,25 @@
     return filled;
 }
 
+__attribute__((no_sanitize("integer")))
+size_t AudioTrackServerProxy::framesReadySafe() const
+{
+    if (mIsShutdown) {
+        return 0;
+    }
+    const audio_track_cblk_t* cblk = mCblk;
+    const int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush);
+    if (flush != mFlush) {
+        return mFrameCount;
+    }
+    const int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+    const ssize_t filled = rear - cblk->u.mStreaming.mFront;
+    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
+        return 0; // error condition, silently return 0.
+    }
+    return filled;
+}
+
 bool  AudioTrackServerProxy::setStreamEndDone() {
     audio_track_cblk_t* cblk = mCblk;
     bool old =
@@ -851,6 +871,7 @@
     return old;
 }
 
+__attribute__((no_sanitize("integer")))
 void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
 {
     audio_track_cblk_t* cblk = mCblk;
@@ -908,6 +929,11 @@
     return mFramesReadySafe;
 }
 
+size_t StaticAudioTrackServerProxy::framesReadySafe() const
+{
+    return mFramesReadySafe;
+}
+
 status_t StaticAudioTrackServerProxy::updateStateWithLoop(
         StaticAudioTrackState *localState, const StaticAudioTrackState &update) const
 {
@@ -1001,6 +1027,7 @@
     return (ssize_t) mState.mPosition;
 }
 
+__attribute__((no_sanitize("integer")))
 status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
 {
     if (mIsShutdown) {
@@ -1047,6 +1074,7 @@
     return NO_ERROR;
 }
 
+__attribute__((no_sanitize("integer")))
 void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
 {
     size_t stepCount = buffer->mFrameCount;
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index 98a0521..ad7f1de 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -48,6 +48,18 @@
     data.writeInt32((int32_t) config->format);
 }
 
+inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
+    clientInfo->uid = (uid_t) data.readUint32();
+    clientInfo->session = (audio_session_t) data.readInt32();
+    clientInfo->source = (audio_source_t) data.readInt32();
+}
+
+inline void writeRecordClientInfoFromParcel(Parcel& data, const record_client_info_t *clientInfo) {
+    data.writeUint32((uint32_t) clientInfo->uid);
+    data.writeInt32((int32_t) clientInfo->session);
+    data.writeInt32((int32_t) clientInfo->source);
+}
+
 // ----------------------------------------------------------------------
 class BpAudioPolicyServiceClient : public BpInterface<IAudioPolicyServiceClient>
 {
@@ -80,14 +92,13 @@
         remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
-    void onRecordingConfigurationUpdate(int event, audio_session_t session,
-            audio_source_t source, const audio_config_base_t *clientConfig,
+    void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+            const audio_config_base_t *clientConfig,
             const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
         data.writeInt32(event);
-        data.writeInt32(session);
-        data.writeInt32(source);
+        writeRecordClientInfoFromParcel(data, clientInfo);
         writeAudioConfigBaseToParcel(data, clientConfig);
         writeAudioConfigBaseToParcel(data, deviceConfig);
         data.writeInt32(patchHandle);
@@ -123,14 +134,14 @@
     case RECORDING_CONFIGURATION_UPDATE: {
             CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
             int event = (int) data.readInt32();
-            audio_session_t session = (audio_session_t) data.readInt32();
-            audio_source_t source = (audio_source_t) data.readInt32();
+            record_client_info_t clientInfo;
             audio_config_base_t clientConfig;
             audio_config_base_t deviceConfig;
+            readRecordClientInfoFromParcel(data, &clientInfo);
             readAudioConfigBaseFromParcel(data, &clientConfig);
             readAudioConfigBaseFromParcel(data, &deviceConfig);
             audio_patch_handle_t patchHandle = (audio_patch_handle_t) data.readInt32();
-            onRecordingConfigurationUpdate(event, session, source, &clientConfig, &deviceConfig,
+            onRecordingConfigurationUpdate(event, &clientInfo, &clientConfig, &deviceConfig,
                     patchHandle);
             return NO_ERROR;
         } break;
diff --git a/media/libaudioclient/OWNERS b/media/libaudioclient/OWNERS
new file mode 100644
index 0000000..482b9fb
--- /dev/null
+++ b/media/libaudioclient/OWNERS
@@ -0,0 +1,3 @@
+gkasten@google.com
+jmtrivi@google.com
+mnaganov@google.com
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 2e39d23..4d5b317 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -33,7 +33,7 @@
 
 typedef void (*audio_error_callback)(status_t err);
 typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
-typedef void (*record_config_callback)(int event, audio_session_t session, int source,
+typedef void (*record_config_callback)(int event, const record_client_info_t *clientInfo,
                 const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
                 audio_patch_handle_t patchHandle);
 
@@ -440,8 +440,9 @@
         virtual void onAudioPortListUpdate();
         virtual void onAudioPatchListUpdate();
         virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
-        virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
-                        audio_source_t source, const audio_config_base_t *clientConfig,
+        virtual void onRecordingConfigurationUpdate(int event,
+                        const record_client_info_t *clientInfo,
+                        const audio_config_base_t *clientConfig,
                         const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
 
     private:
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index d94ad00..e0d2495 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -26,6 +26,16 @@
 
 // ----------------------------------------------------------------------------
 
+struct record_client_info {
+    uid_t uid;
+    audio_session_t session;
+    audio_source_t source;
+};
+
+typedef struct record_client_info record_client_info_t;
+
+// ----------------------------------------------------------------------------
+
 class IAudioPolicyServiceClient : public IInterface
 {
 public:
@@ -38,8 +48,8 @@
     // Notifies a change in the mixing state of a specific mix in a dynamic audio policy
     virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
     // Notifies a change of audio recording configuration
-    virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
-            audio_source_t source,
+    virtual void onRecordingConfigurationUpdate(int event,
+            const record_client_info_t *clientInfo,
             const audio_config_base_t *clientConfig,
             const audio_config_base_t *deviceConfig,
             audio_patch_handle_t patchHandle) = 0;
diff --git a/media/libaudiohal/Android.mk b/media/libaudiohal/Android.mk
index e592169..827908e 100644
--- a/media/libaudiohal/Android.mk
+++ b/media/libaudiohal/Android.mk
@@ -3,6 +3,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SHARED_LIBRARIES := \
+    libaudioutils \
     libcutils   \
     liblog      \
     libutils    \
diff --git a/media/libaudiohal/DeviceHalHidl.cpp b/media/libaudiohal/DeviceHalHidl.cpp
index 71fbd98..49ef991 100644
--- a/media/libaudiohal/DeviceHalHidl.cpp
+++ b/media/libaudiohal/DeviceHalHidl.cpp
@@ -98,7 +98,8 @@
 }  // namespace
 
 DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
-        : ConversionHelperHidl("Device"), mDevice(device) {
+        : ConversionHelperHidl("Device"), mDevice(device),
+          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
 }
 
 DeviceHalHidl::~DeviceHalHidl() {
@@ -120,24 +121,21 @@
 
 status_t DeviceHalHidl::setVoiceVolume(float volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setVoiceVolume", primaryDev->setVoiceVolume(volume));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
 }
 
 status_t DeviceHalHidl::setMasterVolume(float volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setMasterVolume", primaryDev->setMasterVolume(volume));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
 }
 
 status_t DeviceHalHidl::getMasterVolume(float *volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
     Result retval;
-    Return<void> ret = primaryDev->getMasterVolume(
+    Return<void> ret = mPrimaryDevice->getMasterVolume(
             [&](Result r, float v) {
                 retval = r;
                 if (retval == Result::OK) {
@@ -149,9 +147,8 @@
 
 status_t DeviceHalHidl::setMode(audio_mode_t mode) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setMode", primaryDev->setMode(AudioMode(mode)));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
 }
 
 status_t DeviceHalHidl::setMicMute(bool state) {
diff --git a/media/libaudiohal/DeviceHalHidl.h b/media/libaudiohal/DeviceHalHidl.h
index 9da02a4..8651b51 100644
--- a/media/libaudiohal/DeviceHalHidl.h
+++ b/media/libaudiohal/DeviceHalHidl.h
@@ -18,11 +18,13 @@
 #define ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
 
 #include <android/hardware/audio/2.0/IDevice.h>
+#include <android/hardware/audio/2.0/IPrimaryDevice.h>
 #include <media/audiohal/DeviceHalInterface.h>
 
 #include "ConversionHelperHidl.h"
 
 using ::android::hardware::audio::V2_0::IDevice;
+using ::android::hardware::audio::V2_0::IPrimaryDevice;
 using ::android::hardware::Return;
 
 namespace android {
@@ -110,6 +112,7 @@
   private:
     friend class DevicesFactoryHalHidl;
     sp<IDevice> mDevice;
+    sp<IPrimaryDevice> mPrimaryDevice;  // Null if it's not a primary device.
 
     // Can not be constructed directly by clients.
     explicit DeviceHalHidl(const sp<IDevice>& device);
diff --git a/media/libaudiohal/EffectHalHidl.cpp b/media/libaudiohal/EffectHalHidl.cpp
index b49b975..61fb6bab 100644
--- a/media/libaudiohal/EffectHalHidl.cpp
+++ b/media/libaudiohal/EffectHalHidl.cpp
@@ -40,7 +40,7 @@
 namespace android {
 
 EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
-        : mEffect(effect), mEffectId(effectId), mBuffersChanged(true) {
+        : mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
 }
 
 EffectHalHidl::~EffectHalHidl() {
@@ -49,6 +49,9 @@
         mEffect.clear();
         hardware::IPCThreadState::self()->flushCommands();
     }
+    if (mEfGroup) {
+        EventFlag::deleteEventFlag(&mEfGroup);
+    }
 }
 
 // static
diff --git a/media/libaudiohal/OWNERS b/media/libaudiohal/OWNERS
new file mode 100644
index 0000000..1456ab6
--- /dev/null
+++ b/media/libaudiohal/OWNERS
@@ -0,0 +1,2 @@
+krocard@google.com
+mnaganov@google.com
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 42785d5..0cafa36 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -47,7 +47,20 @@
 StreamHalHidl::StreamHalHidl(IStream *stream)
         : ConversionHelperHidl("Stream"),
           mStream(stream),
-          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT) {
+          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
+          mCachedBufferSize(0){
+
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+        // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
+        Return<void> ret = mStream->getAudioProperties(
+                [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
+                mStreamPowerLog.init(sr,
+                        static_cast<audio_channel_mask_t>(m),
+                        static_cast<audio_format_t>(f));
+            });
+    }
 }
 
 StreamHalHidl::~StreamHalHidl() {
@@ -61,7 +74,11 @@
 
 status_t StreamHalHidl::getBufferSize(size_t *size) {
     if (!mStream) return NO_INIT;
-    return processReturn("getBufferSize", mStream->getBufferSize(), size);
+    status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
+    if (status == OK) {
+        mCachedBufferSize = *size;
+    }
+    return status;
 }
 
 status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
@@ -135,6 +152,7 @@
     hidlHandle->data[0] = fd;
     Return<void> ret = mStream->debugDump(hidlHandle);
     native_handle_delete(hidlHandle);
+    mStreamPowerLog.dump(fd);
     return processReturn("dump", ret);
 }
 
@@ -189,6 +207,14 @@
     return OK;
 }
 
+status_t StreamHalHidl::getCachedBufferSize(size_t *size) {
+    if (mCachedBufferSize != 0) {
+        *size = mCachedBufferSize;
+        return OK;
+    }
+    return getBufferSize(size);
+}
+
 bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
     if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
         return true;
@@ -307,11 +333,22 @@
     }
 
     status_t status;
-    if (!mDataMQ && (status = prepareForWriting(bytes)) != OK) {
-        return status;
+    if (!mDataMQ) {
+        // In case if playback starts close to the end of a compressed track, the bytes
+        // that need to be written is less than the actual buffer size. Need to use
+        // full buffer size for the MQ since otherwise after seeking back to the middle
+        // data will be truncated.
+        size_t bufferSize;
+        if ((status = getCachedBufferSize(&bufferSize)) != OK) {
+            return status;
+        }
+        if (bytes > bufferSize) bufferSize = bytes;
+        if ((status = prepareForWriting(bufferSize)) != OK) {
+            return status;
+        }
     }
 
-    return callWriterThread(
+    status = callWriterThread(
             WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
             [&] (const WriteStatus& writeStatus) {
                 *written = writeStatus.reply.written;
@@ -320,6 +357,8 @@
                         "hal reports more bytes written than asked for: %lld > %lld",
                         (long long)*written, (long long)bytes);
             });
+    mStreamPowerLog.log(buffer, *written);
+    return status;
 }
 
 status_t StreamOutHalHidl::callWriterThread(
@@ -580,7 +619,7 @@
     ReadParameters params;
     params.command = ReadCommand::READ;
     params.params.read = bytes;
-    return callReaderThread(params, "read",
+    status = callReaderThread(params, "read",
             [&](const ReadStatus& readStatus) {
                 const size_t availToRead = mDataMQ->availableToRead();
                 if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
@@ -591,6 +630,8 @@
                         (int32_t)availToRead, (int32_t)readStatus.reply.read);
                 *read = readStatus.reply.read;
             });
+    mStreamPowerLog.log(buffer, *read);
+    return status;
 }
 
 status_t StreamInHalHidl::callReaderThread(
diff --git a/media/libaudiohal/StreamHalHidl.h b/media/libaudiohal/StreamHalHidl.h
index a7df276..d4ab943 100644
--- a/media/libaudiohal/StreamHalHidl.h
+++ b/media/libaudiohal/StreamHalHidl.h
@@ -27,6 +27,7 @@
 #include <media/audiohal/StreamHalInterface.h>
 
 #include "ConversionHelperHidl.h"
+#include "StreamPowerLog.h"
 
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
@@ -101,12 +102,18 @@
     // The destructor automatically closes the stream.
     virtual ~StreamHalHidl();
 
+    status_t getCachedBufferSize(size_t *size);
+
     bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
 
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
   private:
     const int HAL_THREAD_PRIORITY_DEFAULT = -1;
     IStream *mStream;
     int mHalThreadPriority;
+    size_t mCachedBufferSize;
 };
 
 class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
diff --git a/media/libaudiohal/StreamHalLocal.cpp b/media/libaudiohal/StreamHalLocal.cpp
index 05800a0..dc17f5c 100644
--- a/media/libaudiohal/StreamHalLocal.cpp
+++ b/media/libaudiohal/StreamHalLocal.cpp
@@ -27,7 +27,15 @@
 namespace android {
 
 StreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device)
-        : mDevice(device), mStream(stream) {
+        : mDevice(device),
+          mStream(stream) {
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+        mStreamPowerLog.init(mStream->get_sample_rate(mStream),
+                mStream->get_channels(mStream),
+                mStream->get_format(mStream));
+    }
 }
 
 StreamHalLocal::~StreamHalLocal() {
@@ -95,7 +103,9 @@
 }
 
 status_t StreamHalLocal::dump(int fd) {
-    return mStream->dump(mStream, fd);
+    status_t status = mStream->dump(mStream, fd);
+    mStreamPowerLog.dump(fd);
+    return status;
 }
 
 status_t StreamHalLocal::setHalThreadPriority(int) {
@@ -133,6 +143,7 @@
     ssize_t writeResult = mStream->write(mStream, buffer, bytes);
     if (writeResult > 0) {
         *written = writeResult;
+        mStreamPowerLog.log(buffer, *written);
         return OK;
     } else {
         *written = 0;
@@ -266,6 +277,7 @@
     ssize_t readResult = mStream->read(mStream, buffer, bytes);
     if (readResult > 0) {
         *read = readResult;
+        mStreamPowerLog.log( buffer, *read);
         return OK;
     } else {
         *read = 0;
diff --git a/media/libaudiohal/StreamHalLocal.h b/media/libaudiohal/StreamHalLocal.h
index 8c96c1f..c7136df 100644
--- a/media/libaudiohal/StreamHalLocal.h
+++ b/media/libaudiohal/StreamHalLocal.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_STREAM_HAL_LOCAL_H
 
 #include <media/audiohal/StreamHalInterface.h>
+#include "StreamPowerLog.h"
 
 namespace android {
 
@@ -83,6 +84,9 @@
 
     sp<DeviceHalLocal> mDevice;
 
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
   private:
     audio_stream_t *mStream;
 };
diff --git a/media/libaudiohal/StreamPowerLog.h b/media/libaudiohal/StreamPowerLog.h
new file mode 100644
index 0000000..a78b1aa
--- /dev/null
+++ b/media/libaudiohal/StreamPowerLog.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_H
+#define ANDROID_HARDWARE_STREAM_POWER_LOG_H
+
+#include <audio_utils/clock.h>
+#include <audio_utils/PowerLog.h>
+#include <cutils/properties.h>
+#include <system/audio.h>
+
+namespace android {
+
+class StreamPowerLog {
+public:
+    StreamPowerLog() :
+        mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
+        mPowerLog(nullptr),
+        mFrameSize(0) {
+        // use init() to set up the power log.
+    }
+
+    ~StreamPowerLog() {
+        power_log_destroy(mPowerLog); // OK for null mPowerLog
+        mPowerLog = nullptr;
+    }
+
+    // A one-time initialization (do not call twice) before using StreamPowerLog.
+    void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
+        if (mPowerLog == nullptr) {
+            // Note: A way to get channel count for both input and output channel masks
+            // but does not check validity of the channel mask.
+            const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
+            mFrameSize = channelCount * audio_bytes_per_sample(format);
+            if (mFrameSize > 0) {
+                const size_t kPowerLogFramesPerEntry =
+                        (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
+                mPowerLog = power_log_create(
+                        sampleRate,
+                        channelCount,
+                        format,
+                        kPowerLogEntries,
+                        kPowerLogFramesPerEntry);
+            }
+        }
+        // mPowerLog may be NULL (not the right build, format not accepted, etc.).
+    }
+
+    // Dump the power log to fd.
+    void dump(int fd) const {
+        // OK for null mPowerLog
+        (void)power_log_dump(
+                mPowerLog, fd, "      " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
+    }
+
+    // Log the audio data contained in buffer.
+    void log(const void *buffer, size_t sizeInBytes) const {
+        if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
+            power_log_log(
+                    mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
+        }
+    }
+
+    bool isUserDebugOrEngBuild() const {
+        return mIsUserDebugOrEngBuild;
+    }
+
+private:
+
+    static inline bool is_userdebug_or_eng_build() {
+        char value[PROPERTY_VALUE_MAX];
+        (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
+        return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
+    }
+
+    // Audio signal power log configuration.
+    static const size_t kPowerLogLines = 40;
+    static const size_t kPowerLogSamplingIntervalMs = 50;
+    static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
+            / kPowerLogSamplingIntervalMs);
+
+    const bool mIsUserDebugOrEngBuild;
+    power_log_t *mPowerLog;
+    size_t mFrameSize;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_H
diff --git a/media/libaudiohal/include/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/DeviceHalInterface.h
rename to media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
diff --git a/media/libaudiohal/include/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/DevicesFactoryHalInterface.h
rename to media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
diff --git a/media/libaudiohal/include/EffectBufferHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectBufferHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectBufferHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectBufferHalInterface.h
diff --git a/media/libaudiohal/include/EffectHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectHalInterface.h
diff --git a/media/libaudiohal/include/EffectsFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/EffectsFactoryHalInterface.h
rename to media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
diff --git a/media/libaudiohal/include/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
similarity index 100%
rename from media/libaudiohal/include/StreamHalInterface.h
rename to media/libaudiohal/include/media/audiohal/StreamHalInterface.h
diff --git a/media/libaudiohal/include/hidl/HalDeathHandler.h b/media/libaudiohal/include/media/audiohal/hidl/HalDeathHandler.h
similarity index 100%
rename from media/libaudiohal/include/hidl/HalDeathHandler.h
rename to media/libaudiohal/include/media/audiohal/hidl/HalDeathHandler.h
diff --git a/media/libaudioprocessing/include/AudioResampler.h b/media/libaudioprocessing/include/media/AudioResampler.h
similarity index 100%
rename from media/libaudioprocessing/include/AudioResampler.h
rename to media/libaudioprocessing/include/media/AudioResampler.h
diff --git a/media/libaudioprocessing/include/AudioResamplerPublic.h b/media/libaudioprocessing/include/media/AudioResamplerPublic.h
similarity index 100%
rename from media/libaudioprocessing/include/AudioResamplerPublic.h
rename to media/libaudioprocessing/include/media/AudioResamplerPublic.h
diff --git a/media/libeffects/Android.bp b/media/libeffects/Android.bp
index ccaa2b4..0dd3f17 100644
--- a/media/libeffects/Android.bp
+++ b/media/libeffects/Android.bp
@@ -1 +1 @@
-subdirs = ["factory"]
+subdirs = ["factory", "config"]
diff --git a/media/libeffects/OWNERS b/media/libeffects/OWNERS
new file mode 100644
index 0000000..7e3de13
--- /dev/null
+++ b/media/libeffects/OWNERS
@@ -0,0 +1,3 @@
+krocard@google.com
+mnaganov@google.com
+rago@google.com
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
new file mode 100644
index 0000000..4398a91
--- /dev/null
+++ b/media/libeffects/config/Android.bp
@@ -0,0 +1,17 @@
+// Effect configuration
+cc_library_shared {
+    name: "libeffectsconfig",
+    vendor_available: true,
+
+    srcs: ["src/EffectsConfig.cpp"],
+
+    shared_libs: [
+        "liblog",
+        "libtinyxml2",
+    ],
+
+    header_libs: ["libaudio_system_headers"],
+    export_header_lib_headers: ["libaudio_system_headers"],
+
+    export_include_dirs: ["include"],
+}
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
new file mode 100644
index 0000000..811730c
--- /dev/null
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_MEDIA_EFFECTSCONFIG_H
+#define ANDROID_MEDIA_EFFECTSCONFIG_H
+
+/** @file Parses audio effects configuration file to C and C++ structure.
+ * @see audio_effects_conf_V2_0.xsd for documentation on each structure
+ */
+
+#include <system/audio_effect.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace effectsConfig {
+
+/** Default path of effect configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_effects.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
+#ifdef __LP64__
+        {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#else
+        {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#endif
+
+struct Library {
+    std::string name;
+    std::string path;
+};
+using Libraries = std::vector<Library>;
+
+struct EffectImpl {
+    Library* library; //< Only valid as long as the associated library vector is unmodified
+    effect_uuid_t uuid;
+};
+
+struct Effect : public EffectImpl {
+    std::string name;
+    bool isProxy;
+    EffectImpl libSw; //< Only valid if isProxy
+    EffectImpl libHw; //< Only valid if isProxy
+};
+
+using Effects = std::vector<Effect>;
+
+template <class Type>
+struct Stream {
+    Type type;
+    std::vector<std::reference_wrapper<Effect>> effects;
+};
+using OutputStream = Stream<audio_stream_type_t>;
+using InputStream = Stream<audio_source_t>;
+
+/** Parsed configuration.
+ * Intended to be a transient structure only used for deserialization.
+ * Note: Everything is copied in the configuration from the xml dom.
+ *       If copies needed to be avoided due to performance issue,
+ *       consider keeping a private handle on the xml dom and replace all strings by dom pointers.
+ *       Or even better, use SAX parsing to avoid the allocations all together.
+ */
+struct Config {
+    float version;
+    Libraries libraries;
+    Effects effects;
+    std::vector<OutputStream> postprocess;
+    std::vector<InputStream> preprocess;
+};
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+    /** Parsed config, nullptr if the xml lib could not load the file */
+    std::unique_ptr<Config> parsedConfig;
+    size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain
+};
+
+/** Parses the provided effect configuration.
+ * Parsing do not stop of first invalid element, but continues to the next.
+ * @see ParsingResult::nbSkippedElement
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+
+} // namespace effectsConfig
+} // namespace android
+#endif  // ANDROID_MEDIA_EFFECTSCONFIG_H
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
new file mode 100644
index 0000000..97462f8
--- /dev/null
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsConfig"
+
+#include <algorithm>
+#include <cstdint>
+#include <functional>
+#include <string>
+
+#include <tinyxml2.h>
+#include <log/log.h>
+
+#include <media/EffectsConfig.h>
+
+using namespace tinyxml2;
+
+namespace android {
+namespace effectsConfig {
+
+/** All functions except `parse(const char*)` are static. */
+namespace {
+
+/** @return all `node`s children that are elements and match the tag if provided. */
+std::vector<std::reference_wrapper<const XMLElement>> getChildren(const XMLNode& node,
+                                                                  const char* childTag = nullptr) {
+    std::vector<std::reference_wrapper<const XMLElement>> children;
+    for (auto* child = node.FirstChildElement(childTag); child != nullptr;
+            child = child->NextSiblingElement(childTag)) {
+        children.emplace_back(*child);
+    }
+    return children;
+}
+
+/** @return xml dump of the provided element.
+ * By not providing a printer, it is implicitly created in the caller context.
+ * In such case the return pointer has the same lifetime as the expression containing dump().
+ */
+const char* dump(const XMLElement& element, XMLPrinter&& printer = {}) {
+    element.Accept(&printer);
+    return printer.CStr();
+}
+
+
+bool stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+    uint32_t tmp[10];
+
+    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        return false;
+    }
+    uuid->timeLow = (uint32_t)tmp[0];
+    uuid->timeMid = (uint16_t)tmp[1];
+    uuid->timeHiAndVersion = (uint16_t)tmp[2];
+    uuid->clockSeq = (uint16_t)tmp[3];
+    uuid->node[0] = (uint8_t)tmp[4];
+    uuid->node[1] = (uint8_t)tmp[5];
+    uuid->node[2] = (uint8_t)tmp[6];
+    uuid->node[3] = (uint8_t)tmp[7];
+    uuid->node[4] = (uint8_t)tmp[8];
+    uuid->node[5] = (uint8_t)tmp[9];
+
+    return true;
+}
+
+/** Map the enum and string representation of a string type.
+ *  Intended to be specialized for each enum to deserialize.
+ *  The general template is disabled.
+ */
+template <class Enum>
+constexpr std::enable_if<false, Enum> STREAM_NAME_MAP;
+
+/** All output stream types which support effects.
+ * This need to be kept in sink with the xsd streamOutputType.
+ */
+template <>
+constexpr std::pair<audio_stream_type_t, const char*> STREAM_NAME_MAP<audio_stream_type_t>[] = {
+        {AUDIO_STREAM_VOICE_CALL, "voice_call"},
+        {AUDIO_STREAM_SYSTEM, "system"},
+        {AUDIO_STREAM_RING, "ring"},
+        {AUDIO_STREAM_MUSIC, "music"},
+        {AUDIO_STREAM_ALARM, "alarm"},
+        {AUDIO_STREAM_NOTIFICATION, "notification"},
+        {AUDIO_STREAM_BLUETOOTH_SCO, "bluetooth_sco"},
+        {AUDIO_STREAM_ENFORCED_AUDIBLE, "enforced_audible"},
+        {AUDIO_STREAM_DTMF, "dtmf"},
+        {AUDIO_STREAM_TTS, "tts"},
+};
+
+/** All input stream types which support effects.
+ * This need to be kept in sink with the xsd streamOutputType.
+ */
+template <>
+constexpr std::pair<audio_source_t, const char*> STREAM_NAME_MAP<audio_source_t>[] = {
+        {AUDIO_SOURCE_MIC, "mic"},
+        {AUDIO_SOURCE_VOICE_UPLINK, "voice_uplink"},
+        {AUDIO_SOURCE_VOICE_DOWNLINK, "voice_downlink"},
+        {AUDIO_SOURCE_VOICE_CALL, "voice_call"},
+        {AUDIO_SOURCE_CAMCORDER, "camcorder"},
+        {AUDIO_SOURCE_VOICE_RECOGNITION, "voice_recognition"},
+        {AUDIO_SOURCE_VOICE_COMMUNICATION, "voice_communication"},
+        {AUDIO_SOURCE_UNPROCESSED, "unprocessed"},
+};
+
+/** Find the stream type enum corresponding to the stream type name or return false */
+template <class Type>
+bool stringToStreamType(const char *streamName, Type* type)
+{
+    for (auto& streamNamePair : STREAM_NAME_MAP<Type>) {
+        if (strcmp(streamNamePair.second, streamName) == 0) {
+            *type = streamNamePair.first;
+            return true;
+        }
+    }
+    return false;
+}
+
+/** Parse a library xml note and push the result in libraries or return false on failure. */
+bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) {
+    const char* name = xmlLibrary.Attribute("name");
+    const char* path = xmlLibrary.Attribute("path");
+    if (name == nullptr || path == nullptr) {
+        ALOGE("library must have a name and a path: %s", dump(xmlLibrary));
+        return false;
+    }
+    libraries->push_back({name, path});
+    return true;
+}
+
+/** Find an element in a collection by its name.
+ * @return nullptr if not found, the ellements address if found.
+ */
+template <class T>
+T* findByName(const char* name, std::vector<T>& collection) {
+    auto it = find_if(begin(collection), end(collection),
+                         [name] (auto& item) { return item.name == name; });
+    return it != end(collection) ? &*it : nullptr;
+}
+
+/** Parse an effect from an xml element describing it.
+ * @return true and pushes the effect in effects on success,
+ *         false on failure. */
+bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* effects) {
+    Effect effect{};
+
+    const char* name = xmlEffect.Attribute("name");
+    if (name == nullptr) {
+        ALOGE("%s must have a name: %s", xmlEffect.Value(), dump(xmlEffect));
+        return false;
+    }
+    effect.name = name;
+
+    // Function to parse effect.library and effect.uuid from xml
+    auto parseImpl = [&libraries](const XMLElement& xmlImpl, EffectImpl& effect) {
+        // Retrieve library name and uuid from xml
+        const char* libraryName = xmlImpl.Attribute("library");
+        const char* uuid = xmlImpl.Attribute("uuid");
+        if (libraryName == nullptr || uuid == nullptr) {
+            ALOGE("effect must have a library name and a uuid: %s", dump(xmlImpl));
+            return false;
+        }
+
+        // Convert library name to a pointer to the previously loaded library
+        auto* library = findByName(libraryName, libraries);
+        if (library == nullptr) {
+            ALOGE("Could not find library referenced in: %s", dump(xmlImpl));
+            return false;
+        }
+        effect.library = library;
+
+        if (!stringToUuid(uuid, &effect.uuid)) {
+            ALOGE("Invalid uuid in: %s", dump(xmlImpl));
+            return false;
+        }
+        return true;
+    };
+
+    if (!parseImpl(xmlEffect, effect)) {
+        return false;
+    }
+
+    // Handle proxy effects
+    effect.isProxy = false;
+    if (std::strcmp(xmlEffect.Name(), "effectProxy") == 0) {
+        effect.isProxy = true;
+
+        // Function to parse libhw and libsw
+        auto parseProxy = [&xmlEffect, &parseImpl](const char* tag, EffectImpl& proxyLib) {
+            auto* xmlProxyLib = xmlEffect.FirstChildElement(tag);
+            if (xmlProxyLib == nullptr) {
+                ALOGE("effectProxy must contain a <%s>: %s", tag, dump(*xmlProxyLib));
+                return false;
+            }
+            return parseImpl(*xmlProxyLib, proxyLib);
+        };
+        if (!parseProxy("libhw", effect.libHw) || !parseProxy("libsw", effect.libSw)) {
+            return false;
+        }
+    }
+
+    effects->push_back(std::move(effect));
+    return true;
+}
+
+/** Parse an stream from an xml element describing it.
+ * @return true and pushes the stream in streams on success,
+ *         false on failure. */
+template <class Stream>
+bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stream>* streams) {
+    const char* streamType = xmlStream.Attribute("type");
+    if (streamType == nullptr) {
+        ALOGE("stream must have a type: %s", dump(xmlStream));
+        return false;
+    }
+    Stream stream;
+    if (!stringToStreamType(streamType, &stream.type)) {
+        ALOGE("Invalid stream type %s: %s", streamType, dump(xmlStream));
+        return false;
+    }
+
+    for (auto& xmlApply : getChildren(xmlStream, "apply")) {
+        const char* effectName = xmlApply.get().Attribute("effect");
+        if (effectName == nullptr) {
+            ALOGE("stream/apply must have reference an effect: %s", dump(xmlApply));
+            return false;
+        }
+        auto* effect = findByName(effectName, effects);
+        if (effect == nullptr) {
+            ALOGE("Could not find effect referenced in: %s", dump(xmlApply));
+            return false;
+        }
+        stream.effects.emplace_back(*effect);
+    }
+    streams->push_back(std::move(stream));
+    return true;
+}
+
+}; // namespace
+
+ParsingResult parse(const char* path) {
+    XMLDocument doc;
+    doc.LoadFile(path);
+    if (doc.Error()) {
+        ALOGE("Failed to parse %s: Tinyxml2 error (%d): %s %s", path,
+              doc.ErrorID(), doc.GetErrorStr1(), doc.GetErrorStr2());
+        return {nullptr, 0};
+    }
+
+    auto config = std::make_unique<Config>();
+    size_t nbSkippedElements = 0;
+    auto registerFailure = [&nbSkippedElements](bool result) {
+        nbSkippedElements += result ? 0 : 1;
+    };
+    for (auto& xmlConfig : getChildren(doc, "audio_effects_conf")) {
+
+        // Parse library
+        for (auto& xmlLibraries : getChildren(xmlConfig, "libraries")) {
+            for (auto& xmlLibrary : getChildren(xmlLibraries, "library")) {
+                registerFailure(parseLibrary(xmlLibrary, &config->libraries));
+            }
+        }
+
+        // Parse effects
+        for (auto& xmlEffects : getChildren(xmlConfig, "effects")) {
+            for (auto& xmlEffect : getChildren(xmlEffects)) {
+                registerFailure(parseEffect(xmlEffect, config->libraries, &config->effects));
+            }
+        }
+
+        // Parse pre processing chains
+        for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) {
+            for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) {
+                registerFailure(parseStream(xmlStream, config->effects, &config->preprocess));
+            }
+        }
+
+        // Parse post processing chains
+        for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) {
+            for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) {
+                registerFailure(parseStream(xmlStream, config->effects, &config->postprocess));
+            }
+        }
+    }
+    return {std::move(config), nbSkippedElements};
+}
+
+} // namespace effectsConfig
+} // namespace android
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
index 73f6ef5..a5fbf14 100644
--- a/media/libeffects/downmix/Android.mk
+++ b/media/libeffects/downmix/Android.mk
@@ -20,6 +20,7 @@
 	$(call include-path-for, audio-effects) \
 	$(call include-path-for, audio-utils)
 
+#-DBUILD_FLOAT
 LOCAL_CFLAGS += -fvisibility=hidden
 LOCAL_CFLAGS += -Wall -Werror
 
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 7c685ec..b4a1d77 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -33,6 +33,10 @@
 
 #define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
 
+#ifdef BUILD_FLOAT
+#define MINUS_3_DB_IN_FLOAT 0.70710678f // -3dB = 0.70710678f
+#endif
+
 // subset of possible audio_channel_mask_t values, and AUDIO_CHANNEL_OUT_* renamed to CHANNEL_MASK_*
 typedef enum {
     CHANNEL_MASK_QUAD_BACK = AUDIO_CHANNEL_OUT_QUAD_BACK,
@@ -82,8 +86,19 @@
 
 // number of effects in this library
 const int kNbEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
-
-
+#ifdef BUILD_FLOAT
+static LVM_FLOAT clamp_float(LVM_FLOAT a) {
+    if (a > 1.0f) {
+        return 1.0f;
+    }
+    else if (a < -1.0f) {
+        return -1.0f;
+    }
+    else {
+        return a;
+    }
+}
+#endif
 /*----------------------------------------------------------------------------
  * Test code
  *--------------------------------------------------------------------------*/
@@ -286,7 +301,7 @@
     return -EINVAL;
 }
 
-
+#ifndef BUILD_FLOAT
 /*--- Effect Control Interface Implementation ---*/
 
 static int Downmix_Process(effect_handle_t self,
@@ -385,7 +400,108 @@
 
     return 0;
 }
+#else /*BUILD_FLOAT*/
+/*--- Effect Control Interface Implementation ---*/
 
+static int Downmix_Process(effect_handle_t self,
+        audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
+
+    downmix_object_t *pDownmixer;
+    LVM_FLOAT *pSrc, *pDst;
+    downmix_module_t *pDwmModule = (downmix_module_t *)self;
+
+    if (pDwmModule == NULL) {
+        return -EINVAL;
+    }
+
+    if (inBuffer == NULL || inBuffer->raw == NULL ||
+        outBuffer == NULL || outBuffer->raw == NULL ||
+        inBuffer->frameCount != outBuffer->frameCount) {
+        return -EINVAL;
+    }
+
+    pDownmixer = (downmix_object_t*) &pDwmModule->context;
+
+    if (pDownmixer->state == DOWNMIX_STATE_UNINITIALIZED) {
+        ALOGE("Downmix_Process error: trying to use an uninitialized downmixer");
+        return -EINVAL;
+    } else if (pDownmixer->state == DOWNMIX_STATE_INITIALIZED) {
+        ALOGE("Downmix_Process error: trying to use a non-configured downmixer");
+        return -ENODATA;
+    }
+
+    pSrc = (LVM_FLOAT *) inBuffer->s16;
+    pDst = (LVM_FLOAT *) outBuffer->s16;
+    size_t numFrames = outBuffer->frameCount;
+
+    const bool accumulate =
+            (pDwmModule->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
+    const uint32_t downmixInputChannelMask = pDwmModule->config.inputCfg.channels;
+
+    switch(pDownmixer->type) {
+
+      case DOWNMIX_TYPE_STRIP:
+          if (accumulate) {
+              while (numFrames) {
+                  pDst[0] = clamp_float(pDst[0] + pSrc[0]);
+                  pDst[1] = clamp_float(pDst[1] + pSrc[1]);
+                  pSrc += pDownmixer->input_channel_count;
+                  pDst += 2;
+                  numFrames--;
+              }
+          } else {
+              while (numFrames) {
+                  pDst[0] = pSrc[0];
+                  pDst[1] = pSrc[1];
+                  pSrc += pDownmixer->input_channel_count;
+                  pDst += 2;
+                  numFrames--;
+              }
+          }
+          break;
+
+      case DOWNMIX_TYPE_FOLD:
+#ifdef DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER
+          // bypass the optimized downmix routines for the common formats
+          if (!Downmix_foldGeneric(
+                  downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
+              ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported",
+                    downmixInputChannelMask);
+              return -EINVAL;
+          }
+          break;
+#endif
+        // optimize for the common formats
+        switch((downmix_input_channel_mask_t)downmixInputChannelMask) {
+        case CHANNEL_MASK_QUAD_BACK:
+        case CHANNEL_MASK_QUAD_SIDE:
+            Downmix_foldFromQuad(pSrc, pDst, numFrames, accumulate);
+            break;
+        case CHANNEL_MASK_5POINT1_BACK:
+        case CHANNEL_MASK_5POINT1_SIDE:
+            Downmix_foldFrom5Point1(pSrc, pDst, numFrames, accumulate);
+            break;
+        case CHANNEL_MASK_7POINT1:
+            Downmix_foldFrom7Point1(pSrc, pDst, numFrames, accumulate);
+            break;
+        default:
+            if (!Downmix_foldGeneric(
+                    downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
+                ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported",
+                      downmixInputChannelMask);
+                return -EINVAL;
+            }
+            break;
+        }
+        break;
+
+      default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+#endif
 
 static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
         void *pCmdData, uint32_t *replySize, void *pReplyData) {
@@ -822,6 +938,7 @@
  *
  *----------------------------------------------------------------------------
  */
+#ifndef BUILD_FLOAT
 void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
     // sample at index 0 is FL
     // sample at index 1 is FR
@@ -849,7 +966,35 @@
         }
     }
 }
-
+#else
+void Downmix_foldFromQuad(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is RL
+    // sample at index 3 is RR
+    if (accumulate) {
+        while (numFrames) {
+            // FL + RL
+            pDst[0] = clamp_float(pDst[0] + ((pSrc[0] + pSrc[2]) / 2.0f));
+            // FR + RR
+            pDst[1] = clamp_float(pDst[1] + ((pSrc[1] + pSrc[3]) / 2.0f));
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // FL + RL
+            pDst[0] = clamp_float((pSrc[0] + pSrc[2]) / 2.0f);
+            // FR + RR
+            pDst[1] = clamp_float((pSrc[1] + pSrc[3]) / 2.0f);
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+#endif
 
 /*----------------------------------------------------------------------------
  * Downmix_foldFrom5Point1()
@@ -868,6 +1013,7 @@
  *
  *----------------------------------------------------------------------------
  */
+#ifndef BUILD_FLOAT
 void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
     int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
     // sample at index 0 is FL
@@ -912,7 +1058,52 @@
         }
     }
 }
-
+#else
+void Downmix_foldFrom5Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+    LVM_FLOAT lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is FC
+    // sample at index 3 is LFE
+    // sample at index 4 is RL
+    // sample at index 5 is RR
+    // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+    // for every sample
+    if (accumulate) {
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+                    + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+            // FL + centerPlusLfeContrib + RL
+            lt = pSrc[0] + centerPlusLfeContrib + pSrc[4];
+            // FR + centerPlusLfeContrib + RR
+            rt = pSrc[1] + centerPlusLfeContrib + pSrc[5];
+            // accumulate in destination
+            pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+            pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+            pSrc += 6;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+                    + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+            // FL + centerPlusLfeContrib + RL
+            lt = pSrc[0] + centerPlusLfeContrib + pSrc[4];
+            // FR + centerPlusLfeContrib + RR
+            rt = pSrc[1] + centerPlusLfeContrib + pSrc[5];
+            // store in destination
+            pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+            pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+            pSrc += 6;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+#endif
 
 /*----------------------------------------------------------------------------
  * Downmix_foldFrom7Point1()
@@ -931,6 +1122,7 @@
  *
  *----------------------------------------------------------------------------
  */
+#ifndef BUILD_FLOAT
 void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
     int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
     // sample at index 0 is FL
@@ -977,8 +1169,54 @@
         }
     }
 }
-
-
+#else
+void Downmix_foldFrom7Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+    LVM_FLOAT lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is FC
+    // sample at index 3 is LFE
+    // sample at index 4 is RL
+    // sample at index 5 is RR
+    // sample at index 6 is SL
+    // sample at index 7 is SR
+    // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+    // for every sample
+    if (accumulate) {
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusLfeContrib + SL + RL
+            lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
+            // FR + centerPlusLfeContrib + SR + RR
+            rt = pSrc[1] + centerPlusLfeContrib + pSrc[7] + pSrc[5];
+            //accumulate in destination
+            pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+            pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+            pSrc += 8;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+                    + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
+            // FL + centerPlusLfeContrib + SL + RL
+            lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
+            // FR + centerPlusLfeContrib + SR + RR
+            rt = pSrc[1] + centerPlusLfeContrib + pSrc[7] + pSrc[5];
+            // store in destination
+            pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+            pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+            pSrc += 8;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+#endif
 /*----------------------------------------------------------------------------
  * Downmix_foldGeneric()
  *----------------------------------------------------------------------------
@@ -1005,6 +1243,7 @@
  *
  *----------------------------------------------------------------------------
  */
+#ifndef BUILD_FLOAT
 bool Downmix_foldGeneric(
         uint32_t mask, int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
 
@@ -1096,3 +1335,96 @@
     }
     return true;
 }
+#else
+bool Downmix_foldGeneric(
+        uint32_t mask, LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate) {
+
+    if (!Downmix_validChannelMask(mask)) {
+        return false;
+    }
+
+    const bool hasSides = (mask & kSides) != 0;
+    const bool hasBacks = (mask & kBacks) != 0;
+
+    const int numChan = audio_channel_count_from_out_mask(mask);
+    const bool hasFC = ((mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) == AUDIO_CHANNEL_OUT_FRONT_CENTER);
+    const bool hasLFE =
+            ((mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) == AUDIO_CHANNEL_OUT_LOW_FREQUENCY);
+    const bool hasBC = ((mask & AUDIO_CHANNEL_OUT_BACK_CENTER) == AUDIO_CHANNEL_OUT_BACK_CENTER);
+    // compute at what index each channel is: samples will be in the following order:
+    //   FL FR FC LFE BL BR BC SL SR
+    // when a channel is not present, its index is set to the same as the index of the preceding
+    // channel
+    const int indexFC  = hasFC    ? 2            : 1;        // front center
+    const int indexLFE = hasLFE   ? indexFC + 1  : indexFC;  // low frequency
+    const int indexBL  = hasBacks ? indexLFE + 1 : indexLFE; // back left
+    const int indexBR  = hasBacks ? indexBL + 1  : indexBL;  // back right
+    const int indexBC  = hasBC    ? indexBR + 1  : indexBR;  // back center
+    const int indexSL  = hasSides ? indexBC + 1  : indexBC;  // side left
+    const int indexSR  = hasSides ? indexSL + 1  : indexSL;  // side right
+
+    LVM_FLOAT lt, rt, centersLfeContrib;
+    // code is mostly duplicated between the two values of accumulate to avoid repeating the test
+    // for every sample
+    if (accumulate) {
+        while (numFrames) {
+            // compute contribution of FC, BC and LFE
+            centersLfeContrib = 0;
+            if (hasFC)  { centersLfeContrib += pSrc[indexFC]; }
+            if (hasLFE) { centersLfeContrib += pSrc[indexLFE]; }
+            if (hasBC)  { centersLfeContrib += pSrc[indexBC]; }
+            centersLfeContrib *= MINUS_3_DB_IN_FLOAT;
+            // always has FL/FR
+            lt = pSrc[0];
+            rt = pSrc[1];
+            // mix in sides and backs
+            if (hasSides) {
+                lt += pSrc[indexSL];
+                rt += pSrc[indexSR];
+            }
+            if (hasBacks) {
+                lt += pSrc[indexBL];
+                rt += pSrc[indexBR];
+            }
+            lt += centersLfeContrib;
+            rt += centersLfeContrib;
+            // accumulate in destination
+            pDst[0] = clamp_float(pDst[0] + (lt / 2.0f));
+            pDst[1] = clamp_float(pDst[1] + (rt / 2.0f));
+            pSrc += numChan;
+            pDst += 2;
+            numFrames--;
+        }
+    } else {
+        while (numFrames) {
+            // compute contribution of FC, BC and LFE
+            centersLfeContrib = 0;
+            if (hasFC)  { centersLfeContrib += pSrc[indexFC]; }
+            if (hasLFE) { centersLfeContrib += pSrc[indexLFE]; }
+            if (hasBC)  { centersLfeContrib += pSrc[indexBC]; }
+            centersLfeContrib *= MINUS_3_DB_IN_FLOAT;
+            // always has FL/FR
+            lt = pSrc[0];
+            rt = pSrc[1];
+            // mix in sides and backs
+            if (hasSides) {
+                lt += pSrc[indexSL];
+                rt += pSrc[indexSR];
+            }
+            if (hasBacks) {
+                lt += pSrc[indexBL];
+                rt += pSrc[indexBR];
+            }
+            lt += centersLfeContrib;
+            rt += centersLfeContrib;
+            // store in destination
+            pDst[0] = clamp_float(lt / 2.0f); // differs from when accumulate is true above
+            pDst[1] = clamp_float(rt / 2.0f); // differs from when accumulate is true above
+            pSrc += numChan;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+    return true;
+}
+#endif
\ No newline at end of file
diff --git a/media/libeffects/downmix/EffectDownmix.h b/media/libeffects/downmix/EffectDownmix.h
index 2399abd..c1be0f2 100644
--- a/media/libeffects/downmix/EffectDownmix.h
+++ b/media/libeffects/downmix/EffectDownmix.h
@@ -27,7 +27,9 @@
 */
 
 #define DOWNMIX_OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
-
+#ifdef BUILD_FLOAT
+#define LVM_FLOAT float
+#endif
 typedef enum {
     DOWNMIX_STATE_UNINITIALIZED,
     DOWNMIX_STATE_INITIALIZED,
@@ -95,11 +97,18 @@
 int Downmix_Reset(downmix_object_t *pDownmixer, bool init);
 int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t size, void *pValue);
 int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t *pSize, void *pValue);
-
+#ifdef BUILD_FLOAT
+void Downmix_foldFromQuad(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom5Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom7Point1(LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+bool Downmix_foldGeneric(
+        uint32_t mask, LVM_FLOAT *pSrc, LVM_FLOAT *pDst, size_t numFrames, bool accumulate);
+#else
 void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
 void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
 void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
 bool Downmix_foldGeneric(
         uint32_t mask, int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+#endif
 
 #endif /*ANDROID_EFFECTDOWNMIX_H_*/
diff --git a/media/libeffects/factory/Android.bp b/media/libeffects/factory/Android.bp
index 16680bd..ddbfdd8 100644
--- a/media/libeffects/factory/Android.bp
+++ b/media/libeffects/factory/Android.bp
@@ -10,18 +10,47 @@
 cc_library_shared {
     name: "libeffects",
     vendor: true,
-    srcs: ["EffectsFactory.c"],
+    srcs: [
+         "EffectsFactory.c",
+         "EffectsConfigLoader.c",
+         "EffectsFactoryState.c",
+         "EffectsXmlConfigLoader.cpp",
+    ],
 
     shared_libs: [
         "libcutils",
         "liblog",
         "libdl",
+        "libeffectsconfig",
     ],
-
-    include_dirs: ["system/media/audio_effects/include"],
+    cflags: ["-fvisibility=hidden"],
 
     local_include_dirs:["include/media"],
 
-    header_libs: ["libeffects_headers"],
+    header_libs: [
+        "libaudioeffects",
+        "libeffects_headers",
+    ],
     export_header_lib_headers: ["libeffects_headers"],
 }
+
+cc_binary {
+    name: "dumpEffectConfigFile",
+    vendor: true,
+    srcs: ["test/DumpConfig.cpp"],
+
+    compile_multilib: "32",
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+
+
+    shared_libs: [
+        "libeffectsconfig",
+        "libeffects",
+    ],
+    local_include_dirs:[".", "include"],
+}
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
new file mode 100644
index 0000000..fcef36f
--- /dev/null
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryConfigLoader"
+//#define LOG_NDEBUG 0
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/config_utils.h>
+#include <cutils/misc.h>
+#include <log/log.h>
+
+#include <system/audio_effects/audio_effects_conf.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+
+/////////////////////////////////////////////////
+//      Local functions prototypes
+/////////////////////////////////////////////////
+
+static int loadEffectConfigFile(const char *path);
+static int loadLibraries(cnode *root);
+static int loadLibrary(cnode *root, const char *name);
+static int loadEffects(cnode *root);
+static int loadEffect(cnode *node);
+// To get and add the effect pointed by the passed node to the gSubEffectList
+static int addSubEffect(cnode *root);
+static lib_entry_t *getLibrary(const char *path);
+
+static lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
+
+int EffectLoadEffectConfig()
+{
+    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+        return loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+        return loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+    }
+    return 0;
+}
+
+int loadEffectConfigFile(const char *path)
+{
+    cnode *root;
+    char *data;
+
+    data = load_file(path, NULL);
+    if (data == NULL) {
+        return -ENODEV;
+    }
+    root = config_node("", "");
+    config_load(root, data);
+    loadLibraries(root);
+    loadEffects(root);
+    config_free(root);
+    free(root);
+    free(data);
+
+    return 0;
+}
+
+int loadLibraries(cnode *root)
+{
+    cnode *node;
+
+    node = config_find(root, LIBRARIES_TAG);
+    if (node == NULL) {
+        return -ENOENT;
+    }
+    node = node->first_child;
+    while (node) {
+        loadLibrary(node, node->name);
+        node = node->next;
+    }
+    return 0;
+}
+
+#ifdef __LP64__
+// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
+static const char *kLibraryPathRoot[] =
+        {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#else
+static const char *kLibraryPathRoot[] =
+        {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#endif
+
+static const int kLibraryPathRootSize =
+        (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0]));
+
+// Checks if the library path passed as lib_path_in can be opened and if not
+// tries in standard effect library directories with just the library name and returns correct path
+// in lib_path_out
+int checkLibraryPath(const char *lib_path_in, char *lib_path_out) {
+    char *str;
+    const char *lib_name;
+    size_t len;
+
+    if (lib_path_in == NULL || lib_path_out == NULL) {
+        return -EINVAL;
+    }
+
+    strlcpy(lib_path_out, lib_path_in, PATH_MAX);
+
+    // Try exact path first
+    str = strstr(lib_path_out, "/lib/soundfx/");
+    if (str == NULL) {
+        return -EINVAL;
+    }
+
+    // Extract library name from input path
+    len = str - lib_path_out;
+    lib_name = lib_path_in + len + strlen("/lib/soundfx/");
+
+    // Then try with library name and standard path names in order of preference
+    for (int i = 0; i < kLibraryPathRootSize; i++) {
+        char path[PATH_MAX];
+
+        snprintf(path,
+                 PATH_MAX,
+                 "%s/%s",
+                 kLibraryPathRoot[i],
+                 lib_name);
+        if (F_OK == access(path, 0)) {
+            strcpy(lib_path_out, path);
+            ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
+                "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
+            return 0;
+        }
+    }
+    return -EINVAL;
+}
+
+
+
+int loadLibrary(cnode *root, const char *name)
+{
+    cnode *node;
+    void *hdl = NULL;
+    audio_effect_library_t *desc;
+    list_elem_t *e;
+    lib_entry_t *l;
+    char path[PATH_MAX];
+
+    node = config_find(root, PATH_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+
+    if (checkLibraryPath((const char *)node->value, path) != 0) {
+        ALOGW("loadLibrary() could not find library %s", path);
+        goto error;
+    }
+
+    hdl = dlopen(path, RTLD_NOW);
+    if (hdl == NULL) {
+        ALOGW("loadLibrary() failed to open %s", path);
+        goto error;
+    }
+
+    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+    if (desc == NULL) {
+        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+        goto error;
+    }
+
+    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
+        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
+        goto error;
+    }
+
+    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
+        ALOGW("loadLibrary() bad lib version %08x", desc->version);
+        goto error;
+    }
+
+    // add entry for library in gLibraryList
+    l = malloc(sizeof(lib_entry_t));
+    l->name = strndup(name, PATH_MAX);
+    l->path = strndup(path, PATH_MAX);
+    l->handle = hdl;
+    l->desc = desc;
+    l->effects = NULL;
+    pthread_mutex_init(&l->lock, NULL);
+
+    e = malloc(sizeof(list_elem_t));
+    e->object = l;
+    pthread_mutex_lock(&gLibLock);
+    e->next = gLibraryList;
+    gLibraryList = e;
+    pthread_mutex_unlock(&gLibLock);
+    ALOGV("getLibrary() linked library %p for path %s", l, path);
+
+    return 0;
+
+error:
+    if (hdl != NULL) {
+        dlclose(hdl);
+    }
+    //add entry for library errors in gLibraryFailedList
+    lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t));
+    fl->name = strndup(name, PATH_MAX);
+    fl->path = strndup(path, PATH_MAX);
+
+    list_elem_t *fe = malloc(sizeof(list_elem_t));
+    fe->object = fl;
+    fe->next = gLibraryFailedList;
+    gLibraryFailedList = fe;
+    ALOGV("getLibrary() linked error in library %p for path %s", fl, path);
+
+    return -EINVAL;
+}
+
+// This will find the library and UUID tags of the sub effect pointed by the
+// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
+// sub_entry_t to the gSubEffectList
+int addSubEffect(cnode *root)
+{
+    ALOGV("addSubEffect");
+    cnode *node;
+    effect_uuid_t uuid;
+    effect_descriptor_t *d;
+    lib_entry_t *l;
+    list_elem_t *e;
+    node = config_find(root, LIBRARY_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+    l = getLibrary(node->value);
+    if (l == NULL) {
+        ALOGW("addSubEffect() could not get library %s", node->value);
+        return -EINVAL;
+    }
+    node = config_find(root, UUID_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+    if (stringToUuid(node->value, &uuid) != 0) {
+        ALOGW("addSubEffect() invalid uuid %s", node->value);
+        return -EINVAL;
+    }
+    d = malloc(sizeof(effect_descriptor_t));
+    if (l->desc->get_descriptor(&uuid, d) != 0) {
+        char s[40];
+        uuidToString(&uuid, s, 40);
+        ALOGW("Error querying effect %s on lib %s", s, l->name);
+        free(d);
+        return -EINVAL;
+    }
+#if (LOG_NDEBUG==0)
+    char s[512];
+    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
+    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
+#endif
+    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+        free(d);
+        return -EINVAL;
+    }
+    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
+    sub_effect->object = d;
+    // lib_entry_t is stored since the sub effects are not linked to the library
+    sub_effect->lib = l;
+    e = malloc(sizeof(list_elem_t));
+    e->object = sub_effect;
+    e->next = gSubEffectList->sub_elem;
+    gSubEffectList->sub_elem = e;
+    ALOGV("addSubEffect end");
+    return 0;
+}
+
+int loadEffects(cnode *root)
+{
+    cnode *node;
+
+    node = config_find(root, EFFECTS_TAG);
+    if (node == NULL) {
+        return -ENOENT;
+    }
+    node = node->first_child;
+    while (node) {
+        loadEffect(node);
+        node = node->next;
+    }
+    return 0;
+}
+
+int loadEffect(cnode *root)
+{
+    cnode *node;
+    effect_uuid_t uuid;
+    lib_entry_t *l;
+    effect_descriptor_t *d;
+    list_elem_t *e;
+
+    node = config_find(root, LIBRARY_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+
+    l = getLibrary(node->value);
+    if (l == NULL) {
+        ALOGW("loadEffect() could not get library %s", node->value);
+        return -EINVAL;
+    }
+
+    node = config_find(root, UUID_TAG);
+    if (node == NULL) {
+        return -EINVAL;
+    }
+    if (stringToUuid(node->value, &uuid) != 0) {
+        ALOGW("loadEffect() invalid uuid %s", node->value);
+        return -EINVAL;
+    }
+    lib_entry_t *tmp;
+    bool skip = false;
+    if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
+        ALOGW("skipping duplicate uuid %s %s", node->value,
+                node->next ? "and its sub-effects" : "");
+        skip = true;
+    }
+
+    d = malloc(sizeof(effect_descriptor_t));
+    if (l->desc->get_descriptor(&uuid, d) != 0) {
+        char s[40];
+        uuidToString(&uuid, s, 40);
+        ALOGW("Error querying effect %s on lib %s", s, l->name);
+        free(d);
+        return -EINVAL;
+    }
+#if (LOG_NDEBUG==0)
+    char s[512];
+    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
+    ALOGV("loadEffect() read descriptor %p:%s",d, s);
+#endif
+    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
+        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
+        free(d);
+        return -EINVAL;
+    }
+    e = malloc(sizeof(list_elem_t));
+    e->object = d;
+    if (skip) {
+        e->next = gSkippedEffects;
+        gSkippedEffects = e;
+        return -EINVAL;
+    } else {
+        e->next = l->effects;
+        l->effects = e;
+    }
+
+    // After the UUID node in the config_tree, if node->next is valid,
+    // that would be sub effect node.
+    // Find the sub effects and add them to the gSubEffectList
+    node = node->next;
+    int count = 2;
+    bool hwSubefx = false, swSubefx = false;
+    list_sub_elem_t *sube = NULL;
+    if (node != NULL) {
+        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
+        sube = malloc(sizeof(list_sub_elem_t));
+        sube->object = d;
+        sube->sub_elem = NULL;
+        sube->next = gSubEffectList;
+        gSubEffectList = sube;
+    }
+    while (node != NULL && count) {
+       if (addSubEffect(node)) {
+           ALOGW("loadEffect() could not add subEffect %s", node->value);
+           // Change the gSubEffectList to point to older list;
+           gSubEffectList = sube->next;
+           free(sube->sub_elem);// Free an already added sub effect
+           sube->sub_elem = NULL;
+           free(sube);
+           return -ENOENT;
+       }
+       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
+       // get_descriptor call,we replace it with the correspoding
+       // sw effect descriptor, but with Proxy UUID
+       // check for Sw desc
+        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
+                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
+             swSubefx = true;
+             *d = *subEffectDesc;
+             d->uuid = uuid;
+             ALOGV("loadEffect() Changed the Proxy desc");
+       } else
+           hwSubefx = true;
+       count--;
+       node = node->next;
+    }
+    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
+    if (hwSubefx && swSubefx) {
+        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+    }
+    return 0;
+}
+
+lib_entry_t *getLibrary(const char *name)
+{
+    list_elem_t *e;
+
+    if (gCachedLibrary &&
+            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
+        return gCachedLibrary;
+    }
+
+    e = gLibraryList;
+    while (e) {
+        lib_entry_t *l = (lib_entry_t *)e->object;
+        if (!strcmp(l->name, name)) {
+            gCachedLibrary = l;
+            return l;
+        }
+        e = e->next;
+    }
+
+    return NULL;
+}
diff --git a/media/libeffects/factory/EffectsConfigLoader.h b/media/libeffects/factory/EffectsConfigLoader.h
new file mode 100644
index 0000000..3f82609
--- /dev/null
+++ b/media/libeffects/factory/EffectsConfigLoader.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSCONFIGLOADER_H
+#define ANDROID_EFFECTSCONFIGLOADER_H
+
+#include <cutils/compiler.h>
+#include "EffectsFactoryState.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/** Parses the platform effect configuration
+ * and stores its content in the global EffectFactoryState. */
+ANDROID_API
+int EffectLoadEffectConfig();
+
+
+#ifdef  __cplusplus
+} // extern "C"
+#endif
+
+#endif  // ANDROID_EFFECTSCONFIGLOADER_H
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index 37c0bb7..cd0e765 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -17,65 +17,46 @@
 #define LOG_TAG "EffectsFactory"
 //#define LOG_NDEBUG 0
 
-#include "EffectsFactory.h"
-
-#include <dlfcn.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#include <cutils/config_utils.h>
-#include <cutils/misc.h>
 #include <cutils/properties.h>
 #include <log/log.h>
 
-#include <system/audio_effects/audio_effects_conf.h>
+#include <media/EffectsFactoryApi.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+#include "EffectsXmlConfigLoader.h"
+
+#include "EffectsFactory.h"
 
 static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
-static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
-static list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid
-// list of effect_descriptor and list of sub effects : all currently loaded
-// It does not contain effects without sub effects.
-static list_sub_elem_t *gSubEffectList;
-static pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
 static uint32_t gNumEffects;         // total number number of effects
 static list_elem_t *gCurLib;    // current library in enumeration process
 static list_elem_t *gCurEffect; // current effect in enumeration process
 static uint32_t gCurEffectIdx;       // current effect index in enumeration process
-static lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
+/** Number of elements skipped during the effects configuration loading.
+ *  -1 if the config loader failed
+ *  -2 if config load was skipped
+ */
+static ssize_t gConfigNbElemSkipped = -2;
 
 static int gInitDone; // true is global initialization has been preformed
 static int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
                           // was not modified since last call to EffectQueryNumberEffects()
-
-static list_elem_t *gLibraryFailedList;  //list of lib_failed_entry_t: libraries failed to load
-
 /////////////////////////////////////////////////
 //      Local functions prototypes
 /////////////////////////////////////////////////
 
 static int init();
-static int loadEffectConfigFile(const char *path);
-static int loadLibraries(cnode *root);
-static int loadLibrary(cnode *root, const char *name);
-static int loadEffects(cnode *root);
-static int loadEffect(cnode *node);
-// To get and add the effect pointed by the passed node to the gSubEffectList
-static int addSubEffect(cnode *root);
-static lib_entry_t *getLibrary(const char *path);
 static void resetEffectEnumeration();
 static uint32_t updateNumEffects();
-static int findEffect(const effect_uuid_t *type,
-               const effect_uuid_t *uuid,
-               lib_entry_t **lib,
-               effect_descriptor_t **desc);
 // To search a subeffect in the gSubEffectList
 static int findSubEffect(const effect_uuid_t *uuid,
                lib_entry_t **lib,
                effect_descriptor_t **desc);
-static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
-static int stringToUuid(const char *str, effect_uuid_t *uuid);
-static int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
 
 /////////////////////////////////////////////////
 //      Effect Control Interface functions
@@ -461,10 +442,12 @@
     if (ignoreFxConfFiles) {
         ALOGI("Audio effects in configuration files will be ignored");
     } else {
-        if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
-            loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
-        } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
-            loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+        gConfigNbElemSkipped = EffectLoadXmlEffectConfig(NULL);
+        if (gConfigNbElemSkipped < 0) {
+            ALOGW("Failed to load XML effect configuration, fallback to .conf");
+            EffectLoadEffectConfig();
+        } else if (gConfigNbElemSkipped > 0) {
+            ALOGE("Effect config is partially invalid, skipped %zd elements", gConfigNbElemSkipped);
         }
     }
 
@@ -474,367 +457,6 @@
     return 0;
 }
 
-int loadEffectConfigFile(const char *path)
-{
-    cnode *root;
-    char *data;
-
-    data = load_file(path, NULL);
-    if (data == NULL) {
-        return -ENODEV;
-    }
-    root = config_node("", "");
-    config_load(root, data);
-    loadLibraries(root);
-    loadEffects(root);
-    config_free(root);
-    free(root);
-    free(data);
-
-    return 0;
-}
-
-int loadLibraries(cnode *root)
-{
-    cnode *node;
-
-    node = config_find(root, LIBRARIES_TAG);
-    if (node == NULL) {
-        return -ENOENT;
-    }
-    node = node->first_child;
-    while (node) {
-        loadLibrary(node, node->name);
-        node = node->next;
-    }
-    return 0;
-}
-
-#ifdef __LP64__
-// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
-static const char *kLibraryPathRoot[] =
-        {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
-#else
-static const char *kLibraryPathRoot[] =
-        {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
-#endif
-
-static const int kLibraryPathRootSize =
-        (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0]));
-
-// Checks if the library path passed as lib_path_in can be opened and if not
-// tries in standard effect library directories with just the library name and returns correct path
-// in lib_path_out
-int checkLibraryPath(const char *lib_path_in, char *lib_path_out) {
-    char *str;
-    const char *lib_name;
-    size_t len;
-
-    if (lib_path_in == NULL || lib_path_out == NULL) {
-        return -EINVAL;
-    }
-
-    strlcpy(lib_path_out, lib_path_in, PATH_MAX);
-
-    // Try exact path first
-    str = strstr(lib_path_out, "/lib/soundfx/");
-    if (str == NULL) {
-        return -EINVAL;
-    }
-
-    // Extract library name from input path
-    len = str - lib_path_out;
-    lib_name = lib_path_in + len + strlen("/lib/soundfx/");
-
-    // Then try with library name and standard path names in order of preference
-    for (int i = 0; i < kLibraryPathRootSize; i++) {
-        char path[PATH_MAX];
-
-        snprintf(path,
-                 PATH_MAX,
-                 "%s/%s",
-                 kLibraryPathRoot[i],
-                 lib_name);
-        if (F_OK == access(path, 0)) {
-            strcpy(lib_path_out, path);
-            ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
-                "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
-            return 0;
-        }
-    }
-    return -EINVAL;
-}
-
-
-
-int loadLibrary(cnode *root, const char *name)
-{
-    cnode *node;
-    void *hdl = NULL;
-    audio_effect_library_t *desc;
-    list_elem_t *e;
-    lib_entry_t *l;
-    char path[PATH_MAX];
-
-    node = config_find(root, PATH_TAG);
-    if (node == NULL) {
-        return -EINVAL;
-    }
-
-    if (checkLibraryPath((const char *)node->value, path) != 0) {
-        ALOGW("loadLibrary() could not find library %s", path);
-        goto error;
-    }
-
-    hdl = dlopen(path, RTLD_NOW);
-    if (hdl == NULL) {
-        ALOGW("loadLibrary() failed to open %s", path);
-        goto error;
-    }
-
-    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
-    if (desc == NULL) {
-        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
-        goto error;
-    }
-
-    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
-        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
-        goto error;
-    }
-
-    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
-            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
-        ALOGW("loadLibrary() bad lib version %08x", desc->version);
-        goto error;
-    }
-
-    // add entry for library in gLibraryList
-    l = malloc(sizeof(lib_entry_t));
-    l->name = strndup(name, PATH_MAX);
-    l->path = strndup(path, PATH_MAX);
-    l->handle = hdl;
-    l->desc = desc;
-    l->effects = NULL;
-    pthread_mutex_init(&l->lock, NULL);
-
-    e = malloc(sizeof(list_elem_t));
-    e->object = l;
-    pthread_mutex_lock(&gLibLock);
-    e->next = gLibraryList;
-    gLibraryList = e;
-    pthread_mutex_unlock(&gLibLock);
-    ALOGV("getLibrary() linked library %p for path %s", l, path);
-
-    return 0;
-
-error:
-    if (hdl != NULL) {
-        dlclose(hdl);
-    }
-    //add entry for library errors in gLibraryFailedList
-    lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t));
-    fl->name = strndup(name, PATH_MAX);
-    fl->path = strndup(path, PATH_MAX);
-
-    list_elem_t *fe = malloc(sizeof(list_elem_t));
-    fe->object = fl;
-    fe->next = gLibraryFailedList;
-    gLibraryFailedList = fe;
-    ALOGV("getLibrary() linked error in library %p for path %s", fl, path);
-
-    return -EINVAL;
-}
-
-// This will find the library and UUID tags of the sub effect pointed by the
-// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
-// sub_entry_t to the gSubEffectList
-int addSubEffect(cnode *root)
-{
-    ALOGV("addSubEffect");
-    cnode *node;
-    effect_uuid_t uuid;
-    effect_descriptor_t *d;
-    lib_entry_t *l;
-    list_elem_t *e;
-    node = config_find(root, LIBRARY_TAG);
-    if (node == NULL) {
-        return -EINVAL;
-    }
-    l = getLibrary(node->value);
-    if (l == NULL) {
-        ALOGW("addSubEffect() could not get library %s", node->value);
-        return -EINVAL;
-    }
-    node = config_find(root, UUID_TAG);
-    if (node == NULL) {
-        return -EINVAL;
-    }
-    if (stringToUuid(node->value, &uuid) != 0) {
-        ALOGW("addSubEffect() invalid uuid %s", node->value);
-        return -EINVAL;
-    }
-    d = malloc(sizeof(effect_descriptor_t));
-    if (l->desc->get_descriptor(&uuid, d) != 0) {
-        char s[40];
-        uuidToString(&uuid, s, 40);
-        ALOGW("Error querying effect %s on lib %s", s, l->name);
-        free(d);
-        return -EINVAL;
-    }
-#if (LOG_NDEBUG==0)
-    char s[512];
-    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
-    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
-#endif
-    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
-            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
-        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
-        free(d);
-        return -EINVAL;
-    }
-    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
-    sub_effect->object = d;
-    // lib_entry_t is stored since the sub effects are not linked to the library
-    sub_effect->lib = l;
-    e = malloc(sizeof(list_elem_t));
-    e->object = sub_effect;
-    e->next = gSubEffectList->sub_elem;
-    gSubEffectList->sub_elem = e;
-    ALOGV("addSubEffect end");
-    return 0;
-}
-
-int loadEffects(cnode *root)
-{
-    cnode *node;
-
-    node = config_find(root, EFFECTS_TAG);
-    if (node == NULL) {
-        return -ENOENT;
-    }
-    node = node->first_child;
-    while (node) {
-        loadEffect(node);
-        node = node->next;
-    }
-    return 0;
-}
-
-int loadEffect(cnode *root)
-{
-    cnode *node;
-    effect_uuid_t uuid;
-    lib_entry_t *l;
-    effect_descriptor_t *d;
-    list_elem_t *e;
-
-    node = config_find(root, LIBRARY_TAG);
-    if (node == NULL) {
-        return -EINVAL;
-    }
-
-    l = getLibrary(node->value);
-    if (l == NULL) {
-        ALOGW("loadEffect() could not get library %s", node->value);
-        return -EINVAL;
-    }
-
-    node = config_find(root, UUID_TAG);
-    if (node == NULL) {
-        return -EINVAL;
-    }
-    if (stringToUuid(node->value, &uuid) != 0) {
-        ALOGW("loadEffect() invalid uuid %s", node->value);
-        return -EINVAL;
-    }
-    lib_entry_t *tmp;
-    bool skip = false;
-    if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
-        ALOGW("skipping duplicate uuid %s %s", node->value,
-                node->next ? "and its sub-effects" : "");
-        skip = true;
-    }
-
-    d = malloc(sizeof(effect_descriptor_t));
-    if (l->desc->get_descriptor(&uuid, d) != 0) {
-        char s[40];
-        uuidToString(&uuid, s, 40);
-        ALOGW("Error querying effect %s on lib %s", s, l->name);
-        free(d);
-        return -EINVAL;
-    }
-#if (LOG_NDEBUG==0)
-    char s[512];
-    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
-    ALOGV("loadEffect() read descriptor %p:%s",d, s);
-#endif
-    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
-            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
-        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
-        free(d);
-        return -EINVAL;
-    }
-    e = malloc(sizeof(list_elem_t));
-    e->object = d;
-    if (skip) {
-        e->next = gSkippedEffects;
-        gSkippedEffects = e;
-        return -EINVAL;
-    } else {
-        e->next = l->effects;
-        l->effects = e;
-    }
-
-    // After the UUID node in the config_tree, if node->next is valid,
-    // that would be sub effect node.
-    // Find the sub effects and add them to the gSubEffectList
-    node = node->next;
-    int count = 2;
-    bool hwSubefx = false, swSubefx = false;
-    list_sub_elem_t *sube = NULL;
-    if (node != NULL) {
-        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
-        sube = malloc(sizeof(list_sub_elem_t));
-        sube->object = d;
-        sube->sub_elem = NULL;
-        sube->next = gSubEffectList;
-        gSubEffectList = sube;
-    }
-    while (node != NULL && count) {
-       if (addSubEffect(node)) {
-           ALOGW("loadEffect() could not add subEffect %s", node->value);
-           // Change the gSubEffectList to point to older list;
-           gSubEffectList = sube->next;
-           free(sube->sub_elem);// Free an already added sub effect
-           sube->sub_elem = NULL;
-           free(sube);
-           return -ENOENT;
-       }
-       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
-       // get_descriptor call,we replace it with the correspoding
-       // sw effect descriptor, but with Proxy UUID
-       // check for Sw desc
-        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
-                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
-             swSubefx = true;
-             *d = *subEffectDesc;
-             d->uuid = uuid;
-             ALOGV("loadEffect() Changed the Proxy desc");
-       } else
-           hwSubefx = true;
-       count--;
-       node = node->next;
-    }
-    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
-    if (hwSubefx && swSubefx) {
-        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
-    }
-    return 0;
-}
-
 // Searches the sub effect matching to the specified uuid
 // in the gSubEffectList. It gets the lib_entry_t for
 // the matched sub_effect . Used in EffectCreate of sub effects
@@ -881,29 +503,6 @@
     return ret;
 }
 
-lib_entry_t *getLibrary(const char *name)
-{
-    list_elem_t *e;
-
-    if (gCachedLibrary &&
-            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
-        return gCachedLibrary;
-    }
-
-    e = gLibraryList;
-    while (e) {
-        lib_entry_t *l = (lib_entry_t *)e->object;
-        if (!strcmp(l->name, name)) {
-            gCachedLibrary = l;
-            return l;
-        }
-        e = e->next;
-    }
-
-    return NULL;
-}
-
-
 void resetEffectEnumeration()
 {
     gCurLib = gLibraryList;
@@ -935,114 +534,6 @@
     return cnt;
 }
 
-int findEffect(const effect_uuid_t *type,
-               const effect_uuid_t *uuid,
-               lib_entry_t **lib,
-               effect_descriptor_t **desc)
-{
-    list_elem_t *e = gLibraryList;
-    lib_entry_t *l = NULL;
-    effect_descriptor_t *d = NULL;
-    int found = 0;
-    int ret = 0;
-
-    while (e && !found) {
-        l = (lib_entry_t *)e->object;
-        list_elem_t *efx = l->effects;
-        while (efx) {
-            d = (effect_descriptor_t *)efx->object;
-            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
-                found = 1;
-                break;
-            }
-            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
-                found = 1;
-                break;
-            }
-            efx = efx->next;
-        }
-        e = e->next;
-    }
-    if (!found) {
-        ALOGV("findEffect() effect not found");
-        ret = -ENOENT;
-    } else {
-        ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
-        *lib = l;
-        if (desc) {
-            *desc = d;
-        }
-    }
-
-    return ret;
-}
-
-void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
-    char s[256];
-    char ss[256];
-    char idt[indent + 1];
-
-    memset(idt, ' ', indent);
-    idt[indent] = 0;
-
-    str[0] = 0;
-
-    snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
-    strlcat(str, s, len);
-
-    uuidToString(&desc->uuid, s, sizeof(s));
-    snprintf(ss, sizeof(ss), "%s  UUID: %s\n", idt, s);
-    strlcat(str, ss, len);
-
-    uuidToString(&desc->type, s, sizeof(s));
-    snprintf(ss, sizeof(ss), "%s  TYPE: %s\n", idt, s);
-    strlcat(str, ss, len);
-
-    sprintf(s, "%s  apiVersion: %08X\n%s  flags: %08X\n", idt,
-            desc->apiVersion, idt, desc->flags);
-    strlcat(str, s, len);
-}
-
-int stringToUuid(const char *str, effect_uuid_t *uuid)
-{
-    int tmp[10];
-
-    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
-            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
-        return -EINVAL;
-    }
-    uuid->timeLow = (uint32_t)tmp[0];
-    uuid->timeMid = (uint16_t)tmp[1];
-    uuid->timeHiAndVersion = (uint16_t)tmp[2];
-    uuid->clockSeq = (uint16_t)tmp[3];
-    uuid->node[0] = (uint8_t)tmp[4];
-    uuid->node[1] = (uint8_t)tmp[5];
-    uuid->node[2] = (uint8_t)tmp[6];
-    uuid->node[3] = (uint8_t)tmp[7];
-    uuid->node[4] = (uint8_t)tmp[8];
-    uuid->node[5] = (uint8_t)tmp[9];
-
-    return 0;
-}
-
-int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
-{
-
-    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
-            uuid->timeLow,
-            uuid->timeMid,
-            uuid->timeHiAndVersion,
-            uuid->clockSeq,
-            uuid->node[0],
-            uuid->node[1],
-            uuid->node[2],
-            uuid->node[3],
-            uuid->node[4],
-            uuid->node[5]);
-
-    return 0;
-}
-
 int EffectDumpEffects(int fd) {
     char s[512];
 
@@ -1092,6 +583,20 @@
             e = e->next;
         }
     }
+    switch (gConfigNbElemSkipped) {
+    case -2:
+        dprintf(fd, "Effect configuration loading skipped.\n");
+        break;
+    case -1:
+        dprintf(fd, "XML effect configuration failed to load.\n");
+        break;
+    case 0:
+        dprintf(fd, "XML effect configuration loaded successfully.\n");
+        break;
+    default:
+        dprintf(fd, "XML effect configuration partially loaded, skipped %zd elements.\n",
+                gConfigNbElemSkipped);
+    }
     return ret;
 }
 
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index 72e0931..29dbc9c 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -20,7 +20,7 @@
 #include <dirent.h>
 #include <pthread.h>
 
-#include <android/log.h>
+#include <cutils/compiler.h>
 #include <hardware/audio_effect.h>
 
 #if __cplusplus
@@ -96,6 +96,7 @@
 //        *pDescriptor:     updated with the sub effect descriptors.
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectGetSubEffects(const effect_uuid_t *pEffectUuid,
                         sub_effect_entry_t **pSube,
                         size_t size);
diff --git a/media/libeffects/factory/EffectsFactoryState.c b/media/libeffects/factory/EffectsFactoryState.c
new file mode 100644
index 0000000..b364004
--- /dev/null
+++ b/media/libeffects/factory/EffectsFactoryState.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryState"
+
+#include "EffectsFactoryState.h"
+
+#include "log/log.h"
+
+list_elem_t *gLibraryList;
+list_elem_t *gSkippedEffects;
+list_sub_elem_t *gSubEffectList;
+pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER;
+
+list_elem_t *gLibraryFailedList;  //list of lib_failed_entry_t: libraries failed to load
+
+
+int findEffect(const effect_uuid_t *type,
+               const effect_uuid_t *uuid,
+               lib_entry_t **lib,
+               effect_descriptor_t **desc)
+{
+    list_elem_t *e = gLibraryList;
+    lib_entry_t *l = NULL;
+    effect_descriptor_t *d = NULL;
+    int found = 0;
+    int ret = 0;
+
+    while (e && !found) {
+        l = (lib_entry_t *)e->object;
+        list_elem_t *efx = l->effects;
+        while (efx) {
+            d = (effect_descriptor_t *)efx->object;
+            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
+                found = 1;
+                break;
+            }
+            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
+                found = 1;
+                break;
+            }
+            efx = efx->next;
+        }
+        e = e->next;
+    }
+    if (!found) {
+        ALOGV("findEffect() effect not found");
+        ret = -ENOENT;
+    } else {
+        ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
+        *lib = l;
+        if (desc) {
+            *desc = d;
+        }
+    }
+
+    return ret;
+}
+
+int stringToUuid(const char *str, effect_uuid_t *uuid)
+{
+    int tmp[10];
+
+    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        return -EINVAL;
+    }
+    uuid->timeLow = (uint32_t)tmp[0];
+    uuid->timeMid = (uint16_t)tmp[1];
+    uuid->timeHiAndVersion = (uint16_t)tmp[2];
+    uuid->clockSeq = (uint16_t)tmp[3];
+    uuid->node[0] = (uint8_t)tmp[4];
+    uuid->node[1] = (uint8_t)tmp[5];
+    uuid->node[2] = (uint8_t)tmp[6];
+    uuid->node[3] = (uint8_t)tmp[7];
+    uuid->node[4] = (uint8_t)tmp[8];
+    uuid->node[5] = (uint8_t)tmp[9];
+
+    return 0;
+}
+
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
+{
+
+    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            uuid->timeLow,
+            uuid->timeMid,
+            uuid->timeHiAndVersion,
+            uuid->clockSeq,
+            uuid->node[0],
+            uuid->node[1],
+            uuid->node[2],
+            uuid->node[3],
+            uuid->node[4],
+            uuid->node[5]);
+
+    return 0;
+}
+
+
+void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
+    char s[256];
+    char ss[256];
+    char idt[indent + 1];
+
+    memset(idt, ' ', indent);
+    idt[indent] = 0;
+
+    str[0] = 0;
+
+    snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
+    strlcat(str, s, len);
+
+    uuidToString(&desc->uuid, s, sizeof(s));
+    snprintf(ss, sizeof(ss), "%s  UUID: %s\n", idt, s);
+    strlcat(str, ss, len);
+
+    uuidToString(&desc->type, s, sizeof(s));
+    snprintf(ss, sizeof(ss), "%s  TYPE: %s\n", idt, s);
+    strlcat(str, ss, len);
+
+    sprintf(s, "%s  apiVersion: %08X\n%s  flags: %08X\n", idt,
+            desc->apiVersion, idt, desc->flags);
+    strlcat(str, s, len);
+}
diff --git a/media/libeffects/factory/EffectsFactoryState.h b/media/libeffects/factory/EffectsFactoryState.h
new file mode 100644
index 0000000..aef945e
--- /dev/null
+++ b/media/libeffects/factory/EffectsFactoryState.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSFACTORYSTATE_H_
+#define ANDROID_EFFECTSFACTORYSTATE_H_
+
+#include "EffectsFactory.h"
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/** @file Contains the state shared with configuration loader of the Effect factory.
+ *        This global state should probably be refactor in a structure
+ *        provided by the config loader on EffectsFactory init.
+ *        This header also contains some helper functions to work on the state.
+ */
+
+extern list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
+// list of effects skipped because of duplicate uuid or invalid version
+extern list_elem_t *gSkippedEffects;
+// list of effect_descriptor and list of sub effects : all currently loaded
+// It does not contain effects without sub effects.
+extern list_sub_elem_t *gSubEffectList;
+extern pthread_mutex_t gLibLock; // controls access to gLibraryList
+
+extern list_elem_t *gLibraryFailedList;  //list of lib_failed_entry_t: libraries failed to load
+
+
+
+int findEffect(const effect_uuid_t *type,
+               const effect_uuid_t *uuid,
+               lib_entry_t **lib,
+               effect_descriptor_t **desc);
+
+int stringToUuid(const char *str, effect_uuid_t *uuid);
+/** Used to log UUIDs */
+int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
+
+/** Used for debuging. */
+void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_EFFECTSFACTORYSTATE_H_
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
new file mode 100644
index 0000000..438b787
--- /dev/null
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactoryConfigLoader"
+//#define LOG_NDEBUG 0
+
+#include <dlfcn.h>
+#include <set>
+#include <stdlib.h>
+#include <string>
+
+#include <log/log.h>
+
+#include <media/EffectsConfig.h>
+
+#include "EffectsConfigLoader.h"
+#include "EffectsFactoryState.h"
+#include "EffectsXmlConfigLoader.h"
+
+namespace android {
+
+using namespace effectsConfig;
+
+/////////////////////////////////////////////////
+//      Local functions
+/////////////////////////////////////////////////
+
+namespace {
+
+/** Similarly to dlopen, looks for the provided path in LD_EFFECT_LIBRARY_PATH.
+ * @return true if the library is found and set resolvedPath to its absolute path.
+ *         false if not found
+ */
+bool resolveLibrary(const std::string& path, std::string* resolvedPath) {
+    for (auto* libraryDirectory : LD_EFFECT_LIBRARY_PATH) {
+        std::string candidatePath = std::string(libraryDirectory) + '/' + path;
+        if (access(candidatePath.c_str(), R_OK) == 0) {
+            *resolvedPath = std::move(candidatePath);
+            return true;
+        }
+    }
+    return false;
+}
+
+/** Loads a library given its relative path and stores the result in libEntry.
+ * @return true on success with libEntry's path, handle and desc filled
+ *         false on success with libEntry's path filled with the path of the failed lib
+ * The caller MUST free the resources path (free) and handle (dlclose) if filled.
+ */
+bool loadLibrary(const char* relativePath, lib_entry_t* libEntry) noexcept {
+
+    std::string absolutePath;
+    if (!resolveLibrary(relativePath, &absolutePath)) {
+        ALOGE("Could not find library in effect directories: %s", relativePath);
+        libEntry->path = strdup(relativePath);
+        return false;
+    }
+    const char* path = absolutePath.c_str();
+    libEntry->path = strdup(path);
+
+    // Make sure the lib is closed on early return
+    std::unique_ptr<void, decltype(dlclose)*> libHandle(dlopen(path, RTLD_NOW),
+                                                       dlclose);
+    if (libHandle == nullptr) {
+        ALOGE("Could not dlopen library %s: %s", path, dlerror());
+        return false;
+    }
+
+    auto* description = static_cast<audio_effect_library_t*>(
+          dlsym(libHandle.get(), AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR));
+    if (description == nullptr) {
+        ALOGE("Invalid effect library, failed not find symbol '%s' in %s: %s",
+              AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR, path, dlerror());
+        return false;
+    }
+
+    if (description->tag != AUDIO_EFFECT_LIBRARY_TAG) {
+        ALOGE("Bad tag %#08x in description structure, expected %#08x for library %s",
+              description->tag, AUDIO_EFFECT_LIBRARY_TAG, path);
+        return false;
+    }
+
+    uint32_t majorVersion = EFFECT_API_VERSION_MAJOR(description->version);
+    uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION);
+    if (majorVersion != expectedMajorVersion) {
+        ALOGE("Unsupported major version %#08x, expected %#08x for library %s",
+              majorVersion, expectedMajorVersion, path);
+        return false;
+    }
+
+    libEntry->handle = libHandle.release();
+    libEntry->desc = description;
+    return true;
+}
+
+/** Because the structures will be destroyed by c code, using new to allocate shared structure
+ * is not possible. Provide a equivalent of unique_ptr for malloc/freed structure to make sure
+ * they are not leaked in the c++ code.
+ @{ */
+struct FreeDeleter {
+    void operator()(void* p) {
+        free(p);
+    }
+};
+/** unique_ptr for object created with malloc. */
+template <class T>
+using UniqueCPtr = std::unique_ptr<T, FreeDeleter>;
+
+/** c version of std::make_unique. Uses malloc and free. */
+template <class T>
+UniqueCPtr<T> makeUniqueC() {
+    T* ptr = new (malloc(sizeof(T))) T{}; // Use placement new to initialize the structure
+    return UniqueCPtr<T>{ptr};
+}
+
+/** @} */
+
+/** Push an not owned element in a list_elem link list with an optional lock. */
+template <class T, class ListElem>
+void listPush(T* object, ListElem** list, pthread_mutex_t* mutex = nullptr) noexcept {
+    auto listElem = makeUniqueC<ListElem>();
+    listElem->object = object;
+    if (mutex != nullptr) {
+        pthread_mutex_lock(mutex);
+    }
+    listElem->next = *list;
+    *list = listElem.release();
+    if (mutex != nullptr) {
+        pthread_mutex_unlock(mutex);
+    }
+}
+
+/** Push an owned element in a list_elem link list with an optional lock. */
+template <class T, class ListElem>
+void listPush(UniqueCPtr<T>&& object, ListElem** list, pthread_mutex_t* mutex = nullptr) noexcept {
+    listPush(object.release(), list, mutex);
+}
+
+size_t loadLibraries(const effectsConfig::Libraries& libs,
+                     list_elem_t** libList, pthread_mutex_t* libListLock,
+                     list_elem_t** libFailedList)
+{
+    size_t nbSkippedElement = 0;
+    for (auto& library : libs) {
+
+        // Construct a lib entry
+        auto libEntry = makeUniqueC<lib_entry_t>();
+        libEntry->name = strdup(library.name.c_str());
+        libEntry->effects = nullptr;
+        pthread_mutex_init(&libEntry->lock, nullptr);
+
+        if (!loadLibrary(library.path.c_str(), libEntry.get())) {
+            // Register library load failure
+            listPush(std::move(libEntry), libFailedList);
+            ++nbSkippedElement;
+            continue;
+        }
+        listPush(std::move(libEntry), libList, libListLock);
+    }
+    return nbSkippedElement;
+}
+
+/** Find a library with the given name in the given list. */
+lib_entry_t* findLibrary(const char* name, list_elem_t* list) {
+
+    while (list != nullptr) {
+        auto* object = static_cast<lib_entry_t*>(list->object);
+        if (strcmp(object->name, name) == 0) {
+            return object;
+        }
+        list = list->next;
+    }
+    return nullptr;
+}
+
+struct UuidStr {
+    /** Length of an uuid represented as string. @TODO: use a constant instead of 40. */
+    char buff[40];
+};
+
+/** @return a string representing the provided uuid.
+ * By not providing an output buffer, it is implicitly created in the caller context.
+ * In such case the return pointer has the same lifetime as the expression containing uuidToString()
+ */
+char* uuidToString(const effect_uuid_t& uuid, UuidStr&& str = {}) {
+    uuidToString(&uuid, str.buff, sizeof(str.buff));
+    return str.buff;
+}
+
+struct LoadEffectResult {
+    /** true if the effect is usable (aka, existing lib, desc, right version, unique uuid) */
+    bool success = false;
+    /** Set if the effect lib was found*/
+    lib_entry_t* lib = nullptr;
+    //* Set if the description was successfuly retrieved from the lib */
+    UniqueCPtr<effect_descriptor_t> effectDesc;
+};
+
+LoadEffectResult loadEffect(const EffectImpl& effect, const std::string& name,
+                            list_elem_t* libList) {
+    LoadEffectResult result;
+
+    // Find the effect library
+    result.lib = findLibrary(effect.library->name.c_str(), libList);
+    if (result.lib == nullptr) {
+        ALOGE("Could not find library %s to load effect %s",
+              effect.library->name.c_str(), name.c_str());
+        return result;
+    }
+
+    result.effectDesc = makeUniqueC<effect_descriptor_t>();
+
+    // Get the effect descriptor
+    if (result.lib->desc->get_descriptor(&effect.uuid, result.effectDesc.get()) != 0) {
+        ALOGE("Error querying effect %s on lib %s",
+              uuidToString(effect.uuid), result.lib->name);
+        result.effectDesc.reset();
+        return result;
+    }
+
+    // Dump effect for debug
+#if (LOG_NDEBUG==0)
+    char s[512];
+    dumpEffectDescriptor(result.effectDesc.get(), s, sizeof(s), 0 /* indent */);
+    ALOGV("loadEffect() read descriptor %p:%s", result.effectDesc.get(), s);
+#endif
+
+    // Check effect is supported
+    uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION);
+    if (EFFECT_API_VERSION_MAJOR(result.effectDesc->apiVersion) != expectedMajorVersion) {
+        ALOGE("Bad API version %#08x for effect %s in lib %s, expected major %#08x",
+              result.effectDesc->apiVersion, name.c_str(), result.lib->name, expectedMajorVersion);
+        return result;
+    }
+
+    lib_entry_t *_;
+    if (findEffect(nullptr, &effect.uuid, &_, nullptr) == 0) {
+        ALOGE("Effect %s uuid %s already exist", uuidToString(effect.uuid), name.c_str());
+        return result;
+    }
+
+    result.success = true;
+    return result;
+}
+
+size_t loadEffects(const Effects& effects, list_elem_t* libList, list_elem_t** skippedEffects,
+                   list_sub_elem_t** subEffectList) {
+    size_t nbSkippedElement = 0;
+
+    for (auto& effect : effects) {
+
+        auto effectLoadResult = loadEffect(effect, effect.name, libList);
+        if (!effectLoadResult.success) {
+            if (effectLoadResult.effectDesc != nullptr) {
+                listPush(std::move(effectLoadResult.effectDesc), skippedEffects);
+            }
+            ++nbSkippedElement;
+            continue;
+        }
+
+        if (effect.isProxy) {
+            auto swEffectLoadResult = loadEffect(effect.libSw, effect.name + " libsw", libList);
+            auto hwEffectLoadResult = loadEffect(effect.libHw, effect.name + " libhw", libList);
+            if (!swEffectLoadResult.success || !hwEffectLoadResult.success) {
+                // Push the main effect in the skipped list even if only a subeffect is invalid
+                // as the main effect is not usable without its subeffects.
+                listPush(std::move(effectLoadResult.effectDesc), skippedEffects);
+                ++nbSkippedElement;
+                continue;
+            }
+            listPush(effectLoadResult.effectDesc.get(), subEffectList);
+
+            // Since we return a dummy 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;
+            effectLoadResult.effectDesc->uuid = effect.uuid;
+
+            effectLoadResult.effectDesc->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+
+            auto registerSubEffect = [subEffectList](auto&& result) {
+                auto entry = makeUniqueC<sub_effect_entry_t>();
+                entry->object = result.effectDesc.release();
+                // lib_entry_t is stored since the sub effects are not linked to the library
+                entry->lib = result.lib;
+                listPush(std::move(entry), &(*subEffectList)->sub_elem);
+            };
+            registerSubEffect(std::move(swEffectLoadResult));
+            registerSubEffect(std::move(hwEffectLoadResult));
+        }
+
+        listPush(std::move(effectLoadResult.effectDesc), &effectLoadResult.lib->effects);
+    }
+    return nbSkippedElement;
+}
+
+} // namespace
+
+/////////////////////////////////////////////////
+//      Interface function
+/////////////////////////////////////////////////
+
+extern "C" ssize_t EffectLoadXmlEffectConfig(const char* path)
+{
+    using effectsConfig::parse;
+    auto result = path ? parse(path) : parse();
+    if (result.parsedConfig == nullptr) {
+        ALOGE("Failed to parse XML configuration file");
+        return -1;
+    }
+    result.nbSkippedElement += loadLibraries(result.parsedConfig->libraries,
+                                             &gLibraryList, &gLibLock, &gLibraryFailedList) +
+                               loadEffects(result.parsedConfig->effects, gLibraryList,
+                                           &gSkippedEffects, &gSubEffectList);
+
+    ALOGE_IF(result.nbSkippedElement != 0, "%zu errors during loading of configuration: %s",
+             result.nbSkippedElement, path ?: effectsConfig::DEFAULT_PATH);
+
+    return result.nbSkippedElement;
+}
+
+} // namespace android
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.h b/media/libeffects/factory/EffectsXmlConfigLoader.h
new file mode 100644
index 0000000..a3fe9a3
--- /dev/null
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTSXMLCONFIGLOADER_H
+#define ANDROID_EFFECTSXMLCONFIGLOADER_H
+
+#include <unistd.h>
+
+#include <cutils/compiler.h>
+
+#include "EffectsFactoryState.h"
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/** Parses the platform effect xml configuration and stores its content in EffectFactoryState.
+ * @param[in] path of the configuration file or NULL to load the default one
+ * @return -1 on unrecoverable error (eg: no configuration file)
+ *         0 on success
+ *         the number of invalid elements (lib & effect) skipped if the config is partially invalid
+ * @note this function is exported for test purpose only. Do not call from outside this library.
+ */
+ANDROID_API
+ssize_t EffectLoadXmlEffectConfig(const char* path);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif  // ANDROID_EFFECTSXMLCONFIGLOADER_H
diff --git a/media/libeffects/factory/include/media/EffectsFactoryApi.h b/media/libeffects/factory/include/media/EffectsFactoryApi.h
index 64a3212..a5a12eb 100644
--- a/media/libeffects/factory/include/media/EffectsFactoryApi.h
+++ b/media/libeffects/factory/include/media/EffectsFactoryApi.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_EFFECTSFACTORYAPI_H_
 #define ANDROID_EFFECTSFACTORYAPI_H_
 
+#include <cutils/compiler.h>
 #include <errno.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -52,6 +53,7 @@
 //        *pNumEffects:     updated with number of effects in factory
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectQueryNumberEffects(uint32_t *pNumEffects);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -79,6 +81,7 @@
 //        *pDescriptor:     updated with the effect descriptor.
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -110,6 +113,7 @@
 //        *pHandle:         updated with the effect handle.
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
         effect_handle_t *pHandle);
 
@@ -130,6 +134,7 @@
 //                          -EINVAL     invalid interface handle
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectRelease(effect_handle_t handle);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -153,6 +158,7 @@
 //        *pDescriptor:     updated with the effect descriptor.
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -169,8 +175,10 @@
 //                           1 if uuid is equal to EFFECT_UUID_NULL.
 //
 ////////////////////////////////////////////////////////////////////////////////
+ANDROID_API
 int EffectIsNullUuid(const effect_uuid_t *pEffectUuid);
 
+ANDROID_API
 int EffectDumpEffects(int fd);
 
 #if __cplusplus
diff --git a/media/libeffects/factory/test/DumpConfig.cpp b/media/libeffects/factory/test/DumpConfig.cpp
new file mode 100644
index 0000000..0a156b4
--- /dev/null
+++ b/media/libeffects/factory/test/DumpConfig.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/EffectsFactoryApi.h>
+#include <unistd.h>
+#include "EffectsXmlConfigLoader.h"
+#include "EffectsConfigLoader.h"
+
+int main(int argc, char* argv[]) {
+    const char* path = nullptr;
+    bool legacyFormat;
+
+    if (argc == 2 && strcmp(argv[1], "--legacy") == 0) {
+        legacyFormat = true;
+        fprintf(stderr, "Dumping legacy effect config file\n");
+    } else if ((argc == 2 || argc == 3) && strcmp(argv[1], "--xml") == 0) {
+        legacyFormat = false;
+        if (argc == 3) {
+            fprintf(stderr, "Dumping XML effect config file: %s\n", path);
+        } else {
+            fprintf(stderr, "Dumping default XML effect config file.\n");
+        }
+    } else {
+        fprintf(stderr, "Invalid arguments.\n"
+                        "Usage: %s [--legacy|--xml [FILE]]\n", argv[0]);
+        return 1;
+    }
+
+    if (!legacyFormat) {
+        ssize_t ret = EffectLoadXmlEffectConfig(path);
+        if (ret < 0) {
+            fprintf(stderr, "loadXmlEffectConfig failed, see logcat for detail.\n");
+            return 2;
+        }
+        if (ret > 0) {
+            fprintf(stderr, "Partially failed to load config. Skipped %zu elements, "
+                    "see logcat for detail.\n", (size_t)ret);
+        }
+    }
+
+    if (legacyFormat) {
+        auto ret = EffectLoadEffectConfig();
+        if (ret < 0) {
+            fprintf(stderr, "loadEffectConfig failed, see logcat for detail.\n");
+            return 3;
+        }
+        fprintf(stderr, "legacy loadEffectConfig has probably succeed, see logcat to make sure.\n");
+    }
+
+    if (EffectDumpEffects(STDOUT_FILENO) != 0) {
+        fprintf(stderr, "Effect dump failed, see logcat for detail.\n");
+        return 4;
+    }
+}
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
index 83e8288..941eb3e 100644
--- a/media/libeffects/lvm/lib/Android.mk
+++ b/media/libeffects/lvm/lib/Android.mk
@@ -72,19 +72,25 @@
     Common/src/From2iToMono_16.c \
     Common/src/Copy_16.c \
     Common/src/MonoTo2I_16.c \
+    Common/src/MonoTo2I_32.c \
     Common/src/LoadConst_16.c \
+    Common/src/LoadConst_32.c \
     Common/src/dB_to_Lin32.c \
     Common/src/Shift_Sat_v16xv16.c \
+    Common/src/Shift_Sat_v32xv32.c \
     Common/src/Abs_32.c \
     Common/src/Int32RShiftToInt16_Sat_32x16.c \
     Common/src/From2iToMono_32.c \
     Common/src/mult3s_16x16.c \
+    Common/src/Mult3s_32x16.c \
     Common/src/NonLinComp_D16.c \
     Common/src/DelayMix_16x16.c \
     Common/src/MSTo2i_Sat_16x16.c \
     Common/src/From2iToMS_16x16.c \
     Common/src/Mac3s_Sat_16x16.c \
+    Common/src/Mac3s_Sat_32x16.c \
     Common/src/Add2_Sat_16x16.c \
+    Common/src/Add2_Sat_32x32.c \
     Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c \
     Common/src/LVC_MixSoft_1St_D16C31_SAT.c \
     Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c \
@@ -120,7 +126,7 @@
     $(LOCAL_PATH)/StereoWidening/src \
     $(LOCAL_PATH)/StereoWidening/lib
 
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
 LOCAL_CFLAGS += -Wall -Werror
 
 include $(BUILD_STATIC_LIBRARY)
@@ -179,6 +185,7 @@
     $(LOCAL_PATH)/Common/lib \
     $(LOCAL_PATH)/Common/src
 
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
 LOCAL_CFLAGS += -Wall -Werror
+
 include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index 228977d..4c2b954 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -198,6 +198,10 @@
 #define LVDBE_CAP_FS_32000               64
 #define LVDBE_CAP_FS_44100               128
 #define LVDBE_CAP_FS_48000               256
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVDBE_CAP_FS_96000               512
+#define LVDBE_CAP_FS_192000              1024
+#endif
 
 typedef enum
 {
@@ -210,6 +214,10 @@
     LVDBE_FS_32000 = 6,
     LVDBE_FS_44100 = 7,
     LVDBE_FS_48000 = 8,
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    LVDBE_FS_96000 = 9,
+    LVDBE_FS_192000 = 10,
+#endif
     LVDBE_FS_MAX   = LVM_MAXINT_32
 } LVDBE_Fs_en;
 
@@ -450,12 +458,17 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t          hInstance,
+                                       const LVM_FLOAT      *pInData,
+                                       LVM_FLOAT            *pOutData,
+                                       LVM_UINT16           NumSamples);
+#else
 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t          hInstance,
                                        const LVM_INT16      *pInData,
                                        LVM_INT16            *pOutData,
                                        LVM_UINT16           NumSamples);
-
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
index b1ebadf..f32ed30 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
@@ -19,6 +19,7 @@
 #define __LVDBE_COEFFS_H__
 
 
+#ifndef BUILD_FLOAT
 /************************************************************************************/
 /*                                                                                  */
 /* General                                                                          */
@@ -514,5 +515,632 @@
 #define MIX_TC_Fs44100                                  32097         /* Floating point value 0.979515 */
 #define MIX_TC_Fs48000                                  32150         /* Floating point value 0.981150 */
 
+#else /*BUILD_FLOAT*/
 
+/************************************************************************************/
+/*                                                                                  */
+/* General                                                                          */
+/*                                                                                  */
+/************************************************************************************/
+
+#define LVDBE_SCALESHIFT                                    10         /* As a power of 2 */
+
+
+/************************************************************************************/
+/*                                                                                  */
+/* High Pass Filter coefficients                                                    */
+/*                                                                                  */
+/************************************************************************************/
+
+ /* Coefficients for centre frequency 55Hz */
+#define HPF_Fs8000_Fc55_A0                        0.958849f
+#define HPF_Fs8000_Fc55_A1                        -1.917698f
+#define HPF_Fs8000_Fc55_A2                        0.958849f
+#define HPF_Fs8000_Fc55_B1                        -1.939001f
+#define HPF_Fs8000_Fc55_B2                        0.940807f
+#define HPF_Fs11025_Fc55_A0                       0.966909f
+#define HPF_Fs11025_Fc55_A1                       -1.933818f
+#define HPF_Fs11025_Fc55_A2                       0.966909f
+#define HPF_Fs11025_Fc55_B1                       -1.955732f
+#define HPF_Fs11025_Fc55_B2                       0.956690f
+#define HPF_Fs12000_Fc55_A0                       0.968650f
+#define HPF_Fs12000_Fc55_A1                       -1.937300f
+#define HPF_Fs12000_Fc55_A2                       0.968650f
+#define HPF_Fs12000_Fc55_B1                       -1.959327f
+#define HPF_Fs12000_Fc55_B2                       0.960138f
+#define HPF_Fs16000_Fc55_A0                       0.973588f
+#define HPF_Fs16000_Fc55_A1                       -1.947176f
+#define HPF_Fs16000_Fc55_A2                       0.973588f
+#define HPF_Fs16000_Fc55_B1                       -1.969494f
+#define HPF_Fs16000_Fc55_B2                       0.969952f
+#define HPF_Fs22050_Fc55_A0                       0.977671f
+#define HPF_Fs22050_Fc55_A1                       -1.955343f
+#define HPF_Fs22050_Fc55_A2                       0.977671f
+#define HPF_Fs22050_Fc55_B1                       -1.977863f
+#define HPF_Fs22050_Fc55_B2                       0.978105f
+#define HPF_Fs24000_Fc55_A0                       0.978551f
+#define HPF_Fs24000_Fc55_A1                       -1.957102f
+#define HPF_Fs24000_Fc55_A2                       0.978551f
+#define HPF_Fs24000_Fc55_B1                       -1.979662f
+#define HPF_Fs24000_Fc55_B2                       0.979866f
+#define HPF_Fs32000_Fc55_A0                       0.981042f
+#define HPF_Fs32000_Fc55_A1                       -1.962084f
+#define HPF_Fs32000_Fc55_A2                       0.981042f
+#define HPF_Fs32000_Fc55_B1                       -1.984746f
+#define HPF_Fs32000_Fc55_B2                       0.984861f
+#define HPF_Fs44100_Fc55_A0                       0.983097f
+#define HPF_Fs44100_Fc55_A1                       -1.966194f
+#define HPF_Fs44100_Fc55_A2                       0.983097f
+#define HPF_Fs44100_Fc55_B1                       -1.988931f
+#define HPF_Fs44100_Fc55_B2                       0.988992f
+#define HPF_Fs48000_Fc55_A0                       0.983539f
+#define HPF_Fs48000_Fc55_A1                       -1.967079f
+#define HPF_Fs48000_Fc55_A2                       0.983539f
+#define HPF_Fs48000_Fc55_B1                       -1.989831f
+#define HPF_Fs48000_Fc55_B2                       0.989882f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc55_A0                       0.986040f
+#define HPF_Fs96000_Fc55_A1                       -1.972080f
+#define HPF_Fs96000_Fc55_A2                       0.986040f
+#define HPF_Fs96000_Fc55_B1                       -1.994915f
+#define HPF_Fs96000_Fc55_B2                       0.994928f
+
+#define HPF_Fs192000_Fc55_A0                      0.987294f
+#define HPF_Fs192000_Fc55_A1                      -1.974588f
+#define HPF_Fs192000_Fc55_A2                      0.987294f
+#define HPF_Fs192000_Fc55_B1                      -1.997458f
+#define HPF_Fs192000_Fc55_B2                      0.997461f
 #endif
+
+
+ /* Coefficients for centre frequency 66Hz */
+#define HPF_Fs8000_Fc66_A0                        0.953016f
+#define HPF_Fs8000_Fc66_A1                        -1.906032f
+#define HPF_Fs8000_Fc66_A2                        0.953016f
+#define HPF_Fs8000_Fc66_B1                        -1.926810f
+#define HPF_Fs8000_Fc66_B2                        0.929396f
+#define HPF_Fs11025_Fc66_A0                       0.962638f
+#define HPF_Fs11025_Fc66_A1                       -1.925275f
+#define HPF_Fs11025_Fc66_A2                       0.962638f
+#define HPF_Fs11025_Fc66_B1                       -1.946881f
+#define HPF_Fs11025_Fc66_B2                       0.948256f
+#define HPF_Fs12000_Fc66_A0                       0.964718f
+#define HPF_Fs12000_Fc66_A1                       -1.929435f
+#define HPF_Fs12000_Fc66_A2                       0.964718f
+#define HPF_Fs12000_Fc66_B1                       -1.951196f
+#define HPF_Fs12000_Fc66_B2                       0.952359f
+#define HPF_Fs16000_Fc66_A0                       0.970622f
+#define HPF_Fs16000_Fc66_A1                       -1.941244f
+#define HPF_Fs16000_Fc66_A2                       0.970622f
+#define HPF_Fs16000_Fc66_B1                       -1.963394f
+#define HPF_Fs16000_Fc66_B2                       0.964052f
+#define HPF_Fs22050_Fc66_A0                       0.975509f
+#define HPF_Fs22050_Fc66_A1                       -1.951019f
+#define HPF_Fs22050_Fc66_A2                       0.975509f
+#define HPF_Fs22050_Fc66_B1                       -1.973436f
+#define HPF_Fs22050_Fc66_B2                       0.973784f
+#define HPF_Fs24000_Fc66_A0                       0.976563f
+#define HPF_Fs24000_Fc66_A1                       -1.953125f
+#define HPF_Fs24000_Fc66_A2                       0.976563f
+#define HPF_Fs24000_Fc66_B1                       -1.975594f
+#define HPF_Fs24000_Fc66_B2                       0.975889f
+#define HPF_Fs32000_Fc66_A0                       0.979547f
+#define HPF_Fs32000_Fc66_A1                       -1.959093f
+#define HPF_Fs32000_Fc66_A2                       0.979547f
+#define HPF_Fs32000_Fc66_B1                       -1.981695f
+#define HPF_Fs32000_Fc66_B2                       0.981861f
+#define HPF_Fs44100_Fc66_A0                       0.982010f
+#define HPF_Fs44100_Fc66_A1                       -1.964019f
+#define HPF_Fs44100_Fc66_A2                       0.982010f
+#define HPF_Fs44100_Fc66_B1                       -1.986718f
+#define HPF_Fs44100_Fc66_B2                       0.986805f
+#define HPF_Fs48000_Fc66_A0                       0.982540f
+#define HPF_Fs48000_Fc66_A1                       -1.965079f
+#define HPF_Fs48000_Fc66_A2                       0.982540f
+#define HPF_Fs48000_Fc66_B1                       -1.987797f
+#define HPF_Fs48000_Fc66_B2                       0.987871f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc66_A0                       0.985539f
+#define HPF_Fs96000_Fc66_A1                       -1.971077f
+#define HPF_Fs96000_Fc66_A2                       0.985539f
+#define HPF_Fs96000_Fc66_B1                       -1.993898f
+#define HPF_Fs96000_Fc66_B2                       0.993917f
+
+#define HPF_Fs192000_Fc66_A0                      0.987043f
+#define HPF_Fs192000_Fc66_A1                      -1.974086f
+#define HPF_Fs192000_Fc66_A2                      0.987043f
+#define HPF_Fs192000_Fc66_B1                      -1.996949f
+#define HPF_Fs192000_Fc66_B2                      0.996954f
+#endif
+
+/* Coefficients for centre frequency 78Hz */
+#define HPF_Fs8000_Fc78_A0                        0.946693f
+#define HPF_Fs8000_Fc78_A1                        -1.893387f
+#define HPF_Fs8000_Fc78_A2                        0.946693f
+#define HPF_Fs8000_Fc78_B1                        -1.913517f
+#define HPF_Fs8000_Fc78_B2                        0.917105f
+#define HPF_Fs11025_Fc78_A0                       0.957999f
+#define HPF_Fs11025_Fc78_A1                       -1.915998f
+#define HPF_Fs11025_Fc78_A2                       0.957999f
+#define HPF_Fs11025_Fc78_B1                       -1.937229f
+#define HPF_Fs11025_Fc78_B2                       0.939140f
+#define HPF_Fs12000_Fc78_A0                       0.960446f
+#define HPF_Fs12000_Fc78_A1                       -1.920892f
+#define HPF_Fs12000_Fc78_A2                       0.960446f
+#define HPF_Fs12000_Fc78_B1                       -1.942326f
+#define HPF_Fs12000_Fc78_B2                       0.943944f
+#define HPF_Fs16000_Fc78_A0                       0.967397f
+#define HPF_Fs16000_Fc78_A1                       -1.934794f
+#define HPF_Fs16000_Fc78_A2                       0.967397f
+#define HPF_Fs16000_Fc78_B1                       -1.956740f
+#define HPF_Fs16000_Fc78_B2                       0.957656f
+#define HPF_Fs22050_Fc78_A0                       0.973156f
+#define HPF_Fs22050_Fc78_A1                       -1.946313f
+#define HPF_Fs22050_Fc78_A2                       0.973156f
+#define HPF_Fs22050_Fc78_B1                       -1.968607f
+#define HPF_Fs22050_Fc78_B2                       0.969092f
+#define HPF_Fs24000_Fc78_A0                       0.974398f
+#define HPF_Fs24000_Fc78_A1                       -1.948797f
+#define HPF_Fs24000_Fc78_A2                       0.974398f
+#define HPF_Fs24000_Fc78_B1                       -1.971157f
+#define HPF_Fs24000_Fc78_B2                       0.971568f
+#define HPF_Fs32000_Fc78_A0                       0.977918f
+#define HPF_Fs32000_Fc78_A1                       -1.955836f
+#define HPF_Fs32000_Fc78_A2                       0.977918f
+#define HPF_Fs32000_Fc78_B1                       -1.978367f
+#define HPF_Fs32000_Fc78_B2                       0.978599f
+#define HPF_Fs44100_Fc78_A0                       0.980824f
+#define HPF_Fs44100_Fc78_A1                       -1.961649f
+#define HPF_Fs44100_Fc78_A2                       0.980824f
+#define HPF_Fs44100_Fc78_B1                       -1.984303f
+#define HPF_Fs44100_Fc78_B2                       0.984425f
+#define HPF_Fs48000_Fc78_A0                       0.981450f
+#define HPF_Fs48000_Fc78_A1                       -1.962900f
+#define HPF_Fs48000_Fc78_A2                       0.981450f
+#define HPF_Fs48000_Fc78_B1                       -1.985578f
+#define HPF_Fs48000_Fc78_B2                       0.985681f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc78_A0                       0.984992f
+#define HPF_Fs96000_Fc78_A1                       -1.969984f
+#define HPF_Fs96000_Fc78_A2                       0.984992f
+#define HPF_Fs96000_Fc78_B1                       -1.992789f
+#define HPF_Fs96000_Fc78_B2                       0.992815f
+
+#define HPF_Fs192000_Fc78_A0                      0.986769f
+#define HPF_Fs192000_Fc78_A1                      -1.973539f
+#define HPF_Fs192000_Fc78_A2                      0.986769f
+#define HPF_Fs192000_Fc78_B1                      -1.996394f
+#define HPF_Fs192000_Fc78_B2                      0.996401f
+#endif
+
+/* Coefficients for centre frequency 90Hz */
+#define HPF_Fs8000_Fc90_A0                       0.940412f
+#define HPF_Fs8000_Fc90_A1                       -1.880825f
+#define HPF_Fs8000_Fc90_A2                       0.940412f
+#define HPF_Fs8000_Fc90_B1                       -1.900231f
+#define HPF_Fs8000_Fc90_B2                       0.904977f
+#define HPF_Fs11025_Fc90_A0                      0.953383f
+#define HPF_Fs11025_Fc90_A1                      -1.906766f
+#define HPF_Fs11025_Fc90_A2                      0.953383f
+#define HPF_Fs11025_Fc90_B1                      -1.927579f
+#define HPF_Fs11025_Fc90_B2                      0.930111f
+#define HPF_Fs12000_Fc90_A0                      0.956193f
+#define HPF_Fs12000_Fc90_A1                      -1.912387f
+#define HPF_Fs12000_Fc90_A2                      0.956193f
+#define HPF_Fs12000_Fc90_B1                      -1.933459f
+#define HPF_Fs12000_Fc90_B2                      0.935603f
+#define HPF_Fs16000_Fc90_A0                      0.964183f
+#define HPF_Fs16000_Fc90_A1                      -1.928365f
+#define HPF_Fs16000_Fc90_A2                      0.964183f
+#define HPF_Fs16000_Fc90_B1                      -1.950087f
+#define HPF_Fs16000_Fc90_B2                      0.951303f
+#define HPF_Fs22050_Fc90_A0                      0.970809f
+#define HPF_Fs22050_Fc90_A1                      -1.941618f
+#define HPF_Fs22050_Fc90_A2                      0.970809f
+#define HPF_Fs22050_Fc90_B1                      -1.963778f
+#define HPF_Fs22050_Fc90_B2                      0.964423f
+#define HPF_Fs24000_Fc90_A0                      0.972239f
+#define HPF_Fs24000_Fc90_A1                      -1.944477f
+#define HPF_Fs24000_Fc90_A2                      0.972239f
+#define HPF_Fs24000_Fc90_B1                      -1.966721f
+#define HPF_Fs24000_Fc90_B2                      0.967266f
+#define HPF_Fs32000_Fc90_A0                      0.976292f
+#define HPF_Fs32000_Fc90_A1                      -1.952584f
+#define HPF_Fs32000_Fc90_A2                      0.976292f
+#define HPF_Fs32000_Fc90_B1                      -1.975040f
+#define HPF_Fs32000_Fc90_B2                      0.975347f
+#define HPF_Fs44100_Fc90_A0                      0.979641f
+#define HPF_Fs44100_Fc90_A1                      -1.959282f
+#define HPF_Fs44100_Fc90_A2                      0.979641f
+#define HPF_Fs44100_Fc90_B1                      -1.981888f
+#define HPF_Fs44100_Fc90_B2                      0.982050f
+#define HPF_Fs48000_Fc90_A0                      0.980362f
+#define HPF_Fs48000_Fc90_A1                      -1.960724f
+#define HPF_Fs48000_Fc90_A2                      0.980362f
+#define HPF_Fs48000_Fc90_B1                      -1.983359f
+#define HPF_Fs48000_Fc90_B2                      0.983497f
+
+#ifdef HIGHER_FS
+#define HPF_Fs96000_Fc90_A0                       0.984446f
+#define HPF_Fs96000_Fc90_A1                       -1.968892f
+#define HPF_Fs96000_Fc90_A2                       0.984446f
+#define HPF_Fs96000_Fc90_B1                       -1.991680f
+#define HPF_Fs96000_Fc90_B2                       0.991714f
+
+#define HPF_Fs192000_Fc90_A0                      0.986496f
+#define HPF_Fs192000_Fc90_A1                      -1.972992f
+#define HPF_Fs192000_Fc90_A2                      0.986496f
+#define HPF_Fs192000_Fc90_B1                      -1.995840f
+#define HPF_Fs192000_Fc90_B2                      0.995848f
+#endif
+
+/************************************************************************************/
+/*                                                                                  */
+/* Band Pass Filter coefficients                                                    */
+/*                                                                                  */
+/************************************************************************************/
+
+/* Coefficients for centre frequency 55Hz */
+#define BPF_Fs8000_Fc55_A0                       0.009197f
+#define BPF_Fs8000_Fc55_A1                       0.000000f
+#define BPF_Fs8000_Fc55_A2                       -0.009197f
+#define BPF_Fs8000_Fc55_B1                       -1.979545f
+#define BPF_Fs8000_Fc55_B2                       0.981393f
+#define BPF_Fs11025_Fc55_A0                      0.006691f
+#define BPF_Fs11025_Fc55_A1                      0.000000f
+#define BPF_Fs11025_Fc55_A2                      -0.006691f
+#define BPF_Fs11025_Fc55_B1                      -1.985488f
+#define BPF_Fs11025_Fc55_B2                      0.986464f
+#define BPF_Fs12000_Fc55_A0                      0.006150f
+#define BPF_Fs12000_Fc55_A1                      0.000000f
+#define BPF_Fs12000_Fc55_A2                      -0.006150f
+#define BPF_Fs12000_Fc55_B1                      -1.986733f
+#define BPF_Fs12000_Fc55_B2                      0.987557f
+#define BPF_Fs16000_Fc55_A0                      0.004620f
+#define BPF_Fs16000_Fc55_A1                      0.000000f
+#define BPF_Fs16000_Fc55_A2                      -0.004620f
+#define BPF_Fs16000_Fc55_B1                      -1.990189f
+#define BPF_Fs16000_Fc55_B2                      0.990653f
+#define BPF_Fs22050_Fc55_A0                      0.003357f
+#define BPF_Fs22050_Fc55_A1                      0.000000f
+#define BPF_Fs22050_Fc55_A2                      -0.003357f
+#define BPF_Fs22050_Fc55_B1                      -1.992964f
+#define BPF_Fs22050_Fc55_B2                      0.993209f
+#define BPF_Fs24000_Fc55_A0                      0.003085f
+#define BPF_Fs24000_Fc55_A1                      0.000000f
+#define BPF_Fs24000_Fc55_A2                      -0.003085f
+#define BPF_Fs24000_Fc55_B1                      -1.993552f
+#define BPF_Fs24000_Fc55_B2                      0.993759f
+#define BPF_Fs32000_Fc55_A0                      0.002315f
+#define BPF_Fs32000_Fc55_A1                      0.000000f
+#define BPF_Fs32000_Fc55_A2                      -0.002315f
+#define BPF_Fs32000_Fc55_B1                      -1.995199f
+#define BPF_Fs32000_Fc55_B2                      0.995316f
+#define BPF_Fs44100_Fc55_A0                      0.001681f
+#define BPF_Fs44100_Fc55_A1                      0.000000f
+#define BPF_Fs44100_Fc55_A2                      -0.001681f
+#define BPF_Fs44100_Fc55_B1                      -1.996537f
+#define BPF_Fs44100_Fc55_B2                      0.996599f
+#define BPF_Fs48000_Fc55_A0                      0.001545f
+#define BPF_Fs48000_Fc55_A1                      0.000000f
+#define BPF_Fs48000_Fc55_A2                      -0.001545f
+#define BPF_Fs48000_Fc55_B1                      -1.996823f
+#define BPF_Fs48000_Fc55_B2                      0.996875f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc55_A0                      0.000762f
+#define BPF_Fs96000_Fc55_A1                      0.000000f
+#define BPF_Fs96000_Fc55_A2                      -0.000762f
+#define BPF_Fs96000_Fc55_B1                      -1.998461f
+#define BPF_Fs96000_Fc55_B2                      0.998477f
+
+#define BPF_Fs192000_Fc55_A0                     0.000381f
+#define BPF_Fs192000_Fc55_A1                     0.000000f
+#define BPF_Fs192000_Fc55_A2                     -0.000381f
+#define BPF_Fs192000_Fc55_B1                     -1.999234f
+#define BPF_Fs192000_Fc55_B2                     0.999238f
+#endif
+
+/* Coefficients for centre frequency 66Hz */
+#define BPF_Fs8000_Fc66_A0                      0.012648f
+#define BPF_Fs8000_Fc66_A1                      0.000000f
+#define BPF_Fs8000_Fc66_A2                      -0.012648f
+#define BPF_Fs8000_Fc66_B1                      -1.971760f
+#define BPF_Fs8000_Fc66_B2                      0.974412f
+#define BPF_Fs11025_Fc66_A0                     0.009209f
+#define BPF_Fs11025_Fc66_A1                     0.000000f
+#define BPF_Fs11025_Fc66_A2                     -0.009209f
+#define BPF_Fs11025_Fc66_B1                     -1.979966f
+#define BPF_Fs11025_Fc66_B2                     0.981368f
+#define BPF_Fs12000_Fc66_A0                     0.008468f
+#define BPF_Fs12000_Fc66_A1                     0.000000f
+#define BPF_Fs12000_Fc66_A2                     -0.008468f
+#define BPF_Fs12000_Fc66_B1                     -1.981685f
+#define BPF_Fs12000_Fc66_B2                     0.982869f
+#define BPF_Fs16000_Fc66_A0                     0.006364f
+#define BPF_Fs16000_Fc66_A1                     0.000000f
+#define BPF_Fs16000_Fc66_A2                     -0.006364f
+#define BPF_Fs16000_Fc66_B1                     -1.986457f
+#define BPF_Fs16000_Fc66_B2                     0.987124f
+#define BPF_Fs22050_Fc66_A0                     0.004626f
+#define BPF_Fs22050_Fc66_A1                     0.000000f
+#define BPF_Fs22050_Fc66_A2                     -0.004626f
+#define BPF_Fs22050_Fc66_B1                     -1.990288f
+#define BPF_Fs22050_Fc66_B2                     0.990641f
+#define BPF_Fs24000_Fc66_A0                     0.004252f
+#define BPF_Fs24000_Fc66_A1                     0.000000f
+#define BPF_Fs24000_Fc66_A2                     -0.004252f
+#define BPF_Fs24000_Fc66_B1                     -1.991100f
+#define BPF_Fs24000_Fc66_B2                     0.991398f
+#define BPF_Fs32000_Fc66_A0                     0.003192f
+#define BPF_Fs32000_Fc66_A1                     0.000000f
+#define BPF_Fs32000_Fc66_A2                     -0.003192f
+#define BPF_Fs32000_Fc66_B1                     -1.993374f
+#define BPF_Fs32000_Fc66_B2                     0.993541f
+#define BPF_Fs44100_Fc66_A0                     0.002318f
+#define BPF_Fs44100_Fc66_A1                     0.000000f
+#define BPF_Fs44100_Fc66_A2                     -0.002318f
+#define BPF_Fs44100_Fc66_B1                     -1.995221f
+#define BPF_Fs44100_Fc66_B2                     0.995309f
+#define BPF_Fs48000_Fc66_A0                     0.002131f
+#define BPF_Fs48000_Fc66_A1                     0.000000f
+#define BPF_Fs48000_Fc66_A2                     -0.002131f
+#define BPF_Fs48000_Fc66_B1                     -1.995615f
+#define BPF_Fs48000_Fc66_B2                     0.995690f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc66_A0                     0.001055f
+#define BPF_Fs96000_Fc66_A1                     0.000000f
+#define BPF_Fs96000_Fc66_A2                     -0.001055f
+#define BPF_Fs96000_Fc66_B1                     -1.997868f
+#define BPF_Fs96000_Fc66_B2                     0.997891f
+
+#define BPF_Fs192000_Fc66_A0                    0.000528f
+#define BPF_Fs192000_Fc66_A1                    0.000000f
+#define BPF_Fs192000_Fc66_A2                   -0.000528f
+#define BPF_Fs192000_Fc66_B1                   -1.998939f
+#define BPF_Fs192000_Fc66_B2                    0.998945f
+#endif
+
+/* Coefficients for centre frequency 78Hz */
+#define BPF_Fs8000_Fc78_A0                      0.018572f
+#define BPF_Fs8000_Fc78_A1                      0.000000f
+#define BPF_Fs8000_Fc78_A2                      -0.018572f
+#define BPF_Fs8000_Fc78_B1                      -1.958745f
+#define BPF_Fs8000_Fc78_B2                      0.962427f
+#define BPF_Fs11025_Fc78_A0                     0.013545f
+#define BPF_Fs11025_Fc78_A1                     0.000000f
+#define BPF_Fs11025_Fc78_A2                     -0.013545f
+#define BPF_Fs11025_Fc78_B1                     -1.970647f
+#define BPF_Fs11025_Fc78_B2                     0.972596f
+#define BPF_Fs12000_Fc78_A0                     0.012458f
+#define BPF_Fs12000_Fc78_A1                     0.000000f
+#define BPF_Fs12000_Fc78_A2                     -0.012458f
+#define BPF_Fs12000_Fc78_B1                     -1.973148f
+#define BPF_Fs12000_Fc78_B2                     0.974795f
+#define BPF_Fs16000_Fc78_A0                     0.009373f
+#define BPF_Fs16000_Fc78_A1                     0.000000f
+#define BPF_Fs16000_Fc78_A2                     -0.009373f
+#define BPF_Fs16000_Fc78_B1                     -1.980108f
+#define BPF_Fs16000_Fc78_B2                     0.981037f
+#define BPF_Fs22050_Fc78_A0                     0.006819f
+#define BPF_Fs22050_Fc78_A1                     0.000000f
+#define BPF_Fs22050_Fc78_A2                     -0.006819f
+#define BPF_Fs22050_Fc78_B1                     -1.985714f
+#define BPF_Fs22050_Fc78_B2                     0.986204f
+#define BPF_Fs24000_Fc78_A0                     0.006268f
+#define BPF_Fs24000_Fc78_A1                     0.000000f
+#define BPF_Fs24000_Fc78_A2                     -0.006268f
+#define BPF_Fs24000_Fc78_B1                     -1.986904f
+#define BPF_Fs24000_Fc78_B2                     0.987318f
+#define BPF_Fs32000_Fc78_A0                     0.004709f
+#define BPF_Fs32000_Fc78_A1                     0.000000f
+#define BPF_Fs32000_Fc78_A2                     -0.004709f
+#define BPF_Fs32000_Fc78_B1                     -1.990240f
+#define BPF_Fs32000_Fc78_B2                     0.990473f
+#define BPF_Fs44100_Fc78_A0                     0.003421f
+#define BPF_Fs44100_Fc78_A1                     0.000000f
+#define BPF_Fs44100_Fc78_A2                     -0.003421f
+#define BPF_Fs44100_Fc78_B1                     -1.992955f
+#define BPF_Fs44100_Fc78_B2                     0.993078f
+#define BPF_Fs48000_Fc78_A0                     0.003144f
+#define BPF_Fs48000_Fc78_A1                     0.000000f
+#define BPF_Fs48000_Fc78_A2                     -0.003144f
+#define BPF_Fs48000_Fc78_B1                     -1.993535f
+#define BPF_Fs48000_Fc78_B2                     0.993639f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc78_A0                     0.001555f
+#define BPF_Fs96000_Fc78_A1                     0.000000f
+#define BPF_Fs96000_Fc78_A2                    -0.0015555f
+#define BPF_Fs96000_Fc78_B1                    -1.996860f
+#define BPF_Fs96000_Fc78_B2                     0.996891f
+
+#define BPF_Fs192000_Fc78_A0                    0.000778f
+#define BPF_Fs192000_Fc78_A1                    0.000000f
+#define BPF_Fs192000_Fc78_A2                   -0.000778f
+#define BPF_Fs192000_Fc78_B1                   -1.998437f
+#define BPF_Fs192000_Fc78_B2                    0.998444f
+#endif
+
+/* Coefficients for centre frequency 90Hz */
+#define BPF_Fs8000_Fc90_A0                       0.022760f
+#define BPF_Fs8000_Fc90_A1                       0.000000f
+#define BPF_Fs8000_Fc90_A2                       -0.022760f
+#define BPF_Fs8000_Fc90_B1                       -1.949073f
+#define BPF_Fs8000_Fc90_B2                       0.953953f
+#define BPF_Fs11025_Fc90_A0                      0.016619f
+#define BPF_Fs11025_Fc90_A1                      0.000000f
+#define BPF_Fs11025_Fc90_A2                      -0.016619f
+#define BPF_Fs11025_Fc90_B1                      -1.963791f
+#define BPF_Fs11025_Fc90_B2                      0.966377f
+#define BPF_Fs12000_Fc90_A0                      0.015289f
+#define BPF_Fs12000_Fc90_A1                      0.000000f
+#define BPF_Fs12000_Fc90_A2                      -0.015289f
+#define BPF_Fs12000_Fc90_B1                      -1.966882f
+#define BPF_Fs12000_Fc90_B2                      0.969067f
+#define BPF_Fs16000_Fc90_A0                      0.011511f
+#define BPF_Fs16000_Fc90_A1                      0.000000f
+#define BPF_Fs16000_Fc90_A2                      -0.011511f
+#define BPF_Fs16000_Fc90_B1                      -1.975477f
+#define BPF_Fs16000_Fc90_B2                      0.976711f
+#define BPF_Fs22050_Fc90_A0                      0.008379f
+#define BPF_Fs22050_Fc90_A1                      0.000000f
+#define BPF_Fs22050_Fc90_A2                      -0.008379f
+#define BPF_Fs22050_Fc90_B1                      -1.982395f
+#define BPF_Fs22050_Fc90_B2                      0.983047f
+#define BPF_Fs24000_Fc90_A0                      0.007704f
+#define BPF_Fs24000_Fc90_A1                      0.000000f
+#define BPF_Fs24000_Fc90_A2                      -0.007704f
+#define BPF_Fs24000_Fc90_B1                      -1.983863f
+#define BPF_Fs24000_Fc90_B2                      0.984414f
+#define BPF_Fs32000_Fc90_A0                      0.005789f
+#define BPF_Fs32000_Fc90_A1                      0.000000f
+#define BPF_Fs32000_Fc90_A2                      -0.005789f
+#define BPF_Fs32000_Fc90_B1                      -1.987977f
+#define BPF_Fs32000_Fc90_B2                      0.988288f
+#define BPF_Fs44100_Fc90_A0                      0.004207f
+#define BPF_Fs44100_Fc90_A1                      0.000000f
+#define BPF_Fs44100_Fc90_A2                      -0.004207f
+#define BPF_Fs44100_Fc90_B1                      -1.991324f
+#define BPF_Fs44100_Fc90_B2                      0.991488f
+#define BPF_Fs48000_Fc90_A0                      0.003867f
+#define BPF_Fs48000_Fc90_A1                      0.000000f
+#define BPF_Fs48000_Fc90_A2                      -0.003867f
+#define BPF_Fs48000_Fc90_B1                      -1.992038f
+#define BPF_Fs48000_Fc90_B2                      0.992177f
+
+#ifdef HIGHER_FS
+#define BPF_Fs96000_Fc90_A0                      0.001913f
+#define BPF_Fs96000_Fc90_A1                      0.000000f
+#define BPF_Fs96000_Fc90_A2                     -0.001913f
+#define BPF_Fs96000_Fc90_B1                     -1.996134f
+#define BPF_Fs96000_Fc90_B2                      0.996174f
+
+#define BPF_Fs192000_Fc90_A0                     0.000958f
+#define BPF_Fs192000_Fc90_A1                     0.000000f
+#define BPF_Fs192000_Fc90_A2                    -0.000958f
+#define BPF_Fs192000_Fc90_B1                    -1.998075f
+#define BPF_Fs192000_Fc90_B2                     0.998085f
+#endif
+
+/************************************************************************************/
+/*                                                                                  */
+/* Automatic Gain Control time constants and gain settings                          */
+/*                                                                                  */
+/************************************************************************************/
+
+/* AGC Time constants */
+#define AGC_ATTACK_Fs8000                             0.841395f
+#define AGC_ATTACK_Fs11025                            0.882223f
+#define AGC_ATTACK_Fs12000                            0.891251f
+#define AGC_ATTACK_Fs16000                            0.917276f
+#define AGC_ATTACK_Fs22050                            0.939267f
+#define AGC_ATTACK_Fs24000                            0.944061f
+#define AGC_ATTACK_Fs32000                            0.957745f
+#define AGC_ATTACK_Fs44100                            0.969158f
+#define AGC_ATTACK_Fs48000                            0.971628f
+
+#ifdef HIGHER_FS
+#define AGC_ATTACK_Fs96000                             0.985712f
+#define AGC_ATTACK_Fs192000                            0.992830f
+#endif
+
+#define DECAY_SHIFT                                   10
+
+#define AGC_DECAY_Fs8000                              0.000042f
+#define AGC_DECAY_Fs11025                             0.000030f
+#define AGC_DECAY_Fs12000                             0.000028f
+#define AGC_DECAY_Fs16000                             0.000021f
+#define AGC_DECAY_Fs22050                             0.000015f
+#define AGC_DECAY_Fs24000                             0.000014f
+#define AGC_DECAY_Fs32000                             0.000010f
+#define AGC_DECAY_Fs44100                             0.000008f
+#define AGC_DECAY_Fs48000                             0.000007f
+
+#ifdef HIGHER_FS
+#define AGC_DECAY_FS96000                            0.0000035f
+#define AGC_DECAY_FS192000                          0.00000175f
+#endif
+
+/* AGC Gain settings */
+#define AGC_GAIN_SCALE                                        31         /* As a power of 2 */
+#define AGC_GAIN_SHIFT                                         4         /* As a power of 2 */
+#define AGC_TARGETLEVEL                            0.988553f
+#define AGC_HPFGAIN_0dB                            0.412538f
+#define AGC_GAIN_0dB                               0.000000f
+#define AGC_HPFGAIN_1dB                            0.584893f
+#define AGC_GAIN_1dB                               0.122018f
+#define AGC_HPFGAIN_2dB                            0.778279f
+#define AGC_GAIN_2dB                               0.258925f
+#define AGC_HPFGAIN_3dB                            0.995262f
+#define AGC_GAIN_3dB                               0.412538f
+#define AGC_HPFGAIN_4dB                            1.238721f
+#define AGC_GAIN_4dB                               0.584893f
+#define AGC_HPFGAIN_5dB                            1.511886f
+#define AGC_GAIN_5dB                               0.778279f
+#define AGC_HPFGAIN_6dB                            1.818383f
+#define AGC_GAIN_6dB                               0.995262f
+#define AGC_HPFGAIN_7dB                            2.162278f
+#define AGC_GAIN_7dB                               1.238721f
+#define AGC_HPFGAIN_8dB                            2.548134f
+#define AGC_GAIN_8dB                               1.511886f
+#define AGC_HPFGAIN_9dB                            2.981072f
+#define AGC_GAIN_9dB                               1.818383f
+#define AGC_HPFGAIN_10dB                           3.466836f
+#define AGC_GAIN_10dB                              2.162278f
+#define AGC_HPFGAIN_11dB                           4.011872f
+#define AGC_GAIN_11dB                              2.548134f
+#define AGC_HPFGAIN_12dB                           4.623413f
+#define AGC_GAIN_12dB                              2.981072f
+#define AGC_HPFGAIN_13dB                           5.309573f
+#define AGC_GAIN_13dB                              3.466836f
+#define AGC_HPFGAIN_14dB                           6.079458f
+#define AGC_GAIN_14dB                              4.011872f
+#define AGC_HPFGAIN_15dB                           6.943282f
+#define AGC_GAIN_15dB                              4.623413f
+
+/************************************************************************************/
+/*                                                                                  */
+/* Volume control                                                                   */
+/*                                                                                  */
+/************************************************************************************/
+
+/* Volume control gain */
+#define VOLUME_MAX                                          0         /* In dBs */
+#define VOLUME_SHIFT                                        0         /* In dBs */
+
+/* Volume control time constants */
+#define VOL_TC_SHIFT                                       21         /* As a power of 2 */
+#define VOL_TC_Fs8000                                   0.024690f
+#define VOL_TC_Fs11025                                  0.017977f
+#define VOL_TC_Fs12000                                  0.016529f
+#define VOL_TC_Fs16000                                  0.012422f
+#define VOL_TC_Fs22050                                  0.009029f
+#define VOL_TC_Fs24000                                  0.008299f
+#define VOL_TC_Fs32000                                  0.006231f
+#define VOL_TC_Fs44100                                  0.004525f
+#define VOL_TC_Fs48000                                  0.004158f
+#ifdef HIGHER_FS
+#define VOL_TC_Fs96000                                  0.002079f
+#define VOL_TC_Fs192000                                 0.001039f
+#endif
+#define MIX_TC_Fs8000                                   29365         /* Floating point value 0.896151 */
+#define MIX_TC_Fs11025                                  30230         /* Floating point value 0.922548 */
+#define MIX_TC_Fs12000                                  30422         /* Floating point value 0.928415 */
+#define MIX_TC_Fs16000                                  30978         /* Floating point value 0.945387 */
+#define MIX_TC_Fs22050                                  31451         /* Floating point value 0.959804 */
+#define MIX_TC_Fs24000                                  31554         /* Floating point value 0.962956 */
+#define MIX_TC_Fs32000                                  31850         /* Floating point value 0.971973 */
+#define MIX_TC_Fs44100                                  32097         /* Floating point value 0.979515 */
+#define MIX_TC_Fs48000                                  32150         /* Floating point value 0.981150 */
+#ifdef HIGHER_FS
+#define MIX_TC_Fs96000                                  32456         /* Floating point value 0.990530 */
+#define MIX_TC_Fs192000                                 32611         /* Floating point value 0.992524 */
+#endif
+
+#endif /*BUILD_FLOAT*/
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
index b6632a3..fd4016b 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
@@ -107,35 +107,68 @@
                          LVDBE_Params_t       *pParams)
 {
 
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
     /*
      * Calculate the table offsets
      */
-    LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
-
+    LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + \
+                                    (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_192000)));
+#else
+    /*
+     * Calculate the table offsets
+     */
+    LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + \
+                                    (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));    
+#endif
 
     /*
      * Setup the high pass filter
      */
-    LoadConst_16(0,                                                 /* Clear the history, value 0 */
-                 (void *)&pInstance->pData->HPFTaps,                /* Destination Cast to void: \
-                                                                     no dereferencing in function*/
+#ifndef BUILD_FLOAT
+    LoadConst_16(0,                                              /* Clear the history, value 0 */
+                 (void *)&pInstance->pData->HPFTaps,             /* Destination Cast to void: \
+                                                                    no dereferencing in function*/
                  sizeof(pInstance->pData->HPFTaps)/sizeof(LVM_INT16));   /* Number of words */
-    BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance,         /* Initialise the filter */
+#else
+    LoadConst_Float(0,                                          /* Clear the history, value 0 */
+                   (void *)&pInstance->pData->HPFTaps,          /* Destination Cast to void: \
+                                                                  no dereferencing in function*/
+                    sizeof(pInstance->pData->HPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
+#endif
+#ifndef BUILD_FLOAT
+    BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance,    /* Initialise the filter */
                                     &pInstance->pData->HPFTaps,
                                     (BQ_C32_Coefs_t *)&LVDBE_HPF_Table[Offset]);
+#else
+    BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance,    /* Initialise the filter */
+                                    &pInstance->pData->HPFTaps,
+                                    (BQ_FLOAT_Coefs_t *)&LVDBE_HPF_Table[Offset]);
+#endif
 
 
     /*
      * Setup the band pass filter
      */
+#ifndef BUILD_FLOAT
     LoadConst_16(0,                                                 /* Clear the history, value 0 */
-                 (void *)&pInstance->pData->BPFTaps,                /* Destination Cast to void:\
+                 (void *)&pInstance->pData->BPFTaps,                /* Destination Cast to void: \
                                                                      no dereferencing in function*/
                  sizeof(pInstance->pData->BPFTaps)/sizeof(LVM_INT16));   /* Number of words */
+#else
+    LoadConst_Float(0,                                           /* Clear the history, value 0 */
+                 (void *)&pInstance->pData->BPFTaps,             /* Destination Cast to void: \
+                                                                    no dereferencing in function*/
+                 sizeof(pInstance->pData->BPFTaps) / sizeof(LVM_FLOAT));   /* Number of words */
+#endif
+#ifndef BUILD_FLOAT
     BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance,         /* Initialise the filter */
                                     &pInstance->pData->BPFTaps,
                                     (BP_C32_Coefs_t *)&LVDBE_BPF_Table[Offset]);
-
+#else
+    BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance,    /* Initialise the filter */
+                                    &pInstance->pData->BPFTaps,
+                                    (BP_FLOAT_Coefs_t *)&LVDBE_BPF_Table[Offset]);
+#endif
 }
 
 
@@ -175,7 +208,9 @@
     {
         pInstance->pData->AGCInstance.AGC_MaxGain   = LVDBE_AGC_GAIN_Table[(LVM_UINT16)pParams->EffectLevel];     /* High pass filter off */
     }
+#ifndef BUILD_FLOAT
     pInstance->pData->AGCInstance.AGC_GainShift = AGC_GAIN_SHIFT;
+#endif
     pInstance->pData->AGCInstance.AGC_Target = AGC_TARGETLEVEL;
 
 }
@@ -212,6 +247,9 @@
     LVM_UINT16      dBOffset;                                   /* Table offset */
     LVM_INT16       Volume = 0;                                 /* Required volume in dBs */
 
+#ifdef BUILD_FLOAT
+    LVM_FLOAT        dBShifts_fac;
+#endif
     /*
      * Apply the volume if enabled
      */
@@ -237,33 +275,58 @@
     dBOffset = (LVM_UINT16)(6 + Volume % 6);                    /* Get the dBs 0-5 */
     dBShifts = (LVM_UINT16)(Volume / -6);                       /* Get the 6dB shifts */
 
-
+#ifdef BUILD_FLOAT
+    dBShifts_fac = (LVM_FLOAT)(1 << dBShifts);
+#endif
     /*
      * When DBE is enabled use AGC volume
      */
+#ifndef BUILD_FLOAT
     pInstance->pData->AGCInstance.Target = ((LVM_INT32)LVDBE_VolumeTable[dBOffset] << 16);
     pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target >> dBShifts;
-
+#else
+    pInstance->pData->AGCInstance.Target = (LVDBE_VolumeTable[dBOffset]);
+    pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target / dBShifts_fac;
+#endif
     pInstance->pData->AGCInstance.VolumeTC    = LVDBE_VolumeTCTable[(LVM_UINT16)pParams->SampleRate];   /* Volume update time constant */
+#ifndef BUILD_FLOAT
     pInstance->pData->AGCInstance.VolumeShift = VOLUME_SHIFT+1;
+#endif
 
     /*
      * When DBE is disabled use the bypass volume control
      */
     if(dBShifts > 0)
     {
+#ifndef BUILD_FLOAT
         LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(((LVM_INT32)LVDBE_VolumeTable[dBOffset]) >> dBShifts));
+#else
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],
+                            LVDBE_VolumeTable[dBOffset] / dBShifts_fac);
+#endif
     }
     else
     {
+#ifndef BUILD_FLOAT
         LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(LVM_INT32)LVDBE_VolumeTable[dBOffset]);
+#else
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],
+                            LVDBE_VolumeTable[dBOffset]);
+#endif
     }
 
     pInstance->pData->BypassVolume.MixerStream[0].CallbackSet = 1;
+#ifndef BUILD_FLOAT
     LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
                                 LVDBE_MIXER_TC,
                                 (LVM_Fs_en)pInstance->Params.SampleRate,
                                 2);
+#else
+    LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
+                                LVDBE_MIXER_TC,
+                                (LVM_Fs_en)pInstance->Params.SampleRate,
+                                2);
+#endif
 }
 
 
@@ -309,7 +372,11 @@
 {
 
     LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
+#ifndef BUILD_FLOAT
     LVMixer3_2St_st     *pBypassMixer_Instance = &pInstance->pData->BypassMixer;
+#else
+    LVMixer3_2St_FLOAT_st     *pBypassMixer_Instance = &pInstance->pData->BypassMixer;
+#endif
 
 
     /*
@@ -332,12 +399,19 @@
     {
         LVDBE_SetAGC(pInstance,                         /* Instance pointer */
                      pParams);                          /* New parameters */
-
+#ifndef BUILD_FLOAT
         LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
             LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
 
         LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
             LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
+#else
+        LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
+            LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate, 2);
+
+        LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
+            LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate, 2);
+#endif
 
 
     }
@@ -357,13 +431,23 @@
 
     if (pInstance->Params.OperatingMode==LVDBE_ON && pParams->OperatingMode==LVDBE_OFF)
     {
+#ifndef BUILD_FLOAT
         LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0);
         LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0x00007FFF);
+#else
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0], 0);
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1], 1.0f);
+#endif
     }
     if (pInstance->Params.OperatingMode==LVDBE_OFF && pParams->OperatingMode==LVDBE_ON)
     {
+#ifndef BUILD_FLOAT
         LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0x00007FFF);
         LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0);
+#else
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0], 1.0f);
+        LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1], 0);
+#endif
     }
 
     /*
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
index a3623bc..3fff2a2 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
@@ -80,7 +80,11 @@
         /*
          * Data memory
          */
+#ifdef BUILD_FLOAT
+        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size   = sizeof(LVDBE_Data_FLOAT_t);
+#else
         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size         = sizeof(LVDBE_Data_t);
+#endif
         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;
@@ -88,7 +92,11 @@
         /*
          * Coef memory
          */
-        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);
+#ifdef BUILD_FLOAT
+        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size   = sizeof(LVDBE_Coef_FLOAT_t);
+#else
+        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);   
+#endif
         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;
@@ -96,7 +104,12 @@
         /*
          * Scratch memory
          */
+#ifdef BUILD_FLOAT
+        ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT) * \
+                                        pCapabilities->MaxBlockSize);
+#else /*BUILD_FLOAT*/
         ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
+#endif
         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size         = ScratchSize;
         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment    = LVDBE_SCRATCH_ALIGN;
         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type         = LVDBE_SCRATCH;
@@ -151,10 +164,16 @@
 {
 
     LVDBE_Instance_t      *pInstance;
+#ifdef BUILD_FLOAT
+    LVMixer3_1St_FLOAT_st       *pMixer_Instance;
+    LVMixer3_2St_FLOAT_st       *pBypassMixer_Instance;
+    LVM_FLOAT             MixGain;
+#else
     LVMixer3_1St_st       *pMixer_Instance;
     LVMixer3_2St_st       *pBypassMixer_Instance;
-    LVM_INT16             i;
     LVM_INT32             MixGain;
+#endif
+    LVM_INT16             i;
 
 
     /*
@@ -235,7 +254,11 @@
     // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up
     // reading uninitialized data
     pMixer_Instance = &pInstance->pData->BypassVolume;
+#ifndef BUILD_FLOAT
     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF);
+#else
+    LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], 1.0, 1.0);
+#endif
 
     /*
      * Initialise the volume
@@ -245,9 +268,13 @@
 
     pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target;
                                                 /* Initialise as the target */
-
+#ifndef BUILD_FLOAT
     MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain);
+#else
+    MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
+    LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], MixGain, MixGain);
+#endif
 
     /* Configure the mixer process path */
     pMixer_Instance->MixerStream[0].CallbackParam = 0;
@@ -268,9 +295,11 @@
     pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
     pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
     pBypassMixer_Instance->MixerStream[0].CallbackSet=0;
+
     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0);
     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
         LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
+
     /*
      * Setup the mixer gain for the unprocessed path
      */
@@ -278,9 +307,15 @@
     pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL;
     pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL;
     pBypassMixer_Instance->MixerStream[1].CallbackSet=0;
+#ifndef BUILD_FLOAT
     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF);
     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
         LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
+#else
+    LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1], 1.0, 1.0);
+    LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
+        LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate, 2);
+#endif
 
     return(LVDBE_SUCCESS);
 }
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index 8339d3c..4e5207f 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -77,6 +77,7 @@
 /****************************************************************************************/
 
 /* Data structure */
+#ifndef BUILD_FLOAT
 typedef struct
 {
     /* AGC parameters */
@@ -98,7 +99,29 @@
     Biquad_Instance_t           BPFInstance;        /* Band pass filter instance */
 
 } LVDBE_Coef_t;
+#else
+/* Data structure */
+typedef struct
+{
+    /* AGC parameters */
+    AGC_MIX_VOL_2St1Mon_FLOAT_t   AGCInstance;        /* AGC instance parameters */
 
+    /* Process variables */
+    Biquad_2I_Order2_FLOAT_Taps_t     HPFTaps;            /* High pass filter taps */
+    Biquad_1I_Order2_FLOAT_Taps_t     BPFTaps;            /* Band pass filter taps */
+    LVMixer3_1St_FLOAT_st             BypassVolume;       /* Bypass volume scaler */
+    LVMixer3_2St_FLOAT_st             BypassMixer;        /* Bypass Mixer for Click Removal */
+
+} LVDBE_Data_FLOAT_t;
+
+/* Coefs structure */
+typedef struct
+{
+    /* Process variables */
+    Biquad_FLOAT_Instance_t           HPFInstance;        /* High pass filter instance */
+    Biquad_FLOAT_Instance_t           BPFInstance;        /* Band pass filter instance */
+} LVDBE_Coef_FLOAT_t;
+#endif
 /* Instance structure */
 typedef struct
 {
@@ -108,8 +131,13 @@
     LVDBE_Capabilities_t        Capabilities;         /* Instance capabilities */
 
     /* Data and coefficient pointers */
+#ifndef BUILD_FLOAT
     LVDBE_Data_t                *pData;                /* Instance data */
     LVDBE_Coef_t                *pCoef;                /* Instance coefficients */
+#else
+    LVDBE_Data_FLOAT_t                *pData;                /* Instance data */
+    LVDBE_Coef_FLOAT_t                *pCoef;                /* Instance coefficients */
+#endif
 } LVDBE_Instance_t;
 
 
@@ -136,5 +164,3 @@
 #endif /* __cplusplus */
 
 #endif      /* __LVDBE_PRIVATE_H__ */
-
-
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
index 69d79d2..10ea700 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
@@ -27,7 +27,6 @@
 #include "AGC.h"
 #include "LVDBE_Coeffs.h"               /* Filter coefficients */
 
-
 /********************************************************************************************/
 /*                                                                                          */
 /* FUNCTION:                 LVDBE_Process                                                  */
@@ -72,136 +71,236 @@
 /*     overall end to end gain is odB.                                                      */
 /*                                                                                          */
 /********************************************************************************************/
+#ifndef BUILD_FLOAT
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
+    const LVM_INT16 *pInData, LVM_INT16 *pOutData, LVM_UINT16 NumSamples) {
 
-LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t            hInstance,
-                                       const LVM_INT16         *pInData,
-                                       LVM_INT16               *pOutData,
-                                       LVM_UINT16                   NumSamples)
+  LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *) hInstance;
+  LVM_INT32 *pScratch =
+      (LVM_INT32 *) pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
+  LVM_INT32 *pMono;
+  LVM_INT16 *pInput = (LVM_INT16 *) pInData;
+
+  /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
+  LVM_INT16 *pScratchVol = (LVM_INT16 *) (&pScratch[NumSamples]);
+
+  /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
+  pMono = &pScratch[2 * NumSamples];
+
+  /*
+   * Check the number of samples is not too large
+   */
+  if (NumSamples > pInstance->Capabilities.MaxBlockSize) {
+    return (LVDBE_TOOMANYSAMPLES);
+  }
+
+  /*
+   * Check if the algorithm is enabled
+   */
+  /* DBE path is processed when DBE is ON or during On/Off transitions */
+  if ((pInstance->Params.OperatingMode == LVDBE_ON)
+      || (LVC_Mixer_GetCurrent(
+          &pInstance->pData->BypassMixer.MixerStream[0])
+          != LVC_Mixer_GetTarget(
+              &pInstance->pData->BypassMixer.MixerStream[0]))) {
+
+    /*
+     * Convert 16-bit samples to 32-bit and scale
+     * (For a 16-bit implementation apply headroom loss here)
+     */
+    Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data    */
+    pScratch, /* Dest. 32-bit data     */
+    (LVM_INT16) (2 * NumSamples), /* Left and right        */
+    LVDBE_SCALESHIFT); /* Shift scale           */
+
+    /*
+     * Apply the high pass filter if selected
+     */
+    if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
+      BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
+      (LVM_INT32 *) pScratch, /* Source               */
+      (LVM_INT32 *) pScratch, /* Destination          */
+      (LVM_INT16) NumSamples); /* Number of samples    */
+    }
+
+    /*
+     * Create the mono stream
+     */
+    From2iToMono_32(pScratch, /* Stereo source         */
+    pMono, /* Mono destination      */
+    (LVM_INT16) NumSamples); /* Number of samples     */
+
+    /*
+     * Apply the band pass filter
+     */
+    BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
+    (LVM_INT32 *) pMono, /* Source                */
+    (LVM_INT32 *) pMono, /* Destination           */
+    (LVM_INT16) NumSamples); /* Number of samples     */
+
+    /*
+     * Apply the AGC and mix
+     */
+    AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
+    pScratch, /* Stereo source         */
+    pMono, /* Mono band pass source */
+    pScratch, /* Stereo destination    */
+    NumSamples); /* Number of samples     */
+
+    /*
+     * Convert 32-bit samples to 16-bit and saturate
+     * (Not required for 16-bit implemenations)
+     */
+    Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data    */
+    (LVM_INT16 *) pScratch, /* Dest. 16-bit data     */
+    (LVM_INT16) (2 * NumSamples), /* Left and right        */
+    LVDBE_SCALESHIFT); /* Shift scale           */
+
+  }
+
+  /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
+  if ((pInstance->Params.OperatingMode == LVDBE_OFF)
+      || (LVC_Mixer_GetCurrent(
+          &pInstance->pData->BypassMixer.MixerStream[1])
+          != LVC_Mixer_GetTarget(
+              &pInstance->pData->BypassMixer.MixerStream[1]))) {
+
+    /*
+     * The algorithm is disabled but volume management is required to compensate for
+     * headroom and volume (if enabled)
+     */
+    LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume, pInData,
+        pScratchVol, (LVM_INT16) (2 * NumSamples)); /* Left and right          */
+
+  }
+
+  /*
+   * Mix DBE processed path and bypass volume path
+   */
+  LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
+      (LVM_INT16 *) pScratch, pScratchVol, pOutData,
+      (LVM_INT16) (2 * NumSamples));
+
+  return (LVDBE_SUCCESS);
+}
+#else /*BUILD_FLOAT*/
+LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
+    const LVM_FLOAT *pInData,
+    LVM_FLOAT *pOutData,
+    LVM_UINT16 NumSamples)
 {
 
-    LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
-    LVM_INT32           *pScratch  = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
-    LVM_INT32           *pMono;
-    LVM_INT16           *pInput    = (LVM_INT16 *)pInData;
+  LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
+  LVM_FLOAT *pScratch_in = (LVM_FLOAT *)pInstance->MemoryTable.Region
+  [LVDBE_MEMREGION_SCRATCH].pBaseAddress;
+  LVM_FLOAT *pScratch = pScratch_in + 2 * NumSamples;
+  LVM_FLOAT *pMono;
+  LVM_INT32 ii = 0;
 
+  /* Scratch for Volume Control starts at offset of 4*NumSamples float values from pScratch */
+  LVM_FLOAT           *pScratchVol = (LVM_FLOAT *)(&pScratch_in[4 * NumSamples]);
+//  LVM_INT16 *pScratchVol_int = (LVM_INT16 *)(pScratchVol);
 
-    /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
-    LVM_INT16           *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]);
+  /* Scratch for Mono path starts at offset of 6*NumSamples 32-bit values from pScratch */
+  pMono = &pScratch_in[4 * NumSamples];
 
-    /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
-    pMono                            = &pScratch[2*NumSamples];
+  /*
+   * Check the number of samples is not too large
+   */
+  if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+  {
+    return(LVDBE_TOOMANYSAMPLES);
+  }
+
+  /*
+   * Convert 16-bit samples to Float
+   */
+  Copy_Float(pInData, /* Source 16-bit data    */
+      pScratch_in, /* Dest. 32-bit data     */
+      (LVM_INT16)(2 * NumSamples)); /* Left and right        */
+
+  for (ii = 0; ii < 2 * NumSamples; ii++) {
+    pScratch[ii] = pScratch_in[ii];
+  }
+  /*
+   * Check if the algorithm is enabled
+   */
+  /* DBE path is processed when DBE is ON or during On/Off transitions */
+  if ((pInstance->Params.OperatingMode == LVDBE_ON)||
+      (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
+          !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
+  {
 
     /*
-     * Check the number of samples is not too large
+     * Apply the high pass filter if selected
      */
-    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+    if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
     {
-        return(LVDBE_TOOMANYSAMPLES);
+      BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
+          (LVM_FLOAT *)pScratch, /* Source               */
+          (LVM_FLOAT *)pScratch, /* Destination          */
+          (LVM_INT16)NumSamples); /* Number of samples    */
     }
 
     /*
-     * Check if the algorithm is enabled
+     * Create the mono stream
      */
-    /* DBE path is processed when DBE is ON or during On/Off transitions */
-    if ((pInstance->Params.OperatingMode == LVDBE_ON)||
-        (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
-         !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
-    {
-
-        /*
-         * Convert 16-bit samples to 32-bit and scale
-         * (For a 16-bit implementation apply headroom loss here)
-         */
-        Int16LShiftToInt32_16x32(pInput,                               /* Source 16-bit data    */
-                                 pScratch,                             /* Dest. 32-bit data     */
-                                 (LVM_INT16)(2*NumSamples),            /* Left and right        */
-                                 LVDBE_SCALESHIFT);                    /* Shift scale           */
-
-
-        /*
-         * Apply the high pass filter if selected
-         */
-        if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
-        {
-              BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
-                                       (LVM_INT32 *)pScratch,           /* Source               */
-                                       (LVM_INT32 *)pScratch,           /* Destination          */
-                                       (LVM_INT16)NumSamples);          /* Number of samples    */
-        }
-
-
-        /*
-         * Create the mono stream
-         */
-        From2iToMono_32(pScratch,                                      /* Stereo source         */
-                        pMono,                                         /* Mono destination      */
-                        (LVM_INT16)NumSamples);                        /* Number of samples     */
-
-
-        /*
-         * Apply the band pass filter
-         */
-        BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance,     /* Filter instance       */
-                                   (LVM_INT32 *)pMono,                 /* Source                */
-                                   (LVM_INT32 *)pMono,                 /* Destination           */
-                                   (LVM_INT16)NumSamples);             /* Number of samples     */
-
-
-        /*
-         * Apply the AGC and mix
-         */
-        AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance,    /* Instance pointer      */
-                                    pScratch,                          /* Stereo source         */
-                                    pMono,                             /* Mono band pass source */
-                                    pScratch,                          /* Stereo destination    */
-                                    NumSamples);                       /* Number of samples     */
-
-        /*
-         * Convert 32-bit samples to 16-bit and saturate
-         * (Not required for 16-bit implemenations)
-         */
-        Int32RShiftToInt16_Sat_32x16(pScratch,                         /* Source 32-bit data    */
-                                     (LVM_INT16 *)pScratch,            /* Dest. 16-bit data     */
-                                     (LVM_INT16)(2*NumSamples),        /* Left and right        */
-                                     LVDBE_SCALESHIFT);                /* Shift scale           */
-
-    }
-
-    /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
-    if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
-        (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
-         !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
-    {
-
-        /*
-         * The algorithm is disabled but volume management is required to compensate for
-         * headroom and volume (if enabled)
-         */
-        LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
-                                  pInData,
-                                  pScratchVol,
-                               (LVM_INT16)(2*NumSamples));           /* Left and right          */
-
-    }
+    From2iToMono_Float((LVM_FLOAT *)pScratch, /* Stereo source         */
+        pMono, /* Mono destination      */
+        (LVM_INT16)NumSamples); /* Number of samples     */
 
     /*
-     * Mix DBE processed path and bypass volume path
+     * Apply the band pass filter
      */
-    LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
-                                    (LVM_INT16 *) pScratch,
-                                    pScratchVol,
-                                    pOutData,
-                                    (LVM_INT16)(2*NumSamples));
+    BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
+        (LVM_FLOAT *)pMono, /* Source                */
+        (LVM_FLOAT *)pMono, /* Destination           */
+        (LVM_INT16)NumSamples); /* Number of samples     */
 
-    return(LVDBE_SUCCESS);
+    /*
+     * Apply the AGC and mix
+     */
+    AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
+        pScratch, /* Stereo source         */
+        pMono, /* Mono band pass source */
+        pScratch, /* Stereo destination    */
+        NumSamples); /* Number of samples     */
+
+    for (ii = 0; ii < 2 * NumSamples; ii++) {
+      //TODO: replace with existing clamping function
+      if(pScratch[ii] < -1.0) {
+        pScratch[ii] = -1.0;
+      } else if(pScratch[ii] > 1.0) {
+        pScratch[ii] = 1.0;
+      }
+    }
+  }
+
+  /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
+  if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
+      (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
+          !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
+  {
+
+    /*
+     * The algorithm is disabled but volume management is required to compensate for
+     * headroom and volume (if enabled)
+     */
+    LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
+        pScratch_in,
+        pScratchVol,
+        (LVM_INT16)(2 * NumSamples)); /* Left and right */
+  }
+
+  /*
+   * Mix DBE processed path and bypass volume path
+   */
+  LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
+      pScratch,
+      pScratchVol,
+      pOutData,
+      (LVM_INT16)(2 * NumSamples));
+
+  return(LVDBE_SUCCESS);
 }
-
-
-
-
-
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
index f5d229e..c4a9b14 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -36,7 +36,11 @@
 /*
  * High Pass Filter Coefficient table
  */
+#ifndef BUILD_FLOAT
 const BQ_C32_Coefs_t LVDBE_HPF_Table[] = {
+#else /*BUILD_FLOAT*/
+const BQ_FLOAT_Coefs_t LVDBE_HPF_Table[] = {
+#endif /*BUILD_FLOAT*/
     /* Coefficients for 55Hz centre frequency */
     {HPF_Fs8000_Fc55_A2,                /* 8kS/s coefficients */
      HPF_Fs8000_Fc55_A1,
@@ -83,6 +87,18 @@
      HPF_Fs48000_Fc55_A0,
      -HPF_Fs48000_Fc55_B2,
      -HPF_Fs48000_Fc55_B1},
+#ifdef HIGHER_FS
+    {HPF_Fs96000_Fc55_A2,                /* 96kS/s coefficients */
+     HPF_Fs96000_Fc55_A1,
+     HPF_Fs96000_Fc55_A0,
+     -HPF_Fs96000_Fc55_B2,
+     -HPF_Fs96000_Fc55_B1},
+    {HPF_Fs192000_Fc55_A2,                /* 192kS/s coefficients */
+     HPF_Fs192000_Fc55_A1,
+     HPF_Fs192000_Fc55_A0,
+     -HPF_Fs192000_Fc55_B2,
+     -HPF_Fs192000_Fc55_B1},
+#endif
 
     /* Coefficients for 66Hz centre frequency */
     {HPF_Fs8000_Fc66_A2,                /* 8kS/s coefficients */
@@ -130,6 +146,19 @@
      HPF_Fs48000_Fc66_A0,
      -HPF_Fs48000_Fc66_B2,
      -HPF_Fs48000_Fc66_B1},
+#ifdef HIGHER_FS
+    {HPF_Fs96000_Fc66_A2,                /* 96kS/s coefficients */
+     HPF_Fs96000_Fc66_A1,
+     HPF_Fs96000_Fc66_A0,
+     -HPF_Fs96000_Fc66_B2,
+     -HPF_Fs96000_Fc66_B1},
+    {HPF_Fs192000_Fc66_A2,                /* 192kS/s coefficients */
+     HPF_Fs192000_Fc66_A1,
+     HPF_Fs192000_Fc66_A0,
+     -HPF_Fs192000_Fc66_B2,
+     -HPF_Fs192000_Fc66_B1},
+#endif
+
 
     /* Coefficients for 78Hz centre frequency */
     {HPF_Fs8000_Fc78_A2,                /* 8kS/s coefficients */
@@ -177,6 +206,19 @@
      HPF_Fs48000_Fc78_A0,
      -HPF_Fs48000_Fc78_B2,
      -HPF_Fs48000_Fc78_B1},
+#ifdef HIGHER_FS
+    {HPF_Fs96000_Fc78_A2,                /* 96kS/s coefficients */
+     HPF_Fs96000_Fc78_A1,
+     HPF_Fs96000_Fc78_A0,
+     -HPF_Fs96000_Fc78_B2,
+     -HPF_Fs96000_Fc78_B1},
+    {HPF_Fs192000_Fc78_A2,                /* 192kS/s coefficients */
+     HPF_Fs192000_Fc78_A1,
+     HPF_Fs192000_Fc78_A0,
+     -HPF_Fs192000_Fc78_B2,
+     -HPF_Fs192000_Fc78_B1},
+#endif
+
 
     /* Coefficients for 90Hz centre frequency */
     {HPF_Fs8000_Fc90_A2,                /* 8kS/s coefficients */
@@ -223,12 +265,32 @@
      HPF_Fs48000_Fc90_A1,
      HPF_Fs48000_Fc90_A0,
      -HPF_Fs48000_Fc90_B2,
-     -HPF_Fs48000_Fc90_B1}};
+     -HPF_Fs48000_Fc90_B1}
+
+#ifdef HIGHER_FS
+    ,
+    {HPF_Fs96000_Fc90_A2,                /* 96kS/s coefficients */
+     HPF_Fs96000_Fc90_A1,
+     HPF_Fs96000_Fc90_A0,
+     -HPF_Fs96000_Fc90_B2,
+     -HPF_Fs96000_Fc90_B1},
+    {HPF_Fs192000_Fc90_A2,                /* 192kS/s coefficients */
+     HPF_Fs192000_Fc90_A1,
+     HPF_Fs192000_Fc90_A0,
+     -HPF_Fs192000_Fc90_B2,
+     -HPF_Fs192000_Fc90_B1}
+#endif
+
+};
 
 /*
  * Band Pass Filter coefficient table
  */
+#ifndef BUILD_FLOAT
 const BP_C32_Coefs_t LVDBE_BPF_Table[] = {
+#else /*BUILD_FLOAT*/
+const BP_FLOAT_Coefs_t LVDBE_BPF_Table[] = {
+#endif /*BUILD_FLOAT*/
     /* Coefficients for 55Hz centre frequency */
     {BPF_Fs8000_Fc55_A0,                /* 8kS/s coefficients */
      -BPF_Fs8000_Fc55_B2,
@@ -257,6 +319,14 @@
     {BPF_Fs48000_Fc55_A0,                /* 48kS/s coefficients */
      -BPF_Fs48000_Fc55_B2,
      -BPF_Fs48000_Fc55_B1},
+#ifdef HIGHER_FS
+     {BPF_Fs96000_Fc55_A0,                /* 96kS/s coefficients */
+     -BPF_Fs96000_Fc55_B2,
+     -BPF_Fs96000_Fc55_B1},
+     {BPF_Fs192000_Fc55_A0,                /* 192kS/s coefficients */
+     -BPF_Fs192000_Fc55_B2,
+     -BPF_Fs192000_Fc55_B1},
+#endif
 
     /* Coefficients for 66Hz centre frequency */
     {BPF_Fs8000_Fc66_A0,                /* 8kS/s coefficients */
@@ -286,6 +356,14 @@
     {BPF_Fs48000_Fc66_A0,                /* 48kS/s coefficients */
      -BPF_Fs48000_Fc66_B2,
      -BPF_Fs48000_Fc66_B1},
+#ifdef HIGHER_FS
+    {BPF_Fs96000_Fc66_A0,                /* 96kS/s coefficients */
+     -BPF_Fs96000_Fc66_B2,
+     -BPF_Fs96000_Fc66_B1},
+    {BPF_Fs192000_Fc66_A0,                /* 192kS/s coefficients */
+     -BPF_Fs192000_Fc66_B2,
+     -BPF_Fs192000_Fc66_B1},
+#endif
 
     /* Coefficients for 78Hz centre frequency */
     {BPF_Fs8000_Fc78_A0,                /* 8kS/s coefficients */
@@ -315,6 +393,14 @@
     {BPF_Fs48000_Fc78_A0,                /* 48kS/s coefficients */
      -BPF_Fs48000_Fc78_B2,
      -BPF_Fs48000_Fc78_B1},
+#ifdef HIGHER_FS
+    {BPF_Fs96000_Fc78_A0,                /* 96kS/s coefficients */
+     -BPF_Fs96000_Fc78_B2,
+     -BPF_Fs96000_Fc78_B1},
+    {BPF_Fs192000_Fc78_A0,                /* 192kS/s coefficients */
+     -BPF_Fs192000_Fc78_B2,
+     -BPF_Fs192000_Fc78_B1},
+#endif
 
     /* Coefficients for 90Hz centre frequency */
     {BPF_Fs8000_Fc90_A0,                /* 8kS/s coefficients */
@@ -343,7 +429,19 @@
      -BPF_Fs44100_Fc90_B1},
     {BPF_Fs48000_Fc90_A0,                /* 48kS/s coefficients */
      -BPF_Fs48000_Fc90_B2,
-     -BPF_Fs48000_Fc90_B1}};
+     -BPF_Fs48000_Fc90_B1}
+#ifdef HIGHER_FS
+    ,
+    {BPF_Fs96000_Fc90_A0,                /* 96kS/s coefficients */
+     -BPF_Fs96000_Fc90_B2,
+     -BPF_Fs96000_Fc90_B1},
+    {BPF_Fs192000_Fc90_A0,                /* 192kS/s coefficients */
+     -BPF_Fs192000_Fc90_B2,
+     -BPF_Fs192000_Fc90_B1}
+#endif
+
+
+};
 
 
 /************************************************************************************/
@@ -353,7 +451,11 @@
 /************************************************************************************/
 
 /* Attack time (signal too large) */
+#ifndef BUILD_FLOAT
 const LVM_INT16 LVDBE_AGC_ATTACK_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_ATTACK_Table[] = {
+#endif /*BUILD_FLOAT*/
     AGC_ATTACK_Fs8000,
     AGC_ATTACK_Fs11025,
     AGC_ATTACK_Fs12000,
@@ -362,10 +464,20 @@
     AGC_ATTACK_Fs24000,
     AGC_ATTACK_Fs32000,
     AGC_ATTACK_Fs44100,
-    AGC_ATTACK_Fs48000};
+    AGC_ATTACK_Fs48000
+#ifdef HIGHER_FS
+    ,AGC_ATTACK_Fs96000
+    ,AGC_ATTACK_Fs192000
+#endif
+
+};
 
 /* Decay time (signal too small) */
+#ifndef BUILD_FLOAT
 const LVM_INT16 LVDBE_AGC_DECAY_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_DECAY_Table[] = {
+#endif /*BUILD_FLOAT*/
     AGC_DECAY_Fs8000,
     AGC_DECAY_Fs11025,
     AGC_DECAY_Fs12000,
@@ -374,10 +486,20 @@
     AGC_DECAY_Fs24000,
     AGC_DECAY_Fs32000,
     AGC_DECAY_Fs44100,
-    AGC_DECAY_Fs48000};
+    AGC_DECAY_Fs48000
+#ifdef HIGHER_FS
+    ,AGC_DECAY_FS96000
+    ,AGC_DECAY_FS192000
+#endif
+
+};
 
 /* Gain for use without the high pass filter */
+#ifndef BUILD_FLOAT
 const LVM_INT32 LVDBE_AGC_GAIN_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_GAIN_Table[] = {
+#endif /*BUILD_FLOAT*/
     AGC_GAIN_0dB,
     AGC_GAIN_1dB,
     AGC_GAIN_2dB,
@@ -396,7 +518,11 @@
     AGC_GAIN_15dB};
 
 /* Gain for use with the high pass filter */
+#ifndef BUILD_FLOAT
 const LVM_INT32 LVDBE_AGC_HPFGAIN_Table[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_AGC_HPFGAIN_Table[] = {
+#endif /*BUILD_FLOAT*/
     AGC_HPFGAIN_0dB,
     AGC_HPFGAIN_1dB,
     AGC_HPFGAIN_2dB,
@@ -422,6 +548,7 @@
 /************************************************************************************/
 
 /* dB to linear conversion table */
+#ifndef BUILD_FLOAT
 const LVM_INT16 LVDBE_VolumeTable[] = {
     0x4000,             /* -6dB */
     0x47FB,             /* -5dB */
@@ -430,8 +557,22 @@
     0x65AD,             /* -2dB */
     0x7215,             /* -1dB */
     0x7FFF};            /*  0dB */
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_VolumeTable[] = {
+    0.500000f,         /* -6dB */
+    0.562341f,         /* -5dB */
+    0.630957f,         /* -4dB */
+    0.707946f,         /* -3dB */
+    0.794328f,         /* -2dB */
+    0.891251f,         /* -1dB */
+    1.000000f};        /*  0dB */
+#endif /*BUILD_FLOAT*/
 
+#ifndef BUILD_FLOAT
 const LVM_INT16 LVDBE_VolumeTCTable[] = {
+#else /*BUILD_FLOAT*/
+const LVM_FLOAT LVDBE_VolumeTCTable[] = {
+#endif /*BUILD_FLOAT*/
     VOL_TC_Fs8000,
     VOL_TC_Fs11025,
     VOL_TC_Fs12000,
@@ -440,9 +581,17 @@
     VOL_TC_Fs24000,
     VOL_TC_Fs32000,
     VOL_TC_Fs44100,
-    VOL_TC_Fs48000};
+    VOL_TC_Fs48000
+#ifdef HIGHER_FS
+    ,VOL_TC_Fs96000
+    ,VOL_TC_Fs192000
+#endif
+};
+
+
 
 const LVM_INT16 LVDBE_MixerTCTable[] = {
+
     MIX_TC_Fs8000,
     MIX_TC_Fs11025,
     MIX_TC_Fs12000,
@@ -451,6 +600,10 @@
     MIX_TC_Fs24000,
     MIX_TC_Fs32000,
     MIX_TC_Fs44100,
-    MIX_TC_Fs48000};
+    MIX_TC_Fs48000
+#ifdef HIGHER_FS
+    ,MIX_TC_Fs96000
+    ,MIX_TC_Fs192000
+#endif
 
-
+};
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
index 476e6a0..ca46e37 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
@@ -31,6 +31,7 @@
 #include "BIQUAD.h"
 #include "LVM_Types.h"
 
+#ifndef BUILD_FLOAT
 /************************************************************************************/
 /*                                                                                  */
 /*    Coefficients constant table                                                   */
@@ -76,8 +77,57 @@
 
 extern const LVM_INT16 LVDBE_VolumeTCTable[];
 
+#else /*BUILD_FLOAT*/
+
+/************************************************************************************/
+/*                                                                                  */
+/*    Coefficients constant table                                                   */
+/*                                                                                  */
+/************************************************************************************/
+
+/*
+ * High Pass Filter Coefficient table
+ */
+extern const BQ_FLOAT_Coefs_t LVDBE_HPF_Table[];
+
+/*
+ * Band Pass Filter coefficient table
+ */
+extern const BP_FLOAT_Coefs_t LVDBE_BPF_Table[];
+
+/************************************************************************************/
+/*                                                                                  */
+/*    AGC constant tables                                                           */
+/*                                                                                  */
+/************************************************************************************/
+
+/* Attack time (signal too large) */
+extern const LVM_FLOAT LVDBE_AGC_ATTACK_Table[];
+
+/* Decay time (signal too small) */
+extern const LVM_FLOAT LVDBE_AGC_DECAY_Table[];
+
+/* Gain for use without the high pass filter */
+extern const LVM_FLOAT LVDBE_AGC_GAIN_Table[];
+
+/* Gain for use with the high pass filter */
+extern const LVM_FLOAT LVDBE_AGC_HPFGAIN_Table[];
+
+/************************************************************************************/
+/*                                                                                  */
+/*    Volume control gain and time constant tables                                  */
+/*                                                                                  */
+/************************************************************************************/
+
+/* dB to linear conversion table */
+extern const LVM_FLOAT LVDBE_VolumeTable[];
+extern const LVM_FLOAT LVDBE_VolumeTCTable[];
+
+#endif /*BUILD_FLOAT*/
+
 extern const LVM_INT16 LVDBE_MixerTCTable[];
 
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Bundle/lib/LVM.h b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
index 1ff2a2c..9b6da31 100644
--- a/media/libeffects/lvm/lib/Bundle/lib/LVM.h
+++ b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
@@ -514,11 +514,19 @@
 /*      STEREO              the number of sample pairs in the block                     */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
+                                const LVM_FLOAT             *pInData,
+                                LVM_FLOAT                      *pOutData,
+                                LVM_UINT16                  NumSamples,
+                                LVM_UINT32                  AudioTime);
+#else
 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
                                 const LVM_INT16             *pInData,
                                 LVM_INT16                   *pOutData,
                                 LVM_UINT16                  NumSamples,
                                 LVM_UINT32                  AudioTime);
+#endif
 
 
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
index 6cbee7d..0a3c30e 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
@@ -48,7 +48,152 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferManagedIn(LVM_Handle_t       hInstance,
+                         const LVM_FLOAT    *pInData,
+                         LVM_FLOAT          **pToProcess,
+                         LVM_FLOAT          **pProcessed,
+                         LVM_UINT16         *pNumSamples)
+{
 
+    LVM_INT16        SampleCount;           /* Number of samples to be processed this call */
+    LVM_INT16        NumSamples;            /* Number of samples in scratch buffer */
+    LVM_FLOAT        *pStart;
+    LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
+    LVM_Buffer_t     *pBuffer;
+    LVM_FLOAT        *pDest;
+    LVM_INT16        NumChannels = 2;
+
+
+    /*
+     * Set the processing address pointers
+     */
+    pBuffer     = pInstance->pBufferManagement;
+    pDest       = pBuffer->pScratch;
+    *pToProcess = pBuffer->pScratch;
+    *pProcessed = pBuffer->pScratch;
+
+    /*
+     * Check if it is the first call of a block
+     */
+    if (pInstance->SamplesToProcess == 0)
+    {
+        /*
+         * First call for a new block of samples
+         */
+        pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
+        pInstance->pInputSamples    = (LVM_FLOAT *)pInData;
+        pBuffer->BufferState        = LVM_FIRSTCALL;
+    }
+    pStart = pInstance->pInputSamples;                 /* Pointer to the input samples */
+    pBuffer->SamplesToOutput  = 0;                     /* Samples to output is same as
+                                                          number read for inplace processing */
+
+
+    /*
+     * Calculate the number of samples to process this call and update the buffer state
+     */
+    if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
+    {
+        /*
+         * Process the maximum bock size of samples.
+         */
+        SampleCount = pInstance->InternalBlockSize;
+        NumSamples  = pInstance->InternalBlockSize;
+    }
+    else
+    {
+        /*
+         * Last call for the block, so calculate how many frames and samples to process
+          */
+        LVM_INT16   NumFrames;
+
+        NumSamples  = pInstance->SamplesToProcess;
+        NumFrames    = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
+        SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
+
+        /*
+         * Update the buffer state
+         */
+        if (pBuffer->BufferState == LVM_FIRSTCALL)
+        {
+            pBuffer->BufferState = LVM_FIRSTLASTCALL;
+        }
+        else
+        {
+            pBuffer->BufferState = LVM_LASTCALL;
+        }
+    }
+    *pNumSamples = (LVM_UINT16)SampleCount;  /* Set the number of samples to process this call */
+
+
+    /*
+     * Copy samples from the delay buffer as required
+     */
+    if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
+        (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
+        (pBuffer->InDelaySamples != 0))
+    {
+        Copy_Float(&pBuffer->InDelayBuffer[0],                             /* Source */
+                   pDest,                                                  /* Destination */
+                   (LVM_INT16)(NumChannels * pBuffer->InDelaySamples));    /* Number of delay \
+                                                                       samples, left and right */
+        NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
+        pDest += NumChannels * pBuffer->InDelaySamples;      /* Update the destination pointer */
+    }
+
+
+    /*
+     * Copy the rest of the samples for this call from the input buffer
+     */
+    if (NumSamples > 0)
+    {
+        Copy_Float(pStart,                                      /* Source */
+                   pDest,                                       /* Destination */
+                   (LVM_INT16)(NumChannels * NumSamples));      /* Number of input samples */
+        pStart += NumChannels * NumSamples;                     /* Update the input pointer */
+
+        /*
+         * Update the input data pointer and samples to output
+         */
+        /* Update samples to output */
+        pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples);
+    }
+
+
+    /*
+      * Update the sample count and input pointer
+     */
+    /* Update the count of samples */
+    pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);
+    pInstance->pInputSamples     = pStart; /* Update input sample pointer */
+
+
+    /*
+     * Save samples to the delay buffer if any left unprocessed
+     */
+    if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
+        (pBuffer->BufferState == LVM_LASTCALL))
+    {
+        NumSamples = pInstance->SamplesToProcess;
+        pStart     = pBuffer->pScratch;                             /* Start of the buffer */
+        pStart    += NumChannels * SampleCount; /* Offset by the number of processed samples */
+        if (NumSamples != 0)
+        {
+            Copy_Float(pStart,                                         /* Source */
+                       &pBuffer->InDelayBuffer[0],                     /* Destination */
+                       (LVM_INT16)(NumChannels * NumSamples));   /* Number of input samples */
+        }
+
+
+        /*
+         * Update the delay sample count
+         */
+        pBuffer->InDelaySamples     = NumSamples;       /* Number of delay sample pairs */
+        pInstance->SamplesToProcess = 0;                            /* All Samples used */
+    }
+}
+#else
 void LVM_BufferManagedIn(LVM_Handle_t       hInstance,
                          const LVM_INT16    *pInData,
                          LVM_INT16          **pToProcess,
@@ -189,7 +334,7 @@
         pInstance->SamplesToProcess = 0;                            /* All Samples used */
     }
 }
-
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -213,7 +358,47 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferUnmanagedIn(LVM_Handle_t     hInstance,
+                           LVM_FLOAT        **pToProcess,
+                           LVM_FLOAT        **pProcessed,
+                           LVM_UINT16       *pNumSamples)
+{
 
+    LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
+
+
+    /*
+     * Check if this is the first call of a block
+     */
+    if (pInstance->SamplesToProcess == 0)
+    {
+        pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;    /* Get the number of samples
+                                                                               on first call */
+        pInstance->pInputSamples    = *pToProcess;                /* Get the I/O pointers */
+        pInstance->pOutputSamples    = *pProcessed;
+
+
+        /*
+         * Set te block size to process
+         */
+        if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
+        {
+            *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
+        }
+        else
+        {
+            *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
+        }
+    }
+
+    /*
+     * Set the process pointers
+     */
+    *pToProcess = pInstance->pInputSamples;
+    *pProcessed = pInstance->pOutputSamples;
+}
+#else
 void LVM_BufferUnmanagedIn(LVM_Handle_t     hInstance,
                            LVM_INT16        **pToProcess,
                            LVM_INT16        **pProcessed,
@@ -252,7 +437,7 @@
     *pToProcess = pInstance->pInputSamples;
     *pProcessed = pInstance->pOutputSamples;
 }
-
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -278,6 +463,7 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef BUILD_FLOAT
 void LVM_BufferOptimisedIn(LVM_Handle_t         hInstance,
                            const LVM_INT16      *pInData,
                            LVM_INT16            **pToProcess,
@@ -416,7 +602,7 @@
         }
     }
 }
-
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                 LVM_BufferIn                                               */
@@ -471,7 +657,37 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferIn(LVM_Handle_t      hInstance,
+                  const LVM_FLOAT   *pInData,
+                  LVM_FLOAT         **pToProcess,
+                  LVM_FLOAT         **pProcessed,
+                  LVM_UINT16        *pNumSamples)
+{
 
+    LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
+
+
+    /*
+     * Check which mode, managed or unmanaged
+     */
+    if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
+    {
+        LVM_BufferManagedIn(hInstance,
+                            pInData,
+                            pToProcess,
+                            pProcessed,
+                            pNumSamples);
+    }
+    else
+    {
+        LVM_BufferUnmanagedIn(hInstance,
+                              pToProcess,
+                              pProcessed,
+                              pNumSamples);
+    }
+}
+#else
 void LVM_BufferIn(LVM_Handle_t      hInstance,
                   const LVM_INT16   *pInData,
                   LVM_INT16         **pToProcess,
@@ -501,7 +717,7 @@
                               pNumSamples);
     }
 }
-
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                 LVM_BufferManagedOut                                       */
@@ -522,7 +738,156 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferManagedOut(LVM_Handle_t        hInstance,
+                          LVM_FLOAT            *pOutData,
+                          LVM_UINT16        *pNumSamples)
+{
 
+    LVM_Instance_t  *pInstance  = (LVM_Instance_t  *)hInstance;
+    LVM_Buffer_t    *pBuffer    = pInstance->pBufferManagement;
+    LVM_INT16       SampleCount = (LVM_INT16)*pNumSamples;
+    LVM_INT16       NumSamples;
+    LVM_FLOAT       *pStart;
+    LVM_FLOAT       *pDest;
+
+
+    /*
+     * Set the pointers
+     */
+    NumSamples = pBuffer->SamplesToOutput;
+    pStart     = pBuffer->pScratch;
+
+
+    /*
+     * check if it is the first call of a block
+      */
+    if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
+        (pBuffer->BufferState == LVM_FIRSTLASTCALL))
+    {
+        /* First call for a new block */
+        pInstance->pOutputSamples = pOutData;                 /* Initialise the destination */
+    }
+    pDest = pInstance->pOutputSamples;                        /* Set the output address */
+
+
+    /*
+     * If the number of samples is non-zero then there are still samples to send to
+     * the output buffer
+     */
+    if ((NumSamples != 0) &&
+        (pBuffer->OutDelaySamples != 0))
+    {
+        /*
+         * Copy the delayed output buffer samples to the output
+         */
+        if (pBuffer->OutDelaySamples <= NumSamples)
+        {
+            /*
+             * Copy all output delay samples to the output
+             */
+            Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
+                       pDest,                                      /* Detsination */
+                       (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
+
+            /*
+             * Update the pointer and sample counts
+             */
+            pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
+            NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
+                                                                                to send */
+            pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
+        }
+        else
+        {
+            /*
+             * Copy only some of the ouput delay samples to the output
+             */
+            Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
+                       pDest,                                          /* Detsination */
+                       (LVM_INT16)(2 * NumSamples));       /* Number of delay samples */
+
+            /*
+             * Update the pointer and sample counts
+             */
+            pDest += 2 * NumSamples; /* Output sample pointer */
+            /* No samples left in the buffer */
+            pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
+
+            /*
+             * Realign the delay buffer data to avoid using circular buffer management
+             */
+            Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples],         /* Source */
+                       &pBuffer->OutDelayBuffer[0],                    /* Destination */
+                       (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
+            NumSamples = 0;                                /* Samples left to send */
+        }
+    }
+
+
+    /*
+     * Copy the processed results to the output
+     */
+    if ((NumSamples != 0) &&
+        (SampleCount != 0))
+    {
+        if (SampleCount <= NumSamples)
+        {
+            /*
+             * Copy all processed samples to the output
+             */
+            Copy_Float(pStart,                                      /* Source */
+                       pDest,                                       /* Detsination */
+                       (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
+            /*
+             * Update the pointer and sample counts
+             */
+            pDest      += 2 * SampleCount;                          /* Output sample pointer */
+            NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
+            SampleCount = 0; /* No samples left in the buffer */
+        }
+        else
+        {
+            /*
+             * Copy only some processed samples to the output
+             */
+            Copy_Float(pStart,                                         /* Source */
+                       pDest,                                          /* Destination */
+                       (LVM_INT16)(2 * NumSamples));     /* Number of processed samples */
+            /*
+             * Update the pointers and sample counts
+               */
+            pStart      += 2 * NumSamples;                        /* Processed sample pointer */
+            pDest       += 2 * NumSamples;                        /* Output sample pointer */
+            SampleCount  = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
+            NumSamples   = 0;                                     /* Clear the sample count */
+        }
+    }
+
+
+    /*
+     * Copy the remaining processed data to the output delay buffer
+     */
+    if (SampleCount != 0)
+    {
+        Copy_Float(pStart,                                                 /* Source */
+                   &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
+                   (LVM_INT16)(2 * SampleCount));               /* Number of processed samples */
+        /* Update the buffer count */
+        pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
+    }
+
+    /*
+     * pointers, counts and set default buffer processing
+     */
+    pBuffer->SamplesToOutput  = NumSamples;                         /* Samples left to send */
+    pInstance->pOutputSamples = pDest;                              /* Output sample pointer */
+    pBuffer->BufferState      = LVM_MAXBLOCKCALL;                   /* Set for the default call \
+                                                                            block size */
+    /* This will terminate the loop when all samples processed */
+    *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
+}
+#else
 void LVM_BufferManagedOut(LVM_Handle_t        hInstance,
                           LVM_INT16            *pOutData,
                           LVM_UINT16        *pNumSamples)
@@ -672,7 +1037,7 @@
     pBuffer->BufferState      = LVM_MAXBLOCKCALL;                   /* Set for the default call block size */
     *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;         /* This will terminate the loop when all samples processed */
 }
-
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -741,6 +1106,7 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef BUILD_FLOAT
 void LVM_BufferOptimisedOut(LVM_Handle_t    hInstance,
                             LVM_UINT16        *pNumSamples)
 {
@@ -805,7 +1171,7 @@
         }
     }
 }
-
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -843,7 +1209,31 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+void LVM_BufferOut(LVM_Handle_t     hInstance,
+                   LVM_FLOAT        *pOutData,
+                   LVM_UINT16       *pNumSamples)
+{
 
+    LVM_Instance_t    *pInstance  = (LVM_Instance_t  *)hInstance;
+
+
+    /*
+     * Check which mode, managed or unmanaged
+     */
+    if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
+    {
+        LVM_BufferManagedOut(hInstance,
+                             pOutData,
+                             pNumSamples);
+    }
+    else
+    {
+        LVM_BufferUnmanagedOut(hInstance,
+                               pNumSamples);
+    }
+}
+#else
 void LVM_BufferOut(LVM_Handle_t     hInstance,
                    LVM_INT16        *pOutData,
                    LVM_UINT16       *pNumSamples)
@@ -867,4 +1257,4 @@
                                pNumSamples);
     }
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
index 2712b2c..353560c 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
@@ -26,10 +26,655 @@
 /************************************************************************************/
 
 #define TrebleBoostCorner                                  8000
-#define TrebleBoostMinRate                                     4
-#define TrebleBoostSteps                                    15
+#define TrebleBoostMinRate                                    4
+#define TrebleBoostSteps                                     15
 
+#ifdef BUILD_FLOAT
+/* Coefficients for sample rate 22050Hz */
+                                                                    /* Gain =  1.000000 dB */
+#define HPF_Fs22050_Gain1_A0                            1.038434
+#define HPF_Fs22050_Gain1_A1                            0.331599
+#define HPF_Fs22050_Gain1_A2                            0.000000
+#define HPF_Fs22050_Gain1_B1                            0.370033
+#define HPF_Fs22050_Gain1_B2                            0.000000
+                                                                    /* Gain =  2.000000 dB */
+#define HPF_Fs22050_Gain2_A0                            1.081557
+#define HPF_Fs22050_Gain2_A1                            0.288475
+#define HPF_Fs22050_Gain2_A2                            0.000000
+#define HPF_Fs22050_Gain2_B1                            0.370033
+#define HPF_Fs22050_Gain2_B2                            0.000000
+                                                                    /* Gain =  3.000000 dB */
+#define HPF_Fs22050_Gain3_A0                            1.129943
+#define HPF_Fs22050_Gain3_A1                            0.240090
+#define HPF_Fs22050_Gain3_A2                            0.000000
+#define HPF_Fs22050_Gain3_B1                            0.370033
+#define HPF_Fs22050_Gain3_B2                            0.000000
+                                                                    /* Gain =  4.000000 dB */
+#define HPF_Fs22050_Gain4_A0                            1.184232
+#define HPF_Fs22050_Gain4_A1                            0.185801
+#define HPF_Fs22050_Gain4_A2                            0.000000
+#define HPF_Fs22050_Gain4_B1                            0.370033
+#define HPF_Fs22050_Gain4_B2                            0.000000
+                                                                    /* Gain =  5.000000 dB */
+#define HPF_Fs22050_Gain5_A0                            1.245145
+#define HPF_Fs22050_Gain5_A1                            0.124887
+#define HPF_Fs22050_Gain5_A2                            0.000000
+#define HPF_Fs22050_Gain5_B1                            0.370033
+#define HPF_Fs22050_Gain5_B2                            0.000000
+                                                                    /* Gain =  6.000000 dB */
+#define HPF_Fs22050_Gain6_A0                            1.313491
+#define HPF_Fs22050_Gain6_A1                            0.056541
+#define HPF_Fs22050_Gain6_A2                            0.000000
+#define HPF_Fs22050_Gain6_B1                            0.370033
+#define HPF_Fs22050_Gain6_B2                            0.000000
+                                                                    /* Gain =  7.000000 dB */
+#define HPF_Fs22050_Gain7_A0                            1.390177
+#define HPF_Fs22050_Gain7_A1                            -0.020144
+#define HPF_Fs22050_Gain7_A2                            0.000000
+#define HPF_Fs22050_Gain7_B1                            0.370033
+#define HPF_Fs22050_Gain7_B2                            0.000000
+                                                                    /* Gain =  8.000000 dB */
+#define HPF_Fs22050_Gain8_A0                            1.476219
+#define HPF_Fs22050_Gain8_A1                            -0.106187
+#define HPF_Fs22050_Gain8_A2                            0.000000
+#define HPF_Fs22050_Gain8_B1                            0.370033
+#define HPF_Fs22050_Gain8_B2                            0.000000
+                                                                    /* Gain =  9.000000 dB */
+#define HPF_Fs22050_Gain9_A0                            1.572761
+#define HPF_Fs22050_Gain9_A1                            -0.202728
+#define HPF_Fs22050_Gain9_A2                            0.000000
+#define HPF_Fs22050_Gain9_B1                            0.370033
+#define HPF_Fs22050_Gain9_B2                            0.000000
+                                                                    /* Gain =  10.000000 dB */
+#define HPF_Fs22050_Gain10_A0                           1.681082
+#define HPF_Fs22050_Gain10_A1                           -0.311049
+#define HPF_Fs22050_Gain10_A2                           0.000000
+#define HPF_Fs22050_Gain10_B1                           0.370033
+#define HPF_Fs22050_Gain10_B2                           0.000000
+                                                                    /* Gain =  11.000000 dB */
+#define HPF_Fs22050_Gain11_A0                           1.802620
+#define HPF_Fs22050_Gain11_A1                           -0.432588
+#define HPF_Fs22050_Gain11_A2                           0.000000
+#define HPF_Fs22050_Gain11_B1                           0.370033
+#define HPF_Fs22050_Gain11_B2                           0.000000
+                                                                    /* Gain =  12.000000 dB */
+#define HPF_Fs22050_Gain12_A0                           1.938989
+#define HPF_Fs22050_Gain12_A1                           -0.568956
+#define HPF_Fs22050_Gain12_A2                           0.000000
+#define HPF_Fs22050_Gain12_B1                           0.370033
+#define HPF_Fs22050_Gain12_B2                           0.000000
+                                                                    /* Gain =  13.000000 dB */
+#define HPF_Fs22050_Gain13_A0                           2.091997
+#define HPF_Fs22050_Gain13_A1                           -0.721964
+#define HPF_Fs22050_Gain13_A2                           0.000000
+#define HPF_Fs22050_Gain13_B1                           0.370033
+#define HPF_Fs22050_Gain13_B2                           0.000000
+                                                                    /* Gain =  14.000000 dB */
+#define HPF_Fs22050_Gain14_A0                           2.263674
+#define HPF_Fs22050_Gain14_A1                           -0.893641
+#define HPF_Fs22050_Gain14_A2                           0.000000
+#define HPF_Fs22050_Gain14_B1                           0.370033
+#define HPF_Fs22050_Gain14_B2                           0.000000
+                                                                    /* Gain =  15.000000 dB */
+#define HPF_Fs22050_Gain15_A0                           2.456300
+#define HPF_Fs22050_Gain15_A1                           -1.086267
+#define HPF_Fs22050_Gain15_A2                           0.000000
+#define HPF_Fs22050_Gain15_B1                           0.370033
+#define HPF_Fs22050_Gain15_B2                           0.000000
+/* Coefficients for sample rate 24000Hz */
+                                                                    /* Gain =  1.000000 dB */
+#define HPF_Fs24000_Gain1_A0                            1.044662
+#define HPF_Fs24000_Gain1_A1                            0.223287
+#define HPF_Fs24000_Gain1_A2                            0.000000
+#define HPF_Fs24000_Gain1_B1                            0.267949
+#define HPF_Fs24000_Gain1_B2                            0.000000
+                                                                    /* Gain =  2.000000 dB */
+#define HPF_Fs24000_Gain2_A0                            1.094773
+#define HPF_Fs24000_Gain2_A1                            0.173176
+#define HPF_Fs24000_Gain2_A2                            0.000000
+#define HPF_Fs24000_Gain2_B1                            0.267949
+#define HPF_Fs24000_Gain2_B2                            0.000000
+                                                                    /* Gain =  3.000000 dB */
+#define HPF_Fs24000_Gain3_A0                            1.150999
+#define HPF_Fs24000_Gain3_A1                            0.116950
+#define HPF_Fs24000_Gain3_A2                            0.000000
+#define HPF_Fs24000_Gain3_B1                            0.267949
+#define HPF_Fs24000_Gain3_B2                            0.000000
+                                                                    /* Gain =  4.000000 dB */
+#define HPF_Fs24000_Gain4_A0                            1.214086
+#define HPF_Fs24000_Gain4_A1                            0.053863
+#define HPF_Fs24000_Gain4_A2                            0.000000
+#define HPF_Fs24000_Gain4_B1                            0.267949
+#define HPF_Fs24000_Gain4_B2                            0.000000
+                                                                    /* Gain =  5.000000 dB */
+#define HPF_Fs24000_Gain5_A0                            1.284870
+#define HPF_Fs24000_Gain5_A1                            -0.016921
+#define HPF_Fs24000_Gain5_A2                            0.000000
+#define HPF_Fs24000_Gain5_B1                            0.267949
+#define HPF_Fs24000_Gain5_B2                            0.000000
+                                                                    /* Gain =  6.000000 dB */
+#define HPF_Fs24000_Gain6_A0                           1.364291
+#define HPF_Fs24000_Gain6_A1                           -0.096342
+#define HPF_Fs24000_Gain6_A2                           0.000000
+#define HPF_Fs24000_Gain6_B1                           0.267949
+#define HPF_Fs24000_Gain6_B2                           0.000000
+                                                                    /* Gain =  7.000000 dB */
+#define HPF_Fs24000_Gain7_A0                            1.453403
+#define HPF_Fs24000_Gain7_A1                            -0.185454
+#define HPF_Fs24000_Gain7_A2                            0.000000
+#define HPF_Fs24000_Gain7_B1                            0.267949
+#define HPF_Fs24000_Gain7_B2                            0.000000
+                                                                    /* Gain =  8.000000 dB */
+#define HPF_Fs24000_Gain8_A0                            1.553389
+#define HPF_Fs24000_Gain8_A1                            -0.285440
+#define HPF_Fs24000_Gain8_A2                            0.000000
+#define HPF_Fs24000_Gain8_B1                            0.267949
+#define HPF_Fs24000_Gain8_B2                            0.000000
+                                                                    /* Gain =  9.000000 dB */
+#define HPF_Fs24000_Gain9_A0                            1.665574
+#define HPF_Fs24000_Gain9_A1                            -0.397625
+#define HPF_Fs24000_Gain9_A2                            0.000000
+#define HPF_Fs24000_Gain9_B1                            0.267949
+#define HPF_Fs24000_Gain9_B2                            0.000000
+                                                                    /* Gain =  10.000000 dB */
+#define HPF_Fs24000_Gain10_A0                           1.791449
+#define HPF_Fs24000_Gain10_A1                           -0.523499
+#define HPF_Fs24000_Gain10_A2                           0.000000
+#define HPF_Fs24000_Gain10_B1                           0.267949
+#define HPF_Fs24000_Gain10_B2                           0.000000
+                                                                    /* Gain =  11.000000 dB */
+#define HPF_Fs24000_Gain11_A0                           1.932682
+#define HPF_Fs24000_Gain11_A1                           -0.664733
+#define HPF_Fs24000_Gain11_A2                           0.000000
+#define HPF_Fs24000_Gain11_B1                           0.267949
+#define HPF_Fs24000_Gain11_B2                           0.000000
+                                                                    /* Gain =  12.000000 dB */
+#define HPF_Fs24000_Gain12_A0                           2.091148
+#define HPF_Fs24000_Gain12_A1                           -0.823199
+#define HPF_Fs24000_Gain12_A2                           0.000000
+#define HPF_Fs24000_Gain12_B1                           0.267949
+#define HPF_Fs24000_Gain12_B2                           0.000000
+                                                                    /* Gain =  13.000000 dB */
+#define HPF_Fs24000_Gain13_A0                           2.268950
+#define HPF_Fs24000_Gain13_A1                           -1.001001
+#define HPF_Fs24000_Gain13_A2                           0.000000
+#define HPF_Fs24000_Gain13_B1                           0.267949
+#define HPF_Fs24000_Gain13_B2                           0.000000
+                                                                    /* Gain =  14.000000 dB */
+#define HPF_Fs24000_Gain14_A0                           2.468447
+#define HPF_Fs24000_Gain14_A1                           -1.200498
+#define HPF_Fs24000_Gain14_A2                           0.000000
+#define HPF_Fs24000_Gain14_B1                           0.267949
+#define HPF_Fs24000_Gain14_B2                           0.000000
+                                                                    /* Gain =  15.000000 dB */
+#define HPF_Fs24000_Gain15_A0                           2.692287
+#define HPF_Fs24000_Gain15_A1                           -1.424338
+#define HPF_Fs24000_Gain15_A2                           0.000000
+#define HPF_Fs24000_Gain15_B1                           0.267949
+#define HPF_Fs24000_Gain15_B2                           0.000000
+/* Coefficients for sample rate 32000Hz */
+                                                                    /* Gain =  1.000000 dB */
+#define HPF_Fs32000_Gain1_A0                            1.061009
+#define HPF_Fs32000_Gain1_A1                            -0.061009
+#define HPF_Fs32000_Gain1_A2                            0.000000
+#define HPF_Fs32000_Gain1_B1                            -0.000000
+#define HPF_Fs32000_Gain1_B2                            0.000000
+                                                                    /* Gain =  2.000000 dB */
+#define HPF_Fs32000_Gain2_A0                             1.129463
+#define HPF_Fs32000_Gain2_A1                             -0.129463
+#define HPF_Fs32000_Gain2_A2                             0.000000
+#define HPF_Fs32000_Gain2_B1                             -0.000000
+#define HPF_Fs32000_Gain2_B2                             0.000000
+                                                                    /* Gain =  3.000000 dB */
+#define HPF_Fs32000_Gain3_A0                             1.206267
+#define HPF_Fs32000_Gain3_A1                             -0.206267
+#define HPF_Fs32000_Gain3_A2                             0.000000
+#define HPF_Fs32000_Gain3_B1                             -0.000000
+#define HPF_Fs32000_Gain3_B2                             0.000000
+                                                                    /* Gain =  4.000000 dB */
+#define HPF_Fs32000_Gain4_A0                            1.292447
+#define HPF_Fs32000_Gain4_A1                            -0.292447
+#define HPF_Fs32000_Gain4_A2                            0.000000
+#define HPF_Fs32000_Gain4_B1                            -0.000000
+#define HPF_Fs32000_Gain4_B2                            0.000000
+                                                                    /* Gain =  5.000000 dB */
+#define HPF_Fs32000_Gain5_A0                            1.389140
+#define HPF_Fs32000_Gain5_A1                            -0.389140
+#define HPF_Fs32000_Gain5_A2                            0.000000
+#define HPF_Fs32000_Gain5_B1                            -0.000000
+#define HPF_Fs32000_Gain5_B2                            0.000000
+                                                                    /* Gain =  6.000000 dB */
+#define HPF_Fs32000_Gain6_A0                             1.497631
+#define HPF_Fs32000_Gain6_A1                             -0.497631
+#define HPF_Fs32000_Gain6_A2                             0.000000
+#define HPF_Fs32000_Gain6_B1                             -0.000000
+#define HPF_Fs32000_Gain6_B2                             0.000000
+                                                                    /* Gain =  7.000000 dB */
+#define HPF_Fs32000_Gain7_A0                             1.619361
+#define HPF_Fs32000_Gain7_A1                             -0.619361
+#define HPF_Fs32000_Gain7_A2                             0.000000
+#define HPF_Fs32000_Gain7_B1                             -0.000000
+#define HPF_Fs32000_Gain7_B2                             0.000000
+                                                                    /* Gain =  8.000000 dB */
+#define HPF_Fs32000_Gain8_A0                             1.755943
+#define HPF_Fs32000_Gain8_A1                             -0.755943
+#define HPF_Fs32000_Gain8_A2                             0.000000
+#define HPF_Fs32000_Gain8_B1                             -0.000000
+#define HPF_Fs32000_Gain8_B2                             0.000000
+                                                                    /* Gain =  9.000000 dB */
+#define HPF_Fs32000_Gain9_A0                             1.909191
+#define HPF_Fs32000_Gain9_A1                             -0.909191
+#define HPF_Fs32000_Gain9_A2                             0.000000
+#define HPF_Fs32000_Gain9_B1                             -0.000000
+#define HPF_Fs32000_Gain9_B2                             0.000000
+                                                                    /* Gain =  10.000000 dB */
+#define HPF_Fs32000_Gain10_A0                            2.081139
+#define HPF_Fs32000_Gain10_A1                            -1.081139
+#define HPF_Fs32000_Gain10_A2                            0.000000
+#define HPF_Fs32000_Gain10_B1                            -0.000000
+#define HPF_Fs32000_Gain10_B2                            0.000000
+                                                                    /* Gain =  11.000000 dB */
+#define HPF_Fs32000_Gain11_A0                           2.274067
+#define HPF_Fs32000_Gain11_A1                           -1.274067
+#define HPF_Fs32000_Gain11_A2                           0.000000
+#define HPF_Fs32000_Gain11_B1                           -0.000000
+#define HPF_Fs32000_Gain11_B2                           0.000000
+                                                                    /* Gain =  12.000000 dB */
+#define HPF_Fs32000_Gain12_A0                          2.490536
+#define HPF_Fs32000_Gain12_A1                          -1.490536
+#define HPF_Fs32000_Gain12_A2                          0.000000
+#define HPF_Fs32000_Gain12_B1                          -0.000000
+#define HPF_Fs32000_Gain12_B2                          0.000000
+                                                                    /* Gain =  13.000000 dB */
+#define HPF_Fs32000_Gain13_A0                           2.733418
+#define HPF_Fs32000_Gain13_A1                           -1.733418
+#define HPF_Fs32000_Gain13_A2                           0.000000
+#define HPF_Fs32000_Gain13_B1                           -0.000000
+#define HPF_Fs32000_Gain13_B2                           0.000000
+                                                                    /* Gain =  14.000000 dB */
+#define HPF_Fs32000_Gain14_A0                           3.005936
+#define HPF_Fs32000_Gain14_A1                           -2.005936
+#define HPF_Fs32000_Gain14_A2                           0.000000
+#define HPF_Fs32000_Gain14_B1                           -0.000000
+#define HPF_Fs32000_Gain14_B2                           0.000000
+                                                                    /* Gain =  15.000000 dB */
+#define HPF_Fs32000_Gain15_A0                          3.311707
+#define HPF_Fs32000_Gain15_A1                          -2.311707
+#define HPF_Fs32000_Gain15_A2                          0.000000
+#define HPF_Fs32000_Gain15_B1                          -0.000000
+#define HPF_Fs32000_Gain15_B2                          0.000000
+/* Coefficients for sample rate 44100Hz */
+                                                                    /* Gain =  1.000000 dB */
+#define HPF_Fs44100_Gain1_A0                            1.074364
+#define HPF_Fs44100_Gain1_A1                            -0.293257
+#define HPF_Fs44100_Gain1_A2                            0.000000
+#define HPF_Fs44100_Gain1_B1                            -0.218894
+#define HPF_Fs44100_Gain1_B2                            0.000000
+                                                                    /* Gain =  2.000000 dB */
+#define HPF_Fs44100_Gain2_A0                            1.157801
+#define HPF_Fs44100_Gain2_A1                            -0.376695
+#define HPF_Fs44100_Gain2_A2                            0.000000
+#define HPF_Fs44100_Gain2_B1                            -0.218894
+#define HPF_Fs44100_Gain2_B2                            0.000000
+                                                                    /* Gain =  3.000000 dB */
+#define HPF_Fs44100_Gain3_A0                           1.251420
+#define HPF_Fs44100_Gain3_A1                           -0.470313
+#define HPF_Fs44100_Gain3_A2                           0.000000
+#define HPF_Fs44100_Gain3_B1                           -0.218894
+#define HPF_Fs44100_Gain3_B2                           0.000000
+                                                                    /* Gain =  4.000000 dB */
+#define HPF_Fs44100_Gain4_A0                            1.356461
+#define HPF_Fs44100_Gain4_A1                            -0.575355
+#define HPF_Fs44100_Gain4_A2                            0.000000
+#define HPF_Fs44100_Gain4_B1                            -0.218894
+#define HPF_Fs44100_Gain4_B2                            0.000000
+                                                                    /* Gain =  5.000000 dB */
+#define HPF_Fs44100_Gain5_A0                            1.474320
+#define HPF_Fs44100_Gain5_A1                            -0.693213
+#define HPF_Fs44100_Gain5_A2                            0.000000
+#define HPF_Fs44100_Gain5_B1                            -0.218894
+#define HPF_Fs44100_Gain5_B2                            0.000000
+                                                                    /* Gain =  6.000000 dB */
+#define HPF_Fs44100_Gain6_A0                           1.606559
+#define HPF_Fs44100_Gain6_A1                           -0.825453
+#define HPF_Fs44100_Gain6_A2                           0.000000
+#define HPF_Fs44100_Gain6_B1                           -0.218894
+#define HPF_Fs44100_Gain6_B2                           0.000000
+                                                                    /* Gain =  7.000000 dB */
+#define HPF_Fs44100_Gain7_A0                           1.754935
+#define HPF_Fs44100_Gain7_A1                           -0.973828
+#define HPF_Fs44100_Gain7_A2                           0.000000
+#define HPF_Fs44100_Gain7_B1                           -0.218894
+#define HPF_Fs44100_Gain7_B2                           0.000000
+                                                                    /* Gain =  8.000000 dB */
+#define HPF_Fs44100_Gain8_A0                            1.921414
+#define HPF_Fs44100_Gain8_A1                            -1.140308
+#define HPF_Fs44100_Gain8_A2                            0.000000
+#define HPF_Fs44100_Gain8_B1                            -0.218894
+#define HPF_Fs44100_Gain8_B2                            0.000000
+                                                                    /* Gain =  9.000000 dB */
+#define HPF_Fs44100_Gain9_A0                            2.108208
+#define HPF_Fs44100_Gain9_A1                            -1.327101
+#define HPF_Fs44100_Gain9_A2                            0.000000
+#define HPF_Fs44100_Gain9_B1                            -0.218894
+#define HPF_Fs44100_Gain9_B2                            0.000000
+                                                                    /* Gain =  10.000000 dB */
+#define HPF_Fs44100_Gain10_A0                          2.317793
+#define HPF_Fs44100_Gain10_A1                          -1.536687
+#define HPF_Fs44100_Gain10_A2                          0.000000
+#define HPF_Fs44100_Gain10_B1                          -0.218894
+#define HPF_Fs44100_Gain10_B2                          0.000000
+                                                                    /* Gain =  11.000000 dB */
+#define HPF_Fs44100_Gain11_A0                          2.552952
+#define HPF_Fs44100_Gain11_A1                          -1.771846
+#define HPF_Fs44100_Gain11_A2                          0.000000
+#define HPF_Fs44100_Gain11_B1                          -0.218894
+#define HPF_Fs44100_Gain11_B2                          0.000000
+                                                                    /* Gain =  12.000000 dB */
+#define HPF_Fs44100_Gain12_A0                          2.816805
+#define HPF_Fs44100_Gain12_A1                          -2.035698
+#define HPF_Fs44100_Gain12_A2                          0.000000
+#define HPF_Fs44100_Gain12_B1                          -0.218894
+#define HPF_Fs44100_Gain12_B2                          0.000000
+                                                                    /* Gain =  13.000000 dB */
+#define HPF_Fs44100_Gain13_A0                           3.112852
+#define HPF_Fs44100_Gain13_A1                           -2.331746
+#define HPF_Fs44100_Gain13_A2                           0.000000
+#define HPF_Fs44100_Gain13_B1                           -0.218894
+#define HPF_Fs44100_Gain13_B2                           0.000000
+                                                                    /* Gain =  14.000000 dB */
+#define HPF_Fs44100_Gain14_A0                          3.445023
+#define HPF_Fs44100_Gain14_A1                          -2.663916
+#define HPF_Fs44100_Gain14_A2                          0.000000
+#define HPF_Fs44100_Gain14_B1                          -0.218894
+#define HPF_Fs44100_Gain14_B2                          0.000000
+                                                                    /* Gain =  15.000000 dB */
+#define HPF_Fs44100_Gain15_A0                          3.817724
+#define HPF_Fs44100_Gain15_A1                          -3.036618
+#define HPF_Fs44100_Gain15_A2                          0.000000
+#define HPF_Fs44100_Gain15_B1                          -0.218894
+#define HPF_Fs44100_Gain15_B2                          0.000000
+/* Coefficients for sample rate 48000Hz */
+                                                                    /* Gain =  1.000000 dB */
+#define HPF_Fs48000_Gain1_A0                          1.077357
+#define HPF_Fs48000_Gain1_A1                          -0.345306
+#define HPF_Fs48000_Gain1_A2                          0.000000
+#define HPF_Fs48000_Gain1_B1                          -0.267949
+#define HPF_Fs48000_Gain1_B2                          0.000000
+                                                                    /* Gain =  2.000000 dB */
+#define HPF_Fs48000_Gain2_A0                          1.164152
+#define HPF_Fs48000_Gain2_A1                          -0.432101
+#define HPF_Fs48000_Gain2_A2                          0.000000
+#define HPF_Fs48000_Gain2_B1                          -0.267949
+#define HPF_Fs48000_Gain2_B2                          0.000000
+                                                                    /* Gain =  3.000000 dB */
+#define HPF_Fs48000_Gain3_A0                          1.261538
+#define HPF_Fs48000_Gain3_A1                          -0.529488
+#define HPF_Fs48000_Gain3_A2                          0.000000
+#define HPF_Fs48000_Gain3_B1                          -0.267949
+#define HPF_Fs48000_Gain3_B2                          0.000000
+                                                                    /* Gain =  4.000000 dB */
+#define HPF_Fs48000_Gain4_A0                           1.370807
+#define HPF_Fs48000_Gain4_A1                           -0.638757
+#define HPF_Fs48000_Gain4_A2                           0.000000
+#define HPF_Fs48000_Gain4_B1                           -0.267949
+#define HPF_Fs48000_Gain4_B2                           0.000000
+                                                                    /* Gain =  5.000000 dB */
+#define HPF_Fs48000_Gain5_A0                           1.493409
+#define HPF_Fs48000_Gain5_A1                           -0.761359
+#define HPF_Fs48000_Gain5_A2                           0.000000
+#define HPF_Fs48000_Gain5_B1                           -0.267949
+#define HPF_Fs48000_Gain5_B2                           0.000000
+                                                                    /* Gain =  6.000000 dB */
+#define HPF_Fs48000_Gain6_A0                            1.630971
+#define HPF_Fs48000_Gain6_A1                            -0.898920
+#define HPF_Fs48000_Gain6_A2                            0.000000
+#define HPF_Fs48000_Gain6_B1                            -0.267949
+#define HPF_Fs48000_Gain6_B2                            0.000000
+                                                                    /* Gain =  7.000000 dB */
+#define HPF_Fs48000_Gain7_A0                            1.785318
+#define HPF_Fs48000_Gain7_A1                            -1.053267
+#define HPF_Fs48000_Gain7_A2                            0.000000
+#define HPF_Fs48000_Gain7_B1                            -0.267949
+#define HPF_Fs48000_Gain7_B2                            0.000000
+                                                                    /* Gain =  8.000000 dB */
+#define HPF_Fs48000_Gain8_A0                           1.958498
+#define HPF_Fs48000_Gain8_A1                           -1.226447
+#define HPF_Fs48000_Gain8_A2                           0.000000
+#define HPF_Fs48000_Gain8_B1                           -0.267949
+#define HPF_Fs48000_Gain8_B2                           0.000000
+                                                                    /* Gain =  9.000000 dB */
+#define HPF_Fs48000_Gain9_A0                          2.152809
+#define HPF_Fs48000_Gain9_A1                          -1.420758
+#define HPF_Fs48000_Gain9_A2                          0.000000
+#define HPF_Fs48000_Gain9_B1                          -0.267949
+#define HPF_Fs48000_Gain9_B2                          0.000000
+                                                                    /* Gain =  10.000000 dB */
+#define HPF_Fs48000_Gain10_A0                         2.370829
+#define HPF_Fs48000_Gain10_A1                         -1.638778
+#define HPF_Fs48000_Gain10_A2                         0.000000
+#define HPF_Fs48000_Gain10_B1                         -0.267949
+#define HPF_Fs48000_Gain10_B2                         0.000000
+                                                                    /* Gain =  11.000000 dB */
+#define HPF_Fs48000_Gain11_A0                          2.615452
+#define HPF_Fs48000_Gain11_A1                          -1.883401
+#define HPF_Fs48000_Gain11_A2                          0.000000
+#define HPF_Fs48000_Gain11_B1                          -0.267949
+#define HPF_Fs48000_Gain11_B2                          0.000000
+                                                                    /* Gain =  12.000000 dB */
+#define HPF_Fs48000_Gain12_A0                          2.889924
+#define HPF_Fs48000_Gain12_A1                          -2.157873
+#define HPF_Fs48000_Gain12_A2                          0.000000
+#define HPF_Fs48000_Gain12_B1                          -0.267949
+#define HPF_Fs48000_Gain12_B2                          0.000000
+                                                                    /* Gain =  13.000000 dB */
+#define HPF_Fs48000_Gain13_A0                           3.197886
+#define HPF_Fs48000_Gain13_A1                           -2.465835
+#define HPF_Fs48000_Gain13_A2                           0.000000
+#define HPF_Fs48000_Gain13_B1                           -0.267949
+#define HPF_Fs48000_Gain13_B2                           0.000000
+                                                                    /* Gain =  14.000000 dB */
+#define HPF_Fs48000_Gain14_A0                          3.543425
+#define HPF_Fs48000_Gain14_A1                          -2.811374
+#define HPF_Fs48000_Gain14_A2                          0.000000
+#define HPF_Fs48000_Gain14_B1                          -0.267949
+#define HPF_Fs48000_Gain14_B2                          0.000000
+                                                                    /* Gain =  15.000000 dB */
+#define HPF_Fs48000_Gain15_A0                         3.931127
+#define HPF_Fs48000_Gain15_A1                         -3.199076
+#define HPF_Fs48000_Gain15_A2                         0.000000
+#define HPF_Fs48000_Gain15_B1                         -0.267949
+#define HPF_Fs48000_Gain15_B2                         0.000000
 
+#ifdef HIGHER_FS
+
+/* Coefficients for sample rate 96000Hz */
+                                                                 /* Gain =  1.000000 dB */
+#define HPF_Fs96000_Gain1_A0                          1.096233
+#define HPF_Fs96000_Gain1_A1                          -0.673583
+#define HPF_Fs96000_Gain1_A2                          0.000000
+#define HPF_Fs96000_Gain1_B1                          -0.577350
+#define HPF_Fs96000_Gain1_B2                          0.000000
+                                                                 /* Gain =  2.000000 dB */
+#define HPF_Fs96000_Gain2_A0                          1.204208
+#define HPF_Fs96000_Gain2_A1                          -0.781558
+#define HPF_Fs96000_Gain2_A2                          0.000000
+#define HPF_Fs96000_Gain2_B1                          -0.577350
+#define HPF_Fs96000_Gain2_B2                          0.000000
+                                                                 /* Gain =  3.000000 dB */
+#define HPF_Fs96000_Gain3_A0                          1.325358
+#define HPF_Fs96000_Gain3_A1                          -0.902708
+#define HPF_Fs96000_Gain3_A2                          0.000000
+#define HPF_Fs96000_Gain3_B1                          -0.577350
+#define HPF_Fs96000_Gain3_B2                          0.000000
+                                                                 /* Gain =  4.000000 dB */
+#define HPF_Fs96000_Gain4_A0                           1.461291
+#define HPF_Fs96000_Gain4_A1                           -1.038641
+#define HPF_Fs96000_Gain4_A2                           0.000000
+#define HPF_Fs96000_Gain4_B1                           -0.577350
+#define HPF_Fs96000_Gain4_B2                           0.000000
+                                                                 /* Gain =  5.000000 dB */
+#define HPF_Fs96000_Gain5_A0                           1.613810
+#define HPF_Fs96000_Gain5_A1                           -1.191160
+#define HPF_Fs96000_Gain5_A2                           0.000000
+#define HPF_Fs96000_Gain5_B1                           -0.577350
+#define HPF_Fs96000_Gain5_B2                           0.000000
+                                                                 /* Gain =  6.000000 dB */
+#define HPF_Fs96000_Gain6_A0                            1.784939
+#define HPF_Fs96000_Gain6_A1                            -1.362289
+#define HPF_Fs96000_Gain6_A2                            0.000000
+#define HPF_Fs96000_Gain6_B1                            -0.577350
+#define HPF_Fs96000_Gain6_B2                            0.000000
+                                                                /* Gain =  7.000000 dB */
+#define HPF_Fs96000_Gain7_A0                            1.976949
+#define HPF_Fs96000_Gain7_A1                            -1.554299
+#define HPF_Fs96000_Gain7_A2                            0.000000
+#define HPF_Fs96000_Gain7_B1                            -0.577350
+#define HPF_Fs96000_Gain7_B2                            0.000000
+                                                                 /* Gain =  8.000000 dB */
+#define HPF_Fs96000_Gain8_A0                           2.192387
+#define HPF_Fs96000_Gain8_A1                           -1.769738
+#define HPF_Fs96000_Gain8_A2                           0.000000
+#define HPF_Fs96000_Gain8_B1                           -0.577350
+#define HPF_Fs96000_Gain8_B2                           0.000000
+                                                                /* Gain =  9.000000 dB */
+#define HPF_Fs96000_Gain9_A0                          2.434113
+#define HPF_Fs96000_Gain9_A1                          -2.011464
+#define HPF_Fs96000_Gain9_A2                          0.000000
+#define HPF_Fs96000_Gain9_B1                          -0.577350
+#define HPF_Fs96000_Gain9_B2                          0.000000
+                                                               /* Gain =  10.000000 dB */
+#define HPF_Fs96000_Gain10_A0                        2.705335
+#define HPF_Fs96000_Gain10_A1                        -2.282685
+#define HPF_Fs96000_Gain10_A2                         0.000000
+#define HPF_Fs96000_Gain10_B1                         -0.577350
+#define HPF_Fs96000_Gain10_B2                         0.000000
+                                                              /* Gain =  11.000000 dB */
+#define HPF_Fs96000_Gain11_A0                          3.009650
+#define HPF_Fs96000_Gain11_A1                          -2.587000
+#define HPF_Fs96000_Gain11_A2                          0.000000
+#define HPF_Fs96000_Gain11_B1                          -0.577350
+#define HPF_Fs96000_Gain11_B2                          0.000000
+                                                                  /* Gain =  12.000000 dB */
+#define HPF_Fs96000_Gain12_A0                          3.351097
+#define HPF_Fs96000_Gain12_A1                          -2.928447
+#define HPF_Fs96000_Gain12_A2                          0.000000
+#define HPF_Fs96000_Gain12_B1                          -0.577350
+#define HPF_Fs96000_Gain12_B2                          0.000000
+                                                                /* Gain =  13.000000 dB */
+#define HPF_Fs96000_Gain13_A0                           3.734207
+#define HPF_Fs96000_Gain13_A1                           -3.311558
+#define HPF_Fs96000_Gain13_A2                           0.000000
+#define HPF_Fs96000_Gain13_B1                           -0.577350
+#define HPF_Fs96000_Gain13_B2                           0.000000
+                                                                 /* Gain =  14.000000 dB */
+#define HPF_Fs96000_Gain14_A0                         4.164064
+#define HPF_Fs96000_Gain14_A1                         -3.741414
+#define HPF_Fs96000_Gain14_A2                          0.000000
+#define HPF_Fs96000_Gain14_B1                          -0.577350
+#define HPF_Fs96000_Gain14_B2                          0.000000
+                                                                 /* Gain =  15.000000 dB */
+#define HPF_Fs96000_Gain15_A0                         4.646371
+#define HPF_Fs96000_Gain15_A1                         -4.223721
+#define HPF_Fs96000_Gain15_A2                         0.000000
+#define HPF_Fs96000_Gain15_B1                         -0.577350
+#define HPF_Fs96000_Gain15_B2                         0.000000
+
+/* Coefficients for sample rate 192000Hz */
+                                                                  /* Gain =  1.000000 dB */
+#define HPF_Fs192000_Gain1_A0                          1.107823
+#define HPF_Fs192000_Gain1_A1                          -0.875150
+#define HPF_Fs192000_Gain1_A2                          0.000000
+#define HPF_Fs192000_Gain1_B1                          -0.767327
+#define HPF_Fs192000_Gain1_B2                          0.000000
+                                                                  /* Gain =  2.000000 dB */
+#define HPF_Fs192000_Gain2_A0                          1.228803
+#define HPF_Fs192000_Gain2_A1                          -0.996130
+#define HPF_Fs192000_Gain2_A2                          0.000000
+#define HPF_Fs192000_Gain2_B1                          -0.767327
+#define HPF_Fs192000_Gain2_B2                          0.000000
+                                                                   /* Gain =  3.000000 dB */
+#define HPF_Fs192000_Gain3_A0                          1.364544
+#define HPF_Fs192000_Gain3_A1                          -1.131871
+#define HPF_Fs192000_Gain3_A2                          0.000000
+#define HPF_Fs192000_Gain3_B1                          -0.767327
+#define HPF_Fs192000_Gain3_B2                          0.000000
+                                                                   /* Gain =  4.000000 dB */
+#define HPF_Fs192000_Gain4_A0                          1.516849
+#define HPF_Fs192000_Gain4_A1                          -1.284176
+#define HPF_Fs192000_Gain4_A2                           0.000000
+#define HPF_Fs192000_Gain4_B1                           -0.767327
+#define HPF_Fs192000_Gain4_B2                           0.000000
+                                                                   /* Gain =  5.000000 dB */
+#define HPF_Fs192000_Gain5_A0                           1.687737
+#define HPF_Fs192000_Gain5_A1                           -1.455064
+#define HPF_Fs192000_Gain5_A2                           0.000000
+#define HPF_Fs192000_Gain5_B1                           -0.767327
+#define HPF_Fs192000_Gain5_B2                           0.000000
+                                                                   /* Gain =  6.000000 dB */
+#define HPF_Fs192000_Gain6_A0                            1.879477
+#define HPF_Fs192000_Gain6_A1                            -1.646804
+#define HPF_Fs192000_Gain6_A2                            0.000000
+#define HPF_Fs192000_Gain6_B1                            -0.767327
+#define HPF_Fs192000_Gain6_B2                            0.000000
+                                                                 /* Gain =  7.000000 dB */
+#define HPF_Fs192000_Gain7_A0                            2.094613
+#define HPF_Fs192000_Gain7_A1                            -1.861940
+#define HPF_Fs192000_Gain7_A2                            0.000000
+#define HPF_Fs192000_Gain7_B1                            -0.767327
+#define HPF_Fs192000_Gain7_B2                            0.000000
+                                                                   /* Gain =  8.000000 dB */
+#define HPF_Fs192000_Gain8_A0                           2.335999
+#define HPF_Fs192000_Gain8_A1                           -2.103326
+#define HPF_Fs192000_Gain8_A2                           0.000000
+#define HPF_Fs192000_Gain8_B1                           -0.767327
+#define HPF_Fs192000_Gain8_B2                           0.000000
+                                                                   /* Gain =  9.000000 dB */
+#define HPF_Fs192000_Gain9_A0                          2.606839
+#define HPF_Fs192000_Gain9_A1                          -2.374166
+#define HPF_Fs192000_Gain9_A2                          0.000000
+#define HPF_Fs192000_Gain9_B1                          -0.767327
+#define HPF_Fs192000_Gain9_B2                          0.000000
+                                                                 /* Gain =  10.000000 dB */
+#define HPF_Fs192000_Gain10_A0                        2.910726
+#define HPF_Fs192000_Gain10_A1                        -2.678053
+#define HPF_Fs192000_Gain10_A2                         0.000000
+#define HPF_Fs192000_Gain10_B1                         -0.767327
+#define HPF_Fs192000_Gain10_B2                         0.000000
+                                                                  /* Gain =  11.000000 dB */
+#define HPF_Fs192000_Gain11_A0                          3.251693
+#define HPF_Fs192000_Gain11_A1                          -3.019020
+#define HPF_Fs192000_Gain11_A2                          0.000000
+#define HPF_Fs192000_Gain11_B1                          -0.767327
+#define HPF_Fs192000_Gain11_B2                          0.000000
+                                                                  /* Gain =  12.000000 dB */
+#define HPF_Fs192000_Gain12_A0                          3.634264
+#define HPF_Fs192000_Gain12_A1                          -3.401591
+#define HPF_Fs192000_Gain12_A2                          0.000000
+#define HPF_Fs192000_Gain12_B1                          -0.767327
+#define HPF_Fs192000_Gain12_B2                          0.000000
+                                                                /* Gain =  13.000000 dB */
+#define HPF_Fs192000_Gain13_A0                           4.063516
+#define HPF_Fs192000_Gain13_A1                           -3.830843
+#define HPF_Fs192000_Gain13_A2                           0.000000
+#define HPF_Fs192000_Gain13_B1                           -0.767327
+#define HPF_Fs192000_Gain13_B2                           0.000000
+                                                                /* Gain =  14.000000 dB */
+#define HPF_Fs192000_Gain14_A0                          4.545145
+#define HPF_Fs192000_Gain14_A1                          -4.312472
+#define HPF_Fs192000_Gain14_A2                          0.000000
+#define HPF_Fs192000_Gain14_B1                          -0.767327
+#define HPF_Fs192000_Gain14_B2                          0.000000
+                                                                  /* Gain =  15.000000 dB */
+#define HPF_Fs192000_Gain15_A0                         5.085542
+#define HPF_Fs192000_Gain15_A1                         -4.852868
+#define HPF_Fs192000_Gain15_A2                         0.000000
+#define HPF_Fs192000_Gain15_B1                         -0.767327
+#define HPF_Fs192000_Gain15_B2                         0.000000
+
+#endif
+
+#else
 /* Coefficients for sample rate 22050Hz */
                                                                     /* Gain =  1.000000 dB */
 #define HPF_Fs22050_Gain1_A0                             5383         /* Floating point value 0.164291 */
@@ -571,3 +1216,4 @@
 
 
 #endif
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index 72564d4..cfe53b8 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -65,9 +65,16 @@
     if(
         /* General parameters */
         ((pParams->OperatingMode != LVM_MODE_OFF) && (pParams->OperatingMode != LVM_MODE_ON))                                         ||
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000)       &&
+     (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000)      &&
+     (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)      &&
+     (pParams->SampleRate != LVM_FS_96000) && (pParams->SampleRate != LVM_FS_192000))      ||
+#else
         ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000)       &&
         (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000)       &&
         (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000))      ||
+#endif
         ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) ||
         (pParams->SpeakerType > LVM_EX_HEADPHONES))
     {
@@ -268,7 +275,12 @@
 void LVM_SetTrebleBoost(LVM_Instance_t         *pInstance,
                         LVM_ControlParams_t    *pParams)
 {
+#ifdef BUILD_FLOAT
+    extern FO_FLOAT_LShx_Coefs_t  LVM_TrebleBoostCoefs[];
+#else
     extern FO_C16_LShx_Coefs_t  LVM_TrebleBoostCoefs[];
+#endif
+
     LVM_INT16               Offset;
     LVM_INT16               EffectLevel = 0;
 
@@ -298,6 +310,20 @@
              * Load the coefficients and enabled the treble boost
              */
             Offset = (LVM_INT16)(EffectLevel - 1 + TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate));
+#ifdef BUILD_FLOAT
+            FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
+                                            &pInstance->pTE_Taps->TrebleBoost_Taps,
+                                            &LVM_TrebleBoostCoefs[Offset]);
+
+            /*
+             * Clear the taps
+             */
+            LoadConst_Float((LVM_FLOAT)0,                                     /* Value */
+                            (void *)&pInstance->pTE_Taps->TrebleBoost_Taps,  /* Destination.\
+                                                     Cast to void: no dereferencing in function */
+                            (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps) / \
+                                                        sizeof(LVM_FLOAT))); /* Number of words */
+#else
             FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
                                             &pInstance->pTE_Taps->TrebleBoost_Taps,
                                             &LVM_TrebleBoostCoefs[Offset]);
@@ -309,6 +335,7 @@
                          (void *)&pInstance->pTE_Taps->TrebleBoost_Taps,  /* Destination.\
                                                      Cast to void: no dereferencing in function */
                          (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps)/sizeof(LVM_INT16))); /* Number of words */
+#endif
         }
     }
     else
@@ -342,6 +369,9 @@
     LVM_UINT16      dBShifts;                                   /* 6dB shifts */
     LVM_UINT16      dBOffset;                                   /* Table offset */
     LVM_INT16       Volume = 0;                                 /* Required volume in dBs */
+#ifdef BUILD_FLOAT
+    LVM_FLOAT        Temp;
+#endif
 
     /*
      * Limit the gain to the maximum allowed
@@ -401,22 +431,46 @@
      */
     if(dBShifts == 0)
     {
+#ifdef BUILD_FLOAT
+        LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
+                                (LVM_FLOAT)LVM_VolumeTable[dBOffset]);
+#else
         LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
                                 (LVM_INT32)LVM_VolumeTable[dBOffset]);
-    }
+#endif
+        }
     else
     {
+#ifdef BUILD_FLOAT
+        Temp = LVM_VolumeTable[dBOffset];
+        while(dBShifts) {
+            Temp = Temp / 2.0f;
+            dBShifts--;
+        }
+        LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], Temp);
+#else
         LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
                                 (((LVM_INT32)LVM_VolumeTable[dBOffset])>>dBShifts));
+#endif
     }
     pInstance->VC_Volume.MixerStream[0].CallbackSet = 1;
     if(pInstance->NoSmoothVolume == LVM_TRUE)
     {
+#ifdef BUILD_FLOAT
+        LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0], 0,
+                                  pInstance->Params.SampleRate, 2);
+#else
         LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,pInstance->Params.SampleRate,2);
+#endif
     }
     else
     {
+#ifdef BUILD_FLOAT
+        LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],
+                                           LVM_VC_MIXER_TIME, pInstance->Params.SampleRate, 2);
+#else
         LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],LVM_VC_MIXER_TIME,pInstance->Params.SampleRate,2);
+#endif
     }
 }
 
@@ -554,8 +608,23 @@
         /* Configure Mixer module for gradual changes to volume*/
         if(LocalParams.VC_Balance < 0)
         {
+#ifdef BUILD_FLOAT
+            LVM_FLOAT Target_Float;
+#else
             LVM_INT32 Target;
+#endif
             /* Drop in right channel volume*/
+#ifdef BUILD_FLOAT
+            Target_Float = LVM_MAXFLOAT;
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+                                               LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+
+            Target_Float = dB_to_LinFloat((LVM_INT16)(LocalParams.VC_Balance << 4));
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+                                               LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+#else
             Target = LVM_MAXINT_16;
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
@@ -563,11 +632,27 @@
             Target = dB_to_Lin32((LVM_INT16)(LocalParams.VC_Balance<<4));
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
         }
         else if(LocalParams.VC_Balance >0)
         {
+#ifdef BUILD_FLOAT
+            LVM_FLOAT Target_Float;
+#else
             LVM_INT32 Target;
+#endif
             /* Drop in left channel volume*/
+#ifdef BUILD_FLOAT
+            Target_Float = dB_to_LinFloat((LVM_INT16)((-LocalParams.VC_Balance) << 4));
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+                                               LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+
+            Target_Float = LVM_MAXFLOAT;
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+                                               LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
+#else
             Target = dB_to_Lin32((LVM_INT16)((-LocalParams.VC_Balance)<<4));
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
@@ -575,17 +660,36 @@
             Target = LVM_MAXINT_16;
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
         }
         else
         {
+#ifdef BUILD_FLOAT
+            LVM_FLOAT Target_Float;
+#else
             LVM_INT32 Target;
+#endif
             /* No drop*/
+#ifdef BUILD_FLOAT
+            Target_Float = LVM_MAXFLOAT;
+#else
             Target = LVM_MAXINT_16;
+#endif
+#ifdef BUILD_FLOAT
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
+                                               LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
+
+            LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target_Float);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
+                                               LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
+#else
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
 
             LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
+#endif
         }
     }
     /*
@@ -1008,18 +1112,30 @@
                             short   CallBackParam)
 {
     LVM_Instance_t *pInstance =(LVM_Instance_t  *)pBundleHandle;
+#ifdef BUILD_FLOAT
+    LVM_FLOAT    Target;
+#else
     LVM_INT32    Target;
+#endif
 
     (void) pGeneralPurpose;
     (void) CallBackParam;
 
     /* When volume mixer has reached 0 dB target then stop it to avoid
        unnecessary processing. */
+#ifdef BUILD_FLOAT
+    Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
+    if(Target == 1.0f)
+    {
+        pInstance->VC_Active = LVM_FALSE;
+    }
+#else
     Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
 
     if(Target == 0x7FFF)
     {
         pInstance->VC_Active = LVM_FALSE;
     }
+#endif
     return 1;
 }
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
index 542c3c8..26c1c4f 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -232,7 +232,11 @@
         /*
          * Set the capabilities
          */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+        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_96000 | LVDBE_CAP_FS_192000;
+#else
         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;
+#endif
         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;
 
@@ -265,7 +269,11 @@
         /*
          * Set the capabilities
          */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+        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_96000 | LVEQNB_CAP_FS_192000;
+#else
         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;
+#endif
         EQNB_Capabilities.SourceFormat = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
         EQNB_Capabilities.MaxBlockSize = InternalBlockSize;
         EQNB_Capabilities.MaxBands     = pInstParams->EQNB_NumBands;
@@ -542,10 +550,15 @@
         BundleScratchSize = (LVM_INT32)(6 * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_INT16));
         pInstance->pBufferManagement->pScratch = InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],   /* Scratch 1 buffer */
                                                                      (LVM_UINT32)BundleScratchSize);
-
+#ifdef BUILD_FLOAT
+        LoadConst_Float(0,                                   /* Clear the input delay buffer */
+                        (LVM_FLOAT *)&pInstance->pBufferManagement->InDelayBuffer,
+                        (LVM_INT16)(2 * MIN_INTERNAL_BLOCKSIZE));
+#else
         LoadConst_16(0,                                                        /* Clear the input delay buffer */
                      (LVM_INT16 *)&pInstance->pBufferManagement->InDelayBuffer,
                      (LVM_INT16)(2 * MIN_INTERNAL_BLOCKSIZE));
+#endif
         pInstance->pBufferManagement->InDelaySamples = MIN_INTERNAL_BLOCKSIZE; /* Set the number of delay samples */
         pInstance->pBufferManagement->OutDelaySamples = 0;                     /* No samples in the output buffer */
         pInstance->pBufferManagement->BufferState = LVM_FIRSTCALL;             /* Set the state ready for the first call */
@@ -598,14 +611,26 @@
     /* In managed buffering, start with low signal level as delay in buffer management causes a click*/
     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
     {
+#ifdef BUILD_FLOAT
+        LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], 0, 0);
+#else
         LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0],0,0);
+#endif
     }
     else
     {
+#ifdef BUILD_FLOAT
+        LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
         LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
     }
 
+#ifdef BUILD_FLOAT
     LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,LVM_FS_8000,2);
+#else
+    LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0], 0, LVM_FS_8000, 2);
+#endif
 
     pInstance->VC_VolumedB                  = 0;
     pInstance->VC_AVLFixedVolume            = 0;
@@ -615,15 +640,24 @@
     pInstance->VC_BalanceMix.MixerStream[0].CallbackSet        = 0;
     pInstance->VC_BalanceMix.MixerStream[0].pCallbackHandle    = pInstance;
     pInstance->VC_BalanceMix.MixerStream[0].pCallBack          = LVM_VCCallBack;
+#ifdef BUILD_FLOAT
+    LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
     LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[0],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
     LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
 
     pInstance->VC_BalanceMix.MixerStream[1].CallbackParam      = 0;
     pInstance->VC_BalanceMix.MixerStream[1].CallbackSet        = 0;
     pInstance->VC_BalanceMix.MixerStream[1].pCallbackHandle    = pInstance;
     pInstance->VC_BalanceMix.MixerStream[1].pCallBack          = LVM_VCCallBack;
+#ifdef BUILD_FLOAT
+    LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[1], LVM_MAXFLOAT, LVM_MAXFLOAT);
+#else
     LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[1],LVM_MAXINT_16,LVM_MAXINT_16);
+#endif
     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
      */
@@ -709,7 +743,11 @@
         /*
          * Set the initialisation capabilities
          */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+        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_96000 | LVDBE_CAP_FS_192000;
+#else
         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;
+#endif
         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;
 
@@ -763,7 +801,11 @@
         /*
          * Set the initialisation capabilities
          */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+        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_96000 | LVEQNB_CAP_FS_192000;
+#else
         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;
+#endif
         EQNB_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
         EQNB_Capabilities.MaxBands        = pInstParams->EQNB_NumBands;
         EQNB_Capabilities.SourceFormat    = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
@@ -868,9 +910,14 @@
                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
 
             /* Fast Temporary */
+#ifdef BUILD_FLOAT
             pInstance->pPSAInput = InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
-                                                                     (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_INT16));
-
+                                                       (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * \
+                                                       sizeof(LVM_FLOAT));
+#else
+            pInstance->pPSAInput = InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
+                                                       (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_INT16));
+#endif
             PSA_MemTab.Region[LVM_TEMPORARY_FAST].pBaseAddress       = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],0);
 
 
@@ -994,7 +1041,6 @@
     /* DC removal filter */
     DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
 
-
     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 2e85f77..b453222 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -138,6 +138,23 @@
 
 
 /* Buffer Management */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT               *pScratch;          /* Bundle scratch buffer */
+
+    LVM_INT16               BufferState;        /* Buffer status */
+    LVM_FLOAT               InDelayBuffer[6 * MIN_INTERNAL_BLOCKSIZE]; /* Input buffer delay line, \
+                                                                           left and right */
+    LVM_INT16               InDelaySamples;     /* Number of samples in the input delay buffer */
+
+    LVM_FLOAT               OutDelayBuffer[2 * MIN_INTERNAL_BLOCKSIZE]; /* Output buffer delay \
+                                                                                      line */
+    LVM_INT16               OutDelaySamples;    /* Number of samples in the output delay buffer, \
+                                                                             left and right */
+    LVM_INT16               SamplesToOutput;    /* Samples to write to the output */
+} LVM_Buffer_t;
+#else
 typedef struct
 {
     LVM_INT16               *pScratch;          /* Bundle scratch buffer */
@@ -150,22 +167,28 @@
     LVM_INT16               OutDelaySamples;    /* Number of samples in the output delay buffer, left and right */
     LVM_INT16               SamplesToOutput;    /* Samples to write to the output */
 } LVM_Buffer_t;
-
+#endif
 
 /* Filter taps */
 typedef struct
 {
+#ifdef BUILD_FLOAT
+    Biquad_2I_Order1_FLOAT_Taps_t TrebleBoost_Taps;   /* Treble boost Taps */
+#else
     Biquad_2I_Order1_Taps_t TrebleBoost_Taps;   /* Treble boost Taps */
+#endif
 } LVM_TE_Data_t;
 
-
 /* Coefficients */
 typedef struct
 {
+#ifdef BUILD_FLOAT
+    Biquad_FLOAT_Instance_t       TrebleBoost_State;  /* State for the treble boost filter */
+#else
     Biquad_Instance_t       TrebleBoost_State;  /* State for the treble boost filter */
+#endif
 } LVM_TE_Coefs_t;
 
-
 typedef struct
 {
     /* Public parameters */
@@ -181,15 +204,24 @@
     LVM_INT16               InternalBlockSize;  /* Maximum internal block size */
     LVM_Buffer_t            *pBufferManagement; /* Buffer management variables */
     LVM_INT16               SamplesToProcess;   /* Input samples left to process */
+#ifdef BUILD_FLOAT
+    LVM_FLOAT               *pInputSamples;     /* External input sample pointer */
+    LVM_FLOAT               *pOutputSamples;    /* External output sample pointer */
+#else
     LVM_INT16               *pInputSamples;     /* External input sample pointer */
     LVM_INT16               *pOutputSamples;    /* External output sample pointer */
+#endif
 
     /* Configuration number */
     LVM_INT32               ConfigurationNumber;
     LVM_INT32               BlickSizeMultiple;
 
     /* DC removal */
+#ifdef BUILD_FLOAT
+    Biquad_FLOAT_Instance_t       DC_RemovalInstance; /* DC removal filter instance */
+#else
     Biquad_Instance_t       DC_RemovalInstance; /* DC removal filter instance */
+#endif
 
     /* Concert Sound */
     LVCS_Handle_t           hCSInstance;        /* Concert Sound instance handle */
@@ -209,8 +241,16 @@
     LVM_INT16               DBE_Active;         /* Control flag */
 
     /* Volume Control */
+#ifdef BUILD_FLOAT
+    LVMixer3_1St_FLOAT_st   VC_Volume;          /* Volume scaler */
+#else
     LVMixer3_1St_st         VC_Volume;          /* Volume scaler */
+#endif
+#ifdef BUILD_FLOAT
+    LVMixer3_2St_FLOAT_st         VC_BalanceMix;      /* VC balance mixer */
+#else
     LVMixer3_2St_st         VC_BalanceMix;      /* VC balance mixer */
+#endif
     LVM_INT16               VC_VolumedB;        /* Gain in dB */
     LVM_INT16               VC_Active;          /* Control flag */
     LVM_INT16               VC_AVLFixedVolume;  /* AVL fixed volume */
@@ -234,7 +274,11 @@
     LVPSA_ControlParams_t   PSA_ControlParams;  /* Spectrum Analyzer control parameters */
     LVM_INT16               PSA_GainOffset;     /* Tone control flag */
     LVM_Callback            CallBack;
+#ifdef BUILD_FLOAT
+    LVM_FLOAT               *pPSAInput;         /* PSA input pointer */
+#else
     LVM_INT16               *pPSAInput;         /* PSA input pointer */
+#endif
 
     LVM_INT16              NoSmoothVolume;      /* Enable or disable smooth volume changes*/
 
@@ -261,16 +305,28 @@
 
 void    LVM_SetHeadroom(    LVM_Instance_t         *pInstance,
                             LVM_ControlParams_t    *pParams);
-
+#ifdef BUILD_FLOAT
+void    LVM_BufferIn(   LVM_Handle_t      hInstance,
+                        const LVM_FLOAT   *pInData,
+                        LVM_FLOAT         **pToProcess,
+                        LVM_FLOAT         **pProcessed,
+                        LVM_UINT16        *pNumSamples);
+#else
 void    LVM_BufferIn(   LVM_Handle_t      hInstance,
                         const LVM_INT16   *pInData,
                         LVM_INT16         **pToProcess,
                         LVM_INT16         **pProcessed,
                         LVM_UINT16        *pNumSamples);
-
+#endif
+#ifdef BUILD_FLOAT
+void    LVM_BufferOut(  LVM_Handle_t     hInstance,
+                        LVM_FLOAT        *pOutData,
+                        LVM_UINT16       *pNumSamples);
+#else
 void    LVM_BufferOut(  LVM_Handle_t     hInstance,
                         LVM_INT16        *pOutData,
                         LVM_UINT16       *pNumSamples);
+#endif
 
 LVM_INT32 LVM_AlgoCallBack(     void          *pBundleHandle,
                                 void          *pData,
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
index f5a01f3..4a19a13 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
@@ -51,7 +51,231 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
+                                const LVM_FLOAT             *pInData,
+                                LVM_FLOAT                   *pOutData,
+                                LVM_UINT16                  NumSamples,
+                                LVM_UINT32                  AudioTime)
+{
 
+    LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
+    LVM_UINT16          SampleCount = NumSamples;
+    LVM_FLOAT           *pInput     = (LVM_FLOAT *)pInData;
+    LVM_FLOAT           *pToProcess = (LVM_FLOAT *)pInData;
+    LVM_FLOAT           *pProcessed = pOutData;
+    LVM_ReturnStatus_en  Status;
+
+    /*
+     * Check if the number of samples is zero
+     */
+    if (NumSamples == 0)
+    {
+        return(LVM_SUCCESS);
+    }
+
+
+    /*
+     * Check valid points have been given
+     */
+    if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
+    {
+        return (LVM_NULLADDRESS);
+    }
+
+    /*
+     * For unmanaged mode only
+     */
+    if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
+    {
+         /*
+         * Check if the number of samples is a good multiple (unmanaged mode only)
+         */
+        if((NumSamples % pInstance->BlickSizeMultiple) != 0)
+        {
+            return(LVM_INVALIDNUMSAMPLES);
+        }
+
+        /*
+         * Check the buffer alignment
+         */
+        if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
+        {
+            return(LVM_ALIGNMENTERROR);
+        }
+    }
+
+
+    /*
+     * Update new parameters if necessary
+     */
+    if (pInstance->ControlPending == LVM_TRUE)
+    {
+        Status = LVM_ApplyNewSettings(hInstance);
+
+        if(Status != LVM_SUCCESS)
+        {
+            return Status;
+        }
+    }
+
+
+    /*
+     * Convert from Mono if necessary
+     */
+    if (pInstance->Params.SourceFormat == LVM_MONO)
+    {
+        MonoTo2I_Float(pInData,                                /* Source */
+                       pOutData,                               /* Destination */
+                       (LVM_INT16)NumSamples);                 /* Number of input samples */
+        pInput     = pOutData;
+        pToProcess = pOutData;
+    }
+
+
+    /*
+     * Process the data with managed buffers
+     */
+    while (SampleCount != 0)
+    {
+        /*
+         * Manage the input buffer and frame processing
+         */
+        LVM_BufferIn(hInstance,
+                     pInput,
+                     &pToProcess,
+                     &pProcessed,
+                     &SampleCount);
+
+        /*
+         * Only process data when SampleCount is none zero, a zero count can occur when
+         * the BufferIn routine is working in managed mode.
+         */
+        if (SampleCount != 0)
+        {
+
+            /*
+             * Apply ConcertSound if required
+             */
+            if (pInstance->CS_Active == LVM_TRUE)
+            {
+                (void)LVCS_Process(pInstance->hCSInstance,     /* Concert Sound instance handle */
+                                   pToProcess,
+                                   pProcessed,
+                                   SampleCount);
+                pToProcess = pProcessed;
+            }
+
+            /*
+             * Apply volume if required
+             */
+            if (pInstance->VC_Active!=0)
+            {
+                LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
+                                       pToProcess,
+                                       pProcessed,
+                                       (LVM_INT16)(2 * SampleCount));     /* Left and right*/
+                pToProcess = pProcessed;
+            }
+
+            /*
+             * Call N-Band equaliser if enabled
+             */
+            if (pInstance->EQNB_Active == LVM_TRUE)
+            {
+                LVEQNB_Process(pInstance->hEQNBInstance,    /* N-Band equaliser instance handle */
+                               pToProcess,
+                               pProcessed,
+                               SampleCount);
+                pToProcess = pProcessed;
+            }
+
+            /*
+             * Call bass enhancement if enabled
+             */
+            if (pInstance->DBE_Active == LVM_TRUE)
+            {
+                LVDBE_Process(pInstance->hDBEInstance,       /* Dynamic Bass Enhancement \
+                                                                instance handle */
+                              pToProcess,
+                              pProcessed,
+                              SampleCount);
+                pToProcess = pProcessed;
+            }
+
+            /*
+             * Bypass mode or everything off, so copy the input to the output
+             */
+            if (pToProcess != pProcessed)
+            {
+                Copy_Float(pToProcess,                             /* Source */
+                           pProcessed,                             /* Destination */
+                           (LVM_INT16)(2 * SampleCount));          /* Left and right */
+            }
+
+            /*
+             * Apply treble boost if required
+             */
+            if (pInstance->TE_Active == LVM_TRUE)
+            {
+                /*
+                 * Apply the filter
+                 */
+                FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
+                                           pProcessed,
+                                           pProcessed,
+                                           (LVM_INT16)SampleCount);
+
+            }
+
+            /*
+             * Volume balance
+             */
+            LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
+                                            pProcessed,
+                                            pProcessed,
+                                            SampleCount);
+
+            /*
+             * Perform Parametric Spectum Analysis
+             */
+            if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
+                                            (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
+            {
+                    From2iToMono_Float(pProcessed,
+                                       pInstance->pPSAInput,
+                                       (LVM_INT16)(SampleCount));
+
+                    LVPSA_Process(pInstance->hPSAInstance,
+                            pInstance->pPSAInput,
+                            (LVM_UINT16)(SampleCount),
+                            AudioTime);
+            }
+
+
+            /*
+             * DC removal
+             */
+            DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
+                                 pProcessed,
+                                 pProcessed,
+                                 (LVM_INT16)SampleCount);
+
+
+        }
+
+        /*
+         * Manage the output buffer
+         */
+        LVM_BufferOut(hInstance,
+                      pOutData,
+                      &SampleCount);
+
+    }
+
+    return(LVM_SUCCESS);
+}
+#else
 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
                                 const LVM_INT16             *pInData,
                                 LVM_INT16                   *pOutData,
@@ -273,3 +497,4 @@
 
     return(LVM_SUCCESS);
 }
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
index e14f909..199ddde 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -29,7 +29,342 @@
 /*    Treble Boost Filter Coefficients                                              */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
 
+FO_FLOAT_LShx_Coefs_t    LVM_TrebleBoostCoefs[] = {
+
+                    /* 22kHz sampling rate */
+                    {HPF_Fs22050_Gain1_A1,             /* Gain setting 1 */
+                     HPF_Fs22050_Gain1_A0,
+                     -HPF_Fs22050_Gain1_B1},
+                    {HPF_Fs22050_Gain2_A1,             /* Gain setting 2 */
+                     HPF_Fs22050_Gain2_A0,
+                     -HPF_Fs22050_Gain2_B1},
+                    {HPF_Fs22050_Gain3_A1,             /* Gain setting 3 */
+                     HPF_Fs22050_Gain3_A0,
+                     -HPF_Fs22050_Gain3_B1},
+                    {HPF_Fs22050_Gain4_A1,             /* Gain setting 4 */
+                     HPF_Fs22050_Gain4_A0,
+                     -HPF_Fs22050_Gain4_B1},
+                    {HPF_Fs22050_Gain5_A1,             /* Gain setting 5 */
+                     HPF_Fs22050_Gain5_A0,
+                     -HPF_Fs22050_Gain5_B1},
+                    {HPF_Fs22050_Gain6_A1,             /* Gain setting 6 */
+                     HPF_Fs22050_Gain6_A0,
+                     -HPF_Fs22050_Gain6_B1},
+                    {HPF_Fs22050_Gain7_A1,             /* Gain setting 7 */
+                     HPF_Fs22050_Gain7_A0,
+                     -HPF_Fs22050_Gain7_B1},
+                    {HPF_Fs22050_Gain8_A1,             /* Gain setting 8 */
+                     HPF_Fs22050_Gain8_A0,
+                     -HPF_Fs22050_Gain8_B1},
+                    {HPF_Fs22050_Gain9_A1,             /* Gain setting 9 */
+                     HPF_Fs22050_Gain9_A0,
+                     -HPF_Fs22050_Gain9_B1},
+                    {HPF_Fs22050_Gain10_A1,             /* Gain setting 10 */
+                     HPF_Fs22050_Gain10_A0,
+                     -HPF_Fs22050_Gain10_B1},
+                    {HPF_Fs22050_Gain11_A1,             /* Gain setting 11 */
+                     HPF_Fs22050_Gain11_A0,
+                     -HPF_Fs22050_Gain11_B1},
+                    {HPF_Fs22050_Gain12_A1,             /* Gain setting 12 */
+                     HPF_Fs22050_Gain12_A0,
+                     -HPF_Fs22050_Gain12_B1},
+                    {HPF_Fs22050_Gain13_A1,             /* Gain setting 13 */
+                     HPF_Fs22050_Gain13_A0,
+                     -HPF_Fs22050_Gain13_B1},
+                    {HPF_Fs22050_Gain14_A1,             /* Gain setting 14 */
+                     HPF_Fs22050_Gain14_A0,
+                     -HPF_Fs22050_Gain14_B1},
+                    {HPF_Fs22050_Gain15_A1,             /* Gain setting 15 */
+                     HPF_Fs22050_Gain15_A0,
+                     -HPF_Fs22050_Gain15_B1},
+
+                    /* 24kHz sampling rate */
+                    {HPF_Fs24000_Gain1_A1,             /* Gain setting 1 */
+                     HPF_Fs24000_Gain1_A0,
+                     -HPF_Fs24000_Gain1_B1},
+                    {HPF_Fs24000_Gain2_A1,             /* Gain setting 2 */
+                     HPF_Fs24000_Gain2_A0,
+                     -HPF_Fs24000_Gain2_B1},
+                    {HPF_Fs24000_Gain3_A1,             /* Gain setting 3 */
+                     HPF_Fs24000_Gain3_A0,
+                     -HPF_Fs24000_Gain3_B1},
+                    {HPF_Fs24000_Gain4_A1,             /* Gain setting 4 */
+                     HPF_Fs24000_Gain4_A0,
+                     -HPF_Fs24000_Gain4_B1},
+                    {HPF_Fs24000_Gain5_A1,             /* Gain setting 5 */
+                     HPF_Fs24000_Gain5_A0,
+                     -HPF_Fs24000_Gain5_B1},
+                    {HPF_Fs24000_Gain6_A1,             /* Gain setting 6 */
+                     HPF_Fs24000_Gain6_A0,
+                     -HPF_Fs24000_Gain6_B1},
+                    {HPF_Fs24000_Gain7_A1,             /* Gain setting 7 */
+                     HPF_Fs24000_Gain7_A0,
+                     -HPF_Fs24000_Gain7_B1},
+                    {HPF_Fs24000_Gain8_A1,             /* Gain setting 8 */
+                     HPF_Fs24000_Gain8_A0,
+                     -HPF_Fs24000_Gain8_B1},
+                    {HPF_Fs24000_Gain9_A1,             /* Gain setting 9 */
+                     HPF_Fs24000_Gain9_A0,
+                     -HPF_Fs24000_Gain9_B1},
+                    {HPF_Fs24000_Gain10_A1,             /* Gain setting 10 */
+                     HPF_Fs24000_Gain10_A0,
+                     -HPF_Fs24000_Gain10_B1},
+                    {HPF_Fs24000_Gain11_A1,             /* Gain setting 11 */
+                     HPF_Fs24000_Gain11_A0,
+                     -HPF_Fs24000_Gain11_B1},
+                    {HPF_Fs24000_Gain12_A1,             /* Gain setting 12 */
+                     HPF_Fs24000_Gain12_A0,
+                     -HPF_Fs24000_Gain12_B1},
+                    {HPF_Fs24000_Gain13_A1,             /* Gain setting 13 */
+                     HPF_Fs24000_Gain13_A0,
+                     -HPF_Fs24000_Gain13_B1},
+                    {HPF_Fs24000_Gain14_A1,             /* Gain setting 14 */
+                     HPF_Fs24000_Gain14_A0,
+                     -HPF_Fs24000_Gain14_B1},
+                    {HPF_Fs24000_Gain15_A1,             /* Gain setting 15 */
+                     HPF_Fs24000_Gain15_A0,
+                     -HPF_Fs24000_Gain15_B1},
+
+                    /* 32kHz sampling rate */
+                    {HPF_Fs32000_Gain1_A1,             /* Gain setting 1 */
+                     HPF_Fs32000_Gain1_A0,
+                     -HPF_Fs32000_Gain1_B1},
+                    {HPF_Fs32000_Gain2_A1,             /* Gain setting 2 */
+                     HPF_Fs32000_Gain2_A0,
+                     -HPF_Fs32000_Gain2_B1},
+                    {HPF_Fs32000_Gain3_A1,             /* Gain setting 3 */
+                     HPF_Fs32000_Gain3_A0,
+                     -HPF_Fs32000_Gain3_B1},
+                    {HPF_Fs32000_Gain4_A1,             /* Gain setting 4 */
+                     HPF_Fs32000_Gain4_A0,
+                     -HPF_Fs32000_Gain4_B1},
+                    {HPF_Fs32000_Gain5_A1,             /* Gain setting 5 */
+                     HPF_Fs32000_Gain5_A0,
+                     -HPF_Fs32000_Gain5_B1},
+                    {HPF_Fs32000_Gain6_A1,             /* Gain setting 6 */
+                     HPF_Fs32000_Gain6_A0,
+                     -HPF_Fs32000_Gain6_B1},
+                    {HPF_Fs32000_Gain7_A1,             /* Gain setting 7 */
+                     HPF_Fs32000_Gain7_A0,
+                     -HPF_Fs32000_Gain7_B1},
+                    {HPF_Fs32000_Gain8_A1,             /* Gain setting 8 */
+                     HPF_Fs32000_Gain8_A0,
+                     -HPF_Fs32000_Gain8_B1},
+                    {HPF_Fs32000_Gain9_A1,             /* Gain setting 9 */
+                     HPF_Fs32000_Gain9_A0,
+                     -HPF_Fs32000_Gain9_B1},
+                    {HPF_Fs32000_Gain10_A1,             /* Gain setting 10 */
+                     HPF_Fs32000_Gain10_A0,
+                     -HPF_Fs32000_Gain10_B1},
+                    {HPF_Fs32000_Gain11_A1,             /* Gain setting 11 */
+                     HPF_Fs32000_Gain11_A0,
+                     -HPF_Fs32000_Gain11_B1},
+                    {HPF_Fs32000_Gain12_A1,             /* Gain setting 12 */
+                     HPF_Fs32000_Gain12_A0,
+                     -HPF_Fs32000_Gain12_B1},
+                    {HPF_Fs32000_Gain13_A1,             /* Gain setting 13 */
+                     HPF_Fs32000_Gain13_A0,
+                     -HPF_Fs32000_Gain13_B1},
+                    {HPF_Fs32000_Gain14_A1,             /* Gain setting 14 */
+                     HPF_Fs32000_Gain14_A0,
+                     -HPF_Fs32000_Gain14_B1},
+                    {HPF_Fs32000_Gain15_A1,             /* Gain setting 15 */
+                     HPF_Fs32000_Gain15_A0,
+                     -HPF_Fs32000_Gain15_B1},
+
+                    /* 44kHz sampling rate */
+                    {HPF_Fs44100_Gain1_A1,             /* Gain setting 1 */
+                     HPF_Fs44100_Gain1_A0,
+                     -HPF_Fs44100_Gain1_B1,},
+                    {HPF_Fs44100_Gain2_A1,             /* Gain setting 2 */
+                     HPF_Fs44100_Gain2_A0,
+                     -HPF_Fs44100_Gain2_B1},
+                    {HPF_Fs44100_Gain3_A1,             /* Gain setting 3 */
+                     HPF_Fs44100_Gain3_A0,
+                     -HPF_Fs44100_Gain3_B1},
+                    {HPF_Fs44100_Gain4_A1,             /* Gain setting 4 */
+                     HPF_Fs44100_Gain4_A0,
+                     -HPF_Fs44100_Gain4_B1},
+                    {HPF_Fs44100_Gain5_A1,             /* Gain setting 5 */
+                     HPF_Fs44100_Gain5_A0,
+                     -HPF_Fs44100_Gain5_B1},
+                    {HPF_Fs44100_Gain6_A1,             /* Gain setting 6 */
+                     HPF_Fs44100_Gain6_A0,
+                     -HPF_Fs44100_Gain6_B1},
+                    {HPF_Fs44100_Gain7_A1,             /* Gain setting 7 */
+                     HPF_Fs44100_Gain7_A0,
+                     -HPF_Fs44100_Gain7_B1},
+                    {HPF_Fs44100_Gain8_A1,             /* Gain setting 8 */
+                     HPF_Fs44100_Gain8_A0,
+                     -HPF_Fs44100_Gain8_B1},
+                    {HPF_Fs44100_Gain9_A1,             /* Gain setting 9 */
+                     HPF_Fs44100_Gain9_A0,
+                     -HPF_Fs44100_Gain9_B1},
+                    {HPF_Fs44100_Gain10_A1,             /* Gain setting 10 */
+                     HPF_Fs44100_Gain10_A0,
+                     -HPF_Fs44100_Gain10_B1},
+                    {HPF_Fs44100_Gain11_A1,             /* Gain setting 11 */
+                     HPF_Fs44100_Gain11_A0,
+                     -HPF_Fs44100_Gain11_B1},
+                    {HPF_Fs44100_Gain12_A1,             /* Gain setting 12 */
+                     HPF_Fs44100_Gain12_A0,
+                     -HPF_Fs44100_Gain12_B1},
+                    {HPF_Fs44100_Gain13_A1,             /* Gain setting 13 */
+                     HPF_Fs44100_Gain13_A0,
+                     -HPF_Fs44100_Gain13_B1},
+                    {HPF_Fs44100_Gain14_A1,             /* Gain setting 14 */
+                     HPF_Fs44100_Gain14_A0,
+                     -HPF_Fs44100_Gain14_B1},
+                    {HPF_Fs44100_Gain15_A1,             /* Gain setting 15 */
+                     HPF_Fs44100_Gain15_A0,
+                     -HPF_Fs44100_Gain15_B1},
+
+                    /* 48kHz sampling rate */
+                    {HPF_Fs48000_Gain1_A1,             /* Gain setting 1 */
+                     HPF_Fs48000_Gain1_A0,
+                     -HPF_Fs48000_Gain1_B1},
+                    {HPF_Fs48000_Gain2_A1,             /* Gain setting 2 */
+                     HPF_Fs48000_Gain2_A0,
+                     -HPF_Fs48000_Gain2_B1},
+                    {HPF_Fs48000_Gain3_A1,             /* Gain setting 3 */
+                     HPF_Fs48000_Gain3_A0,
+                     -HPF_Fs48000_Gain3_B1},
+                    {HPF_Fs48000_Gain4_A1,             /* Gain setting 4 */
+                     HPF_Fs48000_Gain4_A0,
+                     -HPF_Fs48000_Gain4_B1},
+                    {HPF_Fs48000_Gain5_A1,             /* Gain setting 5 */
+                     HPF_Fs48000_Gain5_A0,
+                     -HPF_Fs48000_Gain5_B1},
+                    {HPF_Fs48000_Gain6_A1,             /* Gain setting 6 */
+                     HPF_Fs48000_Gain6_A0,
+                     -HPF_Fs48000_Gain6_B1},
+                    {HPF_Fs48000_Gain7_A1,             /* Gain setting 7 */
+                     HPF_Fs48000_Gain7_A0,
+                     -HPF_Fs48000_Gain7_B1},
+                    {HPF_Fs48000_Gain8_A1,             /* Gain setting 8 */
+                     HPF_Fs48000_Gain8_A0,
+                     -HPF_Fs48000_Gain8_B1},
+                    {HPF_Fs48000_Gain9_A1,             /* Gain setting 9 */
+                     HPF_Fs48000_Gain9_A0,
+                     -HPF_Fs48000_Gain9_B1},
+                    {HPF_Fs48000_Gain10_A1,             /* Gain setting 10 */
+                     HPF_Fs48000_Gain10_A0,
+                     -HPF_Fs48000_Gain10_B1},
+                    {HPF_Fs48000_Gain11_A1,             /* Gain setting 11 */
+                     HPF_Fs48000_Gain11_A0,
+                     -HPF_Fs48000_Gain11_B1},
+                    {HPF_Fs48000_Gain12_A1,             /* Gain setting 12 */
+                     HPF_Fs48000_Gain12_A0,
+                     -HPF_Fs48000_Gain12_B1},
+                    {HPF_Fs48000_Gain13_A1,             /* Gain setting 13 */
+                     HPF_Fs48000_Gain13_A0,
+                     -HPF_Fs48000_Gain13_B1},
+                    {HPF_Fs48000_Gain14_A1,             /* Gain setting 14 */
+                     HPF_Fs48000_Gain14_A0,
+                     -HPF_Fs48000_Gain14_B1},
+                    {HPF_Fs48000_Gain15_A1,             /* Gain setting 15 */
+                     HPF_Fs48000_Gain15_A0,
+                     -HPF_Fs48000_Gain15_B1}
+#ifdef HIGHER_FS
+                    ,
+                    /* 96kHz sampling rate */
+                    {HPF_Fs96000_Gain1_A1,             /* Gain setting 1 */
+                    HPF_Fs96000_Gain1_A0,
+                    -HPF_Fs96000_Gain1_B1},
+                    {HPF_Fs96000_Gain2_A1,             /* Gain setting 2 */
+                    HPF_Fs96000_Gain2_A0,
+                    -HPF_Fs96000_Gain2_B1},
+                    {HPF_Fs96000_Gain3_A1,             /* Gain setting 3 */
+                    HPF_Fs96000_Gain3_A0,
+                    -HPF_Fs96000_Gain3_B1},
+                    {HPF_Fs96000_Gain4_A1,             /* Gain setting 4 */
+                    HPF_Fs96000_Gain4_A0,
+                    -HPF_Fs96000_Gain4_B1},
+                    {HPF_Fs96000_Gain5_A1,             /* Gain setting 5 */
+                    HPF_Fs96000_Gain5_A0,
+                    -HPF_Fs96000_Gain5_B1},
+                    {HPF_Fs96000_Gain6_A1,             /* Gain setting 6 */
+                    HPF_Fs96000_Gain6_A0,
+                    -HPF_Fs96000_Gain6_B1},
+                    {HPF_Fs96000_Gain7_A1,             /* Gain setting 7 */
+                    HPF_Fs96000_Gain7_A0,
+                    -HPF_Fs96000_Gain7_B1},
+                    {HPF_Fs96000_Gain8_A1,             /* Gain setting 8 */
+                    HPF_Fs96000_Gain8_A0,
+                    -HPF_Fs96000_Gain8_B1},
+                    {HPF_Fs96000_Gain9_A1,             /* Gain setting 9 */
+                    HPF_Fs96000_Gain9_A0,
+                    -HPF_Fs96000_Gain9_B1},
+                    {HPF_Fs96000_Gain10_A1,             /* Gain setting 10 */
+                    HPF_Fs96000_Gain10_A0,
+                    -HPF_Fs96000_Gain10_B1},
+                    {HPF_Fs96000_Gain11_A1,             /* Gain setting 11 */
+                    HPF_Fs96000_Gain11_A0,
+                    -HPF_Fs96000_Gain11_B1},
+                    {HPF_Fs96000_Gain12_A1,             /* Gain setting 12 */
+                    HPF_Fs96000_Gain12_A0,
+                    -HPF_Fs96000_Gain12_B1},
+                    {HPF_Fs96000_Gain13_A1,             /* Gain setting 13 */
+                    HPF_Fs96000_Gain13_A0,
+                    -HPF_Fs96000_Gain13_B1},
+                    {HPF_Fs96000_Gain14_A1,             /* Gain setting 14 */
+                    HPF_Fs96000_Gain14_A0,
+                    -HPF_Fs96000_Gain14_B1},
+                    {HPF_Fs96000_Gain15_A1,             /* Gain setting 15 */
+                    HPF_Fs96000_Gain15_A0,
+                    -HPF_Fs96000_Gain15_B1},
+
+                    /* 192kHz sampling rate */
+                    {HPF_Fs192000_Gain1_A1,             /* Gain setting 1 */
+                    HPF_Fs192000_Gain1_A0,
+                    -HPF_Fs192000_Gain1_B1},
+                    {HPF_Fs192000_Gain2_A1,             /* Gain setting 2 */
+                    HPF_Fs192000_Gain2_A0,
+                    -HPF_Fs192000_Gain2_B1},
+                    {HPF_Fs192000_Gain3_A1,             /* Gain setting 3 */
+                    HPF_Fs192000_Gain3_A0,
+                    -HPF_Fs192000_Gain3_B1},
+                    {HPF_Fs192000_Gain4_A1,             /* Gain setting 4 */
+                    HPF_Fs192000_Gain4_A0,
+                    -HPF_Fs192000_Gain4_B1},
+                    {HPF_Fs192000_Gain5_A1,             /* Gain setting 5 */
+                    HPF_Fs192000_Gain5_A0,
+                    -HPF_Fs192000_Gain5_B1},
+                    {HPF_Fs192000_Gain6_A1,             /* Gain setting 6 */
+                    HPF_Fs192000_Gain6_A0,
+                    -HPF_Fs192000_Gain6_B1},
+                    {HPF_Fs192000_Gain7_A1,             /* Gain setting 7 */
+                    HPF_Fs192000_Gain7_A0,
+                    -HPF_Fs192000_Gain7_B1},
+                    {HPF_Fs192000_Gain8_A1,             /* Gain setting 8 */
+                    HPF_Fs192000_Gain8_A0,
+                    -HPF_Fs192000_Gain8_B1},
+                    {HPF_Fs192000_Gain9_A1,             /* Gain setting 9 */
+                    HPF_Fs192000_Gain9_A0,
+                    -HPF_Fs192000_Gain9_B1},
+                    {HPF_Fs192000_Gain10_A1,             /* Gain setting 10 */
+                    HPF_Fs192000_Gain10_A0,
+                    -HPF_Fs192000_Gain10_B1},
+                    {HPF_Fs192000_Gain11_A1,             /* Gain setting 11 */
+                    HPF_Fs192000_Gain11_A0,
+                    -HPF_Fs192000_Gain11_B1},
+                    {HPF_Fs192000_Gain12_A1,             /* Gain setting 12 */
+                    HPF_Fs192000_Gain12_A0,
+                    -HPF_Fs192000_Gain12_B1},
+                    {HPF_Fs192000_Gain13_A1,             /* Gain setting 13 */
+                    HPF_Fs192000_Gain13_A0,
+                    -HPF_Fs192000_Gain13_B1},
+                    {HPF_Fs192000_Gain14_A1,             /* Gain setting 14 */
+                    HPF_Fs192000_Gain14_A0,
+                    -HPF_Fs192000_Gain14_B1},
+                    {HPF_Fs192000_Gain15_A1,             /* Gain setting 15 */
+                    HPF_Fs192000_Gain15_A0,
+                    -HPF_Fs192000_Gain15_B1}
+#endif
+                    };
+#else
 FO_C16_LShx_Coefs_t    LVM_TrebleBoostCoefs[] = {
 
                     /* 22kHz sampling rate */
@@ -340,8 +675,9 @@
                     {HPF_Fs48000_Gain15_A1,             /* Gain setting 15 */
                      HPF_Fs48000_Gain15_A0,
                      -HPF_Fs48000_Gain15_B1,
-                     HPF_Fs48000_Gain15_Shift}};
-
+                     HPF_Fs48000_Gain15_Shift}
+                    };
+#endif
 
 /************************************************************************************/
 /*                                                                                    */
@@ -350,6 +686,16 @@
 /************************************************************************************/
 
 /* dB to linear conversion table */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT LVM_VolumeTable[] = {
+    1.000f,             /*  0dB */
+    0.891f,             /* -1dB */
+    0.794f,             /* -2dB */
+    0.708f,             /* -3dB */
+    0.631f,             /* -4dB */
+    0.562f,             /* -5dB */
+    0.501f};            /* -6dB */
+#else
 const LVM_INT16 LVM_VolumeTable[] = {
     0x7FFF,             /*  0dB */
     0x7215,             /* -1dB */
@@ -358,6 +704,7 @@
     0x50C3,             /* -4dB */
     0x47FB,             /* -5dB */
     0x4000};            /* -6dB */
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
index a7601ff..4cf7119 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
@@ -37,16 +37,23 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BUILD_FLOAT
+extern FO_FLOAT_LShx_Coefs_t     LVM_TrebleBoostCoefs[];
+#else
 extern FO_C16_LShx_Coefs_t     LVM_TrebleBoostCoefs[];
-
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
 /*    Volume control gain and time constant tables                                  */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifdef BUILD_FLOAT
+extern const LVM_FLOAT LVM_VolumeTable[];
+#else
 extern const LVM_INT16 LVM_VolumeTable[];
+#endif
+
 extern const LVM_INT16 LVM_MixerTCTable[];
 
 
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index 2080d64..9a3d35d 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -37,7 +37,7 @@
 /*    Types                                                                       */
 /*                                                                                */
 /**********************************************************************************/
-
+#ifndef BUILD_FLOAT
 typedef struct
 {
     LVM_INT32  AGC_Gain;                        /* The current AGC gain */
@@ -52,20 +52,39 @@
     LVM_INT16  VolumeTC;                        /* Volume update time constant */
 
 } AGC_MIX_VOL_2St1Mon_D32_t;
+#else
+typedef struct
+{
+    LVM_FLOAT  AGC_Gain;                        /* The current AGC gain */
+    LVM_FLOAT  AGC_MaxGain;                     /* The maximum AGC gain */
+    LVM_FLOAT  Volume;                          /* The current volume setting */
+    LVM_FLOAT  Target;                          /* The target volume setting */
+    LVM_FLOAT  AGC_Target;                      /* AGC target level */
+    LVM_FLOAT  AGC_Attack;                      /* AGC attack scaler */
+    LVM_FLOAT  AGC_Decay;                       /* AGC decay scaler */
+    LVM_FLOAT  VolumeTC;                        /* Volume update time constant */
 
+} AGC_MIX_VOL_2St1Mon_FLOAT_t;
+#endif
 
 /**********************************************************************************/
 /*                                                                                */
 /*    Function Prototypes                                                              */
 /*                                                                                */
 /**********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t  *pInstance,     /* Instance pointer */
+                                 const LVM_FLOAT            *pStSrc,        /* Stereo source */
+                                 const LVM_FLOAT            *pMonoSrc,      /* Mono source */
+                                 LVM_FLOAT                  *pDst,          /* Stereo destination */
+                                 LVM_UINT16                 n);             /* Number of samples */
+#else
 void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_D32_t  *pInstance,     /* Instance pointer */
                                  const LVM_INT32            *pStSrc,        /* Stereo source */
                                  const LVM_INT32            *pMonoSrc,      /* Mono source */
                                  LVM_INT32                  *pDst,          /* Stereo destination */
                                  LVM_UINT16                 n);             /* Number of samples */
-
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index 7ac7fbd..3ee7f63 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -27,19 +27,34 @@
 /**********************************************************************************
    INSTANCE MEMORY TYPE DEFINITION
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT Storage[6];
 
+} Biquad_FLOAT_Instance_t;
+#else
 typedef struct
 {
     LVM_INT32 Storage[6];
 
 } Biquad_Instance_t;
-
-
+#endif
 /**********************************************************************************
    COEFFICIENT TYPE DEFINITIONS
 ***********************************************************************************/
 
 /*** Biquad coefficients **********************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT  A2;   /*  a2  */
+    LVM_FLOAT  A1;   /*  a1  */
+    LVM_FLOAT  A0;   /*  a0  */
+    LVM_FLOAT  B2;   /* -b2! */
+    LVM_FLOAT  B1;   /* -b1! */
+} BQ_FLOAT_Coefs_t;
+#else
 typedef struct
 {
     LVM_INT16 A2;   /*  a2  */
@@ -57,8 +72,17 @@
     LVM_INT32  B2;   /* -b2! */
     LVM_INT32  B1;   /* -b1! */
 } BQ_C32_Coefs_t;
+#endif
 
 /*** First order coefficients *****************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT A1;   /*  a1  */
+    LVM_FLOAT A0;   /*  a0  */
+    LVM_FLOAT B1;   /* -b1! */
+} FO_FLOAT_Coefs_t;
+#else
 typedef struct
 {
     LVM_INT16 A1;   /*  a1  */
@@ -72,8 +96,17 @@
     LVM_INT32  A0;   /*  a0  */
     LVM_INT32  B1;   /* -b1! */
 } FO_C32_Coefs_t;
+#endif
 
 /*** First order coefficients with Shift*****************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT A1;    /*  a1  */
+    LVM_FLOAT A0;    /*  a0  */
+    LVM_FLOAT B1;    /* -b1! */
+} FO_FLOAT_LShx_Coefs_t;
+#else
 typedef struct
 {
     LVM_INT16 A1;    /*  a1  */
@@ -81,8 +114,16 @@
     LVM_INT16 B1;    /* -b1! */
     LVM_INT16 Shift; /* Shift */
 } FO_C16_LShx_Coefs_t;
-
+#endif
 /*** Band pass coefficients *******************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT  A0;   /*  a0  */
+    LVM_FLOAT  B2;   /* -b2! */
+    LVM_FLOAT  B1;   /* -b1! */
+} BP_FLOAT_Coefs_t;
+#else
 typedef struct
 {
     LVM_INT16 A0;   /*  a0  */
@@ -96,8 +137,18 @@
     LVM_INT32  B2;   /* -b2! */
     LVM_INT32  B1;   /* -b1! */
 } BP_C32_Coefs_t;
+#endif
 
 /*** Peaking coefficients *********************************************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT A0;   /*  a0  */
+    LVM_FLOAT B2;   /* -b2! */
+    LVM_FLOAT B1;   /* -b1! */
+    LVM_FLOAT  G;   /* Gain */
+} PK_FLOAT_Coefs_t;
+#else
 typedef struct
 {
     LVM_INT16 A0;   /*  a0  */
@@ -113,16 +164,26 @@
     LVM_INT32  B1;   /* -b1! */
     LVM_INT16  G;   /* Gain */
 } PK_C32_Coefs_t;
-
+#endif
 
 /**********************************************************************************
    TAPS TYPE DEFINITIONS
 ***********************************************************************************/
 
 /*** Types used for first order and shelving filter *******************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT Storage[ (1 * 2) ];  /* One channel, two taps of size LVM_INT32 */
+} Biquad_1I_Order1_FLOAT_Taps_t;
 
 typedef struct
 {
+    LVM_FLOAT Storage[ (2 * 2) ];  /* Two channels, two taps of size LVM_INT32 */
+} Biquad_2I_Order1_FLOAT_Taps_t;
+#else
+typedef struct
+{
     LVM_INT32 Storage[ (1*2) ];  /* One channel, two taps of size LVM_INT32 */
 } Biquad_1I_Order1_Taps_t;
 
@@ -130,12 +191,22 @@
 {
     LVM_INT32 Storage[ (2*2) ];  /* Two channels, two taps of size LVM_INT32 */
 } Biquad_2I_Order1_Taps_t;
-
+#endif
 
 /*** Types used for biquad, band pass and peaking filter **************************/
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT Storage[ (1 * 4) ];  /* One channel, four taps of size LVM_INT32 */
+} Biquad_1I_Order2_FLOAT_Taps_t;
 
 typedef struct
 {
+    LVM_FLOAT Storage[ (2 * 4) ];  /* Two channels, four taps of size LVM_INT32 */
+} Biquad_2I_Order2_FLOAT_Taps_t;
+#else
+typedef struct
+{
     LVM_INT32 Storage[ (1*4) ];  /* One channel, four taps of size LVM_INT32 */
 } Biquad_1I_Order2_Taps_t;
 
@@ -143,7 +214,7 @@
 {
     LVM_INT32 Storage[ (2*4) ];  /* Two channels, four taps of size LVM_INT32 */
 } Biquad_2I_Order2_Taps_t;
-
+#endif
 /* 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
 #define BP_1I_D32F32C30_TRC_WRA_02       TWO_BP_1I_D32F32C30_TRC_WRA_02
@@ -154,59 +225,148 @@
 
 /*** 16 bit data path *************************************************************/
 
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef);
+#else
 void BQ_2I_D16F32Css_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
                                             BQ_C16_Coefs_t          *pCoef);
+#endif
 
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C15_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples);
+#else
 void BQ_2I_D16F32C15_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
                                             LVM_INT16                    NrSamples);
+#endif
 
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C14_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples);
+#else
 void BQ_2I_D16F32C14_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
                                             LVM_INT16                    NrSamples);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C13_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples);
+#else
 void BQ_2I_D16F32C13_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
                                             LVM_INT16                    NrSamples);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef);
+#else
 void BQ_2I_D16F16Css_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
                                             BQ_C16_Coefs_t          *pCoef);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT               *pDataIn,
+                                 LVM_FLOAT               *pDataOut,
+                                 LVM_INT16               NrSamples);
+#else
 void BQ_2I_D16F16C15_TRC_WRA_01(            Biquad_Instance_t       *pInstance,
                                             LVM_INT16                   *pDataIn,
                                             LVM_INT16                   *pDataOut,
                                             LVM_INT16                   NrSamples);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C14_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT               *pDataIn,
+                                 LVM_FLOAT               *pDataOut,
+                                 LVM_INT16               NrSamples);
+#else
 void BQ_2I_D16F16C14_TRC_WRA_01(            Biquad_Instance_t       *pInstance,
                                             LVM_INT16                   *pDataIn,
                                             LVM_INT16                   *pDataOut,
                                             LVM_INT16                   NrSamples);
+#endif
 
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef);
+#else
 void BQ_1I_D16F16Css_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order2_Taps_t *pTaps,
                                             BQ_C16_Coefs_t          *pCoef);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples);
+#else
 void BQ_1I_D16F16C15_TRC_WRA_01(            Biquad_Instance_t       *pInstance,
                                             LVM_INT16                   *pDataIn,
                                             LVM_INT16                   *pDataOut,
                                             LVM_INT16                   NrSamples);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef);
+#else
 void BQ_1I_D16F32Css_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order2_Taps_t *pTaps,
                                             BQ_C16_Coefs_t          *pCoef);
 
+#endif
+
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT              *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples);
+#else
 void BQ_1I_D16F32C14_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
                                             LVM_INT16                    NrSamples);
 
+#endif
 /*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32Cll_TRC_WRA_01_Init (      Biquad_FLOAT_Instance_t       *pInstance,
+                                            Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+                                            BQ_FLOAT_Coefs_t          *pCoef);
+void BQ_2I_D32F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t  *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                 NrSamples);
+#else
 void BQ_2I_D32F32Cll_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
                                             BQ_C32_Coefs_t          *pCoef);
@@ -215,33 +375,66 @@
                                             LVM_INT32                    *pDataIn,
                                             LVM_INT32                    *pDataOut,
                                             LVM_INT16                    NrSamples);
+#endif
 
 /**********************************************************************************
    FUNCTION PROTOTYPES: FIRST ORDER FILTERS
 ***********************************************************************************/
 
 /*** 16 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16Css_TRC_WRA_01_Init(    Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order1_FLOAT_Taps_t   *pTaps,
+                                         FO_FLOAT_Coefs_t            *pCoef);
+#else
 void FO_1I_D16F16Css_TRC_WRA_01_Init(       Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order1_Taps_t *pTaps,
                                             FO_C16_Coefs_t          *pCoef);
+#endif
 
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT               *pDataIn,
+                                 LVM_FLOAT               *pDataOut,
+                                 LVM_INT16               NrSamples);
+#else
 void FO_1I_D16F16C15_TRC_WRA_01(            Biquad_Instance_t       *pInstance,
                                             LVM_INT16                   *pDataIn,
                                             LVM_INT16                   *pDataOut,
                                             LVM_INT16                   NrSamples);
+#endif
 
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t       *pInstance,
+                                          Biquad_2I_Order1_FLOAT_Taps_t *pTaps,
+                                          FO_FLOAT_LShx_Coefs_t     *pCoef);
+#else
 void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_Instance_t       *pInstance,
                                           Biquad_2I_Order1_Taps_t *pTaps,
                                           FO_C16_LShx_Coefs_t     *pCoef);
+#endif
 
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
+                                     LVM_FLOAT               *pDataIn,
+                                     LVM_FLOAT               *pDataOut,
+                                     LVM_INT16               NrSamples);
+#else
 void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t       *pInstance,
                                      LVM_INT16               *pDataIn,
                                      LVM_INT16               *pDataOut,
                                      LVM_INT16               NrSamples);
-
+#endif
 /*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t       *pInstance,
+                                      Biquad_1I_Order1_FLOAT_Taps_t *pTaps,
+                                      FO_FLOAT_Coefs_t          *pCoef);
+void FO_1I_D32F32C31_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT                     *pDataIn,
+                                 LVM_FLOAT                     *pDataOut,
+                                 LVM_INT16                     NrSamples);
+#else
 void FO_1I_D32F32Cll_TRC_WRA_01_Init(       Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order1_Taps_t *pTaps,
                                             FO_C32_Coefs_t          *pCoef);
@@ -250,13 +443,28 @@
                                             LVM_INT32               *pDataIn,
                                             LVM_INT32               *pDataOut,
                                             LVM_INT16               NrSamples);
-
+#endif
 /**********************************************************************************
    FUNCTION PROTOTYPES: BAND PASS FILTERS
 ***********************************************************************************/
 
 /*** 16 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16Css_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t       *pInstance,
+                                      Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+                                      BP_FLOAT_Coefs_t              *pCoef);
+void BP_1I_D16F16C14_TRC_WRA_01 (     Biquad_FLOAT_Instance_t       *pInstance,
+                                      LVM_FLOAT                     *pDataIn,
+                                      LVM_FLOAT                     *pDataOut,
+                                      LVM_INT16                     NrSamples);
+void BP_1I_D16F32Cll_TRC_WRA_01_Init (Biquad_FLOAT_Instance_t       *pInstance,
+                                      Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+                                      BP_FLOAT_Coefs_t              *pCoef);
+void BP_1I_D16F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples);
+#else
 void BP_1I_D16F16Css_TRC_WRA_01_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order2_Taps_t *pTaps,
                                             BP_C16_Coefs_t          *pCoef);
@@ -274,10 +482,17 @@
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
                                             LVM_INT16                    NrSamples);
-
-
+#endif
 /*** 32 bit data path *************************************************************/
-
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32Cll_TRC_WRA_02_Init (      Biquad_FLOAT_Instance_t       *pInstance,
+                                            Biquad_1I_Order2_FLOAT_Taps_t *pTaps,
+                                            BP_FLOAT_Coefs_t          *pCoef);
+void BP_1I_D32F32C30_TRC_WRA_02(            Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples);
+#else
 void BP_1I_D32F32Cll_TRC_WRA_02_Init (      Biquad_Instance_t       *pInstance,
                                             Biquad_1I_Order2_Taps_t *pTaps,
                                             BP_C32_Coefs_t          *pCoef);
@@ -286,42 +501,59 @@
                                             LVM_INT32                    *pDataIn,
                                             LVM_INT32                    *pDataOut,
                                             LVM_INT16                    NrSamples);
-
+#endif
 
 /*** 32 bit data path STEREO ******************************************************/
-
+#ifndef BUILD_FLOAT
 void PK_2I_D32F32CllGss_TRC_WRA_01_Init (   Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
                                             PK_C32_Coefs_t          *pCoef);
-
 void PK_2I_D32F32C30G11_TRC_WRA_01 (        Biquad_Instance_t       *pInstance,
                                             LVM_INT32                    *pDataIn,
                                             LVM_INT32                    *pDataOut,
                                             LVM_INT16                    NrSamples);
-
+#endif
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32CssGss_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t       *pInstance,
+                                            Biquad_2I_Order2_FLOAT_Taps_t *pTaps,
+                                            PK_FLOAT_Coefs_t          *pCoef);
+#else
 void PK_2I_D32F32CssGss_TRC_WRA_01_Init (   Biquad_Instance_t       *pInstance,
                                             Biquad_2I_Order2_Taps_t *pTaps,
                                             PK_C16_Coefs_t          *pCoef);
-
+#endif
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32C14G11_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                    LVM_FLOAT               *pDataIn,
+                                    LVM_FLOAT               *pDataOut,
+                                    LVM_INT16               NrSamples);
+#else
 void PK_2I_D32F32C14G11_TRC_WRA_01 (        Biquad_Instance_t       *pInstance,
                                             LVM_INT32                    *pDataIn,
                                             LVM_INT32                    *pDataOut,
                                             LVM_INT16                    NrSamples);
-
+#endif
 
 /**********************************************************************************
    FUNCTION PROTOTYPES: DC REMOVAL FILTERS
 ***********************************************************************************/
 
 /*** 16 bit data path STEREO ******************************************************/
+#ifdef BUILD_FLOAT
+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);
+#else
 void DC_2I_D16_TRC_WRA_01_Init     (        Biquad_Instance_t       *pInstance);
 
 void DC_2I_D16_TRC_WRA_01          (        Biquad_Instance_t       *pInstance,
                                             LVM_INT16               *pDataIn,
                                             LVM_INT16               *pDataOut,
                                             LVM_INT16               NrSamples);
-
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/CompLim.h b/media/libeffects/lvm/lib/Common/lib/CompLim.h
index 4cb8aa2..498faa3 100644
--- a/media/libeffects/lvm/lib/Common/lib/CompLim.h
+++ b/media/libeffects/lvm/lib/Common/lib/CompLim.h
@@ -66,13 +66,17 @@
 /*  Function Prototypes                                                             */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifdef BUILD_FLOAT
+void NonLinComp_Float(LVM_FLOAT        Gain,
+                      LVM_FLOAT        *pDataIn,
+                      LVM_FLOAT        *pDataOut,
+                      LVM_INT32        BlockLength);
+#else
 void NonLinComp_D16(LVM_INT16        Gain,
                     LVM_INT16        *pSterBfIn,
                     LVM_INT16        *pSterBfOut,
                     LVM_INT32        BlockLength);
-
-
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/lib/Filter.h b/media/libeffects/lvm/lib/Common/lib/Filter.h
index 229701a..0c8955d 100644
--- a/media/libeffects/lvm/lib/Common/lib/Filter.h
+++ b/media/libeffects/lvm/lib/Common/lib/Filter.h
@@ -33,11 +33,32 @@
    DEFINES
 ***********************************************************************************/
 #define FILTER_LOSS     32730       /* -0.01dB loss to avoid wrapping due to band ripple */
-
+#ifdef BUILD_FLOAT
+#define FILTER_LOSS_FLOAT    0.998849f
+#endif
 /**********************************************************************************
    FUNCTION PROTOTYPES
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
 
+LVM_FLOAT LVM_Power10(   LVM_FLOAT  X);
+
+LVM_FLOAT LVM_Polynomial(LVM_UINT16 N,
+                         LVM_FLOAT  *pCoefficients,
+                         LVM_FLOAT  X);
+#ifdef HIGHER_FS
+LVM_FLOAT   LVM_GetOmega(LVM_UINT32  Fc,
+#else
+LVM_FLOAT   LVM_GetOmega(LVM_UINT16  Fc,
+#endif
+                         LVM_Fs_en   SampleRate);
+
+LVM_FLOAT LVM_FO_LPF(    LVM_FLOAT  w,
+                         FO_FLOAT_Coefs_t  *pCoeffs);
+
+LVM_FLOAT LVM_FO_HPF(    LVM_FLOAT  w,
+                         FO_FLOAT_Coefs_t  *pCoeffs);
+#else
 LVM_INT32 LVM_Polynomial(LVM_UINT16 N,
                          LVM_INT32  *pCoefficients,
                          LVM_INT32  X);
@@ -52,7 +73,7 @@
 
 LVM_INT32   LVM_GetOmega(LVM_UINT16  Fc,
                          LVM_Fs_en   SampleRate);
-
+#endif
 /**********************************************************************************/
 #ifdef __cplusplus
 }
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 68c55f7..cb15b60 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -44,6 +44,9 @@
 
 #define LVM_MAXINT_8            127                 /* Maximum positive integer size */
 #define LVM_MAXINT_16           32767
+#ifdef BUILD_FLOAT
+#define LVM_MAXFLOAT            1.0f
+#endif
 #define LVM_MAXINT_32           2147483647
 #define LVM_MAXENUM             2147483647
 
@@ -95,7 +98,9 @@
 typedef     int32_t             LVM_INT32;          /* Signed 32-bit word */
 typedef     uint32_t            LVM_UINT32;         /* Unsigned 32-bit word */
 
-
+#ifdef BUILD_FLOAT
+typedef     float               LVM_FLOAT;          /* single precission floating point*/
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /*  Standard Enumerated types                                                           */
@@ -133,6 +138,10 @@
     LVM_FS_32000 = 6,
     LVM_FS_44100 = 7,
     LVM_FS_48000 = 8,
+#ifdef HIGHER_FS
+    LVM_FS_96000 = 9,
+    LVM_FS_192000 = 10,
+#endif
     LVM_FS_INVALID = LVM_MAXENUM-1,
     LVM_FS_DUMMY = LVM_MAXENUM
 } LVM_Fs_en;
diff --git a/media/libeffects/lvm/lib/Common/lib/Mixer.h b/media/libeffects/lvm/lib/Common/lib/Mixer.h
index 89deb0d..07c53cd 100644
--- a/media/libeffects/lvm/lib/Common/lib/Mixer.h
+++ b/media/libeffects/lvm/lib/Common/lib/Mixer.h
@@ -30,6 +30,43 @@
    INSTANCE MEMORY TYPE DEFINITION
 ***********************************************************************************/
 
+#ifdef BUILD_FLOAT /* BUILD_FLOAT*/
+typedef struct
+{
+    LVM_FLOAT   Alpha;                   /* Time constant. Set by calling application. \
+                                            Can be changed at any time */
+    LVM_FLOAT   Target;                  /* Target value.  Set by calling application. \
+                                            Can be changed at any time */
+    LVM_FLOAT   Current;                 /* Current value.  Set by the mixer function. */
+    LVM_INT16   CallbackSet;             /* Boolean.  Should be set by calling application \
+                                            each time the target value is updated */
+    LVM_INT16   CallbackParam;           /* Parameter that will be used in the calback function */
+    void        *pCallbackHandle;        /* Pointer to the instance of the callback function */
+    void        *pGeneralPurpose;        /* Pointer for general purpose usage */
+    LVM_Callback pCallBack;              /* Pointer to the callback function */
+} Mix_1St_Cll_FLOAT_t;
+typedef struct
+{
+    LVM_FLOAT   Alpha1;
+    LVM_FLOAT   Target1;
+    LVM_FLOAT   Current1;
+    LVM_INT16   CallbackSet1;
+    LVM_INT16   CallbackParam1;
+    void        *pCallbackHandle1;
+    void        *pGeneralPurpose1;
+    LVM_Callback pCallBack1;
+
+    LVM_FLOAT   Alpha2;                   /* Warning the address of this location is passed as a \
+                                             pointer to Mix_1St_Cll_t in some functions */
+    LVM_FLOAT   Target2;
+    LVM_FLOAT   Current2;
+    LVM_INT16   CallbackSet2;
+    LVM_INT16   CallbackParam2;
+    void        *pCallbackHandle2;
+    void        *pGeneralPurpose2;
+    LVM_Callback pCallBack2;
+} Mix_2St_Cll_FLOAT_t;
+#else
 typedef struct
 {
     LVM_INT32   Alpha;                    /* Time constant. Set by calling application.  Can be changed at any time */
@@ -64,9 +101,35 @@
 
 } Mix_2St_Cll_t;
 
+#endif
 
 /*** General functions ************************************************************/
+#ifdef BUILD_FLOAT
 
+LVM_FLOAT LVM_Mixer_TimeConstant(LVM_UINT32   tc,
+#ifdef HIGHER_FS
+                                 LVM_UINT32   Fs,
+#else
+                                 LVM_UINT16   Fs,
+#endif
+                                 LVM_UINT16   NumChannels);
+
+void MixSoft_1St_D32C31_WRA(    Mix_1St_Cll_FLOAT_t       *pInstance,
+                                const LVM_FLOAT     *src,
+                                LVM_FLOAT     *dst,
+                                LVM_INT16     n);
+
+void MixSoft_2St_D32C31_SAT(    Mix_2St_Cll_FLOAT_t       *pInstance,
+                                const LVM_FLOAT     *src1,
+                                const LVM_FLOAT     *src2,
+                                LVM_FLOAT     *dst,
+                                LVM_INT16     n);
+
+void MixInSoft_D32C31_SAT(      Mix_1St_Cll_FLOAT_t       *pInstance,
+                                const LVM_FLOAT     *src,
+                                LVM_FLOAT     *dst,
+                                LVM_INT16     n);
+#else
 LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32   tc,
                                   LVM_UINT16   Fs,
                                   LVM_UINT16   NumChannels);
@@ -88,10 +151,26 @@
                                       LVM_INT32     *dst,
                                       LVM_INT16     n);
 
+#endif
+
 /**********************************************************************************
    FUNCTION PROTOTYPES (LOW LEVEL SUBFUNCTIONS)
 ***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void Core_MixSoft_1St_D32C31_WRA(   Mix_1St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n);
+void Core_MixHard_2St_D32C31_SAT(   Mix_2St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src1,
+                                    const LVM_FLOAT     *src2,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n);
+void Core_MixInSoft_D32C31_SAT(     Mix_1St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n);
+#else
 void Core_MixSoft_1St_D32C31_WRA(   Mix_1St_Cll_t       *pInstance,
                                     const LVM_INT32     *src,
                                           LVM_INT32     *dst,
@@ -107,6 +186,7 @@
                                     const LVM_INT32     *src,
                                           LVM_INT32     *dst,
                                           LVM_INT16     n);
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
@@ -115,13 +195,3 @@
 /**********************************************************************************/
 
 #endif /* __MIXER_H__ */
-
-
-
-
-
-
-
-
-
-
diff --git a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
index 3d62704..cdb3837 100644
--- a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
@@ -34,7 +34,12 @@
 /*######################################################################################*/
 
 /* Absolute value including the corner case for the extreme negative value */
+
+#ifdef BUILD_FLOAT
+LVM_FLOAT   Abs_Float(LVM_FLOAT     input);
+#else
 LVM_INT32   Abs_32(LVM_INT32     input);
+#endif
 
 /****************************************************************************************
  *  Name        : dB_to_Lin32()
@@ -48,8 +53,11 @@
  *                  (15->01) = decimal part
  *  Returns     : Lin value format 1.16.15
  ****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT dB_to_LinFloat(LVM_INT16    db_fix);
+#else
 LVM_INT32 dB_to_Lin32(LVM_INT16  db_fix);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 2b791bd..0ba20a3 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -29,6 +29,11 @@
     VARIOUS FUNCTIONS
 ***********************************************************************************/
 
+#ifdef BUILD_FLOAT
+void LoadConst_Float(          const LVM_FLOAT val,
+                               LVM_FLOAT *dst,
+                               LVM_INT16 n );
+#else
 void LoadConst_16(            const LVM_INT16 val,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n );
@@ -36,10 +41,17 @@
 void LoadConst_32(            const LVM_INT32 val,
                                     LVM_INT32 *dst,
                                     LVM_INT16 n );
+#endif
 
+#ifdef BUILD_FLOAT
+void Copy_Float(                 const LVM_FLOAT *src,
+                                 LVM_FLOAT *dst,
+                                 LVM_INT16 n );
+#else
 void Copy_16(                 const LVM_INT16 *src,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n );
+#endif
 
 /*********************************************************************************
  * note: In Mult3s_16x16() saturation of result is not taken care when           *
@@ -49,10 +61,17 @@
  *       This is the only case which will give wrong result.                     *
  *       For more information refer to Vector_Arithmetic.doc in /doc folder      *
  *********************************************************************************/
+#ifdef BUILD_FLOAT
+void Mult3s_Float(            const LVM_FLOAT *src,
+                              const LVM_FLOAT val,
+                              LVM_FLOAT *dst,
+                              LVM_INT16 n);
+#else
 void Mult3s_16x16(            const LVM_INT16 *src,
                               const LVM_INT16 val,
-                                    LVM_INT16 *dst,
-                                    LVM_INT16 n);
+                              LVM_INT16 *dst,
+                              LVM_INT16 n);
+#endif
 
 /*********************************************************************************
  * note: In Mult3s_32x16() saturation of result is not taken care when           *
@@ -66,20 +85,31 @@
                               const LVM_INT16 val,
                                     LVM_INT32  *dst,
                                     LVM_INT16 n);
-
+#ifdef BUILD_FLOAT
+void DelayMix_Float(const LVM_FLOAT *src,           /* Source 1, to be delayed */
+                    LVM_FLOAT *delay,         /* Delay buffer */
+                    LVM_INT16 size,           /* Delay size */
+                    LVM_FLOAT *dst,           /* Source/destination */
+                    LVM_INT16 *pOffset,       /* Delay offset */
+                    LVM_INT16 n)  ;            /* Number of stereo samples */
+#else
 void DelayMix_16x16(          const LVM_INT16 *src,
                                     LVM_INT16 *delay,
                                     LVM_INT16 size,
                                     LVM_INT16 *dst,
                                     LVM_INT16 *pOffset,
                                     LVM_INT16 n);
-
+#endif
 void DelayWrite_32(           const LVM_INT32  *src,               /* Source 1, to be delayed */
                                     LVM_INT32  *delay,             /* Delay buffer */
                                     LVM_UINT16 size,               /* Delay size */
                                     LVM_UINT16 *pOffset,           /* Delay offset */
                                     LVM_INT16 n);
-
+#ifdef BUILD_FLOAT
+void Add2_Sat_Float(          const LVM_FLOAT *src,
+                              LVM_FLOAT *dst,
+                              LVM_INT16 n );
+#else
 void Add2_Sat_16x16(          const LVM_INT16 *src,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n );
@@ -87,7 +117,13 @@
 void Add2_Sat_32x32(          const LVM_INT32  *src,
                                     LVM_INT32  *dst,
                                     LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void Mac3s_Sat_Float(         const LVM_FLOAT *src,
+                              const LVM_FLOAT val,
+                              LVM_FLOAT *dst,
+                              LVM_INT16 n);
+#else
 void Mac3s_Sat_16x16(         const LVM_INT16 *src,
                               const LVM_INT16 val,
                                     LVM_INT16 *dst,
@@ -97,7 +133,7 @@
                               const LVM_INT16 val,
                                     LVM_INT32  *dst,
                                     LVM_INT16 n);
-
+#endif
 void DelayAllPass_Sat_32x16To32(    LVM_INT32  *delay,              /* Delay buffer */
                                     LVM_UINT16 size,                /* Delay size */
                                     LVM_INT16 coeff,                /* All pass filter coefficient */
@@ -109,7 +145,12 @@
 /**********************************************************************************
     SHIFT FUNCTIONS
 ***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void Shift_Sat_Float (const   LVM_INT16   val,
+                      const   LVM_FLOAT   *src,
+                      LVM_FLOAT   *dst,
+                      LVM_INT16   n);
+#else
 void Shift_Sat_v16xv16 (      const LVM_INT16 val,
                               const LVM_INT16 *src,
                                     LVM_INT16 *dst,
@@ -119,11 +160,15 @@
                               const LVM_INT32 *src,
                                     LVM_INT32 *dst,
                                     LVM_INT16 n);
-
+#endif
 /**********************************************************************************
     AUDIO FORMAT CONVERSION FUNCTIONS
 ***********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void MonoTo2I_Float( const LVM_FLOAT     *src,
+                     LVM_FLOAT     *dst,
+                     LVM_INT16 n);
+#else
 void MonoTo2I_16(             const LVM_INT16 *src,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n);
@@ -131,29 +176,52 @@
 void MonoTo2I_32(             const LVM_INT32  *src,
                                     LVM_INT32  *dst,
                                     LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void From2iToMono_Float(         const LVM_FLOAT  *src,
+                                 LVM_FLOAT  *dst,
+                                 LVM_INT16 n);
+#else
 void From2iToMono_32(         const LVM_INT32  *src,
                                     LVM_INT32  *dst,
                                     LVM_INT16 n);
-
+#endif
+#ifdef BUILD_FLOAT
+void MSTo2i_Sat_Float(        const LVM_FLOAT *srcM,
+                              const LVM_FLOAT *srcS,
+                              LVM_FLOAT *dst,
+                              LVM_INT16 n );
+#else
 void MSTo2i_Sat_16x16(        const LVM_INT16 *srcM,
                               const LVM_INT16 *srcS,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void From2iToMS_Float(        const LVM_FLOAT *src,
+                              LVM_FLOAT *dstM,
+                              LVM_FLOAT *dstS,
+                              LVM_INT16 n );
+#else
 void From2iToMS_16x16(        const LVM_INT16 *src,
                                     LVM_INT16 *dstM,
                                     LVM_INT16 *dstS,
                                     LVM_INT16 n );
-
+#endif
+#ifdef BUILD_FLOAT
+void JoinTo2i_Float(          const LVM_FLOAT  *srcL,
+                              const LVM_FLOAT  *srcR,
+                              LVM_FLOAT  *dst,
+                              LVM_INT16 n );
+#else
 void From2iToMono_16(         const LVM_INT16 *src,
                                     LVM_INT16 *dst,
                                     LVM_INT16 n);
-
 void JoinTo2i_32x32(          const LVM_INT32  *srcL,
                               const LVM_INT32  *srcR,
-                                    LVM_INT32  *dst,
-                                    LVM_INT16 n );
+                              LVM_INT32  *dst,
+                              LVM_INT16 n );
+#endif
 
 /**********************************************************************************
     DATA TYPE CONVERSION FUNCTIONS
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
index 920b515..fa9f01f 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
@@ -33,7 +33,10 @@
 
 #define VOL_TC_SHIFT                                        21          /* As a power of 2 */
 #define DECAY_SHIFT                                        10           /* As a power of 2 */
-
+#ifdef BUILD_FLOAT
+#define VOL_TC_FLOAT                                      2.0f          /* As a power of 2 */
+#define DECAY_FAC_FLOAT                                  64.0f          /* As a power of 2 */
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -69,7 +72,7 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
-
+#ifndef BUILD_FLOAT
 void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_D32_t  *pInstance,     /* Instance pointer */
                                  const LVM_INT32            *pStSrc,        /* Stereo source */
                                  const LVM_INT32            *pMonoSrc,      /* Mono source */
@@ -193,4 +196,113 @@
 
     return;
 }
+#else
+void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t  *pInstance,     /* Instance pointer */
+                                 const LVM_FLOAT            *pStSrc,        /* Stereo source */
+                                 const LVM_FLOAT            *pMonoSrc,      /* Mono source */
+                                 LVM_FLOAT                  *pDst,          /* Stereo destination */
+                                 LVM_UINT16                 NumSamples)     /* Number of samples */
+{
 
+    /*
+     * General variables
+     */
+    LVM_UINT16      i;                                          /* Sample index */
+    LVM_FLOAT       Left;                                       /* Left sample */
+    LVM_FLOAT       Right;                                      /* Right sample */
+    LVM_FLOAT       Mono;                                       /* Mono sample */
+    LVM_FLOAT       AbsPeak;                                    /* Absolute peak signal */
+    LVM_FLOAT       AGC_Mult;                                   /* Short AGC gain */
+    LVM_FLOAT       Vol_Mult;                                   /* Short volume */
+
+
+    /*
+     * Instance control variables
+     */
+    LVM_FLOAT      AGC_Gain      = pInstance->AGC_Gain;         /* Get the current AGC gain */
+    LVM_FLOAT      AGC_MaxGain   = pInstance->AGC_MaxGain;      /* Get maximum AGC gain */
+    LVM_FLOAT      AGC_Attack    = pInstance->AGC_Attack;       /* Attack scaler */
+    LVM_FLOAT      AGC_Decay     = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT)));/* Decay scaler */
+    LVM_FLOAT      AGC_Target    = pInstance->AGC_Target;       /* Get the target level */
+    LVM_FLOAT      Vol_Current   = pInstance->Volume;           /* Actual volume setting */
+    LVM_FLOAT      Vol_Target    = pInstance->Target;           /* Target volume setting */
+    LVM_FLOAT      Vol_TC        = pInstance->VolumeTC;         /* Time constant */
+
+
+    /*
+     * Process on a sample by sample basis
+     */
+    for (i = 0; i < NumSamples; i++)                                  /* For each sample */
+    {
+
+        /*
+         * Get the short scalers
+         */
+        AGC_Mult    = (LVM_FLOAT)(AGC_Gain);              /* Get the short AGC gain */
+        Vol_Mult    = (LVM_FLOAT)(Vol_Current);           /* Get the short volume gain */
+
+
+        /*
+         * Get the input samples
+         */
+        Left  = *pStSrc++;                                      /* Get the left sample */
+        Right = *pStSrc++;                                      /* Get the right sample */
+        Mono  = *pMonoSrc++;                                    /* Get the mono sample */
+
+
+        /*
+         * Apply the AGC gain to the mono input and mix with the stereo signal
+         */
+        Left  += (Mono * AGC_Mult);                               /* Mix in the mono signal */
+        Right += (Mono * AGC_Mult);
+
+        /*
+         * Apply the volume and write to the output stream
+         */
+        Left  = Left  * Vol_Mult;
+        Right = Right * Vol_Mult;
+        *pDst++ = Left;                                         /* Save the results */
+        *pDst++ = Right;
+
+        /*
+         * Update the AGC gain
+         */
+        AbsPeak = Abs_Float(Left) > Abs_Float(Right) ? Abs_Float(Left) : Abs_Float(Right);
+        if (AbsPeak > AGC_Target)
+        {
+            /*
+             * The signal is too large so decrease the gain
+             */
+            AGC_Gain = AGC_Gain * AGC_Attack;
+        }
+        else
+        {
+            /*
+             * The signal is too small so increase the gain
+             */
+            if (AGC_Gain > AGC_MaxGain)
+            {
+                AGC_Gain -= (AGC_Decay);
+            }
+            else
+            {
+                AGC_Gain += (AGC_Decay);
+            }
+        }
+
+        /*
+         * Update the gain
+         */
+        Vol_Current +=  (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
+    }
+
+
+    /*
+     * Update the parameters
+     */
+    pInstance->Volume = Vol_Current;                            /* Actual volume setting */
+    pInstance->AGC_Gain = AGC_Gain;
+
+    return;
+}
+#endif /*BUILD_FLOAT*/
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.c b/media/libeffects/lvm/lib/Common/src/Abs_32.c
index 9128b82..84fabd8 100644
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.c
+++ b/media/libeffects/lvm/lib/Common/src/Abs_32.c
@@ -47,4 +47,14 @@
     }
     return input;
 }
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT    Abs_Float(LVM_FLOAT    input)
+{
+    if(input <  0)
+    {
+        /* Negative input, so invert */
+        input = (LVM_FLOAT)(-input);
+    }
+    return input;
+}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
index 69d357e..e3edccc 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
@@ -57,4 +57,33 @@
     return;
 }
 
+#ifdef BUILD_FLOAT
+void Add2_Sat_Float( const LVM_FLOAT  *src,
+                           LVM_FLOAT  *dst,
+                           LVM_INT16  n )
+{
+    LVM_FLOAT Temp;
+    LVM_INT16 ii;
+    for (ii = n; ii != 0; ii--)
+    {
+        Temp = ((LVM_FLOAT) *src) + ((LVM_FLOAT) *dst);
+        src++;
+
+        if (Temp > 1.000000f)
+        {
+            *dst = 1.000000f;
+        }
+        else if (Temp < -1.000000f)
+        {
+            *dst = -1.000000f;
+        }
+        else
+        {
+            *dst = Temp;
+        }
+        dst++;
+    }
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
index f4c5757..88f9986 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
@@ -33,7 +33,51 @@
  pBiquadState->pDelays[2] is y(n-1)L in Q0 format
  pBiquadState->pDelays[3] is y(n-2)L in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
 
+
+    {
+        LVM_FLOAT ynL;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL= (A0  * (x(n)L  - x(n-2)L  ) )
+            ynL = pBiquadState->coefs[0] * ((*pDataIn)-pBiquadState->pDelays[1]);
+
+            // ynL+= ((-B2  * y(n-2)L  ) )
+            ynL += pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+
+            // ynL+= ((-B1  * y(n-1)L  ) )
+            ynL += pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++=ynL; // Write Left output
+
+        }
+
+    }
+#else
 void BP_1I_D16F16C14_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -78,4 +122,5 @@
         }
 
     }
+#endif
 
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
index 88914ad..27ab57a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,19 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F16Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t          *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t    *pTaps,
+                                         BP_FLOAT_Coefs_t                  *pCoef)
+{
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps;
+
+    pBiquadState->coefs[0] = pCoef->A0;
+    pBiquadState->coefs[1] = pCoef->B2;
+    pBiquadState->coefs[2] = pCoef->B1;
+}
+#else
 void BP_1I_D16F16Css_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order2_Taps_t   *pTaps,
                                          BP_C16_Coefs_t            *pCoef)
@@ -49,6 +62,7 @@
   pBiquadState->coefs[1]=pCoef->B2;
   pBiquadState->coefs[2]=pCoef->B1;
   }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D16F16Css_TRC_WRA_01_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
index 980539c..e194f92 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[3];       /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
 #endif /*_BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
index ba1a42f..3abdd43 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
@@ -33,7 +33,48 @@
  pBiquadState->pDelays[2] is y(n-1)L in Q16 format
  pBiquadState->pDelays[3] is y(n-2)L in Q16 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F32C30_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+{
+    LVM_FLOAT ynL,templ;
+    LVM_INT16 ii;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT)pInstance;
 
+    for (ii = NrSamples; ii != 0; ii--)
+    {
+        /**************************************************************************
+                       PROCESSING OF THE LEFT CHANNEL
+        ***************************************************************************/
+        // ynL= (A0 * (x(n)L - x(n-2)L ))
+        templ = (LVM_FLOAT) *pDataIn - pBiquadState->pDelays[1];
+        ynL = pBiquadState->coefs[0] * templ;
+
+        // ynL+= ((-B2  * y(n-2)L  ) )
+        templ = pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+        ynL += templ;
+
+        // ynL+= ((-B1  * y(n-1)L  ))
+        templ = pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+        ynL += templ;
+
+        /**************************************************************************
+                        UPDATING THE DELAYS
+        ***************************************************************************/
+        pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+        pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+        pBiquadState->pDelays[2] = ynL; // Update y(n-1)L in Q16
+        pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L in Q0
+
+        /**************************************************************************
+                        WRITING THE OUTPUT
+        ***************************************************************************/
+        *pDataOut++ = (ynL); // Write Left output
+        }
+}
+#else
 void BP_1I_D16F32C30_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -80,4 +121,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
index e833218..d6e047a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
@@ -48,6 +48,20 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D16F32Cll_TRC_WRA_01_Init (    Biquad_FLOAT_Instance_t         *pInstance,
+                                          Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                          BP_FLOAT_Coefs_t                *pCoef)
+{
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays       =(LVM_FLOAT *) pTaps;
+
+
+    pBiquadState->coefs[0] =  pCoef->A0;
+    pBiquadState->coefs[1] =  pCoef->B2;
+    pBiquadState->coefs[2] =  pCoef->B1;
+}
+#else
 void BP_1I_D16F32Cll_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order2_Taps_t   *pTaps,
                                          BP_C32_Coefs_t            *pCoef)
@@ -59,6 +73,7 @@
   pBiquadState->coefs[1] =  pCoef->B2;
   pBiquadState->coefs[2] =  pCoef->B1;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D16F32Cll_TRC_WRA_01_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
index 9cca627..aa9e669 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
@@ -26,5 +26,12 @@
 }Filter_State;
 
 typedef Filter_State * PFilter_State ;
-
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[3];       /* pointer to the filter coefficients */
+}Filter_State_Float;
+typedef Filter_State_Float * PFilter_State_FLOAT ;
+#endif
 #endif /*_BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
index b09c1aa..abdb2f7 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
@@ -33,7 +33,52 @@
  pBiquadState->pDelays[2] is y(n-1)L in Q0 format
  pBiquadState->pDelays[3] is y(n-2)L in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32C30_TRC_WRA_02 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT ynL,templ;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+        for (ii = NrSamples; ii != 0; ii--)
+        {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL= (A0  * (x(n)L  - x(n-2)L  ) )
+            templ = (*pDataIn) - pBiquadState->pDelays[1];
+            ynL = pBiquadState->coefs[0] * templ;
+
+            // ynL+= ((-B2  * y(n-2)L  ) )
+            templ = pBiquadState->coefs[1] * pBiquadState->pDelays[3];
+            ynL += templ;
+
+            // ynL+= ((-B1  * y(n-1)L  ) )
+            templ = pBiquadState->coefs[2] * pBiquadState->pDelays[2];
+            ynL += templ;
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = ynL; // Write Left output in Q0
+
+        }
+
+    }
+#else
 void BP_1I_D32F32C30_TRC_WRA_02 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT32               *pDataIn,
                                   LVM_INT32               *pDataOut,
@@ -78,4 +123,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
index 9367912..5590c32 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
@@ -37,6 +37,21 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BP_1I_D32F32Cll_TRC_WRA_02_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BP_FLOAT_Coefs_t            *pCoef)
+{
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays       =(LVM_FLOAT *) pTaps;
+
+    pBiquadState->coefs[0] = pCoef->A0;
+
+    pBiquadState->coefs[1] = pCoef->B2;
+
+    pBiquadState->coefs[2] = pCoef->B1;
+}
+#else
 void BP_1I_D32F32Cll_TRC_WRA_02_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order2_Taps_t   *pTaps,
                                          BP_C32_Coefs_t            *pCoef)
@@ -50,6 +65,7 @@
 
   pBiquadState->coefs[2]=pCoef->B1;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BP_1I_D32F32Cll_TRC_WRA_02_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
index 5cc1ce2..80c3920 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
@@ -26,5 +26,13 @@
 }Filter_State;
 
 typedef Filter_State * PFilter_State ;
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[3];       /* pointer to the filter coefficients */
+}Filter_State_Float;
+typedef Filter_State_Float* PFilter_State_FLOAT ;
+#endif
 
 #endif /*_BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
index f2f8c6b..ee9bf7a 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
@@ -32,7 +32,56 @@
  pBiquadState->pDelays[2] is y(n-1)L in Q0 format
  pBiquadState->pDelays[3] is y(n-2)L in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A2  * x(n-2)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[1];
+
+            // ynL+=A1 * x(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            // ynL+=A0 * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            // ynL+=  (-B2  * y(n-2)L )
+            ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[3];
+
+            // ynL+= (-B1  * y(n-1)L  )
+            ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[2];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[2]; // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[1] = pBiquadState->pDelays[0]; // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[2] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
+
+
+        }
+
+    }
+#else
 void BQ_1I_D16F16C15_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -82,4 +131,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
index baf0c1a..3d5befa 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -37,6 +37,26 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F16Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps ;
+    temp = pCoef->A2;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A1;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[2] = temp;
+    temp = pCoef->B2;
+    pBiquadState->coefs[3] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[4] = temp;
+}
+#else
 void BQ_1I_D16F16Css_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order2_Taps_t   *pTaps,
                                          BQ_C16_Coefs_t            *pCoef)
@@ -56,6 +76,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[4]=temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_1I_D16F16Css_TRC_WRA_01_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
index 909c699..811da8b 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[5];       /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
 #endif /*_BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
index 92f6caf..c74a137 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
@@ -32,7 +32,54 @@
  pBiquadState->pDelays[2] is y(n-1)L in Q16 format
  pBiquadState->pDelays[3] is y(n-2)L in Q16 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A2  * x(n-2)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[1];
+
+            // ynL+=A1  * x(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            // ynL+=A0  * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            // ynL+= ( (-B2  * y(n-2)L )
+            ynL += pBiquadState->pDelays[3] * pBiquadState->coefs[3];
+
+            // ynL+= -B1  * y(n-1)L
+            ynL += pBiquadState->pDelays[2] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[2];  // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[1] = pBiquadState->pDelays[0];  // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[2] = ynL;                    // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++);              // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)(ynL); // Write Left output
+
+        }
+    }
+#else
 void BQ_1I_D16F32C14_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -81,4 +128,4 @@
 
         }
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
index aea10f0..9812274 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
@@ -27,4 +27,13 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *   pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT     coefs[5];       /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
 #endif /*_BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
index 1d6be4e..feae20d 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
@@ -38,6 +38,27 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_1I_D16F32Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *)pTaps;
+
+    temp = pCoef->A2;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A1;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[2] = temp;
+    temp = pCoef->B2;
+    pBiquadState->coefs[3] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[4] = temp;
+}
+#else
 void BQ_1I_D16F32Css_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order2_Taps_t   *pTaps,
                                          BQ_C16_Coefs_t            *pCoef)
@@ -57,6 +78,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[4]=temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_1I_D16F32Css_TRC_WRA_01_Init                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
index 972e704..9b0fde3 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
@@ -37,7 +37,81 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q0 format
  pBiquadState->pDelays[7] is y(n-2)R in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C14_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL,ynR;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A2  * x(n-2)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            // ynL+=A1  * x(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            // ynL+=A0  * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            // ynL+= ( -B2  * y(n-2)L  )
+            ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+
+            // ynL+=( -B1  * y(n-1)L )
+            ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+
+
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            // ynR=A2  * x(n-2)R
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            // ynR+=A1  * x(n-1)R
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+            // ynR+=A0  * x(n)R
+            ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+            // ynR+= ( -B2  * y(n-2)R  )
+            ynR += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+
+            // ynR+=( -B1  * y(n-1)R  )
+            ynR += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5];  // y(n-2)R=y(n-1)R
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4];  // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1];  // x(n-2)R=x(n-1)R
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0];  // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[5] = ynR;                       // Update y(n-1)R
+            pBiquadState->pDelays[4] = ynL;                       // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++);              // Update x(n-1)L
+            pBiquadState->pDelays[1] = (*pDataIn++);              // Update x(n-1)R
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+            *pDataOut++ = (LVM_FLOAT)ynR; // Write Right ouput
+
+
+        }
+
+    }
+#else
 void BQ_2I_D16F16C14_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -112,3 +186,4 @@
 
     }
 
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
index e056373..f24db8f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
@@ -37,7 +37,81 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q0 format
  pBiquadState->pDelays[7] is y(n-2)R in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16C15_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                  LVM_FLOAT               *pDataIn,
+                                  LVM_FLOAT               *pDataOut,
+                                  LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL,ynR;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A2  * x(n-2)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            // ynL+=A1  * x(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            // ynL+=A0  * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            // ynL+= ( -B2  * y(n-2)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+
+            // ynL+=( -B1  * y(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+
+
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            // ynR=A2  * x(n-2)R
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            // ynR+=A1  * x(n-1)R
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+            // ynR+=A0  * x(n)R
+            ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+            // ynR+= ( -B2  * y(n-2)R  )
+            ynR += (LVM_FLOAT)pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+
+            // ynR+=( -B1  * y(n-1)R  )
+            ynR += (LVM_FLOAT)pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5];  // y(n-2)R=y(n-1)R
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4];  // y(n-2)L=y(n-1)L
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1];  // x(n-2)R=x(n-1)R
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0];  // x(n-2)L=x(n-1)L
+            pBiquadState->pDelays[5] = ynR;                       // Update y(n-1)R
+            pBiquadState->pDelays[4] = ynL;                       // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++);              // Update x(n-1)L
+            pBiquadState->pDelays[1] = (*pDataIn++);              // Update x(n-1)R
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+            *pDataOut++ = (LVM_FLOAT)ynR; // Write Right ouput
+
+        }
+
+    }
+#else
 void BQ_2I_D16F16C15_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                   LVM_INT16               *pDataIn,
                                   LVM_INT16               *pDataOut,
@@ -111,4 +185,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
index 0a8ac35..39e1bda 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,27 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F16Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps            ;
+
+    temp = pCoef->A2;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A1;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[2] = temp;
+    temp = pCoef->B2;
+    pBiquadState->coefs[3] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[4] = temp;
+}
+#else
 void BQ_2I_D16F16Css_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_2I_Order2_Taps_t   *pTaps,
                                          BQ_C16_Coefs_t            *pCoef)
@@ -57,6 +78,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[4]=temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D16F16Css_TRC_WRA_01_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
index 7d42ced..0691b8c 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *   pDelays;            /* pointer to the delayed samples (data of 32 bits) */
+    LVM_FLOAT     coefs[5];           /* pointer to the filter coefficients */
+
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
 #endif /* _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
index 4a0cce4..61c07c7 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
@@ -37,7 +37,79 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q16 format
  pBiquadState->pDelays[7] is y(n-2)R in Q16 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C13_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples)
+    {
+        LVM_FLOAT  ynL,ynR;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+        for (ii = NrSamples; ii != 0; ii--)
+        {
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            /* ynL=A2 * x(n-2)L */
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            /* ynL+=A1* x(n-1)L */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            /* ynL+=A0* x(n)L   */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            /* ynL+=-B2*y(n-2)L */
+            ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+            /* ynL+=-B1*y(n-1)L */
+            ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            /* ynR=A2 * x(n-2)R */
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            /* ynR+=A1* x(n-1)R */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+            /* ynR+=A0* x(n)R   */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+            /* ynR+=-B2 * y(n-2)R */
+            ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+            /* ynR+=-B1 * y(n-1)R */
+            ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5];  /* y(n-2)R=y(n-1)R*/
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4];  /* y(n-2)L=y(n-1)L*/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1];  /* x(n-2)R=x(n-1)R*/
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0];  /* x(n-2)L=x(n-1)L*/
+            pBiquadState->pDelays[5] = ynR;                       /* Update y(n-1)R */
+            pBiquadState->pDelays[4] = ynL;                       /* Update y(n-1)L */
+            pBiquadState->pDelays[0] = (*pDataIn);                /* Update x(n-1)L */
+            pDataIn++;
+            pBiquadState->pDelays[1] = (*pDataIn);                /* Update x(n-1)R */
+            pDataIn++;
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output */
+            pDataOut++;
+            *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput */
+            pDataOut++;
+        }
+    }
+#else
 void BQ_2I_D16F32C13_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
@@ -115,4 +187,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
index 052e2a0..cf19e06 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
@@ -36,7 +36,82 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q16 format
  pBiquadState->pDelays[7] is y(n-2)R in Q16 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C14_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples)
+    {
+        LVM_FLOAT  ynL,ynR;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+        for (ii = NrSamples; ii != 0; ii--)
+        {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            /* ynL=A2  * x(n-2)L */
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            /* ynL+=A1  * x(n-1)L */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            /* ynL+=A0  * x(n)L */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            /* ynL+= ( (-B2  * y(n-2)L  ))*/
+            ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+
+            /* ynL+=( (-B1  * y(n-1)L  ))  */
+            ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            /* ynR=A2  * x(n-2)R */
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            /* ynR+=A1  * x(n-1)R */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+            /* ynR+=A0  * x(n)R */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+            /* ynR+= ( (-B2  * y(n-2)R  ))*/
+            ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+            /* ynR+=( (-B1  * y(n-1)R  ))  */
+            ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5];  /* y(n-2)R=y(n-1)R*/
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4];  /* y(n-2)L=y(n-1)L*/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1];  /* x(n-2)R=x(n-1)R*/
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0];  /* x(n-2)L=x(n-1)L*/
+            pBiquadState->pDelays[5] = ynR;                    /* Update y(n-1)R */
+            pBiquadState->pDelays[4] = ynL;                    /* Update y(n-1)L */
+            pBiquadState->pDelays[0] = (*pDataIn);                /* Update x(n-1)L */
+            pDataIn++;
+            pBiquadState->pDelays[1] = (*pDataIn);                /* Update x(n-1)R */
+            pDataIn++;
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output */
+            pDataOut++;
+            *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput */
+            pDataOut++;
+        }
+
+    }
+#else
 void BQ_2I_D16F32C14_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
@@ -114,4 +189,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
index 8c741e1..2611b19 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
@@ -36,7 +36,84 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q16 format
  pBiquadState->pDelays[7] is y(n-2)R in Q16 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32C15_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples)
+    {
+        LVM_FLOAT  ynL,ynR;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            /* ynL=A2  * x(n-2)L */
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            /* ynL+=A1  * x(n-1)L */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+
+            /* ynL+=A0  * x(n)L */
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * (*pDataIn);
+
+            /* ynL+= ( (-B2  * y(n-2)L )  */
+            ynL += pBiquadState->pDelays[6] * pBiquadState->coefs[3];
+
+
+            /* ynL+=( (-B1  * y(n-1)L  ))  */
+            ynL += pBiquadState->pDelays[4] * pBiquadState->coefs[4];
+
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            /* ynR=A2  * x(n-2)R */
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            /* ynR+=A1  * x(n-1)R */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+
+            /* ynR+=A0  * x(n)R */
+            ynR += (LVM_FLOAT)pBiquadState->coefs[2] * (*(pDataIn+1));
+
+            /* ynR+= ( (-B2  * y(n-2)R ) */
+            ynR += pBiquadState->pDelays[7] * pBiquadState->coefs[3];
+
+
+            /* ynR+=( (-B1  * y(n-1)R  )) in Q15 */
+            ynR += pBiquadState->pDelays[5] * pBiquadState->coefs[4];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+            pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R*/
+            pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L*/
+            pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L*/
+            pDataIn++;
+            pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R*/
+            pDataIn++;
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut = (LVM_FLOAT)(ynL); /* Write Left output*/
+            pDataOut++;
+            *pDataOut = (LVM_FLOAT)(ynR); /* Write Right ouput*/
+            pDataOut++;
+        }
+
+    }
+#else
 void BQ_2I_D16F32C15_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT16                    *pDataIn,
                                             LVM_INT16                    *pDataOut,
@@ -114,4 +191,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
index 4f0cf67..c0319c9 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *                          pDelays;        /* pointer to the delayed samples \
+                                                           (data of 32 bits)   */
+    LVM_FLOAT                           coefs[5];        /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
 #endif /* _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
index 4591ee0..4d9bbfe 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
@@ -37,6 +37,26 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D16F32Css_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps;
+    temp = pCoef->A2;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A1;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[2] = temp;
+    temp = pCoef->B2;
+    pBiquadState->coefs[3] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[4] = temp;
+}
+#else
 void BQ_2I_D16F32Css_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_2I_Order2_Taps_t   *pTaps,
                                          BQ_C16_Coefs_t            *pCoef)
@@ -56,6 +76,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[4]=temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D16F32Css_TRC_WRA_01_Init                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
index fd8212e4..960de79 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
@@ -36,7 +36,94 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q0 format
  pBiquadState->pDelays[7] is y(n-2)R in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32C30_TRC_WRA_01 (           Biquad_FLOAT_Instance_t       *pInstance,
+                                            LVM_FLOAT                    *pDataIn,
+                                            LVM_FLOAT                    *pDataOut,
+                                            LVM_INT16                    NrSamples)
 
+
+    {
+        LVM_FLOAT ynL,ynR,templ,tempd;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            /* ynL= ( A2  * x(n-2)L  ) */
+            ynL = pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+            /* ynL+= ( A1  * x(n-1)L  )*/
+            templ = pBiquadState->coefs[1] * pBiquadState->pDelays[0];
+            ynL += templ;
+
+            /* ynL+= ( A0  * x(n)L  ) */
+            templ = pBiquadState->coefs[2] * (*pDataIn);
+            ynL += templ;
+
+             /* ynL+= (-B2  * y(n-2)L  ) */
+            templ = pBiquadState->coefs[3] * pBiquadState->pDelays[6];
+            ynL += templ;
+
+            /* ynL+= (-B1  * y(n-1)L  )*/
+            templ = pBiquadState->coefs[4] * pBiquadState->pDelays[4];
+            ynL += templ;
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            /* ynR= ( A2  * x(n-2)R  ) */
+            ynR = pBiquadState->coefs[0] * pBiquadState->pDelays[3];
+
+            /* ynR+= ( A1  * x(n-1)R  ) */
+            templ = pBiquadState->coefs[1] * pBiquadState->pDelays[1];
+            ynR += templ;
+
+            /* ynR+= ( A0  * x(n)R  ) */
+            tempd =* (pDataIn+1);
+            templ = pBiquadState->coefs[2] * tempd;
+            ynR += templ;
+
+            /* ynR+= (-B2  * y(n-2)R  ) */
+            templ = pBiquadState->coefs[3] * pBiquadState->pDelays[7];
+            ynR += templ;
+
+            /* ynR+= (-B1  * y(n-1)R  )  */
+            templ = pBiquadState->coefs[4] * pBiquadState->pDelays[5];
+            ynR += templ;
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+            pBiquadState->pDelays[5] = (LVM_FLOAT)ynR; /* Update y(n-1)R */
+            pBiquadState->pDelays[4] = (LVM_FLOAT)ynL; /* Update y(n-1)L */
+            pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+            pDataIn++;
+            pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+            pDataIn++;
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut = (LVM_FLOAT)ynL; /* Write Left output */
+            pDataOut++;
+            *pDataOut = (LVM_FLOAT)ynR; /* Write Right ouput */
+            pDataOut++;
+
+
+        }
+
+    }
+#else
 void BQ_2I_D32F32C30_TRC_WRA_01 (           Biquad_Instance_t       *pInstance,
                                             LVM_INT32                    *pDataIn,
                                             LVM_INT32                    *pDataOut,
@@ -123,4 +210,4 @@
         }
 
     }
-
+#endif /*BUILD_FLOAT*/
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
index 1709f71..fff05ed 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
@@ -37,6 +37,26 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void BQ_2I_D32F32Cll_TRC_WRA_01_Init (   Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         BQ_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps;
+    temp = pCoef->A2;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A1;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[2] = temp;
+    temp = pCoef->B2;
+    pBiquadState->coefs[3] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[4] = temp;
+}
+#else
 void BQ_2I_D32F32Cll_TRC_WRA_01_Init (   Biquad_Instance_t         *pInstance,
                                          Biquad_2I_Order2_Taps_t   *pTaps,
                                          BQ_C32_Coefs_t            *pCoef)
@@ -56,6 +76,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[4]=temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: BQ_2I_D32F32C32_TRC_WRA_01_Init.c                              */
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
index 747af6a..c0f0dcc 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
@@ -29,4 +29,14 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *                          pDelays;        /* pointer to the delayed samples \
+                                                            (data of 32 bits)   */
+    LVM_FLOAT                            coefs[5];       /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
+
 #endif /* _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_*/
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index 20404ad..e489031 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -54,5 +54,35 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void Copy_Float( const LVM_FLOAT *src,
+                 LVM_FLOAT *dst,
+                 LVM_INT16  n )
+{
+    LVM_INT16 ii;
 
+    if (src > dst)
+    {
+        for (ii = n; ii != 0; ii--)
+        {
+            *dst = *src;
+            dst++;
+            src++;
+        }
+    }
+    else
+    {
+        src += n - 1;
+        dst += n - 1;
+        for (ii = n; ii != 0; ii--)
+        {
+            *dst = *src;
+            dst--;
+            src--;
+        }
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
index bf69e35..ea98041 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
@@ -25,7 +25,37 @@
 /**********************************************************************************
    FUNCTION CORE_MIXHARD_2ST_D32C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Core_MixHard_2St_D32C31_SAT(   Mix_2St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src1,
+                                    const LVM_FLOAT     *src2,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n)
+{
+    LVM_FLOAT  Temp1,Temp2,Temp3;
+    LVM_INT16 ii;
+    LVM_FLOAT Current1Short;
+    LVM_FLOAT Current2Short;
 
+    Current1Short = (pInstance->Current1);
+    Current2Short = (pInstance->Current2);
+
+    for (ii = n; ii != 0; ii--){
+        Temp1 = *src1++;
+        Temp3 = Temp1 * Current1Short;
+        Temp2 = *src2++;
+        Temp1 = Temp2 * Current2Short;
+        Temp2 = (Temp1 / 2.0f) + (Temp3 / 2.0f);
+        if (Temp2 > 0.5f)
+            Temp2 = 1.0f;
+        else if (Temp2 < -0.5f )
+            Temp2 = -1.0f;
+        else
+            Temp2 = (Temp2 * 2);
+            *dst++ = Temp2;
+    }
+}
+#else
 void Core_MixHard_2St_D32C31_SAT(   Mix_2St_Cll_t       *pInstance,
                                     const LVM_INT32     *src1,
                                     const LVM_INT32     *src2,
@@ -55,6 +85,5 @@
             *dst++ = Temp2;
     }
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
index 3471f05..2814f19 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
@@ -26,6 +26,70 @@
    FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
 ***********************************************************************************/
 
+#ifdef BUILD_FLOAT /* BUILD_FLOAT */
+void Core_MixInSoft_D32C31_SAT(     Mix_1St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     n)
+{
+    LVM_FLOAT    Temp1,Temp2,Temp3;
+    LVM_INT16     OutLoop;
+    LVM_INT16     InLoop;
+    LVM_FLOAT    TargetTimesOneMinAlpha;
+    LVM_FLOAT    CurrentTimesAlpha;
+    LVM_INT16     ii,jj;
+
+
+    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+    OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+    TargetTimesOneMinAlpha = ((1.0f -pInstance->Alpha) * pInstance->Target);
+    if (pInstance->Target >= pInstance->Current){
+        TargetTimesOneMinAlpha +=(LVM_FLOAT)(2.0f / 2147483647.0f); /* Ceil*/
+    }
+
+    if (OutLoop){
+
+        CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+        pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+        for (ii = OutLoop; ii != 0; ii--){
+        Temp1 = *src++;
+        Temp2 = *dst;
+
+        Temp3 = Temp1 * (pInstance->Current);
+        Temp1 = Temp2 + Temp3;
+
+        if (Temp1 > 1.0f)
+            Temp1 = 1.0f;
+        else if (Temp1 < -1.0f)
+            Temp1 = -1.0f;
+
+        *dst++ = Temp1;
+        }
+    }
+
+    for (ii = InLoop; ii != 0; ii--){
+
+        CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+        pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+        for (jj = 4; jj!=0 ; jj--){
+            Temp1 = *src++;
+            Temp2 = *dst;
+
+            Temp3 = Temp1 * (pInstance->Current);
+            Temp1 = Temp2 + Temp3;
+
+            if (Temp1 > 1.0f)
+                Temp1 = 1.0f;
+            else if (Temp1 < -1.0f)
+                Temp1 = -1.0f;
+            *dst++ = Temp1;
+        }
+    }
+}
+#else
 void Core_MixInSoft_D32C31_SAT(     Mix_1St_Cll_t       *pInstance,
                                     const LVM_INT32     *src,
                                           LVM_INT32     *dst,
@@ -89,6 +153,5 @@
         }
     }
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
index 709c304..814ccee 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
@@ -25,7 +25,79 @@
 /**********************************************************************************
    FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Core_MixSoft_1St_D32C31_WRA(   Mix_1St_Cll_FLOAT_t       *pInstance,
+                                    const LVM_FLOAT     *src,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n)
+{
+    LVM_FLOAT Temp1,Temp2;
+    LVM_INT16 OutLoop;
+    LVM_INT16 InLoop;
+    LVM_FLOAT TargetTimesOneMinAlpha;
+    LVM_FLOAT CurrentTimesAlpha;
 
+    LVM_INT16 ii;
+
+    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+    OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+    TargetTimesOneMinAlpha = (1.0f - pInstance->Alpha) * pInstance->Target; /* float * float in float */
+    if (pInstance->Target >= pInstance->Current)
+    {
+        TargetTimesOneMinAlpha += (LVM_FLOAT)(2.0f / 2147483647.0f); /* Ceil*/
+    }
+
+    if (OutLoop != 0)
+    {
+        CurrentTimesAlpha = (pInstance->Current * pInstance->Alpha);
+        pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+        for (ii = OutLoop; ii != 0; ii--)
+        {
+            Temp1 = *src;
+            src++;
+
+            Temp2 = Temp1 * (pInstance->Current);
+            *dst = Temp2;
+            dst++;
+        }
+    }
+
+    for (ii = InLoop; ii != 0; ii--)
+    {
+        CurrentTimesAlpha = pInstance->Current * pInstance->Alpha;
+        pInstance->Current = TargetTimesOneMinAlpha + CurrentTimesAlpha;
+
+            Temp1 = *src;
+            src++;
+
+            Temp2 = Temp1 * (pInstance->Current);
+            *dst = Temp2;
+            dst++;
+
+            Temp1 = *src;
+            src++;
+
+            Temp2 = Temp1 * (pInstance->Current);
+            *dst = Temp2;
+            dst++;
+
+            Temp1 = *src;
+            src++;
+
+            Temp2 = Temp1 * (pInstance->Current);
+            *dst = Temp2;
+            dst++;
+
+            Temp1 = *src;
+            src++;
+            Temp2 = Temp1 * (pInstance->Current);
+            *dst = Temp2;
+            dst++;
+    }
+}
+#else
 void Core_MixSoft_1St_D32C31_WRA(   Mix_1St_Cll_t       *pInstance,
                                     const LVM_INT32     *src,
                                           LVM_INT32     *dst,
@@ -98,6 +170,5 @@
             dst++;
     }
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
index 49fa184..d261c9e 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
@@ -18,7 +18,53 @@
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
+#ifdef BUILD_FLOAT
+void DC_2I_D16_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                           LVM_FLOAT               *pDataIn,
+                           LVM_FLOAT               *pDataOut,
+                           LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT LeftDC,RightDC;
+        LVM_FLOAT Diff;
+        LVM_INT32 j;
+        PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State) pInstance;
 
+        LeftDC = pBiquadState->LeftDC;
+        RightDC = pBiquadState->RightDC;
+        for(j = NrSamples-1; j >= 0; j--)
+        {
+            /* Subtract DC an saturate */
+            Diff =* (pDataIn++) - (LeftDC);
+            if (Diff > 1.0f) {
+                Diff = 1.0f; }
+            else if (Diff < -1.0f) {
+                Diff = -1.0f; }
+            *(pDataOut++) = (LVM_FLOAT)Diff;
+            if (Diff < 0) {
+                LeftDC -= DC_FLOAT_STEP; }
+            else {
+                LeftDC += DC_FLOAT_STEP; }
+
+
+            /* Subtract DC an saturate */
+            Diff =* (pDataIn++) - (RightDC);
+            if (Diff > 1.0f) {
+                Diff = 1.0f; }
+            else if (Diff < -1.0f) {
+                Diff = -1.0f; }
+            *(pDataOut++) = (LVM_FLOAT)Diff;
+            if (Diff < 0) {
+                RightDC -= DC_FLOAT_STEP; }
+            else {
+                RightDC += DC_FLOAT_STEP; }
+
+        }
+        pBiquadState->LeftDC = LeftDC;
+        pBiquadState->RightDC = RightDC;
+
+
+    }
+#else
 void DC_2I_D16_TRC_WRA_01( Biquad_Instance_t       *pInstance,
                            LVM_INT16               *pDataIn,
                            LVM_INT16               *pDataOut,
@@ -64,4 +110,4 @@
 
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
index 468a88d..4f4fcd8 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
@@ -17,11 +17,18 @@
 
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
-
+#ifdef BUILD_FLOAT
+void  DC_2I_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t   *pInstance)
+{
+    PFilter_FLOAT_State pBiquadState  = (PFilter_FLOAT_State) pInstance;
+    pBiquadState->LeftDC        = 0.0f;
+    pBiquadState->RightDC       = 0.0f;
+}
+#else
 void  DC_2I_D16_TRC_WRA_01_Init(Biquad_Instance_t   *pInstance)
 {
     PFilter_State pBiquadState  = (PFilter_State) pInstance;
     pBiquadState->LeftDC        = 0;
     pBiquadState->RightDC       = 0;
 }
-
+#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 89a4e68..fa6b729 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,11 +18,23 @@
 #ifndef _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
 #define _DC_2I_D16_TRC_WRA_01_PRIVATE_H_
 
+#ifdef BUILD_FLOAT
+#define DC_FLOAT_STEP   0.0000002384f;
+#else
 #define DC_D16_STEP     0x200;
+#endif
 
 
 /* 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.*/
+#ifdef BUILD_FLOAT
+typedef struct _Filter_FLOAT_State_
+{
+    LVM_FLOAT  LeftDC;     /* LeftDC  */
+    LVM_FLOAT  RightDC;    /* RightDC  */
+}Filter_FLOAT_State;
+typedef Filter_FLOAT_State * PFilter_FLOAT_State ;
+#else
 typedef struct _Filter_State_
 {
   LVM_INT32  LeftDC;     /* LeftDC  */
@@ -30,5 +42,5 @@
 }Filter_State;
 
 typedef Filter_State * PFilter_State ;
-
+#endif
 #endif /* _DC_2I_D16_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
index 7e3182d..f502716 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
@@ -36,10 +36,55 @@
     LVM_INT16   Offset  = *pOffset;
     LVM_INT16   temp;
 
+    for (i = 0; i < n; i++)
+    {
+        /* Left channel */
+        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
+        *dst = temp;
+        dst++;
+
+        delay[Offset] = *src;
+        Offset++;
+        src++;
+
+
+        /* Right channel */
+        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
+        *dst = temp;
+        dst++;
+
+        delay[Offset] = *src;
+        Offset++;
+        src++;
+
+        /* Make the reverb delay buffer a circular buffer */
+        if (Offset >= size)
+        {
+            Offset = 0;
+        }
+    }
+
+    /* Update the offset */
+    *pOffset = Offset;
+
+    return;
+}
+#ifdef BUILD_FLOAT
+void DelayMix_Float(const LVM_FLOAT *src,           /* Source 1, to be delayed */
+                          LVM_FLOAT *delay,         /* Delay buffer */
+                          LVM_INT16 size,           /* Delay size */
+                          LVM_FLOAT *dst,           /* Source/destination */
+                          LVM_INT16 *pOffset,       /* Delay offset */
+                          LVM_INT16 n)              /* Number of stereo samples */
+{
+    LVM_INT16   i;
+    LVM_INT16   Offset  = *pOffset;
+    LVM_FLOAT   temp;
+
     for (i=0; i<n; i++)
     {
         /* Left channel */
-        temp            = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
+        temp            = (LVM_FLOAT)((LVM_FLOAT)(*dst + (LVM_FLOAT)delay[Offset]) / 2.0f);
         *dst            = temp;
         dst++;
 
@@ -49,7 +94,7 @@
 
 
         /* Right channel */
-        temp            = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
+        temp            = (LVM_FLOAT)((LVM_FLOAT)(*dst - (LVM_FLOAT)delay[Offset]) / 2.0f);
         *dst            = temp;
         dst++;
 
@@ -69,5 +114,5 @@
 
     return;
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
index de77361..039c88c 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
@@ -31,6 +31,46 @@
  pBiquadState->pDelays[1] is y(n-1)L in Q0 format
 ***************************************************************************/
 
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16C15_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT               *pDataIn,
+                                 LVM_FLOAT               *pDataOut,
+                                 LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL;
+        LVM_INT16 ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
+
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A1  * x(n-1)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+
+            // ynL+=A0  * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
+
+            // ynL+=  (-B1  * y(n-1)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[2] * pBiquadState->pDelays[1];
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
+
+        }
+
+    }
+#else
 void FO_1I_D16F16C15_TRC_WRA_01( Biquad_Instance_t       *pInstance,
                                  LVM_INT16               *pDataIn,
                                  LVM_INT16               *pDataOut,
@@ -71,4 +111,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
index 96252cc..b21b8a4 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -38,6 +38,22 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_1I_D16F16Css_TRC_WRA_01_Init(    Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_1I_Order1_FLOAT_Taps_t   *pTaps,
+                                         FO_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT)  pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *)pTaps;
+    temp = pCoef->A1;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[2] = temp;
+}
+#else
 void FO_1I_D16F16Css_TRC_WRA_01_Init(    Biquad_Instance_t         *pInstance,
                                          Biquad_1I_Order1_Taps_t   *pTaps,
                                          FO_C16_Coefs_t            *pCoef)
@@ -53,6 +69,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[2]=temp;
 }
+#endif
 /*------------------------------------------------*/
 /* End Of File: FO_1I_D16F16Css_TRC_WRA_01_Init.c */
 
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
index 516ca83..6fdb039 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -28,4 +28,14 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT
+{
+    LVM_FLOAT *                          pDelays;        /* pointer to the delayed samples \
+                                                            (data of 32 bits)   */
+    LVM_FLOAT                            coefs[3];       /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
 #endif /* _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
index 0f1d5bc..416e8eb 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
@@ -31,7 +31,47 @@
  pBiquadState->pDelays[0] is x(n-1)L in Q0 format
  pBiquadState->pDelays[1] is y(n-1)L in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32C31_TRC_WRA_01( Biquad_FLOAT_Instance_t       *pInstance,
+                                 LVM_FLOAT               *pDataIn,
+                                 LVM_FLOAT               *pDataOut,
+                                 LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT  ynL,templ;
+        LVM_INT16  ii;
+        PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT) pInstance;
 
+        for (ii = NrSamples; ii != 0; ii--)
+        {
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            // ynL=A1  * x(n-1)L
+            ynL = pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+
+            // ynL+=A0  * x(n)L
+            templ = pBiquadState->coefs[1] * (*pDataIn);
+            ynL += templ;
+
+            // ynL+=  (-B1  * y(n-1)L
+            templ = pBiquadState->coefs[2] * pBiquadState->pDelays[1];
+            ynL += templ;
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
+        }
+
+    }
+#else
 void FO_1I_D32F32C31_TRC_WRA_01( Biquad_Instance_t       *pInstance,
                                  LVM_INT32               *pDataIn,
                                  LVM_INT32               *pDataOut,
@@ -71,4 +111,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
index 136e4f6..f33d24d 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
@@ -37,6 +37,23 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_FLOAT_Instance_t         *pInstance,
+                                      Biquad_1I_Order1_FLOAT_Taps_t   *pTaps,
+                                      FO_FLOAT_Coefs_t            *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_State_FLOAT pBiquadState = (PFilter_State_FLOAT)  pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *)    pTaps;
+
+    temp = pCoef->A1;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[2] = temp;
+}
+#else
 void FO_1I_D32F32Cll_TRC_WRA_01_Init( Biquad_Instance_t         *pInstance,
                                       Biquad_1I_Order1_Taps_t   *pTaps,
                                       FO_C32_Coefs_t            *pCoef)
@@ -52,6 +69,7 @@
   temp=pCoef->B1;
   pBiquadState->coefs[2]=temp;
 }
+#endif
 /*------------------------------------------------*/
 /* End Of File: FO_1I_D32F32Cll_TRC_WRA_01_Init.c */
 
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
index 94ad48c..fdb528b 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
@@ -29,4 +29,13 @@
 
 typedef Filter_State * PFilter_State ;
 
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_FLOAT_
+{
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[3];       /* pointer to the filter coefficients */
+}Filter_State_FLOAT;
+
+typedef Filter_State_FLOAT * PFilter_State_FLOAT ;
+#endif
 #endif /* _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
index 8388050..192927c 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
@@ -32,7 +32,92 @@
 pBiquadState->pDelays[2] is x(n-1)R in Q15 format
 pBiquadState->pDelays[3] is y(n-1)R in Q30 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
+                                     LVM_FLOAT               *pDataIn,
+                                     LVM_FLOAT               *pDataOut,
+                                     LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT   ynL,ynR;
+        LVM_FLOAT   Temp;
+        LVM_FLOAT   NegSatValue;
+        LVM_INT16   ii;
 
+        PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
+
+        NegSatValue = -1.0f;
+
+        for (ii = NrSamples; ii != 0; ii--)
+        {
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+
+            // ynL =A1  * x(n-1)L
+            ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
+            // ynR =A1  * x(n-1)R
+            ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
+
+
+            // ynL+=A0  * x(n)L
+            ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
+            // ynR+=A0  * x(n)L
+            ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn+1));
+
+
+            // ynL +=  (-B1  * y(n-1)L  )
+            Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
+            ynL += Temp;
+            // ynR +=  (-B1  * y(n-1)R ) )
+            Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
+            ynR += Temp;
+
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
+            pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
+
+            pBiquadState->pDelays[3] = ynR; // Update y(n-1)R
+            pBiquadState->pDelays[2] = (*pDataIn++); // Update x(n-1)R
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+
+            /*Saturate results*/
+            if(ynL > 1.0f)
+            {
+                ynL = 1.0f;
+            }
+            else
+            {
+                if(ynL < NegSatValue)
+                {
+                    ynL = NegSatValue;
+                }
+            }
+
+            if(ynR > 1.0f)
+            {
+                ynR = 1.0f;
+            }
+            else
+            {
+                if(ynR < NegSatValue)
+                {
+                    ynR = NegSatValue;
+                }
+            }
+
+            *pDataOut++ = (LVM_FLOAT)ynL;
+            *pDataOut++ = (LVM_FLOAT)ynR;
+        }
+
+    }
+#else
 void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t       *pInstance,
                                      LVM_INT16               *pDataIn,
                                      LVM_INT16               *pDataOut,
@@ -125,4 +210,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
index a19c32c..33ca6cf 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
@@ -37,6 +37,23 @@
 /* RETURNS:                                                                */
 /*   void return code                                                      */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t         *pInstance,
+                                          Biquad_2I_Order1_FLOAT_Taps_t   *pTaps,
+                                          FO_FLOAT_LShx_Coefs_t        *pCoef)
+{
+    LVM_FLOAT temp;
+    PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
+    pBiquadState->pDelays      = (LVM_FLOAT *) pTaps            ;
+
+    temp = pCoef->A1;
+    pBiquadState->coefs[0] = temp;
+    temp = pCoef->A0;
+    pBiquadState->coefs[1] = temp;
+    temp = pCoef->B1;
+    pBiquadState->coefs[2] = temp;
+}
+#else
 void FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(Biquad_Instance_t         *pInstance,
                                           Biquad_2I_Order1_Taps_t   *pTaps,
                                           FO_C16_LShx_Coefs_t        *pCoef)
@@ -55,6 +72,7 @@
   temp=pCoef->Shift;
   pBiquadState->Shift = temp;
 }
+#endif
 /*-------------------------------------------------------------------------*/
 /* End Of File: FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c                     */
 
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
index 4640743..368bfce 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
@@ -20,6 +20,15 @@
 
 /* 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.        */
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_
+{
+    LVM_FLOAT     *pDelays;       /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT     coefs[3];       /* pointer to the filter coefficients */
+}Filter_Float_State;
+
+typedef Filter_Float_State * PFilter_Float_State ;
+#else
 typedef struct _Filter_State_
 {
   LVM_INT32     *pDelays;       /* pointer to the delayed samples (data of 32 bits)   */
@@ -28,5 +37,5 @@
 }Filter_State;
 
 typedef Filter_State * PFilter_State ;
-
+#endif
 #endif /* _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/Filters.h b/media/libeffects/lvm/lib/Common/src/Filters.h
index 4d32df1..b1fde0c 100644
--- a/media/libeffects/lvm/lib/Common/src/Filters.h
+++ b/media/libeffects/lvm/lib/Common/src/Filters.h
@@ -34,6 +34,7 @@
  * Biquad with coefficients A0, A1, A2, B1 and B2 coefficients
  */
 /* Single precision (16-bit) Biquad section coefficients */
+#ifndef BUILD_FLOAT
 typedef struct
 {
         LVM_INT16   A0;
@@ -43,12 +44,22 @@
         LVM_INT16   B2;
         LVM_UINT16  Scale;
 } BiquadA012B12CoefsSP_t;
-
-
+#else
+typedef struct
+{
+    LVM_FLOAT   A0;
+    LVM_FLOAT   A1;
+    LVM_FLOAT   A2;
+    LVM_FLOAT   B1;
+    LVM_FLOAT   B2;
+    LVM_UINT16  Scale;
+} BiquadA012B12CoefsSP_t;
+#endif
 /*
  * Biquad with coefficients A0, A1 and B1 coefficients
  */
 /* Single precision (16-bit) Biquad section coefficients */
+#ifndef BUILD_FLOAT
 typedef struct
 {
         LVM_INT16   A0;
@@ -56,8 +67,15 @@
         LVM_INT16   B1;
         LVM_UINT16  Scale;
 } BiquadA01B1CoefsSP_t;
-
-
+#else
+typedef struct
+{
+    LVM_FLOAT   A0;
+    LVM_FLOAT   A1;
+    LVM_FLOAT   B1;
+    LVM_UINT16  Scale;
+} BiquadA01B1CoefsSP_t;
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
index 7975e8b..2c6e6c3 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
@@ -53,5 +53,34 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void From2iToMS_Float( const LVM_FLOAT  *src,
+                             LVM_FLOAT  *dstM,
+                             LVM_FLOAT  *dstS,
+                             LVM_INT16  n )
+{
+    LVM_FLOAT temp1,left,right;
+    LVM_INT16 ii;
+    for (ii = n; ii != 0; ii--)
+    {
+        left = (LVM_FLOAT)*src;
+        src++;
 
+        right = (LVM_FLOAT)*src;
+        src++;
+
+        /* Compute M signal*/
+        temp1 =  (left + right) / 2.0f;
+        *dstM = (LVM_FLOAT)temp1;
+        dstM++;
+
+        /* Compute S signal*/
+        temp1 =  (left - right) / 2.0f;
+        *dstS = (LVM_FLOAT)temp1;
+        dstS++;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
index 8bb292f..ac1eea8 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
@@ -46,5 +46,27 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void From2iToMono_Float( const LVM_FLOAT *src,
+                         LVM_FLOAT *dst,
+                         LVM_INT16 n)
+{
+    LVM_INT16 ii;
+    LVM_FLOAT Temp;
 
+    for (ii = n; ii != 0; ii--)
+    {
+        Temp = (*src);
+        src++;
+
+        Temp += (*src);
+        src++;
+
+        *dst = Temp / 2.0f;
+        dst++;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
index 9b938bd..ebc477e 100644
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
@@ -49,6 +49,31 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void JoinTo2i_Float( const LVM_FLOAT    *srcL,
+                     const LVM_FLOAT    *srcR,
+                           LVM_FLOAT    *dst,
+                           LVM_INT16    n )
+{
+    LVM_INT16 ii;
 
+    srcL += n - 1;
+    srcR += n - 1;
+    dst  += ((2 * n) - 1);
+
+    for (ii = n; ii != 0; ii--)
+    {
+        *dst = *srcR;
+        dst--;
+        srcR--;
+
+        *dst = *srcL;
+        dst--;
+        srcL--;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
index 3d39b93..eb5755e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
@@ -27,7 +27,39 @@
 /**********************************************************************************
    FUNCTION LVC_Core_MixHard_1St_2i_D16C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st        *ptrInstance1,
+                                         LVMixer3_FLOAT_st        *ptrInstance2,
+                                         const LVM_FLOAT    *src,
+                                         LVM_FLOAT          *dst,
+                                         LVM_INT16          n)
+{
+    LVM_FLOAT  Temp;
+    LVM_INT16 ii;
+    Mix_Private_FLOAT_st  *pInstance1 = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
+    for (ii = n; ii != 0; ii--)
+    {
+        Temp = ((LVM_FLOAT)*(src++) * (LVM_FLOAT)pInstance1->Current);
+        if (Temp > 1.0f)
+            *dst++ = 1.0f;
+        else if (Temp < -1.0f)
+            *dst++ = -1.0f;
+        else
+            *dst++ = (LVM_FLOAT)Temp;
 
+        Temp = ((LVM_FLOAT)*(src++) * (LVM_FLOAT)pInstance2->Current);
+        if (Temp > 1.0f)
+            *dst++ = 1.0f;
+        else if (Temp < -1.0f)
+            *dst++ = -1.0f;
+        else
+            *dst++ = (LVM_FLOAT)Temp;
+    }
+
+
+}
+#else
 void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
                                          const LVM_INT16    *src,
@@ -66,4 +98,5 @@
 
 
 }
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
index 2daf74a..ec0baaf 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
@@ -24,7 +24,37 @@
 /**********************************************************************************
    FUNCTION LVCore_MIXHARD_2ST_D16C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance1,
+                                    LVMixer3_FLOAT_st         *ptrInstance2,
+                                    const LVM_FLOAT     *src1,
+                                    const LVM_FLOAT     *src2,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     n)
+{
+    LVM_FLOAT  Temp;
+    LVM_INT16 ii;
+    LVM_FLOAT Current1;
+    LVM_FLOAT Current2;
+    Mix_Private_FLOAT_st  *pInstance1 = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
 
+
+    Current1 = (pInstance1->Current);
+    Current2 = (pInstance2->Current);
+
+    for (ii = n; ii != 0; ii--){
+        Temp = (((LVM_FLOAT)*(src1++) * (LVM_FLOAT)Current1)) +
+               (((LVM_FLOAT)*(src2++) * (LVM_FLOAT)Current2));
+        if (Temp > 1.0f)
+            *dst++ = 1.0f;
+        else if (Temp < -1.0f)
+            *dst++ = -1.0f;
+        else
+            *dst++ = Temp;
+    }
+}
+#else
 void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_st *ptrInstance1,
                                     LVMixer3_st         *ptrInstance2,
                                     const LVM_INT16     *src1,
@@ -54,6 +84,5 @@
             *dst++ = (LVM_INT16)Temp;
     }
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
index caa0951..d2694cc 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
@@ -25,7 +25,96 @@
 /**********************************************************************************
    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT     *src,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     n)
+{
 
+    LVM_INT16   OutLoop;
+    LVM_INT16   InLoop;
+    LVM_INT32   ii,jj;
+    Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+    LVM_FLOAT   Delta = pInstance->Delta;
+    LVM_FLOAT   Current = pInstance->Current;
+    LVM_FLOAT   Target = pInstance->Target;
+    LVM_FLOAT   Temp;
+
+    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+    OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+    if(Current < Target){
+        if (OutLoop){
+            Temp = Current + Delta;
+            Current = Temp;
+            if (Current > Target)
+                Current = Target;
+
+           for (ii = OutLoop; ii != 0; ii--){
+                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = (LVM_FLOAT)Temp;
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--){
+            Temp = Current + Delta;
+            Current = Temp;
+            if (Current > Target)
+                Current = Target;
+
+            for (jj = 4; jj != 0 ; jj--){
+                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = (LVM_FLOAT)Temp;
+            }
+        }
+    }
+    else{
+        if (OutLoop){
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (ii = OutLoop; ii != 0; ii--){
+                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = (LVM_FLOAT)Temp;
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--){
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (jj = 4; jj != 0 ; jj--){
+                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
+                if (Temp > 1.0f)
+                    *dst++ = 1.0f;
+                else if (Temp < -1.0f)
+                    *dst++ = -1.0f;
+                else
+                    *dst++ = (LVM_FLOAT)Temp;
+            }
+        }
+    }
+    pInstance->Current = Current;
+}
+#else
 void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *ptrInstance,
                                     const LVM_INT16     *src,
                                           LVM_INT16     *dst,
@@ -123,6 +212,5 @@
     }
     pInstance->Current=Current;
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
index 09ec427..656a117 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
@@ -26,7 +26,127 @@
 /**********************************************************************************
    FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a,
+                                LVM_FLOAT b,
+                                LVM_FLOAT c)
+{
+    LVM_FLOAT temp;
+    temp = a + b ;
+    if (temp < -1.0f)
+        c = -1.0f;
+    else if (temp > 1.0f)
+        c = 1.0f;
+    else
+        c = temp;
+    return c;
+}
+void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st        *ptrInstance1,
+                                         LVMixer3_FLOAT_st        *ptrInstance2,
+                                         const LVM_FLOAT    *src,
+                                         LVM_FLOAT          *dst,
+                                         LVM_INT16          n)
+{
+    LVM_INT16   OutLoop;
+    LVM_INT16   InLoop;
+    LVM_INT32   ii;
+    Mix_Private_FLOAT_st  *pInstanceL = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams);
+    Mix_Private_FLOAT_st  *pInstanceR = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams);
 
+    LVM_FLOAT   DeltaL = pInstanceL->Delta;
+    LVM_FLOAT   CurrentL = pInstanceL->Current;
+    LVM_FLOAT   TargetL = pInstanceL->Target;
+
+    LVM_FLOAT   DeltaR = pInstanceR->Delta;
+    LVM_FLOAT   CurrentR = pInstanceR->Current;
+    LVM_FLOAT   TargetR = pInstanceR->Target;
+
+    LVM_FLOAT   Temp = 0;
+
+    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+    OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+    if (OutLoop)
+    {
+        if(CurrentL < TargetL)
+        {
+            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
+            CurrentL = Temp;
+            if (CurrentL > TargetL)
+                CurrentL = TargetL;
+        }
+        else
+        {
+            CurrentL -= DeltaL;
+            if (CurrentL < TargetL)
+                CurrentL = TargetL;
+        }
+
+        if(CurrentR < TargetR)
+        {
+            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
+            CurrentR = Temp;
+            if (CurrentR > TargetR)
+                CurrentR = TargetR;
+        }
+        else
+        {
+            CurrentR -= DeltaR;
+            if (CurrentR < TargetR)
+                CurrentR = TargetR;
+        }
+
+        for (ii = OutLoop * 2; ii != 0; ii -= 2)
+        {
+            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+        }
+    }
+
+    for (ii = InLoop * 2; ii != 0; ii-=2)
+    {
+        if(CurrentL < TargetL)
+        {
+            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
+            CurrentL = Temp;
+            if (CurrentL > TargetL)
+                CurrentL = TargetL;
+        }
+        else
+        {
+            CurrentL -= DeltaL;
+            if (CurrentL < TargetL)
+                CurrentL = TargetL;
+        }
+
+        if(CurrentR < TargetR)
+        {
+            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
+            CurrentR = Temp;
+            if (CurrentR > TargetR)
+                CurrentR = TargetR;
+        }
+        else
+        {
+            CurrentR -= DeltaR;
+            if (CurrentR < TargetR)
+                CurrentR = TargetR;
+        }
+
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL));
+        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR));
+    }
+    pInstanceL->Current = CurrentL;
+    pInstanceR->Current = CurrentR;
+
+}
+#else
 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
                                          const LVM_INT16    *src,
@@ -140,4 +260,5 @@
     pInstanceR->Current=CurrentR;
 
 }
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
index f1a9ca3..b5e7f5c 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
@@ -26,7 +26,86 @@
 /**********************************************************************************
    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT     *src,
+                                          LVM_FLOAT     *dst,
+                                          LVM_INT16     n)
+{
+    LVM_INT16   OutLoop;
+    LVM_INT16   InLoop;
+    LVM_INT32   ii;
+    Mix_Private_FLOAT_st  *pInstance=(Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
+    LVM_FLOAT   Delta= (LVM_FLOAT)pInstance->Delta;
+    LVM_FLOAT   Current = (LVM_FLOAT)pInstance->Current;
+    LVM_FLOAT   Target= (LVM_FLOAT)pInstance->Target;
+    LVM_FLOAT   Temp;
 
+    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
+    OutLoop = (LVM_INT16)(n - (InLoop << 2));
+
+    if(Current<Target){
+        if (OutLoop){
+
+            Temp = Current + Delta;
+            if (Temp > 1.0f)
+                Temp = 1.0f;
+            else if (Temp < -1.0f)
+                Temp = -1.0f;
+
+            Current=Temp;
+            if (Current > Target)
+                Current = Target;
+
+            for (ii = OutLoop; ii != 0; ii--){
+                *(dst++) = (((LVM_FLOAT)*(src++) * (LVM_FLOAT)Current));
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--){
+
+            Temp = Current + Delta;
+
+            if (Temp > 1.0f)
+                Temp = 1.0f;
+            else if (Temp < -1.0f)
+                Temp = -1.0f;
+
+            Current=Temp;
+            if (Current > Target)
+                Current = Target;
+
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current) );
+        }
+    }
+    else{
+        if (OutLoop){
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            for (ii = OutLoop; ii != 0; ii--){
+                *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            }
+        }
+
+        for (ii = InLoop; ii != 0; ii--){
+            Current -= Delta;
+            if (Current < Target)
+                Current = Target;
+
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+            *(dst++) = (((LVM_FLOAT)*(src++) * Current));
+        }
+    }
+    pInstance->Current=Current;
+}
+#else
 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *ptrInstance,
                                     const LVM_INT16     *src,
                                           LVM_INT16     *dst,
@@ -101,6 +180,5 @@
     }
     pInstance->Current=Current;
 }
-
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
index 0052dd7..192f126 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
@@ -33,7 +33,80 @@
 /**********************************************************************************
    FUNCTION MIXINSOFT_D16C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
+                               LVM_FLOAT             *src,
+                               LVM_FLOAT             *dst,
+                               LVM_INT16             n)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  *pInstance = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if(pInstance->Delta == 1.0f){
+            pInstance->Current = pInstance->Target;
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            LVC_Core_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing){
+        if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
+            if ((pInstance->Target) == 1.0f){
+                Add2_Sat_Float(src, dst, n);
+            }
+            else{
+                Mac3s_Sat_Float(src, (pInstance->Target), dst, n);
+                /* In case the LVCore function would have changed the Current value */
+                pInstance->Current = pInstance->Target;
+            }
+        }
+    }
+
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet){
+        if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0){
+                (*ptrInstance->MixerStream[0].pCallBack) ( \
+                                                ptrInstance->MixerStream[0].pCallbackHandle,
+                                                ptrInstance->MixerStream[0].pGeneralPurpose,
+                                                ptrInstance->MixerStream[0].CallbackParam );
+            }
+        }
+    }
+
+}
+#else
 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
                                     LVM_INT16             *src,
                                     LVM_INT16             *dst,
@@ -108,5 +181,5 @@
     }
 
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
index f443c8f..bd5a925 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
@@ -33,7 +33,138 @@
 /**********************************************************************************
    FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT             *src,
+                                    LVM_FLOAT             *dst,
+                                    LVM_INT16             n)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  *pInstance1 = \
+                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = \
+                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if ((pInstance1->Current != pInstance1->Target) || (pInstance2->Current != pInstance2->Target))
+    {
+        if(pInstance1->Delta == 1.0f)
+        {
+            pInstance1->Current = pInstance1->Target;
+            TargetGain = pInstance1->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }
+        else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+        {
+            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
+                                                         Make them equal. */
+            TargetGain = pInstance1->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }
+        else
+        {
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+        }
+
+        if(HardMixing == TRUE)
+        {
+            if(pInstance2->Delta == 1.0f)
+            {
+                pInstance2->Current = pInstance2->Target;
+                TargetGain = pInstance2->Target;
+                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
+            }
+            else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+            {
+                pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore. \
+                                                             Make them equal. */
+                TargetGain = pInstance2->Target;
+                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
+            }
+            else
+            {
+                /* Soft mixing has to be applied */
+                HardMixing = FALSE;
+            }
+        }
+
+        if(HardMixing == FALSE)
+        {
+             LVC_Core_MixSoft_1St_2i_D16C31_WRA( &(ptrInstance->MixerStream[0]),
+                                                 &(ptrInstance->MixerStream[1]),
+                                                 src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing)
+    {
+        if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f))
+        {
+            if(src != dst)
+            {
+                Copy_Float(src, dst, n);
+            }
+        }
+        else
+        {
+            LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
+                                               &(ptrInstance->MixerStream[1]),
+                                               src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet)
+    {
+        if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
+        {
+            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
+                                                         Make them equal. */
+            TargetGain = pInstance1->Target;
+            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0)
+            {
+                (*ptrInstance->MixerStream[0].pCallBack) ( \
+                                                ptrInstance->MixerStream[0].pCallbackHandle,
+                                                ptrInstance->MixerStream[0].pGeneralPurpose,
+                                                ptrInstance->MixerStream[0].CallbackParam );
+            }
+        }
+    }
+    if (ptrInstance->MixerStream[1].CallbackSet)
+    {
+        if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
+        {
+            pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
+                                                         Make them equal. */
+            TargetGain = pInstance2->Target;
+            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
+            ptrInstance->MixerStream[1].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[1].pCallBack != 0)
+            {
+                (*ptrInstance->MixerStream[1].pCallBack) (
+                                                ptrInstance->MixerStream[1].pCallbackHandle,
+                                                ptrInstance->MixerStream[1].pGeneralPurpose,
+                                                ptrInstance->MixerStream[1].CallbackParam );
+            }
+        }
+    }
+}
+#else
 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
                                   const LVM_INT16             *src,
                                         LVM_INT16             *dst,
@@ -148,5 +279,5 @@
         }
     }
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
index c8dcad7..1017de3 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
@@ -33,7 +33,77 @@
 /**********************************************************************************
    FUNCTION LVMixer3_MIXSOFT_1ST_D16C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
+                                  const LVM_FLOAT             *src,
+                                        LVM_FLOAT             *dst,
+                                        LVM_INT16             n)
+{
+    char        HardMixing = TRUE;
+    LVM_FLOAT   TargetGain;
+    Mix_Private_FLOAT_st  *pInstance = \
+                          (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if(pInstance->Delta == 1.0f){
+            pInstance->Current = pInstance->Target;
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            LVC_Core_MixSoft_1St_D16C31_WRA(&(ptrInstance->MixerStream[0]), src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing){
+        if (pInstance->Target == 0)
+            LoadConst_Float(0.0, dst, n);
+        else {
+            if ((pInstance->Target) != 1.0f)
+                Mult3s_Float(src, (pInstance->Target), dst, n);
+            else if(src != dst)
+                Copy_Float(src, dst, n);
+        }
+
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (ptrInstance->MixerStream[0].CallbackSet){
+        if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            TargetGain = pInstance->Target;
+            LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
+            ptrInstance->MixerStream[0].CallbackSet = FALSE;
+            if (ptrInstance->MixerStream[0].pCallBack != 0){
+                (*ptrInstance->MixerStream[0].pCallBack) ( \
+                                                ptrInstance->MixerStream[0].pCallbackHandle,
+                                                ptrInstance->MixerStream[0].pGeneralPurpose,
+                                                ptrInstance->MixerStream[0].CallbackParam );
+            }
+        }
+    }
+}
+#else
 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
                                   const LVM_INT16             *src,
                                         LVM_INT16             *dst,
@@ -107,5 +177,5 @@
         }
     }
 }
-
+#endif/*BUILD_FLOAT*/
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
index 7240705..3c90071 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
@@ -25,7 +25,49 @@
 /**********************************************************************************
    FUNCTION LVC_MixSoft_2St_D16C31_SAT.c
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
+                                 const   LVM_FLOAT       *src1,
+                                 LVM_FLOAT       *src2,
+                                 LVM_FLOAT       *dst,
+                                 LVM_INT16       n)
+{
+    Mix_Private_FLOAT_st  *pInstance1 = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
+    Mix_Private_FLOAT_st  *pInstance2 = \
+                             (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if ((pInstance1->Current == pInstance1->Target) && (pInstance1->Current == 0)){
+        LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+                                    src2, dst, n);
+    }
+    else if ((pInstance2->Current == pInstance2->Target) && (pInstance2->Current == 0)){
+        LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+                                    src1, dst, n);
+    }
+    else if ((pInstance1->Current != pInstance1->Target) || \
+                                    (pInstance2->Current != pInstance2->Target))
+    {
+        LVC_MixSoft_1St_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[0]),
+                                   src1, dst, n);
+        LVC_MixInSoft_D16C31_SAT((LVMixer3_1St_FLOAT_st *)(&ptrInstance->MixerStream[1]),
+                                  src2, dst, n);
+    }
+    else{
+        /******************************************************************************
+           HARD MIXING
+        *******************************************************************************/
+        LVC_Core_MixHard_2St_D16C31_SAT( &ptrInstance->MixerStream[0],
+                                         &ptrInstance->MixerStream[1],
+                                         src1, src2, dst, n);
+    }
+}
+#else
 void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
                                     const   LVM_INT16       *src1,
                                             LVM_INT16       *src2,
@@ -66,5 +108,5 @@
             LVC_Core_MixHard_2St_D16C31_SAT( &ptrInstance->MixerStream[0], &ptrInstance->MixerStream[1], src1, src2, dst, n);
     }
 }
-
+#endif /*BUILD_FLOAT*/
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index 980c783..f904915 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -31,6 +31,19 @@
 ***********************************************************************************/
 
 /* LVMixer3_st structure stores Instance parameters for one audio stream */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT       PrivateParams[3];   /* Private Instance params for \
+                                           Audio Stream shift parameter */
+    LVM_INT16       CallbackSet;        /* Boolean.  Should be set by calling application \
+                                           each time the target value is updated */
+    LVM_INT16       CallbackParam;      /* Parameter that will be used in the calback function */
+    void            *pCallbackHandle;   /* Pointer to the instance of the callback function */
+    void            *pGeneralPurpose;   /* Pointer for general purpose usage */
+    LVM_Callback    pCallBack;          /* Pointer to the callback function */
+} LVMixer3_FLOAT_st;
+#else
 typedef struct
 {
     LVM_INT32       PrivateParams[4];   /* Private Instance params for Audio Stream */
@@ -40,22 +53,35 @@
     void            *pGeneralPurpose;   /* Pointer for general purpose usage */
     LVM_Callback    pCallBack;          /* Pointer to the callback function */
 } LVMixer3_st;
-
+#endif
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVMixer3_FLOAT_st     MixerStream[1];    /* Instance Params for one Audio Stream */
+} LVMixer3_1St_FLOAT_st;
+#else
 typedef struct
 {
     LVMixer3_st     MixerStream[1];    /* Instance Params for one Audio Stream */
 } LVMixer3_1St_st;
-
+#endif
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVMixer3_FLOAT_st     MixerStream[2];    /* Instance Params for two Audio Streams */
+} LVMixer3_2St_FLOAT_st;
+#else
 typedef struct
 {
     LVMixer3_st     MixerStream[2];    /* Instance Params for two Audio Streams */
 } LVMixer3_2St_st;
-
+#endif
+#ifndef BUILD_FLOAT
 typedef struct
 {
     LVMixer3_st     MixerStream[3];    /* Instance Params for three Audio Streams */
 } LVMixer3_3St_st;
-
+#endif
 /**********************************************************************************
    FUNCTION PROTOTYPES (HIGH LEVEL FUNCTIONS)
 ***********************************************************************************/
@@ -75,57 +101,115 @@
 /* then the calculation will give an incorrect value for alpha, see the mixer     */
 /* documentation for further details.                                             */
 /* ********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTarget( LVMixer3_FLOAT_st *pStream,
+                          LVM_FLOAT        TargetGain);
+#else
 void LVC_Mixer_SetTarget( LVMixer3_st *pStream,
                                 LVM_INT32           TargetGain);
-
+#endif
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetTarget( LVMixer3_FLOAT_st *pStream);
+#else
 LVM_INT32 LVC_Mixer_GetTarget( LVMixer3_st *pStream);
+#endif
 
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetCurrent( LVMixer3_FLOAT_st *pStream);
+#else
 LVM_INT32 LVC_Mixer_GetCurrent( LVMixer3_st *pStream);
+#endif
 
+#ifdef BUILD_FLOAT
+void LVC_Mixer_Init( LVMixer3_FLOAT_st *pStream,
+                     LVM_FLOAT           TargetGain,
+                     LVM_FLOAT           CurrentGain);
+#else
 void LVC_Mixer_Init( LVMixer3_st *pStream,
                                 LVM_INT32           TargetGain,
                                 LVM_INT32           CurrentGain);
+#endif
 
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+                                LVM_INT32           Tc_millisec,
+                                LVM_Fs_en           Fs,
+                                LVM_INT16           NumChannels);
+#else
 void LVC_Mixer_SetTimeConstant( LVMixer3_st *pStream,
                                 LVM_INT32           Tc_millisec,
                                 LVM_Fs_en           Fs,
                                 LVM_INT16           NumChannels);
+#endif
 
+#ifdef BUILD_FLOAT
+void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+                                         LVM_INT32           Tc_millisec,
+                                         LVM_Fs_en           Fs,
+                                         LVM_INT16           NumChannels);
+#else
 void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_st *pStream,
                                         LVM_INT32           Tc_millisec,
                                         LVM_Fs_en           Fs,
                                         LVM_INT16           NumChannels);
+#endif
 
 /*** 16 bit functions *************************************************************/
 
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
+                                 const LVM_FLOAT           *src,
+                                 LVM_FLOAT           *dst,
+                                 LVM_INT16           n);
+#else
 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *pInstance,
                                   const LVM_INT16           *src,
                                         LVM_INT16           *dst,
                                         LVM_INT16           n);
+#endif
 
+#ifdef BUILD_FLOAT
+void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *pInstance,
+                               LVM_FLOAT           *src,
+                               LVM_FLOAT           *dst,
+                               LVM_INT16           n);
+#else
 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *pInstance,
                                         LVM_INT16           *src,
                                         LVM_INT16           *dst,
                                         LVM_INT16           n);
+#endif
 
+#ifdef BUILD_FLOAT
+void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_FLOAT_st *pInstance,
+                                 const LVM_FLOAT             *src1,
+                                 LVM_FLOAT             *src2,
+                                 LVM_FLOAT             *dst,  /* dst cannot be equal to src2 */
+                                 LVM_INT16             n);
+#else
 void LVC_MixSoft_2St_D16C31_SAT( LVMixer3_2St_st *pInstance,
                                 const LVM_INT16             *src1,
                                       LVM_INT16             *src2,
                                       LVM_INT16             *dst,  /* dst cannot be equal to src2 */
                                       LVM_INT16             n);
-
+#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 BUILD_FLOAT
+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 */
+                                    LVM_INT16           n);     /* Number of stereo samples */
+#else
 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st         *pInstance,
                                 const   LVM_INT16           *src,
                                         LVM_INT16           *dst,   /* dst can be equal to src */
                                         LVM_INT16           n);     /* Number of stereo samples */
-
-
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
index b5ae264..5990412 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
@@ -31,7 +31,15 @@
 /*  CurrentGain      - CurrentGain value in Q 16.15 format              */
 /*                                                                      */
 /************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetCurrent( LVMixer3_FLOAT_st *pStream)
+{
+    LVM_FLOAT       CurrentGain;
+    Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    CurrentGain = pInstance->Current;  // CurrentGain
+    return CurrentGain;
+}
+#else
 LVM_INT32 LVC_Mixer_GetCurrent( LVMixer3_st *pStream)
 {
     LVM_INT32       CurrentGain;
@@ -39,3 +47,4 @@
     CurrentGain=pInstance->Current>>(16-pInstance->Shift);  // CurrentGain in Q16.15 format
     return CurrentGain;
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
index dc2f8e9..c67455a 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
@@ -30,7 +30,16 @@
 /*  TargetGain      - TargetGain value in Q 16.15 format                */
 /*                                                                      */
 /************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVC_Mixer_GetTarget( LVMixer3_FLOAT_st *pStream)
+{
+    LVM_FLOAT       TargetGain;
+    Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    
+    TargetGain = pInstance->Target;  // TargetGain
+    return TargetGain;
+}
+#else
 LVM_INT32 LVC_Mixer_GetTarget( LVMixer3_st *pStream)
 {
     LVM_INT32       TargetGain;
@@ -40,3 +49,4 @@
 
     return TargetGain;
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
index 449e7b1..737e26b 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
@@ -44,7 +44,19 @@
 /*  void                                                                */
 /*                                                                      */
 /************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Mixer_Init( LVMixer3_FLOAT_st *pStream,
+                     LVM_FLOAT           TargetGain,
+                     LVM_FLOAT           CurrentGain)
+{
+    LVM_FLOAT MaxGain = TargetGain;
+    Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    if(CurrentGain > MaxGain)
+        MaxGain = CurrentGain;
+    pInstance->Target = TargetGain;   // Update fractional gain Target
+    pInstance->Current = CurrentGain; // Update fractional gain Current
+}
+#else
 void LVC_Mixer_Init( LVMixer3_st *pStream,
                     LVM_INT32           TargetGain,
                     LVM_INT32           CurrentGain)
@@ -64,4 +76,4 @@
     pInstance->Current=CurrentGain<<(16-Shift); // Update fractional gain Current
     pInstance->Shift=Shift;                     // Update Shift
 }
-
+#endif
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 294e05c..d0d0e1f 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -26,6 +26,15 @@
 #include "VectorArithmetic.h"
 
 /* Instance parameter structure */
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    /* General */
+    LVM_FLOAT                       Target;           /*number specifying value of Target Gain */
+    LVM_FLOAT                       Current;          /*number specifying value of Current Gain */
+    LVM_FLOAT                       Delta;            /*number specifying value of Delta Gain */
+} Mix_Private_FLOAT_st;
+#else
 typedef struct
 {
     /* General */
@@ -34,8 +43,7 @@
     LVM_INT32                       Shift;                  /* Left Shift for Integer part of Gain */
     LVM_INT32                       Delta;                  /* 32 bit number specifying the fractional value of Delta Gain */
 } Mix_Private_st;
-
-
+#endif
 
 /**********************************************************************************
    DEFINITIONS
@@ -49,23 +57,43 @@
 ***********************************************************************************/
 
 /*** 16 bit functions *************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
+                                    const LVM_FLOAT     *src,
+                                    LVM_FLOAT     *dst,
+                                    LVM_INT16     n);
+#else
 void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *pInstance,
                                     const LVM_INT16     *src,
                                           LVM_INT16     *dst,
                                           LVM_INT16     n);
-
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance,
+                                      const LVM_FLOAT     *src,
+                                      LVM_FLOAT     *dst,
+                                      LVM_INT16     n);
+#else
 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *pInstance,
                                     const LVM_INT16     *src,
                                           LVM_INT16     *dst,
                                           LVM_INT16     n);
-
+#endif
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_FLOAT_st *pInstance1,
+                                      LVMixer3_FLOAT_st         *pInstance2,
+                                      const LVM_FLOAT     *src1,
+                                      const LVM_FLOAT     *src2,
+                                      LVM_FLOAT     *dst,
+                                      LVM_INT16     n);
+#else
 void LVC_Core_MixHard_2St_D16C31_SAT( LVMixer3_st *pInstance1,
                                     LVMixer3_st         *pInstance2,
                                     const LVM_INT16     *src1,
                                     const LVM_INT16     *src2,
                                           LVM_INT16     *dst,
                                           LVM_INT16     n);
+#endif
 
 /**********************************************************************************/
 /* For applying different gains to Left and right chennals                        */
@@ -73,12 +101,19 @@
 /* ptrInstance2 applies to Right channel                                          */
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st        *ptrInstance1,
+                                         LVMixer3_FLOAT_st        *ptrInstance2,
+                                         const LVM_FLOAT    *src,
+                                         LVM_FLOAT          *dst,
+                                         LVM_INT16          n);
+#else
 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
                                          const LVM_INT16    *src,
                                          LVM_INT16          *dst,   /* dst can be equal to src */
                                          LVM_INT16          n);     /* Number of stereo samples */
+#endif
 
 /**********************************************************************************/
 /* For applying different gains to Left and right chennals                        */
@@ -86,16 +121,22 @@
 /* ptrInstance2 applies to Right channel                                          */
 /* Gain values should not be more that 1.0                                        */
 /**********************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_FLOAT_st        *ptrInstance1,
+                                         LVMixer3_FLOAT_st        *ptrInstance2,
+                                         const LVM_FLOAT    *src,
+                                         LVM_FLOAT          *dst,
+                                         LVM_INT16          n);
+#else
 void LVC_Core_MixHard_1St_2i_D16C31_SAT( LVMixer3_st        *ptrInstance1,
                                          LVMixer3_st        *ptrInstance2,
                                          const LVM_INT16    *src,
                                          LVM_INT16          *dst,    /* dst can be equal to src */
                                          LVM_INT16          n);      /* Number of stereo samples */
-
-
+#endif
 
 /*** 32 bit functions *************************************************************/
-
+#ifndef BUILD_FLOAT
 void LVC_Core_MixInSoft_D32C31_SAT( LVMixer3_st *pInstance,
                                     const LVM_INT32     *src,
                                           LVM_INT32     *dst,
@@ -112,7 +153,7 @@
                                     const LVM_INT32     *src2,
                                           LVM_INT32     *dst,
                                           LVM_INT16     n);
-
+#endif
 /**********************************************************************************/
 
 #endif //#ifndef __LVC_MIXER_PRIVATE_H__
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
index 5efa501..577179d 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
@@ -43,7 +43,14 @@
 /*  void                                                                */
 /*                                                                      */
 /************************************************************************/
-
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTarget(LVMixer3_FLOAT_st *pStream,
+                         LVM_FLOAT         TargetGain)
+{
+    Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    pInstance->Target = TargetGain;               // Update gain Target
+}
+#else
 void LVC_Mixer_SetTarget(LVMixer3_st *pStream,
                         LVM_INT32           TargetGain)
 {
@@ -64,3 +71,4 @@
     pInstance->Current=CurrentGain<<(16-Shift);             // Update fractional gain Current
     pInstance->Shift=Shift;                                 // Update Shift
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
index 4c1c8b2..48f5d54 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
@@ -44,7 +44,51 @@
 /* RETURNS:                                                             */
 /*  void                                                                */
 /************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_SetTimeConstant(LVMixer3_FLOAT_st *pStream,
+                               LVM_INT32           Tc_millisec,
+                               LVM_Fs_en           Fs,
+                               LVM_INT16           NumChannels)
+{
+#ifdef HIGHER_FS
+    LVM_FLOAT   DeltaTable[11] = {0.500000f,/*8000*/
+                                  0.362812f,/*11025*/
+                                  0.333333f,/*12000*/
+                                  0.250000f,/*16000*/
+                                  0.181406f,/*22050*/
+                                  0.166666f,/*24000*/
+                                  0.125000f,/*32000*/
+                                  0.090703f,/*44100*/
+                                  0.083333f,/*48000*/
+                                  0.041667f,/*96000*/
+                                  0.020833f};/*192000*/
+#else
+    LVM_FLOAT   DeltaTable[9] = {0.500000f,/*8000*/
+                                 0.362812f,/*11025*/
+                                 0.333333f,/*12000*/
+                                 0.250000f,/*16000*/
+                                 0.181406f,/*22050*/
+                                 0.166666f,/*24000*/
+                                 0.125000f,/*32000*/
+                                 0.090703f,/*44100*/
+                                 0.083333f};/*48000*/
+#endif
 
+    Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    LVM_FLOAT Delta = DeltaTable[Fs];
+    Delta = Delta / (NumChannels);
+
+    if(Tc_millisec == 0)
+        Delta = 1.000000f;
+    else
+        Delta = Delta / Tc_millisec;
+
+    if(Delta == 0)
+        Delta = 0.0000000005f;  /* If Time Constant is so large that Delta is 0, \
+                                  assign minimum value to Delta */
+    pInstance->Delta = Delta;  // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec)
+}
+#else
 void LVC_Mixer_SetTimeConstant(LVMixer3_st *pStream,
                             LVM_INT32           Tc_millisec,
                             LVM_Fs_en           Fs,
@@ -73,3 +117,4 @@
 
     pInstance->Delta=Delta;     // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec) in Q 0.31 format
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
index 8d5304e..9dc7d21 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
@@ -45,7 +45,72 @@
 /* RETURNS:                                                             */
 /*  void                                                                */
 /************************************************************************/
+#ifdef BUILD_FLOAT
+void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_FLOAT_st *pStream,
+                                         LVM_INT32           Tc_millisec,
+                                         LVM_Fs_en           Fs,
+                                         LVM_INT16           NumChannels)
+{
+#ifdef HIGHER_FS
+     LVM_FLOAT   DeltaTable[11] = {0.500000f,/*8000*/
+                                   0.362812f,/*11025*/
+                                   0.333333f,/*12000*/
+                                   0.250000f,/*16000*/
+                                   0.181406f,/*22050*/
+                                   0.166666f,/*24000*/
+                                   0.125000f,/*32000*/
+                                   0.090703f,/*44100*/
+                                   0.083333f,/*48000*/
+                                   0.041666f,/*96000*/
+                                   0.020833f};/*192000*/
+#else
+    LVM_FLOAT   DeltaTable[9] = {0.500000f,/*8000*/
+                                 0.362812f,/*11025*/
+                                 0.333333f,/*12000*/
+                                 0.250000f,/*16000*/
+                                 0.181406f,/*22050*/
+                                 0.166666f,/*24000*/
+                                 0.125000f,/*32000*/
+                                 0.090703f,/*44100*/
+                                 0.083333f};/*48000*/
+#endif
+    LVM_FLOAT Tc_millisec_float;
+    Mix_Private_FLOAT_st *pInstance = (Mix_Private_FLOAT_st *)pStream->PrivateParams;
+    LVM_FLOAT Delta = DeltaTable[Fs];
 
+    LVM_FLOAT   Current;
+    LVM_FLOAT   Target;
+
+    Delta=Delta / (NumChannels);
+
+    /*  Get gain values  */
+    Current = pInstance->Current;
+    Target = pInstance->Target;
+
+    if (Current != Target)
+    {
+        Tc_millisec_float = (LVM_FLOAT)(Tc_millisec) / (Current - Target);
+        if (Tc_millisec_float < 0)
+            Tc_millisec_float = -Tc_millisec_float;
+
+        if(Tc_millisec == 0)
+            Delta = 1.000000f;
+        else
+            Delta = Delta / Tc_millisec_float;
+
+        if(Delta == 0)
+            Delta = 0.0000000005f; /* If Time Constant is so large that Delta is 0, \
+                                      assign minimum value to Delta */
+    }
+    else
+    {
+        Delta = 0.0000000005f;  /* Minimum value for proper call-backs \
+                             (setting it to zero has some problems, to be corrected) */
+    }
+
+    pInstance->Delta = Delta;     // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec)
+}
+#else
 void LVC_Mixer_VarSlope_SetTimeConstant( LVMixer3_st *pStream,
                                         LVM_INT32           Tc_millisec,
                                         LVM_Fs_en           Fs,
@@ -93,3 +158,4 @@
 
     pInstance->Delta=Delta;     // Delta=(2147483647*4*1000)/(NumChannels*SampleRate*Tc_millisec) in Q 0.31 format
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
index 6d8fe46..9094622 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
@@ -53,7 +53,7 @@
 /*   A9             194669577                                              */
 /*   A10            8                                                      */
 /*                                                                         */
-/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1                  */
+/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1                  */
 /*                                                                         */
 /*                                                                         */
 /* PARAMETERS:                                                             */
@@ -68,7 +68,36 @@
 /* RETURNS:                                                                */
 /*                                                                         */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_FO_HPF(   LVM_FLOAT       w,
+                        FO_FLOAT_Coefs_t  *pCoeffs)
+{
+    LVM_FLOAT Y,Coefficients[13] = {-0.999996f,
+                                    0.999801f,
+                                    -0.497824f,
+                                    0.322937f,
+                                    -0.180880f,
+                                    0.087658f,
+                                    -0.032102f,
+                                    0.008163f,
+                                    -0.001252f,
+                                    0.000089f,
+                                    0,
+                                    0,
+                                    0};
+    Y=LVM_Polynomial((LVM_UINT16)9, Coefficients, w);
 
+    pCoeffs->B1 = -Y;         /* Store -B1 in filter structure instead of B1!*/
+                            /* A0=(1-B1)/2= B1/2 - 0.5*/
+    Y = Y / 2.0f;                 /* A0=Y=B1/2*/
+    Y = Y - 0.5f;         /* A0=Y=(B1/2 - 0.5)*/
+
+    pCoeffs->A0 = Y * FILTER_LOSS_FLOAT;                  /* Apply loss to avoid overflow*/
+    pCoeffs->A1 = -pCoeffs->A0;                           /* Store A1=-A0*/
+
+    return 1;
+}
+#else
 LVM_INT32 LVM_FO_HPF(   LVM_INT32       w,
                         FO_C32_Coefs_t  *pCoeffs)
 {
@@ -97,4 +126,4 @@
 
     return 1;
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
index 86ec951..9fe67f8 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
@@ -53,7 +53,7 @@
 /*   A9             194669577                                              */
 /*   A10            8                                                      */
 /*                                                                         */
-/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1                  */
+/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1                  */
 /*                                                                         */
 /*                                                                         */
 /* PARAMETERS:                                                             */
@@ -68,7 +68,33 @@
 /* RETURNS:                                                                */
 /*                                                                         */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_FO_LPF(   LVM_FLOAT       w,
+                        FO_FLOAT_Coefs_t  *pCoeffs)
+{
+    LVM_FLOAT Y,Coefficients[13] = {-0.999996f,
+                                    0.999801f,
+                                    -0.497824f,
+                                    0.322937f,
+                                    -0.180880f,
+                                    0.087658f,
+                                    -0.032102f,
+                                    0.008163f,
+                                    -0.001252f,
+                                    0.000089f,
+                                    0};
+    Y=LVM_Polynomial((LVM_UINT16)9, Coefficients, w);
+    pCoeffs->B1 = -Y;     // Store -B1 in filter structure instead of B1!
+                        // A0=(1+B1)/2= B1/2 + 0.5
+    Y = Y / 2.0f;             // A0=Y=B1/2
+    Y = Y + 0.5f;     // A0=Y=(B1/2 + 0.5)
 
+    pCoeffs->A0 = Y * FILTER_LOSS_FLOAT;
+    pCoeffs->A1 = pCoeffs->A0;
+
+    return 1;
+}
+#else
 LVM_INT32 LVM_FO_LPF(   LVM_INT32       w,
                         FO_C32_Coefs_t  *pCoeffs)
 {
@@ -94,4 +120,4 @@
     pCoeffs->A1=pCoeffs->A0;
     return 1;
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
index f3b9b3c..7846ca0 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
@@ -32,16 +32,45 @@
 #define LVVDL_2PiByFs_SHIFT1    12          /* Qformat shift for 8kHz, 11.025kHz and 12kHz i.e. 12=41-29 */
 #define LVVDL_2PiByFs_SHIFT2    13          /* Qformat shift for 16kHz, 22.050kHz and 24kHz i.e. 13=42-29 */
 #define LVVDL_2PiByFs_SHIFT3    14          /* Qformat shift for 32kHz, 44.1kHz and 48kHz i.e. 14=43-29 */
-
+#ifndef BUILD_FLOAT
 const LVM_INT32     LVVDL_2PiOnFsTable[] =  {LVVDL_2PiBy_8000 , /* 8kHz in Q41, 16kHz in Q42, 32kHz in Q43 */
                                             LVVDL_2PiBy_11025,  /* 11025 Hz in Q41, 22050Hz in Q42, 44100 Hz in Q43*/
                                             LVVDL_2PiBy_12000}; /* 12kHz in Q41, 24kHz in Q42, 48kHz in Q43 */
-
+#endif
 
 const LVM_INT32     LVVDL_2PiOnFsShiftTable[]={LVVDL_2PiByFs_SHIFT1 ,         /* 8kHz, 11025Hz, 12kHz */
                                                LVVDL_2PiByFs_SHIFT2,          /* 16kHz, 22050Hz, 24kHz*/
                                                LVVDL_2PiByFs_SHIFT3};         /* 32kHz, 44100Hz, 48kHz */
+#ifdef BUILD_FLOAT
+#define LVVDL_2PiBy_8000_f        0.000785398f
+#define LVVDL_2PiBy_11025_f       0.000569903f
+#define LVVDL_2PiBy_12000_f       0.000523599f
+#define LVVDL_2PiBy_16000_f       0.000392700f
+#define LVVDL_2PiBy_22050_f       0.000284952f
+#define LVVDL_2PiBy_24000_f       0.000261800f
+#define LVVDL_2PiBy_32000_f       0.000196350f
+#define LVVDL_2PiBy_44100_f       0.000142476f
+#define LVVDL_2PiBy_48000_f       0.000130900f
 
+#ifdef HIGHER_FS
+#define LVVDL_2PiBy_96000_f       0.000065450f
+#define LVVDL_2PiBy_192000_f      0.000032725f
+#endif
+const LVM_FLOAT     LVVDL_2PiOnFsTable[] =  {LVVDL_2PiBy_8000_f,
+                                             LVVDL_2PiBy_11025_f,
+                                             LVVDL_2PiBy_12000_f,
+                                             LVVDL_2PiBy_16000_f,
+                                             LVVDL_2PiBy_22050_f,
+                                             LVVDL_2PiBy_24000_f,
+                                             LVVDL_2PiBy_32000_f,
+                                             LVVDL_2PiBy_44100_f,
+                                             LVVDL_2PiBy_48000_f
+#ifdef HIGHER_FS
+                                            ,LVVDL_2PiBy_96000_f
+                                            ,LVVDL_2PiBy_192000_f
+#endif
+                                           };
+#endif
 /*-------------------------------------------------------------------------*/
 /* FUNCTION:                                                               */
 /*   LVM_GetOmega                                                          */
@@ -59,7 +88,20 @@
 /* RETURNS:                                                                */
 /*   w=2*pi*Fc/Fs in Q2.29 format                                          */
 /*-------------------------------------------------------------------------*/
-
+#ifdef BUILD_FLOAT
+#ifdef HIGHER_FS
+LVM_FLOAT LVM_GetOmega(LVM_UINT32                  Fc,
+                       LVM_Fs_en                   Fs)
+#else
+LVM_FLOAT LVM_GetOmega(LVM_UINT16                  Fc,
+                       LVM_Fs_en                   Fs)
+#endif
+{
+    LVM_FLOAT   w;
+    w = (LVM_FLOAT)Fc * LVVDL_2PiOnFsTable[Fs];
+    return w;
+}
+#else
 LVM_INT32 LVM_GetOmega(LVM_UINT16                  Fc,
                        LVM_Fs_en                   Fs)
 {
@@ -67,4 +109,4 @@
     MUL32x32INTO32((LVM_INT32)Fc,LVVDL_2PiOnFsTable[Fs%3],w,LVVDL_2PiOnFsShiftTable[Fs/3])
     return w;
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
index 6846d49..f1e45fa 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
@@ -87,5 +87,58 @@
 #define ALPHA_49                                0      /* Floating point Alpha = 0.000000 */
 #define ALPHA_50                                0      /* Floating point Alpha = 0.000000 */
 
+#ifdef BUILD_FLOAT /* BUILD_FLOAT */
+#define ALPHA_Float_0                        0.999999f
+#define ALPHA_Float_1                        0.999998f
+#define ALPHA_Float_2                        0.999997f
+#define ALPHA_Float_3                        0.999996f
+#define ALPHA_Float_4                        0.999995f
+#define ALPHA_Float_5                        0.999992f
+#define ALPHA_Float_6                        0.999989f
+#define ALPHA_Float_7                        0.999985f
+#define ALPHA_Float_8                        0.999979f
+#define ALPHA_Float_9                        0.999970f
+#define ALPHA_Float_10                       0.999957f
+#define ALPHA_Float_11                       0.999939f
+#define ALPHA_Float_12                       0.999914f
+#define ALPHA_Float_13                       0.999879f
+#define ALPHA_Float_14                       0.999829f
+#define ALPHA_Float_15                       0.999758f
+#define ALPHA_Float_16                       0.999658f
+#define ALPHA_Float_17                       0.999516f
+#define ALPHA_Float_18                       0.999316f
+#define ALPHA_Float_19                       0.999033f
+#define ALPHA_Float_20                       0.998633f
+#define ALPHA_Float_21                       0.998067f
+#define ALPHA_Float_22                       0.997268f
+#define ALPHA_Float_23                       0.996139f
+#define ALPHA_Float_24                       0.994545f
+#define ALPHA_Float_25                       0.992295f
+#define ALPHA_Float_26                       0.989123f
+#define ALPHA_Float_27                       0.984654f
+#define ALPHA_Float_28                       0.978370f
+#define ALPHA_Float_29                       0.969553f
+#define ALPHA_Float_30                       0.957221f
+#define ALPHA_Float_31                       0.940051f
+#define ALPHA_Float_32                       0.916297f
+#define ALPHA_Float_33                       0.883729f
+#define ALPHA_Float_34                       0.839645f
+#define ALPHA_Float_35                       0.781036f
+#define ALPHA_Float_36                       0.705078f
+#define ALPHA_Float_37                       0.610108f
+#define ALPHA_Float_38                       0.497239f
+#define ALPHA_Float_39                       0.372343f
+#define ALPHA_Float_40                       0.247351f
+#define ALPHA_Float_41                       0.138722f
+#define ALPHA_Float_42                       0.061234f
+#define ALPHA_Float_43                       0.019267f
+#define ALPHA_Float_44                       0.003756f
+#define ALPHA_Float_45                       0.000372f
+#define ALPHA_Float_46                       0.000014f
+#define ALPHA_Float_47                       0.000000f
+#define ALPHA_Float_48                       0.000000f
+#define ALPHA_Float_49                       0.000000f
+#define ALPHA_Float_50                       0.000000f
+#endif
 
 #endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
index 809d904..18b2782 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
@@ -57,7 +57,110 @@
 /*  Alpha   - the filter coefficient Q31 format                         */
 /*                                                                      */
 /************************************************************************/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Mixer_TimeConstant(LVM_UINT32   tc,
+#ifdef HIGHER_FS
+                                  LVM_UINT32   Fs,
+#else
+                                  LVM_UINT16   Fs,
+#endif
+                                  LVM_UINT16   NumChannels)
+{
 
+    LVM_UINT32  Product;
+    LVM_FLOAT  ProductFloat;
+    LVM_INT16   InterpolateShort;
+    LVM_FLOAT   Interpolate;
+    LVM_UINT16  Shift;
+    LVM_FLOAT   Diff;
+    LVM_FLOAT  Table[] = {ALPHA_Float_0,             /* Log spaced look-up table */
+                          ALPHA_Float_1,
+                          ALPHA_Float_2,
+                          ALPHA_Float_3,
+                          ALPHA_Float_4,
+                          ALPHA_Float_5,
+                          ALPHA_Float_6,
+                          ALPHA_Float_7,
+                          ALPHA_Float_8,
+                          ALPHA_Float_9,
+                          ALPHA_Float_10,
+                          ALPHA_Float_11,
+                          ALPHA_Float_12,
+                          ALPHA_Float_13,
+                          ALPHA_Float_14,
+                          ALPHA_Float_15,
+                          ALPHA_Float_16,
+                          ALPHA_Float_17,
+                          ALPHA_Float_18,
+                          ALPHA_Float_19,
+                          ALPHA_Float_20,
+                          ALPHA_Float_21,
+                          ALPHA_Float_22,
+                          ALPHA_Float_23,
+                          ALPHA_Float_24,
+                          ALPHA_Float_25,
+                          ALPHA_Float_26,
+                          ALPHA_Float_27,
+                          ALPHA_Float_28,
+                          ALPHA_Float_29,
+                          ALPHA_Float_30,
+                          ALPHA_Float_31,
+                          ALPHA_Float_32,
+                          ALPHA_Float_33,
+                          ALPHA_Float_34,
+                          ALPHA_Float_35,
+                          ALPHA_Float_36,
+                          ALPHA_Float_37,
+                          ALPHA_Float_38,
+                          ALPHA_Float_39,
+                          ALPHA_Float_40,
+                          ALPHA_Float_41,
+                          ALPHA_Float_42,
+                          ALPHA_Float_43,
+                          ALPHA_Float_44,
+                          ALPHA_Float_45,
+                          ALPHA_Float_46,
+                          ALPHA_Float_47,
+                          ALPHA_Float_48,
+                          ALPHA_Float_49,
+                          ALPHA_Float_50};
+
+    /* Calculate the product of the time constant and the sample rate */
+    Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13;  /* Stereo value */
+    Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3);
+
+    if (NumChannels == 1)
+    {
+        Product = Product >> 1;   /* Mono value */
+    }
+
+    /* Normalize to get the table index and interpolation factor */
+    for (Shift = 0; Shift < ((Alpha_TableSize - 1) / 2); Shift++)
+    {
+        if ((Product & 0x80000000) != 0)
+        {
+            break;
+        }
+
+        Product = Product << 1;
+    }
+    Shift = (LVM_UINT16)((Shift << 1));
+
+    if ((Product & 0x40000000)==0)
+    {
+        Shift++;
+    }
+
+    InterpolateShort = (LVM_INT16)((Product >> 15) & 0x00007FFF);
+    Interpolate = (LVM_FLOAT)InterpolateShort / 32768.0f;
+
+    Diff = (Table[Shift] - Table[Shift + 1]);
+    Diff = Diff * Interpolate;
+    ProductFloat = Table[Shift + 1] + Diff;
+
+    return ProductFloat;
+}
+#else
 LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32   tc,
                                   LVM_UINT16   Fs,
                                   LVM_UINT16   NumChannels)
@@ -154,3 +257,4 @@
 
     return Product;
 }
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
index a6d7db2..cd57767 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
@@ -25,7 +25,7 @@
 /*                                                                         */
 /* DESCRIPTION:                                                            */
 /*   This function performs polynomial expansion                           */
-/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1                  */
+/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1                  */
 /*                                                                         */
 /*  LVM_INT32 LVM_Polynomial(LVM_UINT16    N,                              */
 /*                           LVM_INT32    *pCoefficients,                  */
@@ -40,7 +40,48 @@
 /* RETURNS:                                                                */
 /*   The result of the polynomial expansion in Q1.31 format                */
 /*-------------------------------------------------------------------------*/
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Polynomial(LVM_UINT16    N,
+                         LVM_FLOAT    *pCoefficients,
+                         LVM_FLOAT    X)
+{
+    LVM_INT32 i;
+    LVM_FLOAT Y,A,XTemp,Temp,sign;
 
+    Y = *pCoefficients; /* Y=A0*/
+    pCoefficients++;
+
+    if(X == -1.0f)
+    {
+        Temp = -1;
+        sign = Temp;
+        for(i = 1; i <= N; i++)
+        {
+            Y += ((*pCoefficients) * sign);
+            pCoefficients++;
+            sign *= Temp;
+        }
+
+
+    }
+    else
+    {
+        XTemp = X;
+        for(i = N-1; i >= 0; i--)
+        {
+            A = *pCoefficients;
+            pCoefficients++;
+
+            Temp = A * XTemp;
+            Y += Temp;
+
+            Temp = XTemp * X;
+            XTemp = Temp;
+        }
+    }
+    return Y;
+}
+#else
 LVM_INT32 LVM_Polynomial(LVM_UINT16    N,
                          LVM_INT32    *pCoefficients,
                          LVM_INT32    X)
@@ -93,4 +134,4 @@
     }
     return Y;
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
index 6ca1077..8785594 100644
--- a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
@@ -44,7 +44,7 @@
 /*   A11            50477244                                               */
 /*   A12            -2                                                     */
 /*                                                                         */
-/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + Â….. + AN*xN) << AN+1                  */
+/*  Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1                  */
 /*                                                                         */
 /*                                                                         */
 /* PARAMETERS:                                                             */
@@ -54,7 +54,28 @@
 /* RETURNS:                                                                */
 /*   The result of the 10x expansion in Q8.24 format                       */
 /*-------------------------------------------------------------------------*/
-
+#ifdef BUILD_FLOAT
+LVM_FLOAT LVM_Power10(LVM_FLOAT     X)
+{
+    LVM_FLOAT Y,Coefficients[13]={0.999906f,
+                                  2.302475f,
+                                  2.652765f,
+                                  2.035494f,
+                                  1.165667f,
+                                  0.537676f,
+                                  0.213192f,
+                                  0.069603f,
+                                  0.016553f,
+                                  0.004373f,
+                                  0.001817f,
+                                  0.000367f,
+                                  0};
+    Y=LVM_Polynomial((LVM_UINT16)11,
+                     Coefficients,
+                     X);
+    return Y;
+}
+#else
 LVM_INT32 LVM_Power10(LVM_INT32     X)
 {
     LVM_INT32 Y,Coefficients[13]={  16775636,
@@ -75,4 +96,4 @@
                         X);
     return Y;
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
index 2f1e591..9e14c3b 100644
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
+++ b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
@@ -24,7 +24,22 @@
 /**********************************************************************************
    FUNCTION LoadConst_32
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void LoadConst_Float(const LVM_FLOAT   val,
+                     LVM_FLOAT  *dst,
+                     LVM_INT16 n )
+{
+    LVM_INT16 ii;
 
+    for (ii = n; ii != 0; ii--)
+    {
+        *dst = val;
+        dst++;
+    }
+
+    return;
+}
+#else
 void LoadConst_32(const LVM_INT32   val,
                         LVM_INT32  *dst,
                         LVM_INT16 n )
@@ -39,5 +54,6 @@
 
     return;
 }
+#endif
 
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
index 26297e7..02c906a 100644
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
@@ -77,4 +77,58 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void MSTo2i_Sat_Float(const LVM_FLOAT  *srcM,
+                      const LVM_FLOAT  *srcS,
+                      LVM_FLOAT  *dst,
+                      LVM_INT16  n )
+{
+    LVM_FLOAT temp,mVal,sVal;
+    LVM_INT16 ii;
+
+
+    for (ii = n; ii != 0; ii--)
+    {
+        mVal = (LVM_FLOAT)*srcM;
+        srcM++;
+
+        sVal = (LVM_FLOAT)*srcS;
+        srcS++;
+
+        temp = mVal + sVal;
+
+        if (temp > 1.0f)
+        {
+            *dst = 1.0f;
+        }
+        else if (temp < -1.0f)
+        {
+            *dst = -1.0f;
+        }
+        else
+        {
+            *dst = (LVM_FLOAT)temp;
+        }
+        dst++;
+
+        temp = mVal - sVal;
+
+        if (temp > 1.0f)
+        {
+            *dst = 1.0f;
+        }
+        else if (temp < -1.0f)
+        {
+            *dst = - 1.0f;
+        }
+        else
+        {
+            *dst = (LVM_FLOAT)temp;
+        }
+        dst++;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
index f28f366..e3fb40d 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
@@ -64,7 +64,44 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void Mac3s_Sat_Float(const LVM_FLOAT *src,
+                     const LVM_FLOAT val,
+                     LVM_FLOAT *dst,
+                     LVM_INT16 n)
+{
+    LVM_INT16 ii;
+    LVM_FLOAT srcval;
+    LVM_FLOAT Temp,dInVal;
 
+    for (ii = n; ii != 0; ii--)
+    {
+        srcval = *src;
+        src++;
+
+        Temp = srcval * val;
+
+        dInVal  = (LVM_FLOAT)*dst;
+        Temp = Temp + dInVal;
+
+        if (Temp > 1.000000f)
+        {
+            *dst = 1.000000f;
+        }
+        else if (Temp < -1.000000f)
+        {
+            *dst = -1.000000f;
+        }
+        else
+        {
+            *dst = Temp;
+        }
+        dst++;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
 
 
diff --git a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
index 73c26ed..16e367b 100644
--- a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
@@ -32,7 +32,71 @@
 /**********************************************************************************
    FUNCTION MIXINSOFT_D32C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixInSoft_D32C31_SAT( Mix_1St_Cll_FLOAT_t        *pInstance,
+                           const LVM_FLOAT      *src,
+                           LVM_FLOAT      *dst,
+                           LVM_INT16      n)
+{
+    char HardMixing = TRUE;
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if(pInstance->Alpha == 0){
+            pInstance->Current = pInstance->Target;
+        }else if ((pInstance->Current-pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+                 (pInstance->Current-pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            Core_MixInSoft_D32C31_SAT(pInstance, src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing){
+        if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
+            if ((pInstance->Target) == 1.0f)
+                Add2_Sat_Float(src, dst, n);
+            else{
+                Core_MixInSoft_D32C31_SAT(pInstance, src, dst, n);
+                pInstance->Current = pInstance->Target; /* In case the core function would \
+                                                           have changed the Current value */
+            }
+        }
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+    /* Call back before the hard mixing, because in this case, hard mixing makes
+       use of the core soft mix function which can change the Current value!      */
+
+    if (pInstance->CallbackSet){
+        if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+            (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            pInstance->CallbackSet = FALSE;
+            if (pInstance->pCallBack != 0){
+                (*pInstance->pCallBack) ( pInstance->pCallbackHandle,
+                                          pInstance->pGeneralPurpose,
+                                          pInstance->CallbackParam );
+            }
+        }
+    }
+}
+#else
 void MixInSoft_D32C31_SAT( Mix_1St_Cll_t        *pInstance,
                            const LVM_INT32      *src,
                                  LVM_INT32      *dst,
@@ -91,5 +155,5 @@
         }
     }
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
index ca88b04..869293b 100644
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
@@ -34,7 +34,68 @@
 /**********************************************************************************
    FUNCTION MIXSOFT_1ST_D32C31_WRA
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixSoft_1St_D32C31_WRA(    Mix_1St_Cll_FLOAT_t       *pInstance,
+                                const LVM_FLOAT     *src,
+                                      LVM_FLOAT     *dst,
+                                      LVM_INT16     n)
+{
+    char HardMixing = TRUE;
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if (pInstance->Current != pInstance->Target)
+    {
+        if(pInstance->Alpha == 0){
+            pInstance->Current = pInstance->Target;
+        }else if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+                 (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+        }else{
+            /* Soft mixing has to be applied */
+            HardMixing = FALSE;
+            Core_MixSoft_1St_D32C31_WRA(pInstance, src, dst, n);
+        }
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    if (HardMixing){
+        if (pInstance->Target == 0)
+            LoadConst_Float(0, dst, n);
+        else if ((pInstance->Target) == 1.0f){
+            if (src != dst)
+                Copy_Float((LVM_FLOAT*)src, (LVM_FLOAT*)dst, (LVM_INT16)(n));
+        }
+        else
+            Mult3s_Float(src, pInstance->Current, dst, n);
+    }
+
+    /******************************************************************************
+       CALL BACK
+    *******************************************************************************/
+
+    if (pInstance->CallbackSet){
+        if ((pInstance->Current - pInstance->Target < POINT_ZERO_ONE_DB_FLOAT) &&
+            (pInstance->Current - pInstance->Target > -POINT_ZERO_ONE_DB_FLOAT)){
+            pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
+                                                       Make them equal. */
+            pInstance->CallbackSet = FALSE;
+            if (pInstance->pCallBack != 0){
+                (*pInstance->pCallBack) ( pInstance->pCallbackHandle,
+                                          pInstance->pGeneralPurpose,
+                                          pInstance->CallbackParam );
+            }
+        }
+    }
+}
+#else
 void MixSoft_1St_D32C31_WRA(    Mix_1St_Cll_t       *pInstance,
                                 const LVM_INT32     *src,
                                       LVM_INT32     *dst,
@@ -91,5 +152,5 @@
         }
     }
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
index 2e0a099..6fc1b92 100644
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
@@ -26,7 +26,44 @@
 /**********************************************************************************
    FUNCTION MIXSOFT_2ST_D32C31_SAT
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void MixSoft_2St_D32C31_SAT(    Mix_2St_Cll_FLOAT_t       *pInstance,
+                                const LVM_FLOAT     *src1,
+                                const LVM_FLOAT     *src2,
+                                      LVM_FLOAT     *dst,
+                                      LVM_INT16     n)
+{
 
+    if(n <= 0)    return;
+
+    /******************************************************************************
+       SOFT MIXING
+    *******************************************************************************/
+    if ((pInstance->Current1 != pInstance->Target1) || (pInstance->Current2 != pInstance->Target2))
+    {
+        MixSoft_1St_D32C31_WRA((Mix_1St_Cll_FLOAT_t*)pInstance, src1, dst, n);
+        MixInSoft_D32C31_SAT((void *)&pInstance->Alpha2, /* Cast to void: \
+                                                              no dereferencing in function*/
+                              src2, dst, n);
+    }
+
+    /******************************************************************************
+       HARD MIXING
+    *******************************************************************************/
+
+    else
+    {
+        if (pInstance->Current1 == 0)
+            MixSoft_1St_D32C31_WRA((void *) &pInstance->Alpha2, /* Cast to void: no \
+                                                             dereferencing in function*/
+                                    src2, dst, n);
+        else if (pInstance->Current2 == 0)
+            MixSoft_1St_D32C31_WRA((Mix_1St_Cll_FLOAT_t*) pInstance, src1, dst, n);
+        else
+            Core_MixHard_2St_D32C31_SAT(pInstance, src1, src2, dst, n);
+    }
+}
+#else
 void MixSoft_2St_D32C31_SAT(    Mix_2St_Cll_t       *pInstance,
                                 const LVM_INT32     *src1,
                                 const LVM_INT32     *src2,
@@ -61,5 +98,6 @@
             Core_MixHard_2St_D32C31_SAT( pInstance, src1, src2, dst, n);
     }
 }
-
+#endif
 /**********************************************************************************/
+
diff --git a/media/libeffects/lvm/lib/Common/src/Mixer_private.h b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
index 607073c..00d55ed 100644
--- a/media/libeffects/lvm/lib/Common/src/Mixer_private.h
+++ b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
@@ -26,6 +26,10 @@
 
 #define POINT_ZERO_ONE_DB 2473805 /* 0.01 dB on a full scale signal = (10^(0.01/20) -1) * 2^31 */
 
+#ifdef BUILD_FLOAT
+#define POINT_ZERO_ONE_DB_FLOAT 0.001152 /* 0.01 dB on a full scale \
+                                            signal = (10^(0.01/20) -1) * 2^31 */
+#endif
 /**********************************************************************************
    DEFINITIONS
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
index c09ec0f..796a15c 100644
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
@@ -45,5 +45,26 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void MonoTo2I_Float( const LVM_FLOAT  *src,
+                     LVM_FLOAT  *dst,
+                     LVM_INT16 n)
+{
+    LVM_INT16 ii;
+    src += (n - 1);
+    dst += ((n * 2) - 1);
 
+    for (ii = n; ii != 0; ii--)
+    {
+        *dst = *src;
+        dst--;
+
+        *dst = *src;
+        dst--;
+        src--;
+    }
+
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
index a5dc50f..c758560 100644
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
@@ -47,5 +47,23 @@
 
     return;
 }
+#ifdef BUILD_FLOAT
+void Mult3s_Float( const LVM_FLOAT *src,
+                   const LVM_FLOAT val,
+                   LVM_FLOAT *dst,
+                   LVM_INT16 n)
+{
+    LVM_INT16 ii;
+    LVM_FLOAT temp;
 
+    for (ii = n; ii != 0; ii--)
+    {
+        temp = (*src) * val;
+        src++;
+        *dst = temp;
+        dst++;
+    }
+    return;
+}
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
index 73343cd..5156edc 100644
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
@@ -114,4 +114,54 @@
     }
 
 }
+#ifdef BUILD_FLOAT
+void NonLinComp_Float(LVM_FLOAT        Gain,
+                      LVM_FLOAT        *pDataIn,
+                      LVM_FLOAT        *pDataOut,
+                      LVM_INT32        BlockLength)
+{
 
+    LVM_FLOAT            Sample;                    /* Input samples */
+    LVM_INT32            SampleNo;                /* Sample index */
+    LVM_FLOAT            Temp;
+
+
+    /*
+     * Process a block of samples
+     */
+    for(SampleNo = 0; SampleNo < BlockLength; SampleNo++)
+    {
+        /*
+         * Read the input
+         */
+        Sample = *pDataIn;
+        pDataIn++;
+
+
+        /*
+         * Apply the compander, this compresses the signal at the expense of
+         * harmonic distortion. The amount of compression is control by the
+         * gain factor
+         */
+        if (Sample != -1.0f)
+        {
+            Temp = ((Sample * Sample));
+            if(Sample > 0)
+            {
+                Sample = (Sample + ((Gain * (Sample - Temp)) ));
+            }
+            else
+            {
+                Sample = (Sample + ((Gain * (Sample + Temp)) ));
+            }
+        }
+
+
+        /*
+         * Save the output
+         */
+        *pDataOut = Sample;
+        pDataOut++;
+    }
+}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
index c8c1527..9c17a05 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
@@ -38,6 +38,88 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q0 format
  pBiquadState->pDelays[7] is y(n-2)R in Q0 format
 ***************************************************************************/
+#ifdef BUILD_FLOAT
+void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_FLOAT_Instance_t       *pInstance,
+                                     LVM_FLOAT               *pDataIn,
+                                     LVM_FLOAT               *pDataOut,
+                                     LVM_INT16               NrSamples)
+    {
+        LVM_FLOAT ynL,ynR,ynLO,ynRO,templ;
+        LVM_INT16 ii;
+        PFilter_State_Float pBiquadState = (PFilter_State_Float) pInstance;
+
+         for (ii = NrSamples; ii != 0; ii--)
+         {
+
+
+            /**************************************************************************
+                            PROCESSING OF THE LEFT CHANNEL
+            ***************************************************************************/
+            /* ynL= (A0  * (x(n)L - x(n-2)L  ) )*/
+            templ = (*pDataIn) - pBiquadState->pDelays[2];
+            ynL = templ * pBiquadState->coefs[0];
+
+            /* ynL+= ((-B2  * y(n-2)L  )) */
+            templ = pBiquadState->pDelays[6] * pBiquadState->coefs[1];
+            ynL += templ;
+
+            /* ynL+= ((-B1 * y(n-1)L  ) ) */
+            templ = pBiquadState->pDelays[4] * pBiquadState->coefs[2];
+            ynL += templ;
+
+            /* ynLO= ((Gain * ynL )) */
+            ynLO = ynL * pBiquadState->coefs[3];
+
+            /* ynLO=( ynLO + x(n)L  )*/
+            ynLO += (*pDataIn);
+
+            /**************************************************************************
+                            PROCESSING OF THE RIGHT CHANNEL
+            ***************************************************************************/
+            /* ynR= (A0  * (x(n)R  - x(n-2)R  ) ) */
+            templ = (*(pDataIn + 1)) - pBiquadState->pDelays[3];
+            ynR = templ * pBiquadState->coefs[0];
+
+            /* ynR+= ((-B2  * y(n-2)R  ) )  */
+            templ = pBiquadState->pDelays[7] * pBiquadState->coefs[1];
+            ynR += templ;
+
+            /* ynR+= ((-B1  * y(n-1)R  ) )   */
+            templ = pBiquadState->pDelays[5] * pBiquadState->coefs[2];
+            ynR += templ;
+
+            /* ynRO= ((Gain  * ynR )) */
+            ynRO = ynR * pBiquadState->coefs[3];
+
+            /* ynRO=( ynRO + x(n)R  )*/
+            ynRO += (*(pDataIn+1));
+
+            /**************************************************************************
+                            UPDATING THE DELAYS
+            ***************************************************************************/
+            pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
+            pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
+            pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
+            pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
+            pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R */
+            pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L */
+            pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
+            pDataIn++;
+            pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
+            pDataIn++;
+
+            /**************************************************************************
+                            WRITING THE OUTPUT
+            ***************************************************************************/
+            *pDataOut = ynLO; /* Write Left output*/
+            pDataOut++;
+            *pDataOut = ynRO; /* Write Right ouput*/
+            pDataOut++;
+
+        }
+
+    }
+#else
 void PK_2I_D32F32C14G11_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                      LVM_INT32               *pDataIn,
                                      LVM_INT32               *pDataOut,
@@ -118,4 +200,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
index 67a570b..f705cbf 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
@@ -38,6 +38,7 @@
  pBiquadState->pDelays[6] is y(n-2)L in Q0 format
  pBiquadState->pDelays[7] is y(n-2)R in Q0 format
 ***************************************************************************/
+#ifndef BUILD_FLOAT
 void PK_2I_D32F32C30G11_TRC_WRA_01 ( Biquad_Instance_t       *pInstance,
                                      LVM_INT32               *pDataIn,
                                      LVM_INT32               *pDataOut,
@@ -116,4 +117,4 @@
         }
 
     }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
index 1d6142c..65475a3 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
@@ -18,7 +18,7 @@
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CllGss_TRC_WRA_01_Private.h"
 
-
+#ifndef BUILD_FLOAT
 void  PK_2I_D32F32CllGss_TRC_WRA_01_Init(Biquad_Instance_t         *pInstance,
                                          Biquad_2I_Order2_Taps_t   *pTaps,
                                          PK_C32_Coefs_t            *pCoef)
@@ -35,4 +35,4 @@
   pBiquadState->coefs[3]=pCoef->G;
 
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
index b9f64e6..a36330e 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
@@ -17,7 +17,23 @@
 
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
+#ifdef BUILD_FLOAT
+void  PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t         *pInstance,
+                                         Biquad_2I_Order2_FLOAT_Taps_t   *pTaps,
+                                         PK_FLOAT_Coefs_t            *pCoef)
+{
+    PFilter_State_Float pBiquadState = (PFilter_State_Float) pInstance;
+    pBiquadState->pDelays       = (LVM_FLOAT *) pTaps;
 
+    pBiquadState->coefs[0] = pCoef->A0;
+
+    pBiquadState->coefs[1] = pCoef->B2;
+
+    pBiquadState->coefs[2] = pCoef->B1;
+
+    pBiquadState->coefs[3] = pCoef->G;
+}
+#else
 void  PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_Instance_t         *pInstance,
                                          Biquad_2I_Order2_Taps_t   *pTaps,
                                          PK_C16_Coefs_t            *pCoef)
@@ -34,4 +50,4 @@
   pBiquadState->coefs[3]=pCoef->G;
 
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
index e2050e0..1e32062 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
@@ -21,6 +21,16 @@
 
 /* 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.        */
+
+#ifdef BUILD_FLOAT
+typedef struct _Filter_State_Float_
+{
+    LVM_FLOAT *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT         coefs[5];       /* pointer to the filter coefficients */
+}Filter_State_Float;
+
+typedef Filter_State_Float * PFilter_State_Float ;
+#endif
 typedef struct _Filter_State_
 {
   LVM_INT32 *       pDelays;        /* pointer to the delayed samples (data of 32 bits)   */
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
index 8363270..28fea65 100644
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
@@ -24,7 +24,7 @@
 /**********************************************************************************
    FUNCTION Shift_Sat_v16xv16
 ***********************************************************************************/
-
+#ifndef BUILD_FLOAT
 void Shift_Sat_v16xv16 (const   LVM_INT16   val,
                         const   LVM_INT16   *src,
                         LVM_INT16   *dst,
@@ -77,5 +77,5 @@
     }
     return;
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
index fbd132e..fac9de7 100644
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
@@ -24,7 +24,62 @@
 /**********************************************************************************
    FUNCTION Shift_Sat_v32xv32
 ***********************************************************************************/
+#ifdef BUILD_FLOAT
+void Shift_Sat_Float (const   LVM_INT16   val,
+                      const   LVM_FLOAT   *src,
+                      LVM_FLOAT   *dst,
+                      LVM_INT16   n)
+{
+    LVM_FLOAT   temp;
+    LVM_INT32   ii,ij;
+    LVM_INT16   RShift;
 
+    if(val > 0)
+    {
+        for (ii = n; ii != 0; ii--)
+        {
+            temp = (LVM_FLOAT)*src;
+            src++;
+            for(ij = 0; ij < val; ij++)
+            {
+                temp = temp * 2;
+            }
+
+            if(temp > 1.0)
+                temp = 1.0;
+            if(temp < -1.0)
+                temp = -1.0;
+
+            *dst = (LVM_FLOAT)temp;
+            dst++;
+        }
+    }
+    else if(val < 0)
+    {
+        RShift=(LVM_INT16)(-val);
+
+        for (ii = n; ii != 0; ii--)
+        {
+            temp = (LVM_FLOAT)*src;
+            src++;
+            for(ij = 0; ij < RShift; ij++)
+            {
+                temp = temp / 2;
+            }
+            *dst = (LVM_FLOAT)temp;
+            dst++;
+        }
+    }
+    else
+    {
+        if(src != dst)
+        {
+            Copy_Float(src, dst, n);
+        }
+    }
+    return;
+}
+#else
 void Shift_Sat_v32xv32 (const   LVM_INT16   val,
                         const   LVM_INT32   *src,
                         LVM_INT32   *dst,
@@ -79,5 +134,5 @@
     }
     return;
 }
-
+#endif
 /**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c b/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
index ac0343f..9a726f2 100644
--- a/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
+++ b/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
@@ -29,6 +29,9 @@
 /*######################################################################################*/
 
 #include "ScalarArithmetic.h"
+#ifdef BUILD_FLOAT
+#include <math.h>
+#endif
 
 
 /****************************************************************************************
@@ -64,6 +67,18 @@
 #define SECOND_COEF      38836
 #define MAX_VALUE        1536                   /* 96 * 16 */
 
+#ifdef BUILD_FLOAT
+LVM_FLOAT   dB_to_LinFloat(LVM_INT16    db_fix)
+{
+    LVM_FLOAT    dB_Float;
+    LVM_FLOAT    LinFloat;
+
+    dB_Float = (LVM_FLOAT)((LVM_FLOAT)db_fix / 16.0f);
+    LinFloat = pow(10, dB_Float / 20.0);
+
+    return LinFloat;
+}
+#else
 LVM_INT32   dB_to_Lin32(LVM_INT16    db_fix)
 {
     LVM_INT32 Lin_val_32;
@@ -106,4 +121,4 @@
 
     return Lin_val_32;  /* format 1.16.15 */
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index db6aabe..8e0b738 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -200,6 +200,10 @@
 #define LVEQNB_CAP_FS_32000                64
 #define LVEQNB_CAP_FS_44100                128
 #define LVEQNB_CAP_FS_48000                256
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVEQNB_CAP_FS_96000                512
+#define LVEQNB_CAP_FS_192000               1024
+#endif
 
 typedef enum
 {
@@ -212,6 +216,10 @@
     LVEQNB_FS_32000 = 6,
     LVEQNB_FS_44100 = 7,
     LVEQNB_FS_48000 = 8,
+#ifdef HIGHER_FS
+    LVEQNB_FS_96000 = 9,
+    LVEQNB_FS_192000 = 10,
+#endif
     LVEQNB_FS_MAX   = LVM_MAXINT_32
 } LVEQNB_Fs_en;
 
@@ -268,6 +276,7 @@
 {
     /* General parameters */
     LVM_UINT16                  SampleRate;
+
     LVM_UINT16                  SourceFormat;
     LVM_UINT16                  MaxBlockSize;
     LVM_UINT16                  MaxBands;
@@ -460,11 +469,17 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
+                                      const LVM_FLOAT       *pInData,
+                                      LVM_FLOAT             *pOutData,
+                                      LVM_UINT16            NumSamples);
+#else
 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
                                       const LVM_INT16       *pInData,
                                       LVM_INT16             *pOutData,
                                       LVM_UINT16            NumSamples);
+#endif
 
 
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
index fddedb9..ff52b7f 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
@@ -22,7 +22,9 @@
 /****************************************************************************************/
 
 #include "LVEQNB_Private.h"
-
+#ifdef BUILD_FLOAT
+#include <math.h>
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -77,6 +79,7 @@
 /****************************************************************************************/
 
 
+#ifndef BUILD_FLOAT
 LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16        Fs,
                                               LVEQNB_BandDef_t  *pFilterDefinition,
                                               PK_C32_Coefs_t    *pCoefficients)
@@ -168,7 +171,7 @@
     return(LVEQNB_SUCCESS);
 
 }
-
+#endif
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -205,7 +208,67 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16        Fs,
+                                              LVEQNB_BandDef_t  *pFilterDefinition,
+                                              PK_FLOAT_Coefs_t  *pCoefficients)
+{
 
+    extern LVM_FLOAT    LVEQNB_GainTable[];
+    extern LVM_FLOAT    LVEQNB_TwoPiOnFsTable[];
+    extern LVM_FLOAT    LVEQNB_DTable[];
+
+
+    /*
+     * Get the filter definition
+     */
+    LVM_INT16           Gain        = pFilterDefinition->Gain;
+    LVM_UINT16          Frequency   = pFilterDefinition->Frequency;
+    /* As mentioned in effectbundle.h */
+    LVM_FLOAT           QFactor     = (LVM_FLOAT)pFilterDefinition->QFactor / 100.0f;
+
+
+    /*
+     * Intermediate variables and temporary values
+     */
+    LVM_FLOAT           T0;
+    LVM_FLOAT           D;
+    LVM_FLOAT           A0;
+    LVM_FLOAT           B1;
+    LVM_FLOAT           B2;
+
+    /*
+     * Calculating the intermediate values
+     */
+    T0 = Frequency * LVEQNB_TwoPiOnFsTable[Fs];        /* T0 = 2 * Pi * Fc / Fs */
+    if (Gain >= 0)
+    {
+        D = LVEQNB_DTable[15];                         /* D = 1            if GaindB >= 0 */
+    }
+    else
+    {
+        D = LVEQNB_DTable[Gain + 15];                    /* D = 1 / (1 + G)  if GaindB <  0 */
+    }
+
+    /*
+     * Calculate the B2,B1,A0 coefficients
+     */
+    B2 = -0.5 * (2 * QFactor - D * T0) / (2 * QFactor + D * T0);
+    B1 = (0.5 - B2) * cos(T0);
+    A0 = (0.5 + B2) / 2.0;
+
+    /*
+     * Write coeff into the data structure
+     */
+    /* all the coefficients are multiplied with 2 to make them align with fixed point values*/
+    pCoefficients->A0 = 2 * A0;
+    pCoefficients->B1 = 2 * B1;
+    pCoefficients->B2 = 2 * B2;
+    pCoefficients->G  = LVEQNB_GainTable[Gain + 15];
+
+    return(LVEQNB_SUCCESS);
+}
+#else
 LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16        Fs,
                                               LVEQNB_BandDef_t  *pFilterDefinition,
                                               PK_C16_Coefs_t    *pCoefficients)
@@ -296,3 +359,4 @@
     return(LVEQNB_SUCCESS);
 
 }
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
index 95212f2..f0deb6c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
@@ -25,7 +25,39 @@
 /* Gain table for (10^(Gain/20) - 1)                                                */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifdef BUILD_FLOAT
+#define LVEQNB_Gain_Neg15_dB                             -0.822172f
+#define LVEQNB_Gain_Neg14_dB                             -0.800474f
+#define LVEQNB_Gain_Neg13_dB                             -0.776128f
+#define LVEQNB_Gain_Neg12_dB                             -0.748811f
+#define LVEQNB_Gain_Neg11_dB                             -0.718162f
+#define LVEQNB_Gain_Neg10_dB                             -0.683772f
+#define LVEQNB_Gain_Neg9_dB                              -0.645187f
+#define LVEQNB_Gain_Neg8_dB                              -0.601893f
+#define LVEQNB_Gain_Neg7_dB                              -0.553316f
+#define LVEQNB_Gain_Neg6_dB                              -0.498813f
+#define LVEQNB_Gain_Neg5_dB                              -0.437659f
+#define LVEQNB_Gain_Neg4_dB                              -0.369043f
+#define LVEQNB_Gain_Neg3_dB                              -0.292054f
+#define LVEQNB_Gain_Neg2_dB                              -0.205672f
+#define LVEQNB_Gain_Neg1_dB                              -0.108749f
+#define LVEQNB_Gain_0_dB                                  0.000000f
+#define LVEQNB_Gain_1_dB                                  0.122018f
+#define LVEQNB_Gain_2_dB                                  0.258925f
+#define LVEQNB_Gain_3_dB                                  0.412538f
+#define LVEQNB_Gain_4_dB                                  0.584893f
+#define LVEQNB_Gain_5_dB                                  0.778279f
+#define LVEQNB_Gain_6_dB                                  0.995262f
+#define LVEQNB_Gain_7_dB                                  1.238721f
+#define LVEQNB_Gain_8_dB                                  1.511886f
+#define LVEQNB_Gain_9_dB                                  1.818383f
+#define LVEQNB_Gain_10_dB                                 2.162278f
+#define LVEQNB_Gain_11_dB                                 2.548134f
+#define LVEQNB_Gain_12_dB                                 2.981072f
+#define LVEQNB_Gain_13_dB                                 3.466836f
+#define LVEQNB_Gain_14_dB                                 4.011872f
+#define LVEQNB_Gain_15_dB                                 4.623413f
+#else
 #define LVEQNB_GAINSHIFT                                   11         /* As a power of 2 */
 #define LVEQNB_Gain_Neg15_dB                           (-1684)        /* Floating point value -0.822172 */
 #define LVEQNB_Gain_Neg14_dB                           (-1639)        /* Floating point value -0.800474 */
@@ -58,14 +90,30 @@
 #define LVEQNB_Gain_13_dB                                7100         /* Floating point value 3.466836 */
 #define LVEQNB_Gain_14_dB                                8216         /* Floating point value 4.011872 */
 #define LVEQNB_Gain_15_dB                                9469         /* Floating point value 4.623413 */
-
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
 /* Frequency table for 2*Pi/Fs                                                      */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+#define LVEQNB_2PiOn_8000                                0.000785f
+#define LVEQNB_2PiOn_11025                               0.000570f
+#define LVEQNB_2PiOn_12000                               0.000524f
+#define LVEQNB_2PiOn_16000                               0.000393f
+#define LVEQNB_2PiOn_22050                               0.000285f
+#define LVEQNB_2PiOn_24000                               0.000262f
+#define LVEQNB_2PiOn_32000                               0.000196f
+#define LVEQNB_2PiOn_44100                               0.000142f
+#define LVEQNB_2PiOn_48000                               0.000131f
 
+#ifdef HIGHER_FS
+#define LVEQNB_2PiOn_96000                               0.000065f
+#define LVEQNB_2PiOn_192000                              0.000033f
+#endif
+
+#else
 #define LVEQNB_FREQSHIFT                                   25         /* As a power of 2 */
 #define LVEQNB_2PiOn_8000                               26354         /* Floating point value 0.000785 */
 #define LVEQNB_2PiOn_11025                              19123         /* Floating point value 0.000570 */
@@ -76,14 +124,31 @@
 #define LVEQNB_2PiOn_32000                               6588         /* Floating point value 0.000196 */
 #define LVEQNB_2PiOn_44100                               4781         /* Floating point value 0.000142 */
 #define LVEQNB_2PiOn_48000                               4392         /* Floating point value 0.000131 */
-
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
 /* 50D table for 50 / ( 1 + Gain )                                                  */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifdef BUILD_FLOAT
+#define LVEQNB_100D_Neg15_dB                             5.623413f
+#define LVEQNB_100D_Neg14_dB                             5.011872f
+#define LVEQNB_100D_Neg13_dB                             4.466836f
+#define LVEQNB_100D_Neg12_dB                             3.981072f
+#define LVEQNB_100D_Neg11_dB                             3.548134f
+#define LVEQNB_100D_Neg10_dB                             3.162278f
+#define LVEQNB_100D_Neg9_dB                              2.818383f
+#define LVEQNB_100D_Neg8_dB                              2.511886f
+#define LVEQNB_100D_Neg7_dB                              2.238721f
+#define LVEQNB_100D_Neg6_dB                              1.995262f
+#define LVEQNB_100D_Neg5_dB                              1.778279f
+#define LVEQNB_100D_Neg4_dB                              1.584893f
+#define LVEQNB_100D_Neg3_dB                              1.412538f
+#define LVEQNB_100D_Neg2_dB                              1.258925f
+#define LVEQNB_100D_Neg1_dB                              1.122018f
+#define LVEQNB_100D_0_dB                                 1.000000f
+#else
 #define LVEQNB_100DSHIFT                                    5         /* As a power of 2 */
 #define LVEQNB_100D_Neg15_dB                            17995         /* Floating point value 5.623413 */
 #define LVEQNB_100D_Neg14_dB                            16038         /* Floating point value 5.011872 */
@@ -101,6 +166,6 @@
 #define LVEQNB_100D_Neg2_dB                              4029         /* Floating point value 1.258925 */
 #define LVEQNB_100D_Neg1_dB                              3590         /* Floating point value 1.122018 */
 #define LVEQNB_100D_0_dB                                 3200         /* Floating point value 1.000000 */
-
+#endif
 
 #endif
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
index 10e7d74..c290aec 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
@@ -140,8 +140,12 @@
 void    LVEQNB_SetFilters(LVEQNB_Instance_t     *pInstance,
                           LVEQNB_Params_t       *pParams)
 {
-
+#ifdef HIGHER_FS
+    extern const LVM_UINT32   LVEQNB_SampleRateTab[];           /* Sample rate table */
+#else
     extern const LVM_UINT16   LVEQNB_SampleRateTab[];           /* Sample rate table */
+#endif
+
     LVM_UINT16          i;                                      /* Filter band index */
     LVM_UINT32          fs = (LVM_UINT32)LVEQNB_SampleRateTab[(LVM_UINT16)pParams->SampleRate];  /* Sample rate */
     LVM_UINT32          fc;                                     /* Filter centre frequency */
@@ -158,11 +162,15 @@
         fc = (LVM_UINT32)pParams->pBandDefinition[i].Frequency;     /* Get the band centre frequency */
         QFactor = (LVM_INT16)pParams->pBandDefinition[i].QFactor;   /* Get the band Q factor */
 
-
+#ifdef BUILD_FLOAT
+        pInstance->pBiquadType[i] = LVEQNB_SinglePrecision_Float; /* Default to single precision */
+#else
         /*
          * For each filter set the type of biquad required
          */
         pInstance->pBiquadType[i] = LVEQNB_SinglePrecision;         /* Default to single precision */
+#endif
+#ifndef BUILD_FLOAT
         if ((fc << 15) <= (LOW_FREQ * fs))
         {
             /*
@@ -177,7 +185,7 @@
              */
             pInstance->pBiquadType[i] = LVEQNB_DoublePrecision;
         }
-
+#endif
 
         /*
          * Check for out of range frequencies
@@ -230,6 +238,25 @@
         BiquadType = pInstance->pBiquadType[i];
         switch  (BiquadType)
         {
+#ifdef BUILD_FLOAT
+            case    LVEQNB_SinglePrecision_Float:
+            {
+                PK_FLOAT_Coefs_t      Coefficients;
+                /*
+                 * Calculate the single precision coefficients
+                 */
+                LVEQNB_SinglePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate,
+                                       &pInstance->pBandDefinitions[i],
+                                       &Coefficients);
+                /*
+                 * Set the coefficients
+                 */
+                PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState_Float[i],
+                                                   &pInstance->pEQNB_Taps_Float[i],
+                                                   &Coefficients);
+                break;
+            }
+#else
             case    LVEQNB_DoublePrecision:
             {
                 PK_C32_Coefs_t      Coefficients;
@@ -269,6 +296,7 @@
                                                    &Coefficients);
                 break;
             }
+#endif
             default:
                 break;
         }
@@ -288,7 +316,7 @@
 /*  pInstance           Pointer to the instance                                     */
 /*                                                                                  */
 /************************************************************************************/
-
+#ifndef BUILD_FLOAT
 void    LVEQNB_ClearFilterHistory(LVEQNB_Instance_t     *pInstance)
 {
     LVM_INT16       *pTapAddress;
@@ -305,8 +333,24 @@
                      NumTaps);                          /* Number of words */
     }
 }
+#else
+void    LVEQNB_ClearFilterHistory(LVEQNB_Instance_t     *pInstance)
+{
+    LVM_FLOAT       *pTapAddress;
+    LVM_INT16       NumTaps;
 
+    pTapAddress = (LVM_FLOAT *)pInstance->pEQNB_Taps_Float;
+    NumTaps     = (LVM_INT16)((pInstance->Capabilities.MaxBands * \
+                                    sizeof(Biquad_2I_Order2_FLOAT_Taps_t)) / sizeof(LVM_FLOAT));
 
+    if (NumTaps != 0)
+    {
+        LoadConst_Float(0,                                 /* Clear the history, value 0 */
+                        pTapAddress,                       /* Destination */
+                        NumTaps);                          /* Number of words */
+    }
+}
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                LVEQNB_Control                                              */
@@ -422,9 +466,13 @@
         {
             if(pParams->OperatingMode == LVEQNB_ON)
             {
+#ifdef BUILD_FLOAT
+                LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0], 1.0f);
+                LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1], 0.0f);
+#else
                 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],LVM_MAXINT_16);
                 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],0);
-
+#endif
                 pInstance->BypassMixer.MixerStream[0].CallbackSet        = 1;
                 pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
             }
@@ -432,15 +480,18 @@
             {
                 /* Stay on the ON operating mode until the transition is done */
                 pInstance->Params.OperatingMode = LVEQNB_ON;
-
+#ifdef BUILD_FLOAT
+                LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0], 0.0f);
+                LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1], 1.0f);
+#else
                 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],0);
                 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],LVM_MAXINT_16);
+#endif
                 pInstance->BypassMixer.MixerStream[0].CallbackSet        = 1;
                 pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
             }
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
-
             pInstance->bInOperatingModeTransition = LVM_TRUE;
         }
 
@@ -470,8 +521,13 @@
      /*
       * Send an ALGOFF event if the ON->OFF switch transition is finished
       */
+#ifdef BUILD_FLOAT
+    if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0) &&
+       (CallbackParam == 0)){
+#else
     if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0x00000000) &&
        (CallbackParam == 0)){
+#endif
         pInstance->Params.OperatingMode = LVEQNB_BYPASS;
         if (CallBack != LVM_NULL){
             CallBack(pInstance->Capabilities.pBundleInstance, LVM_NULL, ALGORITHM_EQNB_ID|LVEQNB_EVENT_ALGOFF);
@@ -485,9 +541,3 @@
 
     return 1;
 }
-
-
-
-
-
-
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
index e01c1c5..de1bbb7 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
@@ -97,6 +97,21 @@
          */
         InstAlloc_Init(&AllocMem,
                        LVM_NULL);
+#ifdef BUILD_FLOAT
+        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)));
+#else
         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
                             sizeof(Biquad_2I_Order2_Taps_t));
         InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
@@ -107,6 +122,7 @@
                             (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t)));        /* Filter definitions */
         InstAlloc_AddMember(&AllocMem,
                             (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en)));    /* Biquad types */
+#endif
         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;
@@ -117,12 +133,22 @@
          */
         InstAlloc_Init(&AllocMem,
                        LVM_NULL);
+#ifdef BUILD_FLOAT
+        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));
+#else
         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
                             sizeof(Biquad_Instance_t));
         InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
                             sizeof(Biquad_Instance_t));
         InstAlloc_AddMember(&AllocMem,
                             pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
+#endif
         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;
@@ -133,8 +159,14 @@
          */
         InstAlloc_Init(&AllocMem,
                        LVM_NULL);
+#ifdef BUILD_FLOAT
+        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
+                            LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * \
+                                             pCapabilities->MaxBlockSize);
+#else
         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
                             LVEQNB_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
+#endif
         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;
@@ -248,8 +280,15 @@
     InstAlloc_Init(&AllocMem,
                    pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
 
+#ifdef BUILD_FLOAT
+    /* Equaliser Biquad Instance */
+    pInstance->pEQNB_FilterState_Float = InstAlloc_AddMember(&AllocMem,
+                                                             pCapabilities->MaxBands * \
+                                                             sizeof(Biquad_FLOAT_Instance_t));
+#else
     pInstance->pEQNB_FilterState = InstAlloc_AddMember(&AllocMem,
                                                        pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
+#endif
 
 
 
@@ -259,9 +298,15 @@
     InstAlloc_Init(&AllocMem,
                    pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
 
+#ifdef BUILD_FLOAT
+    MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t));
+    pInstance->pEQNB_Taps_Float = (Biquad_2I_Order2_FLOAT_Taps_t *)InstAlloc_AddMember(&AllocMem,
+                                                                                       MemSize);
+#else
     MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t));
     pInstance->pEQNB_Taps = (Biquad_2I_Order2_Taps_t *)InstAlloc_AddMember(&AllocMem,
                                                                            MemSize);
+#endif
     MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
     pInstance->pBandDefinitions  = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
                                                                            MemSize);
@@ -279,8 +324,13 @@
     InstAlloc_Init(&AllocMem,
                    pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
 
+#ifdef BUILD_FLOAT
+    pInstance->pFastTemporary = (LVM_FLOAT *)InstAlloc_AddMember(&AllocMem,
+                                                                 sizeof(LVM_FLOAT));
+#else
     pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
                                                                  sizeof(LVM_INT16));
+#endif
 
     /*
      * Update the instance parameters
@@ -308,15 +358,22 @@
     pInstance->BypassMixer.MixerStream[0].CallbackParam      = 0;
     pInstance->BypassMixer.MixerStream[0].pCallbackHandle    = (void*)pInstance;
     pInstance->BypassMixer.MixerStream[0].pCallBack          = LVEQNB_BypassMixerCallBack;
+
     LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
     LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
 
+
     pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
     pInstance->BypassMixer.MixerStream[1].CallbackParam      = 0;
     pInstance->BypassMixer.MixerStream[1].pCallbackHandle    = LVM_NULL;
     pInstance->BypassMixer.MixerStream[1].pCallBack          = LVM_NULL;
+#ifdef BUILD_FLOAT
+    LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1], 0, 1.0f);
+    LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1], 0, LVM_FS_8000, 2);
+#else
     LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
     LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
+#endif
 
     pInstance->bInOperatingModeTransition      = LVM_FALSE;
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 9df980c..56b02e0 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -60,6 +60,9 @@
 /* Filter biquad types */
 typedef enum
 {
+#ifdef BUILD_FLOAT
+    LVEQNB_SinglePrecision_Float = -1,
+#endif
     LVEQNB_SinglePrecision = 0,
     LVEQNB_DoublePrecision = 1,
     LVEQNB_OutOfRange      = 2,
@@ -84,11 +87,20 @@
     LVEQNB_Capabilities_t           Capabilities;       /* Instance capabilities */
 
     /* Aligned memory pointers */
+#ifdef BUILD_FLOAT
+    LVM_FLOAT                      *pFastTemporary;        /* Fast temporary data base address */
+#else
     LVM_INT16                      *pFastTemporary;        /* Fast temporary data base address */
+#endif
 
+#ifdef BUILD_FLOAT
+    Biquad_2I_Order2_FLOAT_Taps_t   *pEQNB_Taps_Float;        /* Equaliser Taps */
+    Biquad_FLOAT_Instance_t         *pEQNB_FilterState_Float; /* State for each filter band */
+#else
     /* Process variables */
     Biquad_2I_Order2_Taps_t         *pEQNB_Taps;        /* Equaliser Taps */
     Biquad_Instance_t               *pEQNB_FilterState; /* State for each filter band */
+#endif
 
     /* Filter definitions and call back */
     LVM_UINT16                      NBands;             /* Number of bands */
@@ -96,7 +108,12 @@
     LVEQNB_BiquadType_en            *pBiquadType;       /* Filter biquad types */
 
     /* Bypass variable */
+#ifdef BUILD_FLOAT
+    LVMixer3_2St_FLOAT_st     BypassMixer;
+#else
     LVMixer3_2St_st           BypassMixer;              /* Bypass mixer used in transitions */
+#endif
+
     LVM_INT16               bInOperatingModeTransition; /* Operating mode transition flag */
 
 } LVEQNB_Instance_t;
@@ -114,7 +131,11 @@
 void    LVEQNB_SetCoefficients(LVEQNB_Instance_t    *pInstance);
 
 void    LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance);
-
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16        Fs,
+                                              LVEQNB_BandDef_t  *pFilterDefinition,
+                                              PK_FLOAT_Coefs_t    *pCoefficients);
+#else
 LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16        Fs,
                                               LVEQNB_BandDef_t  *pFilterDefinition,
                                               PK_C16_Coefs_t    *pCoefficients);
@@ -122,6 +143,7 @@
 LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16        Fs,
                                               LVEQNB_BandDef_t  *pFilterDefinition,
                                               PK_C32_Coefs_t    *pCoefficients);
+#endif
 
 LVM_INT32 LVEQNB_BypassMixerCallBack (void* hInstance, void *pGeneralPurpose, LVM_INT16 CallbackParam);
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
index 58f58ed..6328181 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
@@ -57,7 +57,121 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
+                                      const LVM_FLOAT       *pInData,
+                                      LVM_FLOAT             *pOutData,
+                                      LVM_UINT16            NumSamples)
+{
 
+    LVM_UINT16          i;
+    Biquad_FLOAT_Instance_t   *pBiquad;
+    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
+    LVM_FLOAT           *pScratch;
+
+
+     /* Check for NULL pointers */
+    if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
+    {
+        return LVEQNB_NULLADDRESS;
+    }
+
+    /* Check if the input and output data buffers are 32-bit aligned */
+    if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
+    {
+        return LVEQNB_ALIGNMENTERROR;
+    }
+
+    pScratch  = (LVM_FLOAT *)pInstance->pFastTemporary;
+
+    /*
+    * Check the number of samples is not too large
+    */
+    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+    {
+        return(LVEQNB_TOOMANYSAMPLES);
+    }
+
+    if (pInstance->Params.OperatingMode == LVEQNB_ON)
+    {
+        /*
+         * Copy input data in to scratch buffer
+         */
+
+        Copy_Float((LVM_FLOAT *)pInData,      /* Source */
+                   pScratch,                  /* Destination */
+                   (LVM_INT16)(2 * NumSamples)); /* Left and Right */
+        /*
+         * For each section execte the filter unless the gain is 0dB
+         */
+        if (pInstance->NBands != 0)
+        {
+            for (i = 0; i < pInstance->NBands; i++)
+            {
+                /*
+                 * Check if band is non-zero dB gain
+                 */
+                if (pInstance->pBandDefinitions[i].Gain != 0)
+                {
+                    /*
+                     * Get the address of the biquad instance
+                     */
+                    pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+
+
+                    /*
+                     * Select single or double precision as required
+                     */
+                    switch (pInstance->pBiquadType[i])
+                    {
+                        case LVEQNB_SinglePrecision_Float:
+                        {
+                            PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
+                                                          (LVM_FLOAT *)pScratch,
+                                                          (LVM_FLOAT *)pScratch,
+                                                          (LVM_INT16)NumSamples);
+                            break;
+                        }
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+
+
+        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
+            LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
+                                       (LVM_FLOAT *)pScratch,
+                                       (LVM_FLOAT *)pInData,
+                                       (LVM_FLOAT *)pScratch,
+                                       (LVM_INT16)(2 * NumSamples));
+            Copy_Float((LVM_FLOAT*)pScratch,                           /* Source */
+                       pOutData,                                       /* Destination */
+                       (LVM_INT16)(2 * NumSamples));                     /* Left and Right samples */
+        }
+        else{
+            Copy_Float(pScratch,              /* Source */
+                       pOutData,              /* Destination */
+                       (LVM_INT16 )(2 * NumSamples)); /* Left and Right */
+        }
+    }
+    else
+    {
+        /*
+         * Mode is OFF so copy the data if necessary
+         */
+        if (pInData != pOutData)
+        {
+            Copy_Float(pInData,                                    /* Source */
+                       pOutData,                                   /* Destination */
+                       (LVM_INT16)(2 * NumSamples));                 /* Left and Right samples */
+        }
+    }
+    return(LVEQNB_SUCCESS);
+
+}
+#else
 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
                                       const LVM_INT16       *pInData,
                                       LVM_INT16             *pOutData,
@@ -198,3 +312,4 @@
     return(LVEQNB_SUCCESS);
 
 }
+#endif
\ No newline at end of file
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
index 8e2e0e8..563181c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -36,6 +36,20 @@
  * Sample rate table for converting between the enumerated type and the actual
  * frequency
  */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_UINT32    LVEQNB_SampleRateTab[] = {8000,                    /* 8kS/s  */
+                                              11025,
+                                              12000,
+                                              16000,
+                                              22050,
+                                              24000,
+                                              32000,
+                                              44100,
+                                              48000,
+                                              96000,
+                                              192000
+};
+#else
 const LVM_UINT16    LVEQNB_SampleRateTab[] = {8000,                    /* 8kS/s  */
                                               11025,
                                               12000,
@@ -44,8 +58,9 @@
                                               24000,
                                               32000,
                                               44100,
-                                              48000};                  /* 48kS/s */
-
+                                              48000
+};
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
@@ -56,6 +71,22 @@
 /*
  * Table for 2 * Pi / Fs
  */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT     LVEQNB_TwoPiOnFsTable[] = {LVEQNB_2PiOn_8000,      /* 8kS/s */
+                                               LVEQNB_2PiOn_11025,
+                                               LVEQNB_2PiOn_12000,
+                                               LVEQNB_2PiOn_16000,
+                                               LVEQNB_2PiOn_22050,
+                                               LVEQNB_2PiOn_24000,
+                                               LVEQNB_2PiOn_32000,
+                                               LVEQNB_2PiOn_44100,
+                                               LVEQNB_2PiOn_48000
+#ifdef HIGHER_FS
+                                              ,LVEQNB_2PiOn_96000
+                                              ,LVEQNB_2PiOn_192000
+#endif
+                                               };
+#else
 const LVM_INT16     LVEQNB_TwoPiOnFsTable[] = {LVEQNB_2PiOn_8000,      /* 8kS/s */
                                                LVEQNB_2PiOn_11025,
                                                LVEQNB_2PiOn_12000,
@@ -65,10 +96,44 @@
                                                LVEQNB_2PiOn_32000,
                                                LVEQNB_2PiOn_44100,
                                                LVEQNB_2PiOn_48000};    /* 48kS/s */
+#endif
 
 /*
  * Gain table
  */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT     LVEQNB_GainTable[] = {LVEQNB_Gain_Neg15_dB,        /* -15dB gain */
+                                          LVEQNB_Gain_Neg14_dB,
+                                          LVEQNB_Gain_Neg13_dB,
+                                          LVEQNB_Gain_Neg12_dB,
+                                          LVEQNB_Gain_Neg11_dB,
+                                          LVEQNB_Gain_Neg10_dB,
+                                          LVEQNB_Gain_Neg9_dB,
+                                          LVEQNB_Gain_Neg8_dB,
+                                          LVEQNB_Gain_Neg7_dB,
+                                          LVEQNB_Gain_Neg6_dB,
+                                          LVEQNB_Gain_Neg5_dB,
+                                          LVEQNB_Gain_Neg4_dB,
+                                          LVEQNB_Gain_Neg3_dB,
+                                          LVEQNB_Gain_Neg2_dB,
+                                          LVEQNB_Gain_Neg1_dB,
+                                          LVEQNB_Gain_0_dB,            /* 0dB gain */
+                                          LVEQNB_Gain_1_dB,
+                                          LVEQNB_Gain_2_dB,
+                                          LVEQNB_Gain_3_dB,
+                                          LVEQNB_Gain_4_dB,
+                                          LVEQNB_Gain_5_dB,
+                                          LVEQNB_Gain_6_dB,
+                                          LVEQNB_Gain_7_dB,
+                                          LVEQNB_Gain_8_dB,
+                                          LVEQNB_Gain_9_dB,
+                                          LVEQNB_Gain_10_dB,
+                                          LVEQNB_Gain_11_dB,
+                                          LVEQNB_Gain_12_dB,
+                                          LVEQNB_Gain_13_dB,
+                                          LVEQNB_Gain_14_dB,
+                                          LVEQNB_Gain_15_dB};          /* +15dB gain */
+#else
 const LVM_INT16     LVEQNB_GainTable[] = {LVEQNB_Gain_Neg15_dB,        /* -15dB gain */
                                           LVEQNB_Gain_Neg14_dB,
                                           LVEQNB_Gain_Neg13_dB,
@@ -101,10 +166,28 @@
                                           LVEQNB_Gain_14_dB,
                                           LVEQNB_Gain_15_dB};          /* +15dB gain */
 
-
+#endif
 /*
  * D table for 100 / (Gain + 1)
  */
+#ifdef BUILD_FLOAT
+const LVM_FLOAT    LVEQNB_DTable[] = {LVEQNB_100D_Neg15_dB,            /* -15dB gain */
+                                      LVEQNB_100D_Neg14_dB,
+                                      LVEQNB_100D_Neg13_dB,
+                                      LVEQNB_100D_Neg12_dB,
+                                      LVEQNB_100D_Neg11_dB,
+                                      LVEQNB_100D_Neg10_dB,
+                                      LVEQNB_100D_Neg9_dB,
+                                      LVEQNB_100D_Neg8_dB,
+                                      LVEQNB_100D_Neg7_dB,
+                                      LVEQNB_100D_Neg6_dB,
+                                      LVEQNB_100D_Neg5_dB,
+                                      LVEQNB_100D_Neg4_dB,
+                                      LVEQNB_100D_Neg3_dB,
+                                      LVEQNB_100D_Neg2_dB,
+                                      LVEQNB_100D_Neg1_dB,
+                                      LVEQNB_100D_0_dB};               /* 0dB gain */
+#else
 const LVM_INT16    LVEQNB_DTable[] = {LVEQNB_100D_Neg15_dB,            /* -15dB gain */
                                       LVEQNB_100D_Neg14_dB,
                                       LVEQNB_100D_Neg13_dB,
@@ -122,7 +205,7 @@
                                       LVEQNB_100D_Neg1_dB,
                                       LVEQNB_100D_0_dB};               /* 0dB gain */
 
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /*    Filter polynomial coefficients                                                */
diff --git a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
index 28e3369..9c2e297 100644
--- a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
+++ b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
@@ -107,8 +107,14 @@
 
     /* Parameters for REV */
     LVM_UINT16                  Level;                  /* Level, 0 to 100 representing percentage of reverb */
+#ifndef HIGHER_FS
     LVM_UINT16                  LPF;                    /* Low pass filter, in Hz */
     LVM_UINT16                  HPF;                    /* High pass filter, in Hz */
+#else
+    LVM_UINT32                  LPF;                    /* Low pass filter, in Hz */
+    LVM_UINT32                  HPF;                    /* High pass filter, in Hz */
+#endif
+
     LVM_UINT16                  T60;                    /* Decay time constant, in ms */
     LVM_UINT16                  Density;                /* Echo density, 0 to 100 for minimum to maximum density */
     LVM_UINT16                  Damping;                /* Damping */
@@ -297,11 +303,17 @@
 /*  1. The input and output buffers must be 32-bit aligned                              */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t      hInstance,
+                                    const LVM_FLOAT     *pInData,
+                                    LVM_FLOAT           *pOutData,
+                                    const LVM_UINT16          NumSamples);
+#else
 LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t      hInstance,
                                     const LVM_INT32     *pInData,
                                     LVM_INT32           *pOutData,
                                     const LVM_UINT16          NumSamples);
-
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
index ac2ef9d..e710844 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
@@ -41,6 +41,7 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef BUILD_FLOAT
 LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st     *pPrivate)
 {
 
@@ -593,8 +594,589 @@
 
     return LVREV_SUCCESS;
 }
+#else /* BUILD_FLOAT*/
+LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st     *pPrivate)
+{
+
+    LVM_Mode_en  OperatingMode;
+    LVM_INT32    NumberOfDelayLines;
 
 
+    /* Check for NULL pointer */
+    if(pPrivate == LVM_NULL)
+    {
+        return LVREV_NULLADDRESS;
+    }
+
+    OperatingMode = pPrivate->NewParams.OperatingMode;
+
+    if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+    {
+        NumberOfDelayLines = 4;
+    }
+    else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+    {
+        NumberOfDelayLines = 2;
+    }
+    else
+    {
+        NumberOfDelayLines = 1;
+    }
+
+    /*
+     * Update the high pass filter coefficients
+     */
+    if((pPrivate->NewParams.HPF        != pPrivate->CurrentParams.HPF)        ||
+       (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+       (pPrivate->bFirstControl        == LVM_TRUE))
+    {
+        LVM_FLOAT       Omega;
+        FO_FLOAT_Coefs_t  Coeffs;
+
+        Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
+        LVM_FO_HPF(Omega, &Coeffs);
+        FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs,
+                                         &pPrivate->pFastData->HPTaps, &Coeffs);
+        LoadConst_Float(0,
+                        (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: \
+                                                                 no dereferencing in function*/
+                        sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+    }
+
+
+    /*
+     * Update the low pass filter coefficients
+     */
+    if((pPrivate->NewParams.LPF        != pPrivate->CurrentParams.LPF)        ||
+       (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+       (pPrivate->bFirstControl        == LVM_TRUE))
+    {
+        LVM_FLOAT       Omega;
+        FO_FLOAT_Coefs_t  Coeffs;
+
+        Coeffs.A0 = 1;
+        Coeffs.A1 = 0;
+        Coeffs.B1 = 0;
+        if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
+        {
+            Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate);
+
+            /*
+             * Do not apply filter if w =2*pi*fc/fs >= 2.9
+             */
+            if(Omega <= (LVM_FLOAT)LVREV_2_9_INQ29)
+            {
+                LVM_FO_LPF(Omega, &Coeffs);
+            }
+        }
+        FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs,
+                                         &pPrivate->pFastData->LPTaps, &Coeffs);
+        LoadConst_Float(0,
+                        (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: \
+                                                                 no dereferencing in function*/
+                        sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+    }
+
+
+    /*
+     * Calculate the room size parameter
+     */
+    if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize)
+    {
+        /* Room size range is 10ms to 200ms
+         * 0%   -- 10ms
+         * 50%  -- 65ms
+         * 100% -- 120ms
+         */
+        pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5) / 10);
+    }
+
+
+    /*
+     * Update the T delay number of samples and the all pass delay number of samples
+     */
+    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
+        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+        (pPrivate->bFirstControl        == LVM_TRUE))
+    {
+
+        LVM_UINT32  Temp;
+        LVM_INT32   APDelaySize;
+        LVM_INT32   Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate);
+        LVM_UINT32  DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms);
+        LVM_INT16   i;
+        LVM_FLOAT   ScaleTable[]  = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, \
+                                     LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
+        LVM_INT16   MaxT_Delay[]  = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, \
+                                     LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY};
+        LVM_INT16   MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, \
+                                     LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
+
+
+        /*
+         * For each delay line
+         */
+        for (i = 0; i < NumberOfDelayLines; i++)
+        {
+            if (i != 0)
+            {
+                LVM_FLOAT Temp1;  /* to avoid QAC warning on type conversion */
+
+                Temp1=(LVM_FLOAT)DelayLengthSamples;
+                Temp = (LVM_UINT32)(Temp1 * ScaleTable[i]);
+            }
+            else
+            {
+               Temp = DelayLengthSamples;
+            }
+            APDelaySize = Temp  / 1500;
+
+
+            /*
+             * Set the fixed delay
+             */
+
+#ifdef HIGHER_FS
+            Temp  = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
+#else
+            Temp  = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000;
+#endif
+            pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
+
+
+            /*
+             * Set the tap selection
+             */
+            if (pPrivate->AB_Selection)
+            {
+                /* Smooth from tap A to tap B */
+                pPrivate->pOffsetB[i]             = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
+                                                                           Temp - APDelaySize];
+                pPrivate->B_DelaySize[i]          = APDelaySize;
+                pPrivate->Mixer_APTaps[i].Target1 = 0;
+                pPrivate->Mixer_APTaps[i].Target2 = 1.0f;
+            }
+            else
+            {
+                /* Smooth from tap B to tap A */
+                pPrivate->pOffsetA[i]             = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
+                                                                           Temp - APDelaySize];
+                pPrivate->A_DelaySize[i]          = APDelaySize;
+                pPrivate->Mixer_APTaps[i].Target2 = 0;
+                pPrivate->Mixer_APTaps[i].Target1 = 1.0f;
+            }
+
+            /*
+             * Set the maximum block size to the smallest delay size
+             */
+            pPrivate->MaxBlkLen   = Temp;
+            if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i])
+            {
+                pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i];
+            }
+            if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i])
+            {
+                pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i];
+            }
+        }
+        if (pPrivate->AB_Selection)
+        {
+            pPrivate->AB_Selection = 0;
+        }
+        else
+        {
+            pPrivate->AB_Selection = 1;
+        }
+
+
+        /*
+         * Limit the maximum block length
+         */
+        /* Just as a precausion, but no problem if we remove this line      */
+        pPrivate->MaxBlkLen = pPrivate->MaxBlkLen - 2;
+        if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize)
+        {
+            pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize;
+        }
+    }
+
+
+
+    /*
+     * Update the low pass filter coefficient
+     */
+    if( (pPrivate->NewParams.Damping    != pPrivate->CurrentParams.Damping)    ||
+        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+        (pPrivate->bFirstControl        == LVM_TRUE))
+    {
+
+        LVM_INT32       Temp;
+        LVM_FLOAT       Omega;
+        FO_FLOAT_Coefs_t  Coeffs;
+        LVM_INT16       i;
+        LVM_INT16       Damping      = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000);
+        LVM_FLOAT       ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4,
+                                        LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4};
+
+
+        /*
+         * For each filter
+         */
+        for (i = 0; i < NumberOfDelayLines; i++)
+        {
+            if (i != 0)
+            {
+                Temp = (LVM_INT32)(ScaleTable[i] * Damping);
+            }
+            else
+            {
+                Temp = Damping;
+            }
+            if(Temp <= (LVM_INT32)(LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
+            {
+                Omega = LVM_GetOmega(Temp, pPrivate->NewParams.SampleRate);
+                LVM_FO_LPF(Omega, &Coeffs);
+            }
+            else
+            {
+                Coeffs.A0 = 1;
+                Coeffs.A1 = 0;
+                Coeffs.B1 = 0;
+            }
+            FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
+                                            &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
+        }
+    }
+
+
+    /*
+     * Update All-pass filter mixer time constants
+     */
+    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
+        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+        (pPrivate->NewParams.Density    != pPrivate->CurrentParams.Density))
+    {
+        LVM_INT16   i;
+        LVM_FLOAT   Alpha;
+        LVM_FLOAT   AlphaTap;
+
+        Alpha = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC,
+                                       LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+                                       1);
+
+        AlphaTap = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC,
+                                          LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+                                          1);
+
+        for (i = 0; i < 4; i++)
+        {
+            pPrivate->Mixer_APTaps[i].Alpha1       = AlphaTap;
+            pPrivate->Mixer_APTaps[i].Alpha2       = AlphaTap;
+            pPrivate->Mixer_SGFeedback[i].Alpha    = Alpha;
+            pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha;
+        }
+    }
+
+
+    /*
+     * Update the feed back gain
+     */
+    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
+        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
+        (pPrivate->NewParams.T60        != pPrivate->CurrentParams.T60)        ||
+        (pPrivate->bFirstControl        == LVM_TRUE))
+    {
+
+        LVM_FLOAT               G[4];                       /* Feedback gain (Q7.24) */
+
+        if(pPrivate->NewParams.T60 == 0)
+        {
+            G[3] = 0;
+            G[2] = 0;
+            G[1] = 0;
+            G[0] = 0;
+        }
+        else
+        {
+            LVM_FLOAT   Temp1;
+            LVM_FLOAT   Temp2;
+            LVM_INT16   i;
+            LVM_FLOAT   ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
+                                        LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
+
+
+            /*
+             * For each delay line
+             */
+            for (i = 0; i < NumberOfDelayLines; i++)
+            {
+                Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60;
+                if(Temp1 >= (4))
+                {
+                    G[i] = 0;
+                }
+                else if((Temp1 >= (2)))
+                {
+                    Temp2 = LVM_Power10(-(Temp1 / 2.0f));
+                    Temp1 = LVM_Power10(-(Temp1 / 2.0f));
+                    Temp1 = Temp1 * Temp2;
+                }
+                else
+                {
+                    Temp1 = LVM_Power10(-(Temp1));
+                }
+                if (NumberOfDelayLines == 1)
+                {
+                    G[i] = Temp1;
+                }
+                else
+                {
+                    LVM_FLOAT   TempG;
+                    TempG = Temp1 * ONE_OVER_SQRT_TWO;
+                    G[i]=TempG;
+                }
+            }
+        }
+
+        /* Set up the feedback mixers for four delay lines */
+        pPrivate->FeedbackMixer[0].Target=G[0];
+        pPrivate->FeedbackMixer[1].Target=G[1];
+        pPrivate->FeedbackMixer[2].Target=G[2];
+        pPrivate->FeedbackMixer[3].Target=G[3];
+    }
+
+
+    /*
+     * Calculate the gain correction
+     */
+    if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
+       (pPrivate->NewParams.Level    != pPrivate->CurrentParams.Level)    ||
+       (pPrivate->NewParams.T60      != pPrivate->CurrentParams.T60) )
+    {
+        LVM_INT32 Index=0;
+        LVM_FLOAT Index_FLOAT;
+        LVM_INT32 i=0;
+        LVM_FLOAT Gain=0;
+        LVM_INT32 RoomSize=0;
+        LVM_FLOAT T60;
+        LVM_FLOAT Coefs[5];
+
+
+        if(pPrivate->NewParams.RoomSize == 0)
+        {
+            RoomSize = 1;
+        }
+        else
+        {
+            RoomSize = (LVM_INT32)pPrivate->NewParams.RoomSize;
+        }
+
+
+        if(pPrivate->NewParams.T60 < 100)
+        {
+            T60 = 100 * LVREV_T60_SCALE;
+        }
+        else
+        {
+            T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE;
+        }
+
+        /* Find the nearest room size in table */
+        for(i = 0; i < 24; i++)
+        {
+            if(RoomSize <= LVREV_GainPolyTable[i][0])
+            {
+                Index = i;
+                break;
+            }
+        }
+
+
+        if(RoomSize == LVREV_GainPolyTable[Index][0])
+        {
+            /* Take table values if the room size is in table */
+            for(i = 1; i < 5; i++)
+            {
+                Coefs[i-1] = LVREV_GainPolyTable[Index][i];
+            }
+            Coefs[4] = 0;
+            Gain = LVM_Polynomial(3, Coefs, T60);       /* Q.24 result */
+        }
+        else
+        {
+            /* Interpolate the gain between nearest room sizes */
+
+            LVM_FLOAT Gain1,Gain2;
+            LVM_INT32 Tot_Dist,Dist;
+
+            Tot_Dist = (LVM_UINT32)LVREV_GainPolyTable[Index][0] - \
+                                            (LVM_UINT32)LVREV_GainPolyTable[Index-1][0];
+            Dist = RoomSize - (LVM_UINT32)LVREV_GainPolyTable[Index - 1][0];
+
+
+            /* Get gain for first */
+            for(i = 1; i < 5; i++)
+            {
+                Coefs[i-1] = LVREV_GainPolyTable[Index-1][i];
+            }
+            Coefs[4] = 0;
+
+            Gain1 = LVM_Polynomial(3, Coefs, T60);      /* Q.24 result */
+
+            /* Get gain for second */
+            for(i = 1; i < 5; i++)
+            {
+                Coefs[i-1] = LVREV_GainPolyTable[Index][i];
+            }
+            Coefs[4] = 0;
+
+            Gain2 = LVM_Polynomial(3, Coefs, T60);      /* Q.24 result */
+
+            /* Linear Interpolate the gain */
+            Gain = Gain1 + (((Gain2 - Gain1) * Dist) / (Tot_Dist));
+        }
+
+
+        /*
+         * Get the inverse of gain: Q.15
+         * Gain is mostly above one except few cases, take only gains above 1
+         */
+        if(Gain < 1)
+        {
+            pPrivate->Gain = 1;
+        }
+        else
+        {
+            pPrivate->Gain = 1 / Gain;
+        }
+
+        Index_FLOAT = 100.0f / (LVM_FLOAT)(100 + pPrivate->NewParams.Level);
+        pPrivate->Gain = pPrivate->Gain * Index_FLOAT;
+        pPrivate->GainMixer.Target = (pPrivate->Gain*Index_FLOAT) / 2;
+    }
+
+
+    /*
+     * Update the all pass comb filter coefficient
+     */
+    if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) ||
+        (pPrivate->bFirstControl     == LVM_TRUE))
+    {
+        LVM_INT16   i;
+        LVM_FLOAT   b = (LVM_FLOAT)pPrivate->NewParams.Density * LVREV_B_8_on_1000;
+
+        for (i = 0; i < 4; i++)
+        {
+            pPrivate->Mixer_SGFeedback[i].Target    = b;
+            pPrivate->Mixer_SGFeedforward[i].Target = b;
+        }
+    }
+
+
+    /*
+     * Update the bypass mixer time constant
+     */
+    if((pPrivate->NewParams.SampleRate   != pPrivate->CurrentParams.SampleRate)   ||
+       (pPrivate->bFirstControl          == LVM_TRUE))
+    {
+        LVM_UINT16   NumChannels = 1;                       /* Assume MONO format */
+        LVM_FLOAT    Alpha;
+
+        Alpha = LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC,
+                                       LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
+                                       NumChannels);
+        pPrivate->FeedbackMixer[0].Alpha = Alpha;
+        pPrivate->FeedbackMixer[1].Alpha = Alpha;
+        pPrivate->FeedbackMixer[2].Alpha = Alpha;
+        pPrivate->FeedbackMixer[3].Alpha = Alpha;
+
+        NumChannels = 2;                                    /* Always stereo output */
+        pPrivate->BypassMixer.Alpha1 = LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC,
+                             LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
+        pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1;
+        pPrivate->GainMixer.Alpha    = pPrivate->BypassMixer.Alpha1;
+    }
+
+
+    /*
+     * Update the bypass mixer targets
+     */
+    if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) &&
+        (pPrivate->NewParams.OperatingMode == LVM_MODE_ON))
+    {
+        pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
+        pPrivate->BypassMixer.Target1 = 0x00000000;
+        if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE))
+        {
+            pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
+        }
+        if (pPrivate->NewParams.Level != 0)
+        {
+            pPrivate->bDisableReverb = LVM_FALSE;
+        }
+    }
+
+    if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode)
+    {
+        if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON)
+        {
+            pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
+            pPrivate->BypassMixer.Target1 = 0x00000000;
+
+            pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE;
+            OperatingMode                      = LVM_MODE_ON;
+            if (pPrivate->NewParams.Level == 0)
+            {
+                pPrivate->bDisableReverb = LVM_TRUE;
+            }
+            else
+            {
+                pPrivate->bDisableReverb = LVM_FALSE;
+            }
+        }
+        else if (pPrivate->bFirstControl == LVM_FALSE)
+        {
+            pPrivate->BypassMixer.Target2 = 0x00000000;
+            pPrivate->BypassMixer.Target1 = 0x00000000;
+            pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
+            pPrivate->GainMixer.Target    = 0.03125f;
+            OperatingMode = LVM_MODE_ON;
+        }
+        else
+        {
+            OperatingMode = LVM_MODE_OFF;
+        }
+    }
+
+
+    /*  If it is the first call to ApplyNew settings force the current to the target \
+        to begin immediate playback of the effect */
+    if(pPrivate->bFirstControl == LVM_TRUE)
+    {
+        pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1;
+        pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2;
+    }
+
+
+    /*
+     * Copy the new parameters
+     */
+    pPrivate->CurrentParams = pPrivate->NewParams;
+    pPrivate->CurrentParams.OperatingMode = OperatingMode;
+
+
+    /*
+     * Update flag
+     */
+    if(pPrivate->bFirstControl == LVM_TRUE)
+    {
+        pPrivate->bFirstControl = LVM_FALSE;
+    }
+
+
+    return LVREV_SUCCESS;
+}
+#endif /*BUILD_FLOAT*/
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                BypassMixer_Callback                                        */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
index 6bb1e88..9491016 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
@@ -61,16 +61,26 @@
      * Clear all filter tap data, delay-lines and other signal related data
      */
 
-
+#ifdef BUILD_FLOAT
+    LoadConst_Float(0,
+                    (void *)&pLVREV_Private->pFastData->HPTaps, /* Destination Cast to void: \
+                                                                   no dereferencing in function*/
+                    2);
+    LoadConst_Float(0,
+                    (void *)&pLVREV_Private->pFastData->LPTaps, /* Destination Cast to void: \
+                                                                   no dereferencing in function*/
+                    2);
+#else
     LoadConst_32(0,
         (void *)&pLVREV_Private->pFastData->HPTaps, /* Destination Cast to void: no dereferencing in function*/
         2);
     LoadConst_32(0,
         (void *)&pLVREV_Private->pFastData->LPTaps, /* Destination Cast to void: no dereferencing in function*/
         2);
-
+#endif
     if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
     {
+#ifndef BUILD_FLOAT
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
@@ -80,24 +90,46 @@
         LoadConst_32(0,pLVREV_Private->pDelay_T[2], (LVM_INT16)LVREV_MAX_T2_DELAY);
         LoadConst_32(0,pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
         LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
 
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
     }
 
     if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2)
     {
+#ifndef BUILD_FLOAT
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
 
         LoadConst_32(0,pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
         LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
     }
 
     if((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1)
     {
+#ifndef BUILD_FLOAT
         LoadConst_32(0, (LVM_INT32 *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
         LoadConst_32(0,pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#else
+        LoadConst_Float(0, (LVM_FLOAT *)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
     }
-
     return LVREV_SUCCESS;
 }
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
index ffa5138..3366bcb 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
@@ -108,11 +108,29 @@
     /*
      * Zero all memory regions
      */
-     LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size)/sizeof(LVM_INT16)));
-     LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size)/sizeof(LVM_INT16)));
-     LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size)/sizeof(LVM_INT16)));
-     LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size)/sizeof(LVM_INT16)));
-
+#ifdef BUILD_FLOAT
+    LoadConst_Float(0,
+                    (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress,
+                    (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size) / \
+                                                    sizeof(LVM_FLOAT)));
+    LoadConst_Float(0,
+                    (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress,
+                    (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size) / \
+                                                    sizeof(LVM_FLOAT)));
+    LoadConst_Float(0,
+                    (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress,
+                    (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size) / \
+                                                    sizeof(LVM_FLOAT)));
+    LoadConst_Float(0,
+                    (LVM_FLOAT *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress,
+                    (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size) / \
+                                                    sizeof(LVM_FLOAT)));
+#else
+    LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size)/sizeof(LVM_INT16)));
+    LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size)/sizeof(LVM_INT16)));
+    LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size)/sizeof(LVM_INT16)));
+    LoadConst_16(0, (LVM_INT16 *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress, (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size)/sizeof(LVM_INT16)));
+#endif
     /*
      * Set the instance handle if not already initialised
      */
@@ -146,7 +164,7 @@
      * Set the data, coefficient and temporary memory pointers
      */
     pLVREV_Private->pFastData = InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));                              /* Fast data memory base address */
-
+#ifndef BUILD_FLOAT
     if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
     {
         pLVREV_Private->pDelay_T[3]     = InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY  * sizeof(LVM_INT32));
@@ -190,7 +208,67 @@
 
         LoadConst_32(0,pLVREV_Private->pDelay_T[0]  , (LVM_INT16)LVREV_MAX_T0_DELAY);
     }
+#else
+    if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
+    {
+        pLVREV_Private->pDelay_T[3]     = InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * \
+                                                              sizeof(LVM_FLOAT));
+        pLVREV_Private->pDelay_T[2]     = InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * \
+                                                              sizeof(LVM_FLOAT));
+        pLVREV_Private->pDelay_T[1]     = InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
+                                                              sizeof(LVM_FLOAT));
+        pLVREV_Private->pDelay_T[0]     = InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
+                                                              sizeof(LVM_FLOAT));
 
+        for(i = 0; i < 4; i++)
+        {
+            /* Scratch for each delay line output */
+            pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+                                                                       sizeof(LVM_FLOAT) * \
+                                                                       MaxBlockSize);
+        }
+
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+    }
+
+    if(pInstanceParams->NumDelays == LVREV_DELAYLINES_2)
+    {
+        pLVREV_Private->pDelay_T[1]  = InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
+                                                           sizeof(LVM_FLOAT));
+        pLVREV_Private->pDelay_T[0]  = InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
+                                                           sizeof(LVM_FLOAT));
+
+        for(i = 0; i < 2; i++)
+        {
+            /* Scratch for each delay line output */
+            pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+                                                                       sizeof(LVM_FLOAT) * \
+                                                                       MaxBlockSize);
+        }
+
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+    }
+
+    if(pInstanceParams->NumDelays == LVREV_DELAYLINES_1)
+    {
+        pLVREV_Private->pDelay_T[0]  = InstAlloc_AddMember(&FastData,
+                                                           LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+
+        for(i = 0; i < 1; i++)
+        {
+            /* Scratch for each delay line output */
+            pLVREV_Private->pScratchDelayLine[i] = InstAlloc_AddMember(&Temporary,
+                                                                       sizeof(LVM_FLOAT) * \
+                                                                       MaxBlockSize);
+        }
+
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+    }
+#endif
     /* All-pass delay buffer addresses and sizes */
     pLVREV_Private->T[0]         = LVREV_MAX_T0_DELAY;
     pLVREV_Private->T[1]         = LVREV_MAX_T1_DELAY;
@@ -200,10 +278,19 @@
 
 
     pLVREV_Private->pFastCoef       = InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));                        /* Fast coefficient memory base address */
+#ifndef BUILD_FLOAT
     pLVREV_Private->pScratch        = InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize);                /* General purpose scratch */
     pLVREV_Private->pInputSave      = InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_INT32) * MaxBlockSize);            /* Mono->stereo input save for end mix */
     LoadConst_32(0, pLVREV_Private->pInputSave, (LVM_INT16)(MaxBlockSize*2));
-
+#else
+    /* General purpose scratch */
+    pLVREV_Private->pScratch        = InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * \
+                                                          MaxBlockSize);
+    /* Mono->stereo input save for end mix */
+    pLVREV_Private->pInputSave      = InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * \
+                                                          MaxBlockSize);
+    LoadConst_Float(0, pLVREV_Private->pInputSave, (LVM_INT16)(MaxBlockSize * 2));
+#endif
 
     /*
      * Save the instance parameters in the instance structure
@@ -252,9 +339,13 @@
     pLVREV_Private->GainMixer.pGeneralPurpose    = LVM_NULL;
     pLVREV_Private->GainMixer.pCallBack          = LVM_NULL;
     pLVREV_Private->GainMixer.CallbackSet        = LVM_FALSE;
+#ifndef BUILD_FLOAT
     pLVREV_Private->GainMixer.Current            = 0x03ffffff;
     pLVREV_Private->GainMixer.Target             = 0x03ffffff;
-
+#else
+    pLVREV_Private->GainMixer.Current            = 0.03125f;//0x03ffffff;
+    pLVREV_Private->GainMixer.Target             = 0.03125f;//0x03ffffff;
+#endif
 
     /*
      * Set the All-Pass Filter mixers
@@ -277,7 +368,11 @@
         pLVREV_Private->Mixer_APTaps[i].pCallBack1       = LVM_NULL;
         pLVREV_Private->Mixer_APTaps[i].CallbackSet1     = LVM_FALSE;
         pLVREV_Private->Mixer_APTaps[i].Current1         = 0;
+#ifndef BUILD_FLOAT
         pLVREV_Private->Mixer_APTaps[i].Target1          = 0x7fffffff;
+#else
+        pLVREV_Private->Mixer_APTaps[i].Target1          = 1;
+#endif
         /* Feedforward mixer */
         pLVREV_Private->Mixer_SGFeedforward[i].CallbackParam   = 0;
         pLVREV_Private->Mixer_SGFeedforward[i].pCallbackHandle = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
index 2012432..f6d446b 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
@@ -161,21 +161,37 @@
         InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
         if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
         {
+#ifndef BUILD_FLOAT
             InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY  * sizeof(LVM_INT32));
             InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY  * sizeof(LVM_INT32));
             InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_INT32));
             InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
         }
 
         if(pInstanceParams->NumDelays == LVREV_DELAYLINES_2)
         {
+#ifndef BUILD_FLOAT
             InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_INT32));
             InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
         }
 
         if(pInstanceParams->NumDelays == LVREV_DELAYLINES_1)
         {
+#ifndef BUILD_FLOAT
             InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_INT32));
+#else
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
         }
 
         pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size         = InstAlloc_GetTotal(&FastData);
@@ -195,14 +211,25 @@
         /*
          * Temporary fast memory
          */
+#ifndef BUILD_FLOAT
         InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize);          /* General purpose scratch memory */
         InstAlloc_AddMember(&Temporary, 2*sizeof(LVM_INT32) * MaxBlockSize);        /* Mono->stereo input saved for end mix */
-
+#else
+        /* General purpose scratch memory */
+        InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+        /* Mono->stereo input saved for end mix */
+        InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
         if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
         {
             for(i=0; i<4; i++)
             {
+#ifndef BUILD_FLOAT
                 InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize);      /* A Scratch buffer for each delay line */
+#else
+                /* A Scratch buffer for each delay line */
+                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
             }
         }
 
@@ -210,7 +237,12 @@
         {
             for(i=0; i<2; i++)
             {
+#ifndef BUILD_FLOAT
                 InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize);      /* A Scratch buffer for each delay line */
+#else
+                /* A Scratch buffer for each delay line */
+                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
             }
         }
 
@@ -218,7 +250,12 @@
         {
             for(i=0; i<1; i++)
             {
+#ifndef BUILD_FLOAT
                 InstAlloc_AddMember(&Temporary, sizeof(LVM_INT32) * MaxBlockSize);      /* A Scratch buffer for each delay line */
+#else
+                /* A Scratch buffer for each delay line */
+                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+#endif
             }
         }
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index fbfa437..ff7475e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -42,16 +42,27 @@
 /*  Defines                                                                             */
 /*                                                                                      */
 /****************************************************************************************/
+#ifndef BUILD_FLOAT
 /* General */
 #define ONE_OVER_SQRT_TWO               23170           /* 1/sqrt(2) * 2^15 */
 #define LVREV_B_8_on_1000            17179869           /* 0.8 * 2^31 */
 #define LVREV_HEADROOM                   8192           /* -12dB * 2^15 */
 #define LVREV_2_9_INQ29           1583769190L           /* 2.9 in Q29 format */
 #define LVREV_MIN3DB                   0x5A82           /* -3dB in Q15 format */
+#else
+/* General */
+#define ONE_OVER_SQRT_TWO            0.707107f           /* 1/sqrt(2) * 2^15 */
+#define LVREV_B_8_on_1000               0.008f           /* 0.8 * 2^31 */
+#define LVREV_HEADROOM                   0.25f           /* -12dB * 2^15 */
+#define LVREV_2_9_INQ29                   2.9f           /* 2.9 in Q29 format */
+#define LVREV_MIN3DB                0.7079457f           /* -3dB in Q15 format */
+#endif
 
 /* Intenal constants */
 #define LVREV_LP_Poly_Order                 4
 #define LVREV_LP_Poly_Shift                 5
+
+#ifndef BUILD_FLOAT
 #define LVREV_T_3_Power_0_on_4          32768
 #define LVREV_T_3_Power_1_on_4          43125
 #define LVREV_T_3_Power_2_on_4          56755
@@ -61,14 +72,47 @@
 #define LVREV_T_3_Power_minus1_on_4     24898           /* 3^(-1/4) * 2^15 */
 #define LVREV_T_3_Power_minus2_on_4     18919           /* 3^(-2/4) * 2^15 */
 #define LVREV_T_3_Power_minus3_on_4     14375           /* 3^(-3/4) * 2^15 */
-#define LVREV_MAX_T3_DELAY               2527           /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T2_DELAY               3326           /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T1_DELAY               4377           /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
-#define LVREV_MAX_T0_DELAY               5760           /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
-#define LVREV_MAX_AP3_DELAY              1685           /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP2_DELAY              2218           /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP1_DELAY              2918           /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
-#define LVREV_MAX_AP0_DELAY              3840           /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#else/*BUILD_FLOAT*/
+#define LVREV_T60_SCALE                0.000142f           /*(1/7000) */
+
+#define LVREV_T_3_Power_0_on_4              1.0f
+#define LVREV_T_3_Power_1_on_4         1.316074f
+#define LVREV_T_3_Power_2_on_4         1.732051f
+#define LVREV_T_3_Power_3_on_4         2.279507f
+#define LVREV_T_3_Power_minus0_on_4         1.0f        /* 3^(-0/4) * 2^15 */
+#define LVREV_T_3_Power_minus1_on_4    0.759836f        /* 3^(-1/4) * 2^15 */
+#define LVREV_T_3_Power_minus2_on_4    0.577350f        /* 3^(-2/4) * 2^15 */
+#define LVREV_T_3_Power_minus3_on_4    0.438691f        /* 3^(-3/4) * 2^15 */
+#endif
+
+#ifndef HIGHER_FS
+#define LVREV_MAX_T3_DELAY                2527           /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T2_DELAY                3326           /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T1_DELAY                4377           /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T0_DELAY                5760           /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
+#define LVREV_MAX_AP3_DELAY               1685           /* ((48000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP2_DELAY               2218           /* ((48000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP1_DELAY               2918           /* ((48000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP0_DELAY               3840           /* ((48000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#else
+    /* ((192000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T3_DELAY               10108
+    /* ((192000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T2_DELAY               13304
+    /* ((192000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T1_DELAY               17508
+    /* ((192000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1000 */
+#define LVREV_MAX_T0_DELAY               23040
+    /* ((192000 * 120 * LVREV_T_3_Power_minus3_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP3_DELAY               6740
+    /* ((192000 * 120 * LVREV_T_3_Power_minus2_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP2_DELAY               8872
+    /* ((192000 * 120 * LVREV_T_3_Power_minus1_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP1_DELAY              11672
+    /* ((192000 * 120 * LVREV_T_3_Power_minus0_on_4) >> 15) / 1500 */
+#define LVREV_MAX_AP0_DELAY              15360
+#endif
+
 #define LVREV_BYPASSMIXER_TC             1000           /* Bypass mixer time constant*/
 #define LVREV_ALLPASS_TC                 1000           /* All-pass filter time constant */
 #define LVREV_ALLPASS_TAP_TC             10000           /* All-pass filter dely tap change */
@@ -76,7 +120,12 @@
 #define LVREV_OUTPUTGAIN_SHIFT              5           /* Bits shift for output gain correction */
 
 /* Parameter limits */
+#ifndef HIGHER_FS
 #define LVREV_NUM_FS                        9           /* Number of supported sample rates */
+#else
+#define LVREV_NUM_FS                       11           /* Number of supported sample rates */
+#endif
+
 #define LVREV_MAXBLKSIZE_LIMIT             64           /* Maximum block size low limit */
 #define LVREV_MAX_LEVEL                   100           /* Maximum level, 100% */
 #define LVREV_MIN_LPF_CORNER               50           /* Low pass filter limits */
@@ -95,6 +144,7 @@
 /*  Structures                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
+#ifndef BUILD_FLOAT
 /* Fast data structure */
 typedef struct
 {
@@ -161,7 +211,81 @@
 
 } LVREV_Instance_st;
 
+#else /* BUILD_FLOAT */
 
+/* Fast data structure */
+typedef struct
+{
+    Biquad_1I_Order1_FLOAT_Taps_t HPTaps;                     /* High pass filter taps */
+    Biquad_1I_Order1_FLOAT_Taps_t LPTaps;                     /* Low pass filter taps */
+    Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4];               /* Reverb low pass filters taps */
+
+} LVREV_FastData_st;
+
+
+/* Fast coefficient structure */
+typedef struct
+{
+
+    Biquad_FLOAT_Instance_t       HPCoefs;              /* High pass filter coefficients */
+    Biquad_FLOAT_Instance_t       LPCoefs;              /* Low pass filter coefficients */
+    Biquad_FLOAT_Instance_t       RevLPCoefs[4];        /* Reverb low pass filters coefficients */
+
+} LVREV_FastCoef_st;
+typedef struct
+{
+    /* General */
+    LVREV_InstanceParams_st InstanceParams;           /* Initialisation time instance parameters */
+    LVREV_MemoryTable_st    MemoryTable;              /* Memory table */
+    LVREV_ControlParams_st  CurrentParams;            /* Parameters being used */
+    LVREV_ControlParams_st  NewParams;                /* New parameters from the \
+                                                         calling application */
+    LVM_CHAR                bControlPending;          /* Flag to indicate new parameters \
+                                                         are available */
+    LVM_CHAR                bFirstControl;            /* Flag to indicate that the control \
+                                                         function is called for the first time */
+    LVM_CHAR                bDisableReverb;           /* Flag to indicate that the mix level is
+                                                         0% and the reverb can be disabled */
+    LVM_INT32               RoomSizeInms;             /* Room size in msec */
+    LVM_INT32               MaxBlkLen;                /* Maximum block size for internal
+                                                         processing */
+
+    /* Aligned memory pointers */
+    LVREV_FastData_st       *pFastData;               /* Fast data memory base address */
+    LVREV_FastCoef_st       *pFastCoef;               /* Fast coefficient memory base address */
+    LVM_FLOAT               *pScratchDelayLine[4];    /* Delay line scratch memory */
+    LVM_FLOAT               *pScratch;                /* Multi ussge scratch */
+    LVM_FLOAT               *pInputSave;              /* Reverb block input save for dry/wet
+                                                         mixing*/
+
+    /* Feedback matrix */
+    Mix_1St_Cll_FLOAT_t     FeedbackMixer[4];         /* Mixer for Pop and Click Supression \
+                                                         caused by feedback Gain */
+
+
+    /* All-Pass Filter */
+    LVM_INT32               T[4];                     /* Maximum delay size of buffer */
+    LVM_FLOAT               *pDelay_T[4];             /* Pointer to delay buffers */
+    LVM_INT32               Delay_AP[4];              /* Offset to AP delay buffer start */
+    LVM_INT16               AB_Selection;             /* Smooth from tap A to B when 1 \
+                                                         otherwise B to A */
+    LVM_INT32               A_DelaySize[4];           /* A delay length in samples */
+    LVM_INT32               B_DelaySize[4];           /* B delay length in samples */
+    LVM_FLOAT               *pOffsetA[4];             /* Offset for the A delay tap */
+    LVM_FLOAT               *pOffsetB[4];             /* Offset for the B delay tap */
+    Mix_2St_Cll_FLOAT_t     Mixer_APTaps[4];          /* Smoothed AP delay mixer */
+    Mix_1St_Cll_FLOAT_t     Mixer_SGFeedback[4];      /* Smoothed SAfeedback gain */
+    Mix_1St_Cll_FLOAT_t     Mixer_SGFeedforward[4];   /* Smoothed AP feedforward gain */
+
+    /* Output gain */
+    Mix_2St_Cll_FLOAT_t     BypassMixer;              /* Dry/wet mixer */
+    LVM_FLOAT               Gain;                     /* Gain applied to output to maintain
+                                                         average signal power */
+    Mix_1St_Cll_FLOAT_t     GainMixer;                /* Gain smoothing */
+
+} LVREV_Instance_st;
+
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /*  Function prototypes                                                                 */
@@ -169,12 +293,17 @@
 /****************************************************************************************/
 
 LVREV_ReturnStatus_en   LVREV_ApplyNewSettings(LVREV_Instance_st     *pPrivate);
-
+#ifdef BUILD_FLOAT
+void                    ReverbBlock(LVM_FLOAT           *pInput,
+                                    LVM_FLOAT           *pOutput,
+                                    LVREV_Instance_st   *pPrivate,
+                                    LVM_UINT16          NumSamples);
+#else
 void                    ReverbBlock(LVM_INT32           *pInput,
                                     LVM_INT32           *pOutput,
                                     LVREV_Instance_st   *pPrivate,
                                     LVM_UINT16          NumSamples);
-
+#endif
 LVM_INT32               BypassMixer_Callback(void       *pCallbackData,
                                              void       *pGeneralPurpose,
                                              LVM_INT16  GeneralPurpose );
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
index 5c7a8a0..566d84f 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
@@ -46,14 +46,26 @@
 /*  1. The input and output buffers must be 32-bit aligned                              */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t      hInstance,
+                                    const LVM_FLOAT     *pInData,
+                                    LVM_FLOAT           *pOutData,
+                                    const LVM_UINT16    NumSamples)
+#else
 LVREV_ReturnStatus_en LVREV_Process(LVREV_Handle_t      hInstance,
                                     const LVM_INT32     *pInData,
                                     LVM_INT32           *pOutData,
                                     const LVM_UINT16    NumSamples)
+#endif
 {
    LVREV_Instance_st     *pLVREV_Private = (LVREV_Instance_st *)hInstance;
+#ifdef BUILD_FLOAT
+   LVM_FLOAT             *pInput  = (LVM_FLOAT *)pInData;
+   LVM_FLOAT             *pOutput = pOutData;
+#else
    LVM_INT32             *pInput  = (LVM_INT32 *)pInData;
    LVM_INT32             *pOutput = pOutData;
+#endif
    LVM_INT32             SamplesToProcess, RemainingSamples;
    LVM_INT32             format = 1;
 
@@ -105,7 +117,7 @@
             /*
              * Copy the data to the output buffer, convert to stereo is required
              */
-
+#ifndef BUILD_FLOAT
             if(pLVREV_Private->CurrentParams.SourceFormat == LVM_MONO){
                 MonoTo2I_32(pInput, pOutput, NumSamples);
             } else {
@@ -113,6 +125,15 @@
                         (LVM_INT16 *)pOutput,
                         (LVM_INT16)(NumSamples << 2)); // 32 bit data, stereo
             }
+#else
+            if(pLVREV_Private->CurrentParams.SourceFormat == LVM_MONO){
+                MonoTo2I_Float(pInput, pOutput, NumSamples);
+            } else {
+                Copy_Float(pInput,
+                           pOutput,
+                           (LVM_INT16)(NumSamples << 1)); // 32 bit data, stereo
+            }
+#endif
         }
 
         return LVREV_SUCCESS;
@@ -143,9 +164,13 @@
         }
 
         ReverbBlock(pInput, pOutput, pLVREV_Private, (LVM_UINT16)SamplesToProcess);
-
+#ifdef BUILD_FLOAT
+        pInput  = (LVM_FLOAT *)(pInput + (SamplesToProcess * format));
+        pOutput = (LVM_FLOAT *)(pOutput + (SamplesToProcess * 2));      // Always stereo output
+#else
         pInput  = (LVM_INT32 *)(pInput +(SamplesToProcess*format));
-        pOutput = (LVM_INT32 *)(pOutput+(SamplesToProcess*2));      // Always stereo output
+        pOutput = (LVM_INT32 *)(pOutput+(SamplesToProcess*2));
+#endif
     }
 
     return LVREV_SUCCESS;
@@ -175,7 +200,7 @@
 /*  1. The input and output buffers must be 32-bit aligned                              */
 /*                                                                                      */
 /****************************************************************************************/
-
+#ifndef BUILD_FLOAT
 void ReverbBlock(LVM_INT32 *pInput, LVM_INT32 *pOutput, LVREV_Instance_st *pPrivate, LVM_UINT16 NumSamples)
 {
     LVM_INT16   j, size;
@@ -479,7 +504,322 @@
 
     return;
 }
+#else
+void ReverbBlock(LVM_FLOAT *pInput, LVM_FLOAT *pOutput,
+                 LVREV_Instance_st *pPrivate, LVM_UINT16 NumSamples)
+{
+    LVM_INT16   j, size;
+    LVM_FLOAT   *pDelayLine;
+    LVM_FLOAT   *pDelayLineInput = pPrivate->pScratch;
+    LVM_FLOAT   *pScratch = pPrivate->pScratch;
+    LVM_FLOAT   *pIn;
+    LVM_FLOAT   *pTemp = pPrivate->pInputSave;
+    LVM_INT32   NumberOfDelayLines;
+
+    /******************************************************************************
+     * All calculations will go into the buffer pointed to by pTemp, this will    *
+     * then be mixed with the original input to create the final output.          *
+     *                                                                            *
+     * When INPLACE processing is selected this must be a temporary buffer and    *
+     * hence this is the worst case, so for simplicity this will ALWAYS be so     *
+     *                                                                            *
+     * The input buffer will remain untouched until the output of the mixer if    *
+     * INPLACE processing is selected.                                            *
+     *                                                                            *
+     * The temp buffer will always be NumSamples in size regardless of MONO or    *
+     * STEREO input. In the case of stereo input all processing is done in MONO   *
+     * and the final output is converted to STEREO after the mixer                *
+     ******************************************************************************/
+
+    if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+    {
+        NumberOfDelayLines = 4;
+    }
+    else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+    {
+        NumberOfDelayLines = 2;
+    }
+    else
+    {
+        NumberOfDelayLines = 1;
+    }
+
+    if(pPrivate->CurrentParams.SourceFormat == LVM_MONO)
+    {
+        pIn = pInput;
+    }
+    else
+    {
+        /*
+         *  Stereo to mono conversion
+         */
+
+        From2iToMono_Float(pInput,
+                           pTemp,
+                           (LVM_INT16)NumSamples);
+        pIn = pTemp;
+    }
+
+    Mult3s_Float(pIn,
+                 (LVM_FLOAT)LVREV_HEADROOM,
+                 pTemp,
+                 (LVM_INT16)NumSamples);
+
+    /*
+     *  High pass filter
+     */
+    FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->HPCoefs,
+                               pTemp,
+                               pTemp,
+                               (LVM_INT16)NumSamples);
+    /*
+     *  Low pass filter
+     */
+    FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->LPCoefs,
+                               pTemp,
+                               pTemp,
+                               (LVM_INT16)NumSamples);
+    
+    /*
+     *  Process all delay lines
+     */
+
+    for(j = 0; j < NumberOfDelayLines; j++)
+    {
+        pDelayLine = pPrivate->pScratchDelayLine[j];
+
+        /*
+         * All-pass filter with pop and click suppression
+         */
+        /* Get the smoothed, delayed output. Put it in the output buffer */
+        MixSoft_2St_D32C31_SAT(&pPrivate->Mixer_APTaps[j],
+                               pPrivate->pOffsetA[j],
+                               pPrivate->pOffsetB[j],
+                               pDelayLine,
+                               (LVM_INT16)NumSamples);
+        /* Re-align the all pass filter delay buffer and copying the fixed delay data \
+           to the AP delay in the process */
+        Copy_Float(&pPrivate->pDelay_T[j][NumSamples],
+                   pPrivate->pDelay_T[j],
+                   (LVM_INT16)(pPrivate->T[j] - NumSamples));         /* 32-bit data */
+        /* Apply the smoothed feedback and save to fixed delay input (currently empty) */
+        MixSoft_1St_D32C31_WRA(&pPrivate->Mixer_SGFeedback[j],
+                               pDelayLine,
+                               &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+                               (LVM_INT16)NumSamples);
+        /* Sum into the AP delay line */
+        Mac3s_Sat_Float(&pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+                        -1.0f,    /* Invert since the feedback coefficient is negative */
+                        &pPrivate->pDelay_T[j][pPrivate->Delay_AP[j] - NumSamples],
+                        (LVM_INT16)NumSamples);
+        /* Apply smoothed feedforward sand save to fixed delay input (currently empty) */
+        MixSoft_1St_D32C31_WRA(&pPrivate->Mixer_SGFeedforward[j],
+                               &pPrivate->pDelay_T[j][pPrivate->Delay_AP[j] - NumSamples],
+                               &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+                               (LVM_INT16)NumSamples);
+        /* Sum into the AP output */
+        Mac3s_Sat_Float(&pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+                        1.0f,
+                        pDelayLine,
+                        (LVM_INT16)NumSamples);
+
+        /*
+         *  Feedback gain
+         */
+        MixSoft_1St_D32C31_WRA(&pPrivate->FeedbackMixer[j], pDelayLine, pDelayLine, NumSamples);
+
+        /*
+         *  Low pass filter
+         */
+        FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->RevLPCoefs[j],
+                                   pDelayLine,
+                                   pDelayLine,
+                                   (LVM_INT16)NumSamples);
+    }
+
+    /*
+     *  Apply rotation matrix and delay samples
+     */
+    for(j = 0; j < NumberOfDelayLines; j++)
+    {
+
+        Copy_Float(pTemp,
+                   pDelayLineInput,
+                   (LVM_INT16)(NumSamples));
+        /*
+         *  Rotation matrix mix
+         */
+        switch(j)
+        {
+            case 3:
+                /*
+                 *  Add delay line 1 and 2 contribution
+                 */
+                 Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+                                 pDelayLineInput, (LVM_INT16)NumSamples);
+                 Mac3s_Sat_Float(pPrivate->pScratchDelayLine[2], -1.0f,
+                                 pDelayLineInput, (LVM_INT16)NumSamples);
+
+                break;
+            case 2:
+
+                /*
+                 *  Add delay line 0 and 3 contribution
+                 */
+                 Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+                                 pDelayLineInput, (LVM_INT16)NumSamples);
+                 Mac3s_Sat_Float(pPrivate->pScratchDelayLine[3], -1.0f,
+                                 pDelayLineInput, (LVM_INT16)NumSamples);
+
+                break;
+            case 1:
+                if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+                {
+                    /*
+                     *  Add delay line 0 and 3 contribution
+                     */
+                    Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+                                    pDelayLineInput, (LVM_INT16)NumSamples);
+                    Add2_Sat_Float(pPrivate->pScratchDelayLine[3], pDelayLineInput,
+                                   (LVM_INT16)NumSamples);
+
+                }
+                else
+                {
+                    /*
+                     *  Add delay line 0 and 1 contribution
+                     */
+                     Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0], -1.0f,
+                                     pDelayLineInput, (LVM_INT16)NumSamples);
+                     Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+                                     pDelayLineInput, (LVM_INT16)NumSamples);
+
+                }
+                break;
+            case 0:
+                if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
+                {
+                    /*
+                     *  Add delay line 1 and 2 contribution
+                     */
+                    Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+                                    pDelayLineInput, (LVM_INT16)NumSamples);
+                    Add2_Sat_Float(pPrivate->pScratchDelayLine[2], pDelayLineInput,
+                                   (LVM_INT16)NumSamples);
+
+                }
+                else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
+                {
+                    /*
+                     *  Add delay line 0 and 1 contribution
+                     */
+                    Add2_Sat_Float(pPrivate->pScratchDelayLine[0], pDelayLineInput,
+                                   (LVM_INT16)NumSamples);
+                    Mac3s_Sat_Float(pPrivate->pScratchDelayLine[1], -1.0f,
+                                    pDelayLineInput, (LVM_INT16)NumSamples);
+
+                }
+                else
+                {
+                    /*
+                     *  Add delay line 0 contribution
+                     */
+
+                    /*             SOURCE                          DESTINATION*/
+                    Add2_Sat_Float(pPrivate->pScratchDelayLine[0], pDelayLineInput,
+                                   (LVM_INT16)NumSamples);
+                }
+                break;
+            default:
+                break;
+        }
+
+        /*
+         *  Delay samples
+         */
+        Copy_Float(pDelayLineInput,
+                   &pPrivate->pDelay_T[j][pPrivate->T[j] - NumSamples],
+                   (LVM_INT16)(NumSamples));              /* 32-bit data */
+    }
 
 
+    /*
+     *  Create stereo output
+     */
+    switch(pPrivate->InstanceParams.NumDelays)
+    {
+        case LVREV_DELAYLINES_4:
+             Add2_Sat_Float(pPrivate->pScratchDelayLine[3],
+                            pPrivate->pScratchDelayLine[0],
+                            (LVM_INT16)NumSamples);
+             Add2_Sat_Float(pPrivate->pScratchDelayLine[2],
+                            pPrivate->pScratchDelayLine[1],
+                            (LVM_INT16)NumSamples);
+
+
+            JoinTo2i_Float(pPrivate->pScratchDelayLine[0],
+                           pPrivate->pScratchDelayLine[1],
+                           pTemp,
+                           (LVM_INT16)NumSamples);
+
+
+            break;
+        case LVREV_DELAYLINES_2:
+
+             Copy_Float(pPrivate->pScratchDelayLine[1],
+                        pScratch,
+                        (LVM_INT16)(NumSamples));
+
+             Mac3s_Sat_Float(pPrivate->pScratchDelayLine[0],
+                            -1.0f,
+                            pScratch,
+                            (LVM_INT16)NumSamples);
+
+             Add2_Sat_Float(pPrivate->pScratchDelayLine[1],
+                            pPrivate->pScratchDelayLine[0],
+                            (LVM_INT16)NumSamples);
+
+
+             JoinTo2i_Float(pPrivate->pScratchDelayLine[0],
+                            pScratch,
+                            pTemp,
+                            (LVM_INT16)NumSamples);
+            break;
+        case LVREV_DELAYLINES_1:
+            MonoTo2I_Float(pPrivate->pScratchDelayLine[0],
+                           pTemp,
+                           (LVM_INT16)NumSamples);
+            break;
+        default:
+            break;
+    }
+
+
+    /*
+     *  Dry/wet mixer
+     */
+
+    size = (LVM_INT16)(NumSamples << 1);
+    MixSoft_2St_D32C31_SAT(&pPrivate->BypassMixer,
+                           pTemp,
+                           pTemp,
+                           pOutput,
+                           size);
+
+    /* Apply Gain*/
+
+    Shift_Sat_Float(LVREV_OUTPUTGAIN_SHIFT,
+                    pOutput,
+                    pOutput,
+                    size);
+
+    MixSoft_1St_D32C31_WRA(&pPrivate->GainMixer,
+                           pOutput,
+                           pOutput,
+                           size);
+
+    return;
+}
+#endif
 /* End of file */
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
index f5895a7..a719053 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -61,10 +61,15 @@
      * Check all new control parameters are in range
      */
     if(    ((pNewParams->OperatingMode != LVM_MODE_OFF) && (pNewParams->OperatingMode != LVM_MODE_ON))                                         ||
-        ((pNewParams->SampleRate != LVM_FS_8000) && (pNewParams->SampleRate != LVM_FS_11025) && (pNewParams->SampleRate != LVM_FS_12000)       &&
+        (
+        (pNewParams->SampleRate != LVM_FS_8000) && (pNewParams->SampleRate != LVM_FS_11025) && (pNewParams->SampleRate != LVM_FS_12000)       &&
         (pNewParams->SampleRate != LVM_FS_16000) && (pNewParams->SampleRate != LVM_FS_22050) && (pNewParams->SampleRate != LVM_FS_24000)       &&
-        (pNewParams->SampleRate != LVM_FS_32000) && (pNewParams->SampleRate != LVM_FS_44100) && (pNewParams->SampleRate != LVM_FS_48000))      ||
-        ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
+        (pNewParams->SampleRate != LVM_FS_32000) && (pNewParams->SampleRate != LVM_FS_44100) && (pNewParams->SampleRate != LVM_FS_48000)      
+#ifdef HIGHER_FS
+        && (pNewParams->SampleRate != LVM_FS_96000) && (pNewParams->SampleRate != LVM_FS_192000)
+#endif
+        )
+        || ((pNewParams->SourceFormat != LVM_STEREO) && (pNewParams->SourceFormat != LVM_MONOINSTEREO) && (pNewParams->SourceFormat != LVM_MONO)) )
     {
         return (LVREV_OUTOFRANGE);
     }
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
index 5a6d43d..b3edc60 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -29,6 +29,7 @@
 /****************************************************************************************/
 
 /* Table with supported sampling rates.  The table can be indexed using LVM_Fs_en       */
+#ifndef HIGHER_FS
 const LVM_UINT16 LVM_FsTable[] = {
     8000 ,
     11025,
@@ -40,14 +41,37 @@
     44100,
     48000
 };
-
+#else
+const LVM_UINT32 LVM_FsTable[] = {
+    8000 ,
+    11025,
+    12000,
+    16000,
+    22050,
+    24000,
+    32000,
+    44100,
+    48000,
+    96000,
+    192000
+};
+#endif
 /* Table with supported sampling rates.  The table can be indexed using LVM_Fs_en       */
+#ifndef HIGHER_FS
 LVM_UINT16 LVM_GetFsFromTable(LVM_Fs_en FsIndex){
     if (FsIndex > LVM_FS_48000)
         return 0;
 
     return (LVM_FsTable[FsIndex]);
 }
+#else
+LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex){
+    if (FsIndex > LVM_FS_192000)
+        return 0;
+
+    return (LVM_FsTable[FsIndex]);
+}
+#endif
 
 /* In order to maintain consistant input and out put signal strengths
    output gain/attenuation is applied. This gain depends on T60 and Rooms
@@ -69,6 +93,7 @@
   */
 
 /* Normalizing output including Reverb Level part (only shift up)*/
+#ifndef BUILD_FLOAT
 const LVM_INT32 LVREV_GainPolyTable[24][5]={{1,17547434,128867434,-120988896,50761228,},
                                             {2,18256869,172666902,-193169292,88345744,},
                                             {3,16591311,139250151,-149667234,66770059,},
@@ -94,6 +119,32 @@
                                             {90,16003322,48323661,-35607378,13153872,},
                                             {100,15955223,48558201,-33706865,11715792,},
                                             };
-
+#else
+const LVM_FLOAT LVREV_GainPolyTable[24][5]={{1,1.045909f,7.681098f,-7.211500f,3.025605f,},
+                                            {2,1.088194f,10.291749f,-11.513787f,5.265817f,},
+                                            {3,0.988919f,8.299956f,-8.920862f,3.979806f,},
+                                            {4,1.035927f,10.182567f,-10.346134f,4.546533f,},
+                                            {5,1.130313f,12.538727f,-13.627023f,6.165208f,},
+                                            {6,1.060743f,8.091713f,-8.588079f,3.834230f,},
+                                            {7,1.040381f,10.406566f,-11.176650f,5.075132f,},
+                                            {8,1.026944f,8.387302f,-8.689796f,3.895863f,},
+                                            {9,1.013312f,9.727236f,-10.534165f,4.742272f,},
+                                            {10,0.996095f,8.492249f,-7.947677f,3.478917f,},
+                                            {13,1.079346f,8.894425f,-9.641768f,4.434442f,},
+                                            {15,0.994327f,7.441335f,-8.003979f,3.581177f,},
+                                            {17,0.991067f,7.208373f,-7.257859f,3.167774f,},
+                                            {20,1.033445f,7.476371f,-7.546960f,3.369703f,},
+                                            {25,0.982830f,5.913867f,-5.638448f,2.420932f,},
+                                            {30,0.928782f,5.035343f,-4.492104f,1.844904f,},
+                                            {40,0.953714f,5.060232f,-4.472204f,1.829642f,},
+                                            {50,0.899258f,4.273357f,-3.537492f,1.387576f,},
+                                            {60,0.943584f,4.093228f,-3.469658f,1.410911f,},
+                                            {70,0.926021f,3.973125f,-3.331985f,1.344690f,},
+                                            {75,0.894853f,2.871747f,-1.438758f,0.311856f,},
+                                            {80,0.935122f,2.991857f,-2.038882f,0.686395f,},
+                                            {90,0.953872f,2.880315f,-2.122365f,0.784032f,},
+                                            {100,0.951005f,2.894294f,-2.009086f,0.698316f,},
+};
+#endif
 /* End of file */
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
index 5f993bd..0658186 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -37,10 +37,19 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef HIGHER_FS
 extern const    LVM_UINT16  LVM_FsTable[];
 extern          LVM_UINT16  LVM_GetFsFromTable(LVM_Fs_en FsIndex);
-extern          LVM_INT32   LVREV_GainPolyTable[24][5];
+#else
+extern const    LVM_UINT32  LVM_FsTable[];
+extern          LVM_UINT32  LVM_GetFsFromTable(LVM_Fs_en FsIndex);
+#endif
 
+#ifndef BUILD_FLOAT
+extern          LVM_INT32   LVREV_GainPolyTable[24][5];
+#else
+extern          LVM_FLOAT   LVREV_GainPolyTable[24][5];
+#endif
 #ifdef __cplusplus
 }
 #endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
index a675cb2..2038fbb 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
@@ -216,11 +216,17 @@
 /*  otherwise           Error due to bad parameters                                                                              */
 /*                                                                                                                               */
 /*********************************************************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
+                                       LVM_FLOAT           *pLVPSA_InputSamples,
+                                       LVM_UINT16           InputBlockSize,
+                                       LVPSA_Time           AudioTime             );
+#else
 LVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
                                        LVM_INT16           *pLVPSA_InputSamples,
                                        LVM_UINT16           InputBlockSize,
                                        LVPSA_Time           AudioTime             );
-
+#endif
 /*********************************************************************************************************************************/
 /*                                                                                                                               */
 /* FUNCTION:            LVPSA_GetSpectrum                                                                                        */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
index cd5f69c..f6c4ea7 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
@@ -28,6 +28,15 @@
 LVPSA_RETURN LVPSA_SetQPFCoefficients( LVPSA_InstancePr_t        *pInst,
                                        LVPSA_ControlParams_t      *pParams  );
 
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPSinglePrecCoefs(  LVM_UINT16             Fs,
+                                       LVPSA_FilterParam_t   *pFilterParams,
+                                       BP_FLOAT_Coefs_t        *pCoefficients);
+
+LVPSA_RETURN LVPSA_BPDoublePrecCoefs(  LVM_UINT16            Fs,
+                                       LVPSA_FilterParam_t  *pFilterParams,
+                                       BP_FLOAT_Coefs_t       *pCoefficients);
+#else
 LVPSA_RETURN LVPSA_BPSinglePrecCoefs(  LVM_UINT16             Fs,
                                        LVPSA_FilterParam_t   *pFilterParams,
                                        BP_C16_Coefs_t        *pCoefficients);
@@ -39,7 +48,7 @@
 LVPSA_RETURN LVPSA_BPDoublePrecCoefs(  LVM_UINT16              Fs,
                                        LVPSA_FilterParam_t     *pFilterParams,
                                        BP_C32_Coefs_t          *pCoefficients);
-
+#endif
 LVPSA_RETURN LVPSA_SetBPFCoefficients( LVPSA_InstancePr_t        *pInst,
                                        LVPSA_ControlParams_t      *pParams  );
 
@@ -179,7 +188,11 @@
     LVM_UINT16 Freq;
     LVPSA_ControlParams_t   Params;
     extern LVM_INT16        LVPSA_nSamplesBufferUpdate[];
+#ifndef HIGHER_FS
     extern LVM_UINT16       LVPSA_SampleRateTab[];
+#else
+    extern LVM_UINT32       LVPSA_SampleRateTab[];
+#endif
     extern LVM_UINT16       LVPSA_DownSamplingFactor[];
 
 
@@ -267,8 +280,11 @@
 LVPSA_RETURN LVPSA_SetBPFiltersType (   LVPSA_InstancePr_t        *pInst,
                                         LVPSA_ControlParams_t      *pParams  )
 {
-
+#ifndef HIGHER_FS
     extern LVM_UINT16   LVPSA_SampleRateTab[];                                            /* Sample rate table */
+#else
+    extern LVM_UINT32   LVPSA_SampleRateTab[];                 /* Sample rate table */
+#endif
     LVM_UINT16          ii;                                                         /* Filter band index */
     LVM_UINT32          fs = (LVM_UINT32)LVPSA_SampleRateTab[(LVM_UINT16)pParams->Fs];      /* Sample rate */
     LVM_UINT32          fc;                                                         /* Filter centre frequency */
@@ -342,26 +358,42 @@
         {
             case    LVPSA_DoublePrecisionFilter:
             {
+#ifndef BUILD_FLOAT
                 BP_C32_Coefs_t      Coefficients;
 
                 /*
                  * Calculate the double precision coefficients
                  */
                 LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs,
-                                       &pInst->pFiltersParams[ii],
-                                       &Coefficients);
-
+                                        &pInst->pFiltersParams[ii],
+                                        &Coefficients);
                 /*
                  * Set the coefficients
                  */
                 BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
                                                   &pInst->pBP_Taps[ii],
                                                   &Coefficients);
+#else
+                BP_FLOAT_Coefs_t      Coefficients;
+                /*
+                 * Calculate the double precision coefficients
+                 */
+                LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs,
+                                        &pInst->pFiltersParams[ii],
+                                        &Coefficients);
+                /*
+                 * Set the coefficients
+                 */
+                BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
+                                                  &pInst->pBP_Taps[ii],
+                                                  &Coefficients);
+#endif
                 break;
             }
 
             case    LVPSA_SimplePrecisionFilter:
             {
+#ifndef BUILD_FLOAT
                 BP_C16_Coefs_t      Coefficients;
 
                 /*
@@ -374,9 +406,26 @@
                 /*
                  * Set the coefficients
                  */
-                BP_1I_D16F16Css_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
+                BP_1I_D16F16Css_TRC_WRA_01_Init (&pInst->pBP_Instances[ii],
                                                   &pInst->pBP_Taps[ii],
                                                   &Coefficients);
+#else
+                BP_FLOAT_Coefs_t      Coefficients;
+
+                /*
+                 * Calculate the single precision coefficients
+                 */
+                LVPSA_BPSinglePrecCoefs((LVM_UINT16)pParams->Fs,
+                                        &pInst->pFiltersParams[ii],
+                                        &Coefficients);
+
+                /*
+                 * Set the coefficients
+                 */
+                BP_1I_D16F16Css_TRC_WRA_01_Init (&pInst->pBP_Instances[ii],
+                                                  &pInst->pBP_Taps[ii],
+                                                  &Coefficients);
+#endif
                 break;
             }
         }
@@ -409,18 +458,31 @@
 {
     LVM_UINT16     ii;
     LVM_Fs_en      Fs = pParams->Fs;
+#ifndef BUILD_FLOAT
     QPD_C32_Coefs  *pCoefficients;
     extern         QPD_C32_Coefs     LVPSA_QPD_Coefs[];
 
-
     pCoefficients = &LVPSA_QPD_Coefs[(pParams->LevelDetectionSpeed * LVPSA_NR_SUPPORTED_RATE) + Fs];
+#else
+    QPD_FLOAT_Coefs  *pCoefficients;
+    extern         QPD_FLOAT_Coefs     LVPSA_QPD_Float_Coefs[];
+
+    pCoefficients = &LVPSA_QPD_Float_Coefs[(pParams->LevelDetectionSpeed * \
+                                    LVPSA_NR_SUPPORTED_RATE) + Fs];
+#endif
 
 
     for (ii = 0; ii < pInst->nRelevantFilters; ii++)
     {
-            LVPSA_QPD_Init (&pInst->pQPD_States[ii],
-                            &pInst->pQPD_Taps[ii],
-                            pCoefficients );
+#ifndef BUILD_FLOAT
+        LVPSA_QPD_Init (&pInst->pQPD_States[ii],
+                        &pInst->pQPD_Taps[ii],
+                        pCoefficients );
+#else
+        LVPSA_QPD_Init_Float (&pInst->pQPD_States[ii],
+                              &pInst->pQPD_Taps[ii],
+                              pCoefficients );
+#endif
     }
 
     return(LVPSA_OK);
@@ -460,6 +522,87 @@
 /*     of the n bands equalizer (LVEQNB                                                 */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPSinglePrecCoefs(    LVM_UINT16              Fs,
+                                         LVPSA_FilterParam_t     *pFilterParams,
+                                         BP_FLOAT_Coefs_t        *pCoefficients)
+{
+
+    extern LVM_FLOAT    LVPSA_Float_TwoPiOnFsTable[];
+    extern LVM_FLOAT    LVPSA_Float_CosCoef[];
+
+
+    /*
+     * Intermediate variables and temporary values
+     */
+    LVM_FLOAT           T0;
+    LVM_FLOAT           D;
+    LVM_FLOAT           A0;
+    LVM_FLOAT           B1;
+    LVM_FLOAT           B2;
+    LVM_FLOAT           Dt0;
+    LVM_FLOAT           B2_Den;
+    LVM_FLOAT           B2_Num;
+    LVM_FLOAT           COS_T0;
+    LVM_FLOAT           coef;
+    LVM_FLOAT           factor;
+    LVM_FLOAT           t0;
+    LVM_INT16           i;
+
+
+    /*
+     * Get the filter definition
+     */
+    LVM_FLOAT          Frequency   = (LVM_FLOAT)(pFilterParams->CenterFrequency);
+    LVM_FLOAT          QFactor     = ((LVM_FLOAT)(pFilterParams->QFactor)) / 100;
+
+    /*
+     * Calculating the intermediate values
+     */
+    T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs];   /* T0 = 2 * Pi * Fc / Fs */
+    D = 3200;                 /* Floating point value 1.000000 (1*100*2^5) */
+                    /* Force D = 1 : the function was originally used for a peaking filter.
+                       The D parameter do not exist for a BandPass filter coefficients */
+
+    /*
+     * Calculate the B2 coefficient
+     */
+    Dt0 =  T0 / 2048 ;
+    B2_Den = QFactor + Dt0;
+    B2_Num = Dt0 - QFactor;
+    B2 = B2_Num / (2 * B2_Den);
+
+    /*
+     * Calculate the cosine by a polynomial expansion using the equation:
+     *
+     *  Cos += coef(n) * t0^n                   For n = 0 to 6
+     */
+    T0 = (T0 / 2048) * 0.63658558f;              /* Scale to 1.0 in 16-bit for range 0 to fs/2 */
+    t0 = T0 ;
+    factor = 1.0f;                            /* Initialise to 1.0 for the a0 coefficient */
+    COS_T0 = 0.0f;                                 /* Initialise the error to zero */
+    for (i = 1; i < 7; i++)
+    {
+        coef    = LVPSA_Float_CosCoef[i];                /* Get the nth coefficient */
+        COS_T0 += (factor * coef);         /* The nth partial sum */
+        factor  = (factor * t0) ;           /* Calculate t0^n */
+    }
+    COS_T0 = COS_T0 * 8;    /*LVPSA_CosCoef_float[0]*/      /* Correct the scaling */
+
+
+    B1 = ((LVM_FLOAT)0.5 - B2) * (COS_T0);    /* B1 = (0.5 - b2) * cos(t0) */
+    A0 = ((LVM_FLOAT)0.5 + B2) / 2;                        /* A0 = (0.5 + b2) / 2 */
+
+    /*
+     * Write coeff into the data structure
+     */
+    pCoefficients->A0 = A0 * 2;
+    pCoefficients->B1 = B1 * 2;
+    pCoefficients->B2 = B2 * 2;
+
+    return(LVPSA_OK);
+}
+#else
 LVPSA_RETURN LVPSA_BPSinglePrecCoefs(    LVM_UINT16              Fs,
                                          LVPSA_FilterParam_t    *pFilterParams,
                                          BP_C16_Coefs_t         *pCoefficients)
@@ -541,7 +684,7 @@
 
     return(LVPSA_OK);
 }
-
+#endif
 /****************************************************************************************/
 /*                                                                                      */
 /* FUNCTION:                 LVPSA_BPDoublePrecCoefs                                    */
@@ -584,6 +727,90 @@
 /*     of the n bands equalizer (LVEQNB                                                 */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_BPDoublePrecCoefs(   LVM_UINT16            Fs,
+                                        LVPSA_FilterParam_t   *pFilterParams,
+                                        BP_FLOAT_Coefs_t      *pCoefficients)
+{
+
+    extern LVM_FLOAT    LVPSA_Float_TwoPiOnFsTable[];
+    extern LVM_FLOAT    LVPSA_Float_DPCosCoef[];
+
+    /*
+     * Intermediate variables and temporary values
+     */
+    LVM_FLOAT           T0;
+    LVM_FLOAT           D;
+    LVM_FLOAT           A0;
+    LVM_FLOAT           B1;
+    LVM_FLOAT           B2;
+    LVM_FLOAT           Dt0;
+    LVM_FLOAT           B2_Den;
+    LVM_FLOAT           B2_Num;
+    LVM_FLOAT           CosErr;
+    LVM_FLOAT           coef;
+    LVM_FLOAT           factor;
+    LVM_FLOAT           t0;
+    LVM_INT16           i;
+
+    /*
+     * Get the filter definition
+     */
+    LVM_FLOAT          Frequency   = (LVM_FLOAT)(pFilterParams->CenterFrequency);
+    LVM_FLOAT          QFactor     = ((LVM_FLOAT)(pFilterParams->QFactor)) / 100;
+
+
+    /*
+     * Calculating the intermediate values
+     */
+    T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs];   /* T0 = 2 * Pi * Fc / Fs */
+    D = 3200;    /* Floating point value 1.000000 (1*100*2^5) */
+                 /* Force D = 1 : the function was originally used for a peaking filter.
+                    The D parameter do not exist for a BandPass filter coefficients */
+
+    /*
+     * Calculate the B2 coefficient
+     */
+    Dt0 =  T0 / 2048 ;
+    B2_Den = QFactor + Dt0;
+    B2_Num = Dt0 - QFactor;
+    B2 = B2_Num / (2 * B2_Den);
+
+    /*
+     * Calculate the cosine error by a polynomial expansion using the equation:
+     *
+     *  CosErr += coef(n) * t0^n                For n = 0 to 4
+     */
+    T0 = T0 * 0.994750f;                    /* Scale to 1.0 in 16-bit for range 0 to fs/50 */
+    t0 = T0;
+    factor = 1.0f;                            /* Initialise to 1.0 for the a0 coefficient */
+    CosErr = 0.0f;                                 /* Initialise the error to zero */
+    for (i = 1; i < 5; i++)
+    {
+        coef = LVPSA_Float_DPCosCoef[i];              /* Get the nth coefficient */
+        CosErr += factor * coef;         /* The nth partial sum */
+        factor = factor * t0;           /* Calculate t0^n */
+    }
+    CosErr = CosErr * 2;          /* Correct the scaling */
+
+    /*
+     * Calculate the B1 and A0 coefficients
+     */
+    B1 = ((LVM_FLOAT)0.5 - B2);                     /* B1 = (0.5 - b2) */
+    A0 = B1 * CosErr ;    /* Temporary storage for (0.5 - b2) * coserr(t0) */
+    B1 -= A0;                                   /* B1 = (0.5 - b2) * (1 - coserr(t0))  */
+    A0 = ((LVM_FLOAT)0.5  + B2) / 2;                /* A0 = (0.5 + b2) / 2 */
+
+    /*
+     * Write coeff into the data structure
+     */
+    pCoefficients->A0 = A0;
+    pCoefficients->B1 = B1;
+    pCoefficients->B2 = B2;
+
+    return(LVPSA_OK);
+}
+#else
 LVPSA_RETURN LVPSA_BPDoublePrecCoefs(   LVM_UINT16            Fs,
                                         LVPSA_FilterParam_t  *pFilterParams,
                                         BP_C32_Coefs_t       *pCoefficients)
@@ -666,7 +893,7 @@
 
     return(LVPSA_OK);
 }
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:            LVPSA_ClearFilterHistory                                    */
@@ -690,11 +917,17 @@
 
     /* Band Pass filters taps */
     pTapAddress = (LVM_INT8 *)pInst->pBP_Taps;
+#ifdef BUILD_FLOAT
+    for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_FLOAT_Taps_t); i++)
+    {
+        pTapAddress[i] = 0;
+    }
+#else
     for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_Taps_t); i++)
     {
         pTapAddress[i] = 0;
     }
-
+#endif
     /* Quasi-peak filters taps */
     pTapAddress = (LVM_INT8 *)pInst->pQPD_Taps;
     for(i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++)
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
index 27a4bc3..1c26860 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
@@ -47,7 +47,11 @@
     LVPSA_InstancePr_t          *pLVPSA_Inst;
     LVPSA_RETURN                errorCode       = LVPSA_OK;
     LVM_UINT32                  ii;
+#ifndef BUILD_FLOAT
     extern LVM_INT16            LVPSA_GainTable[];
+#else
+    extern LVM_FLOAT            LVPSA_Float_GainTable[];
+#endif
     LVM_UINT32                  BufferLength = 0;
 
     /* Ints_Alloc instances, needed for memory alignment management */
@@ -141,19 +145,37 @@
 
 
     /* Assign the pointers */
-
+#ifndef BUILD_FLOAT
     pLVPSA_Inst->pPostGains                 = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT16) );
+#else
+    pLVPSA_Inst->pPostGains             = InstAlloc_AddMember( &Instance, pInitParams->nBands * \
+                                                               sizeof(LVM_FLOAT) );
+#endif
     pLVPSA_Inst->pFiltersParams             = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
     pLVPSA_Inst->pSpectralDataBufferStart   = InstAlloc_AddMember( &Instance, pInitParams->nBands * pLVPSA_Inst->SpectralDataBufferLength * sizeof(LVM_UINT8) );
     pLVPSA_Inst->pPreviousPeaks             = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT8) );
     pLVPSA_Inst->pBPFiltersPrecision        = InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_BPFilterPrecision_en) );
-
+#ifndef BUILD_FLOAT
     pLVPSA_Inst->pBP_Instances          = InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_Instance_t) );
     pLVPSA_Inst->pQPD_States            = InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_State_t) );
+#else
+    pLVPSA_Inst->pBP_Instances          = InstAlloc_AddMember( &Coef, pInitParams->nBands * \
+                                                               sizeof(Biquad_FLOAT_Instance_t) );
+    pLVPSA_Inst->pQPD_States            = InstAlloc_AddMember( &Coef, pInitParams->nBands * \
+                                                               sizeof(QPD_FLOAT_State_t) );
+#endif
 
+#ifndef BUILD_FLOAT
     pLVPSA_Inst->pBP_Taps               = InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_Taps_t) );
     pLVPSA_Inst->pQPD_Taps              = InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_Taps_t) );
 
+#else
+    pLVPSA_Inst->pBP_Taps               = InstAlloc_AddMember( &Data,
+                                                               pInitParams->nBands * \
+                                                               sizeof(Biquad_1I_Order2_FLOAT_Taps_t));
+    pLVPSA_Inst->pQPD_Taps              = InstAlloc_AddMember( &Data, pInitParams->nBands * \
+                                                               sizeof(QPD_FLOAT_Taps_t) );
+#endif
 
     /* Copy filters parameters in the private instance */
     for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
@@ -164,7 +186,12 @@
     /* Set Post filters gains*/
     for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
     {
+#ifndef BUILD_FLOAT
         pLVPSA_Inst->pPostGains[ii] =(LVM_UINT16) LVPSA_GainTable[pInitParams->pFiltersParams[ii].PostGain + 15];
+#else
+        pLVPSA_Inst->pPostGains[ii] = LVPSA_Float_GainTable[15 + \
+                                                        pInitParams->pFiltersParams[ii].PostGain];
+#endif
     }
     pLVPSA_Inst->pSpectralDataBufferWritePointer = pLVPSA_Inst->pSpectralDataBufferStart;
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
index 0984b10..06a8f9d 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
@@ -106,7 +106,11 @@
          */
 
         InstAlloc_AddMember( &Instance, sizeof(LVPSA_InstancePr_t) );
+#ifdef BUILD_FLOAT
+        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_FLOAT) );
+#else
         InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT16) );
+#endif
         InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
 
         {
@@ -134,7 +138,11 @@
         /*
          * Scratch memory
          */
+#ifndef BUILD_FLOAT
         InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_INT16) );
+#else
+        InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT) );
+#endif
         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;
@@ -142,8 +150,13 @@
         /*
          * Persistent coefficients memory
          */
+#ifndef BUILD_FLOAT
         InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_Instance_t) );
         InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_State_t) );
+#else
+        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_FLOAT_Instance_t) );
+        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_FLOAT_State_t) );
+#endif
         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;
@@ -151,8 +164,13 @@
         /*
          * Persistent data memory
          */
+#ifndef BUILD_FLOAT
         InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_Taps_t) );
         InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_Taps_t) );
+#else
+        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_FLOAT_Taps_t) );
+        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_FLOAT_Taps_t) );
+#endif
         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;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index 03522fb..a750bb0 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -43,8 +43,11 @@
 #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          9      /* From 8000Hz to 48000Hz                                           */
+#ifndef HIGHER_FS
+#define LVPSA_NR_SUPPORTED_RATE          9      /* From 8000Hz to 48000Hz*/
+#else
+#define LVPSA_NR_SUPPORTED_RATE          11      /* From 8000Hz to 192000Hz*/
+#endif
 #define LVPSA_NR_SUPPORTED_SPEED         3      /* LOW, MEDIUM, HIGH                                                */
 
 #define LVPSA_MAXBUFFERDURATION          4000   /* Maximum length in ms of the levels buffer                        */
@@ -93,12 +96,27 @@
     LVPSA_MemTab_t              MemoryTable;
 
     LVPSA_BPFilterPrecision_en *pBPFiltersPrecision;                /* Points a nBands elements array that contains the filter precision for each band              */
+#ifndef BUILD_FLOAT
     Biquad_Instance_t          *pBP_Instances;                      /* Points a nBands elements array that contains the band pass filter instance for each band     */
     Biquad_1I_Order2_Taps_t    *pBP_Taps;                           /* Points a nBands elements array that contains the band pass filter taps for each band         */
     QPD_State_t                *pQPD_States;                        /* Points a nBands elements array that contains the QPD filter instance for each band           */
     QPD_Taps_t                 *pQPD_Taps;                          /* Points a nBands elements array that contains the QPD filter taps for each band               */
-    LVM_UINT16                 *pPostGains;                         /* Points a nBands elements array that contains the post-filter gains for each band             */
+#else
+    Biquad_FLOAT_Instance_t          *pBP_Instances;
+    /* Points a nBands elements array that contains the band pass filter taps for each band */
+    Biquad_1I_Order2_FLOAT_Taps_t    *pBP_Taps;
+    /* Points a nBands elements array that contains the QPD filter instance for each band */
+    QPD_FLOAT_State_t                *pQPD_States;
+    /* Points a nBands elements array that contains the QPD filter taps for each band */
+    QPD_FLOAT_Taps_t                 *pQPD_Taps;
+#endif
 
+#ifndef BUILD_FLOAT
+    LVM_UINT16                 *pPostGains;                         /* Points a nBands elements array that contains the post-filter gains for each band             */
+#else
+    /* Points a nBands elements array that contains the post-filter gains for each band */
+    LVM_FLOAT                  *pPostGains;
+#endif
     LVPSA_FilterParam_t        *pFiltersParams;                     /* Copy of the filters parameters from the input parameters                                     */
 
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
index 9e29f68..ea5f74a 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
@@ -43,6 +43,96 @@
 /*  otherwise           Error due to bad parameters                                 */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
+                                       LVM_FLOAT           *pLVPSA_InputSamples,
+                                       LVM_UINT16           InputBlockSize,
+                                       LVPSA_Time           AudioTime            )
+
+{
+    LVPSA_InstancePr_t     *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
+    LVM_FLOAT               *pScratch;
+    LVM_INT16               ii;
+    LVM_INT32               AudioTimeInc;
+    extern LVM_UINT32       LVPSA_SampleRateInvTab[];
+    LVM_UINT8               *pWrite_Save;         /* Position of the write pointer
+                                                     at the beginning of the process  */
+
+    /******************************************************************************
+       CHECK PARAMETERS
+    *******************************************************************************/
+    if(hInstance == LVM_NULL || pLVPSA_InputSamples == LVM_NULL)
+    {
+        return(LVPSA_ERROR_NULLADDRESS);
+    }
+    if(InputBlockSize == 0 || InputBlockSize > pLVPSA_Inst->MaxInputBlockSize)
+    {
+        return(LVPSA_ERROR_INVALIDPARAM);
+    }
+
+    pScratch = (LVM_FLOAT*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress;
+    pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer;
+
+    /******************************************************************************
+       APPLY NEW SETTINGS IF NEEDED
+    *******************************************************************************/
+    if (pLVPSA_Inst->bControlPending == LVM_TRUE)
+    {
+        pLVPSA_Inst->bControlPending = 0;
+        LVPSA_ApplyNewSettings( pLVPSA_Inst);
+    }
+
+    /******************************************************************************
+       PROCESS SAMPLES
+    *******************************************************************************/
+    /* Put samples in range [-0.5;0.5[ for BP filters (see Biquads documentation) */
+    Copy_Float(pLVPSA_InputSamples, pScratch, (LVM_INT16)InputBlockSize);
+    Shift_Sat_Float(-1, pScratch, pScratch, (LVM_INT16)InputBlockSize);
+
+    for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++)
+    {
+        switch(pLVPSA_Inst->pBPFiltersPrecision[ii])
+        {
+            case LVPSA_SimplePrecisionFilter:
+                BP_1I_D16F16C14_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
+                                              pScratch,
+                                              pScratch + InputBlockSize,
+                                              (LVM_INT16)InputBlockSize);
+                break;
+
+            case LVPSA_DoublePrecisionFilter:
+                BP_1I_D16F32C30_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
+                                              pScratch,
+                                              pScratch + InputBlockSize,
+                                              (LVM_INT16)InputBlockSize);
+                break;
+            default:
+                break;
+        }
+
+
+        LVPSA_QPD_Process_Float   ( pLVPSA_Inst,
+                                    pScratch + InputBlockSize,
+                                    (LVM_INT16)InputBlockSize,
+                                    ii);
+    }
+
+    /******************************************************************************
+       UPDATE SpectralDataBufferAudioTime
+    *******************************************************************************/
+
+    if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save)
+    {
+        MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)),
+                        (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
+                        AudioTimeInc,
+                        LVPSA_FsInvertShift)
+        pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc;
+    }
+
+    return(LVPSA_OK);
+}
+#else
 LVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
                                        LVM_INT16           *pLVPSA_InputSamples,
                                        LVM_UINT16           InputBlockSize,
@@ -130,7 +220,7 @@
 
     return(LVPSA_OK);
 }
-
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
index 836bfd7..99d844b 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
@@ -31,6 +31,15 @@
   LVM_INT32                            Coefs[2];       /* pointer to the filter coefficients */
 }QPD_State_t, *pQPD_State_t;
 
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    /* pointer to the delayed samples (data of 32 bits)   */
+    LVM_FLOAT                            *pDelay;
+    LVM_FLOAT                            Coefs[2];       /* pointer to the filter coefficients */
+}QPD_FLOAT_State_t, *pQPD_FLOAT_State_t;
+#endif
+
 typedef struct
 {
     LVM_INT32 KP;    /*should store a0*/
@@ -38,12 +47,30 @@
 
 } QPD_C32_Coefs, *PQPD_C32_Coefs;
 
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT KP;    /*should store a0*/
+    LVM_FLOAT KM;    /*should store b2*/
+
+} QPD_FLOAT_Coefs, *PQPD_FLOAT_Coefs;
+#endif
+
+
 typedef struct
 {
     LVM_INT32 Storage[1];
 
 } QPD_Taps_t, *pQPD_Taps_t;
 
+#ifdef BUILD_FLOAT
+typedef struct
+{
+    LVM_FLOAT Storage[1];
+
+} QPD_FLOAT_Taps_t, *pQPD_FLOAT_Taps_t;
+
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:            LVPSA_QPD_Process                                           */
@@ -62,6 +89,12 @@
                                     LVM_INT16                           numSamples,
                                     LVM_INT16                           BandIndex);
 
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_Process_Float (      void                               *hInstance,
+                                    LVM_FLOAT                          *pInSamps,
+                                    LVM_INT16                           numSamples,
+                                    LVM_INT16                           BandIndex);
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:            LVPSA_QPD_Init                                              */
@@ -80,8 +113,12 @@
 void LVPSA_QPD_Init (   QPD_State_t       *pInstance,
                         QPD_Taps_t        *pTaps,
                         QPD_C32_Coefs     *pCoef     );
+#ifdef BUILD_FLOAT
 
-
+void LVPSA_QPD_Init_Float (   QPD_FLOAT_State_t       *pInstance,
+                              QPD_FLOAT_Taps_t        *pTaps,
+                              QPD_FLOAT_Coefs         *pCoef     );
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
index 50e0a80..2cc32ab 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
@@ -40,3 +40,14 @@
     pQPD_State->Coefs[0]  = pCoef->KP;
     pQPD_State->Coefs[1]  = pCoef->KM;
 }
+
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_Init_Float (   pQPD_FLOAT_State_t       pQPD_State,
+                              QPD_FLOAT_Taps_t         *pTaps,
+                              QPD_FLOAT_Coefs          *pCoef     )
+{
+    pQPD_State->pDelay  = pTaps->Storage;
+    pQPD_State->Coefs[0]  = ((LVM_FLOAT)pCoef->KP);
+    pQPD_State->Coefs[1]  = ((LVM_FLOAT)pCoef->KM);
+}
+#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
index 67197c1..e233172 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
@@ -35,12 +35,16 @@
 /*                                                                                  */
 /************************************************************************************/
 void LVPSA_QPD_WritePeak(   pLVPSA_InstancePr_t       pLVPSA_Inst,
-                            LVM_UINT8             **ppWrite,
-                            LVM_INT16               BandIndex,
-                            LVM_INT16               Value   );
+                            LVM_UINT8                 **ppWrite,
+                            LVM_INT16                 BandIndex,
+                            LVM_INT16                 Value   );
 
-
-
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_WritePeak_Float(   pLVPSA_InstancePr_t       pLVPSA_Inst,
+                                  LVM_UINT8             **ppWrite,
+                                  LVM_INT16               BandIndex,
+                                  LVM_FLOAT               Value   );
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:            LVPSA_QPD_Process                                           */
@@ -54,6 +58,7 @@
 /* RETURNS:             void                                                        */
 /*                                                                                  */
 /************************************************************************************/
+#ifndef BUILD_FLOAT
 void LVPSA_QPD_Process (            void                               *hInstance,
                                     LVM_INT16                          *pInSamps,
                                     LVM_INT16                           numSamples,
@@ -173,7 +178,131 @@
         pLVPSA_Inst->DownSamplingCount = (LVM_UINT16)(-ii);
     }
 }
+#else
+void LVPSA_QPD_Process_Float (      void                               *hInstance,
+                                    LVM_FLOAT                          *pInSamps,
+                                    LVM_INT16                           numSamples,
+                                    LVM_INT16                           BandIndex)
+{
 
+    /******************************************************************************
+       PARAMETERS
+    *******************************************************************************/
+    LVPSA_InstancePr_t     *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
+    QPD_FLOAT_State_t *pQPDState =  (QPD_FLOAT_State_t*)&pLVPSA_Inst->pQPD_States[BandIndex];
+
+    /* Pointer to taps */
+    LVM_FLOAT* pDelay  = pQPDState->pDelay;
+
+    /* Parameters needed during quasi peak calculations */
+    LVM_FLOAT   X0;
+    LVM_FLOAT   temp,temp2;
+    LVM_FLOAT   accu;
+    LVM_FLOAT   Xg0;
+    LVM_FLOAT   D0;
+    LVM_FLOAT   V0 = (LVM_FLOAT)(*pDelay);
+
+    /* Filter's coef */
+    LVM_FLOAT   Kp = ((LVM_FLOAT)(pQPDState->Coefs[0]));
+    LVM_FLOAT   Km = ((LVM_FLOAT)(pQPDState->Coefs[1]));
+
+    LVM_INT16   ii = numSamples;
+
+    LVM_UINT8  *pWrite = pLVPSA_Inst->pSpectralDataBufferWritePointer;
+    LVM_INT32   BufferUpdateSamplesCount = pLVPSA_Inst->BufferUpdateSamplesCount;
+    LVM_UINT16  DownSamplingFactor = pLVPSA_Inst->DownSamplingFactor;
+
+    /******************************************************************************
+       INITIALIZATION
+    *******************************************************************************/
+    /* Correct the pointer to take the first down sampled signal sample */
+    pInSamps += pLVPSA_Inst->DownSamplingCount;
+    /* Correct also the number of samples */
+    ii = (LVM_INT16)(ii - (LVM_INT16)pLVPSA_Inst->DownSamplingCount);
+
+    while (ii > 0)
+    {
+        /* Apply post gain */
+        /* - 1 to compensate scaling in process function*/
+        X0 = (*pInSamps) * pLVPSA_Inst->pPostGains[BandIndex];
+        pInSamps = pInSamps + DownSamplingFactor;
+
+        /* Saturate and take absolute value */
+        if(X0 < 0.0f)
+            X0 = -X0;
+        if (X0 > 1.0f)
+            Xg0 = 1.0f;
+        else
+            Xg0 =X0;
+
+
+        /* Quasi peak filter calculation */
+        D0  = Xg0 - V0;
+
+        temp2 = D0;
+
+        accu = temp2 * Kp;
+        D0    = D0 / 2.0f;
+        if (D0 < 0.0f){
+            D0 = -D0;
+        }
+
+        temp2 = D0;
+
+        temp = D0 * Km;
+        accu += temp + Xg0;
+
+        if (accu > 1.0f)
+            accu = 1.0f;
+        else if(accu < 0.0f)
+            accu = 0.0f;
+
+        V0 = accu;
+
+        if(((pLVPSA_Inst->nSamplesBufferUpdate - BufferUpdateSamplesCount) < DownSamplingFactor))
+        {
+            LVPSA_QPD_WritePeak_Float( pLVPSA_Inst,
+                                       &pWrite,
+                                       BandIndex,
+                                       V0);
+
+            BufferUpdateSamplesCount -= pLVPSA_Inst->nSamplesBufferUpdate;
+            pLVPSA_Inst->LocalSamplesCount = (LVM_UINT16)(numSamples - ii);
+        }
+        BufferUpdateSamplesCount += DownSamplingFactor;
+
+        ii = (LVM_INT16)(ii - DownSamplingFactor);
+
+    }
+
+    /* Store last taps in memory */
+    *pDelay = V0;
+
+    /* If this is the last call to the function after last band processing,
+       update the parameters. */
+    if(BandIndex == (pLVPSA_Inst->nRelevantFilters - 1))
+    {
+        pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
+        /* Adjustment for 11025Hz input, 220,5 is normally
+           the exact number of samples for 20ms.*/
+        if((pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite)&&
+                                        (pLVPSA_Inst->CurrentParams.Fs == LVM_FS_11025))
+        {
+            if(pLVPSA_Inst->nSamplesBufferUpdate == 220)
+            {
+                pLVPSA_Inst->nSamplesBufferUpdate = 221;
+            }
+            else
+            {
+                pLVPSA_Inst->nSamplesBufferUpdate = 220;
+            }
+        }
+        pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
+        pLVPSA_Inst->BufferUpdateSamplesCount = BufferUpdateSamplesCount;
+        pLVPSA_Inst->DownSamplingCount = (LVM_UINT16)(-ii);
+    }
+}
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:            LVPSA_QPD_WritePeak                                         */
@@ -209,4 +338,23 @@
     *ppWrite = pWrite;
 
 }
+#ifdef BUILD_FLOAT
+void LVPSA_QPD_WritePeak_Float(   pLVPSA_InstancePr_t     pLVPSA_Inst,
+                                  LVM_UINT8               **ppWrite,
+                                  LVM_INT16               BandIndex,
+                                  LVM_FLOAT               Value   )
+{
+    LVM_UINT8 *pWrite = *ppWrite;
 
+    /* Write the value and update the write pointer */
+    *(pWrite + BandIndex) = (LVM_UINT8)(Value * 256);
+    pWrite += pLVPSA_Inst->nBands;
+    if (pWrite == (pLVPSA_Inst->pSpectralDataBufferStart + pLVPSA_Inst->nBands * \
+                                    pLVPSA_Inst->SpectralDataBufferLength))
+    {
+        pWrite = pLVPSA_Inst->pSpectralDataBufferStart;
+    }
+
+    *ppWrite = pWrite;
+}
+#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
index 21a5d8d..1287503 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -34,6 +34,7 @@
  * Sample rate table for converting between the enumerated type and the actual
  * frequency
  */
+#ifndef HIGHER_FS
 const LVM_UINT16    LVPSA_SampleRateTab[] = {   8000,                    /* 8kS/s  */
                                                 11025,
                                                 12000,
@@ -43,6 +44,19 @@
                                                 32000,
                                                 44100,
                                                 48000};                  /* 48kS/s */
+#else
+const LVM_UINT32    LVPSA_SampleRateTab[] = {   8000,                    /* 8kS/s  */
+                                                11025,
+                                                12000,
+                                                16000,
+                                                22050,
+                                                24000,
+                                                32000,
+                                                44100,
+                                                48000,
+                                                96000,
+                                               192000};                  /* 192kS/s */
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
@@ -62,7 +76,12 @@
                                                     89478,
                                                     67109,
                                                     48696,
-                                                    44739};                  /* 48kS/s */
+                                                    44739
+#ifdef HIGHER_FS
+                                                    ,22369
+                                                    ,11185                  /* 192kS/s */
+#endif
+                                               };
 
 
 
@@ -84,7 +103,12 @@
                                                         480,
                                                         640,
                                                         882,
-                                                        960};                  /* 48kS/s */
+                                                        960
+#ifdef HIGHER_FS
+                                                        ,1920
+                                                        ,3840                  /* 192kS/s */
+#endif
+                                                    };
 /************************************************************************************/
 /*                                                                                  */
 /*  Down sampling factors                                                           */
@@ -102,7 +126,12 @@
                                                         16,                   /* 24000 S/s  */
                                                         21,                   /* 32000 S/s  */
                                                         30,                   /* 44100 S/s  */
-                                                        32};                  /* 48000 S/s  */
+                                                        32                    /* 48000 S/s  */
+#ifdef HIGHER_FS
+                                                       ,64                   /* 96000 S/s  */
+                                                       ,128                  /*192000 S/s  */
+#endif
+                                                  };
 
 
 /************************************************************************************/
@@ -122,8 +151,30 @@
                                                  8785,
                                                  6588,
                                                  4781,
-                                                 4392};    /* 48kS/s */
+                                                 4392
+#ifdef HIGHER_FS
+                                                ,2196
+                                                ,1098    /* 192kS/s */
+#endif
+                                             };
 
+#ifdef BUILD_FLOAT
+const LVM_FLOAT     LVPSA_Float_TwoPiOnFsTable[] = {  0.8042847f,      /* 8kS/s */
+                                                      0.5836054f,
+                                                      0.5361796f,
+                                                      0.4021423f,
+                                                      0.2917874f,
+                                                      0.2681051f,
+                                                      0.2010559f,
+                                                      0.1459089f,
+                                                      0.1340372f
+#ifdef HIGHER_FS
+                                                     ,0.0670186f
+                                                     ,0.0335093f    /* 192kS/s */
+#endif
+                                                   };
+
+#endif
 /*
  * Gain table
  */
@@ -159,6 +210,39 @@
                                             10264,
                                             11576};        /* +15dB gain */
 
+#ifdef BUILD_FLOAT
+const LVM_FLOAT  LVPSA_Float_GainTable[]={  0.177734375f,          /* -15dB gain */
+                                            0.199218750f,
+                                            0.223632812f,
+                                            0.250976562f,
+                                            0.281738281f,
+                                            0.315917968f,
+                                            0.354492187f,
+                                            0.397949218f,
+                                            0.446289062f,
+                                            0.500976562f,
+                                            0.562011718f,
+                                            0.630859375f,
+                                            0.707519531f,
+                                            0.793945312f,
+                                            0.891113281f,
+                                            1.000000000f,         /* 0dB gain */
+                                            1.121582031f,
+                                            1.258789062f,
+                                            1.412109375f,
+                                            1.584472656f,
+                                            1.777832031f,
+                                            2.000000000f,
+                                            2.238281250f,
+                                            2.511718750f,
+                                            2.818359375f,
+                                            3.162109375f,
+                                            3.547851562f,
+                                            3.980957031f,
+                                            4.466796875f,
+                                            5.011718750f,
+                                            5.652343750f};        /* +15dB gain */
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /*  Cosone polynomial coefficients                                                  */
@@ -181,7 +265,15 @@
                                         -2671,                         /* a3 */
                                         23730,                         /* a4 */
                                         -9490};                        /* a5 */
-
+#ifdef BUILD_FLOAT
+const LVM_FLOAT     LVPSA_Float_CosCoef[] = { 3,                             /* Shifts */
+                                              0.1250038f,                          /* a0 */
+                                              -0.0010986f,                           /* a1 */
+                                              -0.6019775f,                        /* a2 */
+                                              -0.0815149f,                         /* a3 */
+                                              0.7242042f,                         /* a4 */
+                                              -0.2896206f};                        /* a5 */
+#endif
 /*
  * Coefficients for calculating the cosine error with the equation:
  *
@@ -201,7 +293,13 @@
                                             -6,                          /* a1 */
                                             16586,                       /* a2 */
                                             -44};                        /* a3 */
-
+#ifdef BUILD_FLOAT
+const LVM_FLOAT    LVPSA_Float_DPCosCoef[] = {1.0f,                        /* Shifts */
+                                              0.0f,                        /* a0 */
+                                              -0.00008311f,                 /* a1 */
+                                              0.50617999f,                 /* a2 */
+                                              -0.00134281f};                /* a3 */
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /*  Quasi peak filter coefficients table                                            */
@@ -239,3 +337,54 @@
                                          {0xA375B2C6,0x1E943BBC},
                                          {0xA2E1E950,0x1E2A532E}}; /* 48kS/s */
 
+#ifdef BUILD_FLOAT
+const QPD_FLOAT_Coefs     LVPSA_QPD_Float_Coefs[] = {
+
+                                         /* 8kS/s  */    /* LVPSA_SPEED_LOW   */
+                                         {-0.9936831989325583f,0.0062135565094650f},
+                                         {-0.9935833332128823f,0.0063115493394434f},
+                                         {-0.9932638457976282f,0.0066249934025109f},
+                                         {-0.9936831989325583f,0.0062135565094650f},
+                                         {-0.9931269618682563f,0.0067592649720609f},
+                                         {-0.9932638457976282f,0.0066249934025109f},
+                                         {-0.9933686633594334f,0.0065221670083702f},
+                                         {-0.9931269618682563f,0.0067592649720609f},
+                                          /* 48kS/s */
+                                         {-0.9932638457976282f,0.0066249934025109f},
+#ifdef HIGHER_FS
+                                         {-0.9932638457976282f,0.0066249934025109f},
+                                         {-0.9932638457976282f,0.0066249934025109f},
+#endif
+                                         /* 8kS/s  */    /* LVPSA_SPEED_MEDIUM      */
+                                         {-0.9568079425953329f,0.0418742666952312f},
+                                         {-0.9561413046903908f,0.0425090822391212f},
+                                         {-0.9540119562298059f,0.0445343819446862f},
+                                         {-0.9568079425953329f,0.0418742666952312f},
+                                         {-0.9531011912040412f,0.0453995238058269f},
+                                         {-0.9540119562298059f,0.0445343819446862f},
+                                         {-0.9547099955379963f,0.0438708555884659f},
+                                          //{0x8600C7B9,0x05CFA6CF},
+                                         {-0.9531011912040412f,0.0453995238058269f},
+                                          /* 48kS/s */
+                                         {-0.9540119562298059f,0.0445343819446862f},
+#ifdef HIGHER_FS
+                                         {-0.9540119562298059f,0.0445343819446862f},
+                                         {-0.9540119562298059f,0.0445343819446862f},
+#endif
+                                          /* 8kS/s  */   /* LVPSA_SPEED_HIGH      */
+                                         {-0.7415186790749431f,0.2254409026354551f},
+                                         {-0.7381451204419136f,0.2279209652915597f},
+                                         {-0.7274807319045067f,0.2356666540727019f},
+                                         {-0.7415186790749431f,0.2254409026354551f},
+                                         {-0.7229706319049001f,0.2388987224549055f},
+                                         {-0.7274807319045067f,0.2356666540727019f},
+                                         {-0.7309581353329122f,0.2331568226218224f},
+                                         {-0.7229706319049001f,0.2388987224549055f},
+                                           /* 48kS/s */
+                                         {-0.7274807319045067f,0.2356666540727019f}
+#ifdef HIGHER_FS
+                                        ,{-0.7274807319045067f,0.2356666540727019f}
+                                        ,{-0.7274807319045067f,0.2356666540727019f}
+#endif
+                                        };
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
index 0d62274..e75695e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
+++ b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
@@ -374,12 +374,17 @@
 /* NOTES:                                                                               */
 /*                                                                                      */
 /****************************************************************************************/
-
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t             hInstance,
+                                  const LVM_FLOAT           *pInData,
+                                  LVM_FLOAT                 *pOutData,
+                                  LVM_UINT16                NumSamples);
+#else
 LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t             hInstance,
                                   const LVM_INT16           *pInData,
                                   LVM_INT16                 *pOutData,
                                   LVM_UINT16                NumSamples);
-
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
index 3e48c7e..29e3c9e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
@@ -70,11 +70,17 @@
 {
 
     LVM_UINT16          Offset;
+#ifndef BUILD_FLOAT
     LVM_UINT32          Gain;
+    LVM_INT32           Current;
+#else
+    LVM_FLOAT           Gain;
+    LVM_FLOAT           Current;
+#endif
     LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
     LVCS_BypassMix_t    *pConfig   = (LVCS_BypassMix_t *)&pInstance->BypassMix;
     const Gain_t        *pOutputGainTable;
-    LVM_INT32           Current;
+
 
 
     /*
@@ -85,7 +91,11 @@
         && (pInstance->MSTarget1 != 0x7FFF) /* this indicates an off->on transtion */
         )
     {
+#ifndef BUILD_FLOAT
         pInstance->TransitionGain = pParams->EffectLevel;
+#else
+        pInstance->TransitionGain = ((LVM_FLOAT)pParams->EffectLevel / 32767);
+#endif
     }
     else
     {
@@ -102,23 +112,46 @@
     /*
      * Setup the mixer gain for the processed path
      */
+#ifndef BUILD_FLOAT
     Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * pInstance->TransitionGain);
+#else
+    Gain =  (LVM_FLOAT)(pOutputGainTable[Offset].Loss * pInstance->TransitionGain);
+#endif
 
     pConfig->Mixer_Instance.MixerStream[0].CallbackParam = 0;
     pConfig->Mixer_Instance.MixerStream[0].pCallbackHandle = LVM_NULL;
     pConfig->Mixer_Instance.MixerStream[0].pCallBack = LVM_NULL;
     pConfig->Mixer_Instance.MixerStream[0].CallbackSet=1;
+
+#ifndef BUILD_FLOAT
     Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[0]);
     LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[0],(LVM_INT32)(Gain >> 15),Current);
     LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+    Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[0]);
+    LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[0], (LVM_FLOAT)(Gain), Current);
+    LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],
+                                       LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
+
     /*
      * Setup the mixer gain for the unprocessed path
      */
+#ifndef BUILD_FLOAT
     Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * (0x7FFF - pInstance->TransitionGain));
     Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15);
     Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[1]);
     LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[1],(LVM_INT32)(Gain >> 15),Current);
     LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+    Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss * (1.0 - \
+                                    (LVM_FLOAT)pInstance->TransitionGain));
+    Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * Gain;
+    Current = LVC_Mixer_GetCurrent(&pConfig->Mixer_Instance.MixerStream[1]);
+    LVC_Mixer_Init(&pConfig->Mixer_Instance.MixerStream[1], (LVM_FLOAT)(Gain), Current);
+    LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],
+                                       LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
     pConfig->Mixer_Instance.MixerStream[1].CallbackParam = 0;
     pConfig->Mixer_Instance.MixerStream[1].pCallbackHandle = hInstance;
     pConfig->Mixer_Instance.MixerStream[1].CallbackSet=1;
@@ -134,7 +167,7 @@
      * Correct gain for the effect level
      */
     {
-
+#ifndef BUILD_FLOAT
         LVM_INT16           GainCorrect;
         LVM_INT32           Gain1;
         LVM_INT32           Gain2;
@@ -172,6 +205,43 @@
         LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
         LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[1],Gain2>>16);
         LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+        LVM_FLOAT           GainCorrect;
+        LVM_FLOAT           Gain1;
+        LVM_FLOAT           Gain2;
+
+        Gain1 = LVC_Mixer_GetTarget(&pConfig->Mixer_Instance.MixerStream[0]);
+        Gain2 = LVC_Mixer_GetTarget(&pConfig->Mixer_Instance.MixerStream[1]);
+        /*
+         * Calculate the gain correction
+         */
+        if (pInstance->Params.CompressorMode == LVM_MODE_ON)
+        {
+        GainCorrect = (LVM_FLOAT)(  pInstance->VolCorrect.GainMin
+                                    - (((LVM_FLOAT)pInstance->VolCorrect.GainMin * \
+                                                         ((LVM_FLOAT)pInstance->TransitionGain)))
+                                    + (((LVM_FLOAT)pInstance->VolCorrect.GainFull * \
+                                                        ((LVM_FLOAT)pInstance->TransitionGain))));
+
+        /*
+         * Apply the gain correction
+         */
+        Gain1 = (Gain1 * GainCorrect);
+        Gain2 = (Gain2 * GainCorrect);
+
+        }
+
+        /*
+         * Set the gain values
+         */
+        pConfig->Output_Shift = pConfig->Output_Shift;
+        LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[0],Gain1);
+        LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[0],
+                                           LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+        LVC_Mixer_SetTarget(&pConfig->Mixer_Instance.MixerStream[1],Gain2);
+        LVC_Mixer_VarSlope_SetTimeConstant(&pConfig->Mixer_Instance.MixerStream[1],
+                                           LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
     }
 
     return(LVCS_SUCCESS);
@@ -206,9 +276,15 @@
 /************************************************************************************/
 
 LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t         hInstance,
+#ifndef BUILD_FLOAT
                                       const LVM_INT16       *pProcessed,
                                       const LVM_INT16       *pUnprocessed,
                                       LVM_INT16             *pOutData,
+#else
+                                      const LVM_FLOAT       *pProcessed,
+                                      const LVM_FLOAT       *pUnprocessed,
+                                      LVM_FLOAT             *pOutData,
+#endif
                                       LVM_UINT16            NumSamples)
 {
 
@@ -223,6 +299,7 @@
         /*
          * Apply the bypass mix
          */
+#ifndef BUILD_FLOAT
         LVC_MixSoft_2St_D16C31_SAT(&pConfig->Mixer_Instance,
                                         pProcessed,
                                         (LVM_INT16 *) pUnprocessed,
@@ -236,6 +313,20 @@
                           (LVM_INT16*)pOutData,
                           (LVM_INT16*)pOutData,
                           (LVM_INT16)(2*NumSamples));          /* Left and right*/
+#else
+        LVC_MixSoft_2St_D16C31_SAT(&pConfig->Mixer_Instance,
+                                   pProcessed,
+                                   (LVM_FLOAT *) pUnprocessed,
+                                   pOutData,
+                                   (LVM_INT16)(2 * NumSamples));
+        /*
+         * Apply output gain correction shift
+         */
+        Shift_Sat_Float((LVM_INT16)pConfig->Output_Shift,
+                        (LVM_FLOAT*)pOutData,
+                        (LVM_FLOAT*)pOutData,
+                        (LVM_INT16)(2 * NumSamples));          /* Left and right*/
+#endif
     }
 
     return(LVCS_SUCCESS);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
index d1ef70a..f69ba38 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
@@ -42,12 +42,16 @@
 typedef struct
 {
     /* Mixer settings */
+#ifdef BUILD_FLOAT
+    LVMixer3_2St_FLOAT_st   Mixer_Instance;             /* Mixer instance */
+#else
     LVMixer3_2St_st         Mixer_Instance;             /* Mixer instance */
+#endif
     LVM_UINT16              Output_Shift;               /* Correcting gain output shift */
 
 } LVCS_BypassMix_t;
 
-
+#ifndef BUILD_FLOAT
 /* Output gain type */
 typedef struct
 {
@@ -56,8 +60,15 @@
     LVM_UINT16              Loss;                       /* Loss required */
     LVM_UINT16              UnprocLoss;                 /* Unprocessed path loss */
 } Gain_t;
-
-
+#else
+typedef struct
+{
+    /* Output gain settings, Gain = (Loss/32768) * 2^Shift */
+    LVM_UINT16             Shift;                      /* Left shifts required */
+    LVM_FLOAT              Loss;                       /* Loss required */
+    LVM_FLOAT              UnprocLoss;                 /* Unprocessed path loss */
+} Gain_t;
+#endif
 /************************************************************************************/
 /*                                                                                    */
 /*    Function prototypes                                                                */
@@ -67,13 +78,19 @@
 LVCS_ReturnStatus_en LVCS_BypassMixInit(LVCS_Handle_t       hInstance,
                                            LVCS_Params_t    *pParams);
 
-
+#ifndef BUILD_FLOAT
 LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t         hInstance,
                                       const LVM_INT16       *pProcessed,
                                       const LVM_INT16       *unProcessed,
-                                            LVM_INT16       *pOutData,
-                                            LVM_UINT16      NumSamples);
-
+                                      LVM_INT16       *pOutData,
+                                      LVM_UINT16      NumSamples);
+#else
+LVCS_ReturnStatus_en LVCS_BypassMixer(LVCS_Handle_t         hInstance,
+                                      const LVM_FLOAT       *pProcessed,
+                                      const LVM_FLOAT       *unProcessed,
+                                      LVM_FLOAT       *pOutData,
+                                      LVM_UINT16      NumSamples);
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
index ce6d410..3bf6ec6 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
@@ -120,11 +120,13 @@
         pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
 
         pInstance->CompressGain = pInstance->VolCorrect.CompMin;
-
+#ifdef BUILD_FLOAT
+        LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 0, 0);
+#else
         LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
-
-
+#endif
         {
+#ifndef BUILD_FLOAT
             LVM_UINT32          Gain;
             const Gain_t        *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
             Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16);
@@ -140,7 +142,23 @@
                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
+#else
+            LVM_FLOAT          Gain;
+            const Gain_t        *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
+            Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss);
+            Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * (Gain);
 
+            /*
+             * Apply the gain correction
+             */
+            Gain = (Gain * pInstance->VolCorrect.GainMin);
+
+            LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 0, Gain);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
+                    LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+            LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
+                    LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
+#endif
         }
 
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
index 25b0d86..ec5312e 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
@@ -53,7 +53,72 @@
 /* NOTES:                                                                           */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t       hInstance,
+                                        LVCS_Params_t       *pParams)
+{
 
+    LVM_UINT16          Offset;
+    LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVCS_Equaliser_t    *pConfig   = (LVCS_Equaliser_t *)&pInstance->Equaliser;
+    LVCS_Data_t         *pData;
+    LVCS_Coefficient_t  *pCoefficients;
+    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;
+    /*
+     * If the sample rate changes re-initialise the filters
+     */
+    if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
+        (pInstance->Params.SpeakerType != pParams->SpeakerType))
+    {
+        /*
+         * Setup the filter coefficients and clear the history
+         */
+        Offset = (LVM_UINT16)(pParams->SampleRate + (pParams->SpeakerType * (1 + LVM_FS_48000)));
+        pEqualiserCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_EqualiserCoefTable[0];
+
+        /* Left and right filters */
+        /* Convert incoming coefficients to the required format/ordering */
+        Coeffs.A0 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A0;
+        Coeffs.A1 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A1;
+        Coeffs.A2 = (LVM_FLOAT) pEqualiserCoefTable[Offset].A2;
+        Coeffs.B1 = (LVM_FLOAT)-pEqualiserCoefTable[Offset].B1;
+        Coeffs.B2 = (LVM_FLOAT)-pEqualiserCoefTable[Offset].B2;
+
+        LoadConst_Float((LVM_INT16)0,                                         /* Value */
+                        (void *)&pData->EqualiserBiquadTaps,   /* Destination Cast to void:\
+                                                                  no dereferencing in function*/
+                        /* Number of words */
+                        (LVM_UINT16)(sizeof(pData->EqualiserBiquadTaps) / sizeof(LVM_FLOAT)));
+
+        BQ_2I_D16F32Css_TRC_WRA_01_Init(&pCoefficients->EqualiserBiquadInstance,
+                                        &pData->EqualiserBiquadTaps,
+                                        &Coeffs);
+
+        /* Callbacks */
+        switch(pEqualiserCoefTable[Offset].Scale)
+        {
+            case 13:
+                pConfig->pBiquadCallBack  = BQ_2I_D16F32C13_TRC_WRA_01;
+                break;
+            case 14:
+                pConfig->pBiquadCallBack  = BQ_2I_D16F32C14_TRC_WRA_01;
+                break;
+            case 15:
+                pConfig->pBiquadCallBack  = BQ_2I_D16F32C15_TRC_WRA_01;
+                break;
+        }
+    }
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t       hInstance,
                                         LVCS_Params_t       *pParams)
 {
@@ -112,7 +177,7 @@
 
     return(LVCS_SUCCESS);
 }
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:                LVCS_Equaliser                                          */
@@ -132,7 +197,37 @@
 /*  1.  Always processes in place.                                                  */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t       hInstance,
+                                    LVM_FLOAT           *pInputOutput,
+                                    LVM_UINT16          NumSamples)
+{
 
+    LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
+    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;
+
+
+    /*
+     * Check if the equaliser is required
+     */
+    if ((pInstance->Params.OperatingMode & LVCS_EQUALISERSWITCH) != 0)
+    {
+        /* Apply filter to the left and right channels */
+        (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*) \
+                                        &pCoefficients->EqualiserBiquadInstance,
+                                        (LVM_FLOAT *)pInputOutput,
+                                        (LVM_FLOAT *)pInputOutput,
+                                        (LVM_INT16)NumSamples);
+    }
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t       hInstance,
                                     LVM_INT16           *pInputOutput,
                                     LVM_UINT16          NumSamples)
@@ -157,4 +252,4 @@
 
     return(LVCS_SUCCESS);
 }
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
index cf96f5b..0e756e7 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
@@ -32,8 +32,11 @@
 /* Equaliser structure */
 typedef struct
 {
+#ifndef BUILD_FLOAT
     void (*pBiquadCallBack) (Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
+#else
+    void (*pBiquadCallBack) (Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
 } LVCS_Equaliser_t;
 
 
@@ -45,12 +48,15 @@
 
 LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t       hInstance,
                                         LVCS_Params_t       *pParams);
-
+#ifndef BUILD_FLOAT
 LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t            hInstance,
                                     LVM_INT16                *pInputOutput,
                                     LVM_UINT16                NumSamples);
-
-
+#else
+LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t            hInstance,
+                                    LVM_FLOAT                *pInputOutput,
+                                    LVM_UINT16                NumSamples);
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
index 3e640cb..4f5221a 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
@@ -24,7 +24,463 @@
 /* The Stereo Enhancer                                                              */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+/* Stereo Enhancer coefficients for 8000 Hz sample rate, scaled with 0.161258 */
+#define CS_MIDDLE_8000_A0                           0.227720
+#define CS_MIDDLE_8000_A1                          -0.215125
+#define CS_MIDDLE_8000_A2                           0.000000
+#define CS_MIDDLE_8000_B1                          -0.921899
+#define CS_MIDDLE_8000_B2                           0.000000
+#define CS_MIDDLE_8000_SCALE                        15
+#define CS_SIDE_8000_A0                             0.611441
+#define CS_SIDE_8000_A1                            -0.380344
+#define CS_SIDE_8000_A2                            -0.231097
+#define CS_SIDE_8000_B1                            -0.622470
+#define CS_SIDE_8000_B2                            -0.130759
+#define CS_SIDE_8000_SCALE                         15
 
+/* Stereo Enhancer coefficients for 11025Hz sample rate, scaled with 0.162943 */
+#define CS_MIDDLE_11025_A0                       0.230838
+#define CS_MIDDLE_11025_A1                      -0.221559
+#define CS_MIDDLE_11025_A2                       0.000000
+#define CS_MIDDLE_11025_B1                      -0.943056
+#define CS_MIDDLE_11025_B2                       0.000000
+#define CS_MIDDLE_11025_SCALE                    15
+#define CS_SIDE_11025_A0                         0.557372
+#define CS_SIDE_11025_A1                        -0.391490
+#define CS_SIDE_11025_A2                        -0.165881
+#define CS_SIDE_11025_B1                        -0.880608
+#define CS_SIDE_11025_B2                         0.032397
+#define CS_SIDE_11025_SCALE                      15
+
+/* Stereo Enhancer coefficients for 12000Hz sample rate, scaled with 0.162191 */
+#define CS_MIDDLE_12000_A0                        0.229932
+#define CS_MIDDLE_12000_A1                       -0.221436
+#define CS_MIDDLE_12000_A2                        0.000000
+#define CS_MIDDLE_12000_B1                       -0.947616
+#define CS_MIDDLE_12000_B2                        0.000000
+#define CS_MIDDLE_12000_SCALE                        15
+#define CS_SIDE_12000_A0                         0.558398
+#define CS_SIDE_12000_A1                        -0.392211
+#define CS_SIDE_12000_A2                        -0.166187
+#define CS_SIDE_12000_B1                        -0.892550
+#define CS_SIDE_12000_B2                         0.032856
+#define CS_SIDE_12000_SCALE                          15
+
+/* Stereo Enhancer coefficients for 16000Hz sample rate, scaled with 0.162371 */
+#define CS_MIDDLE_16000_A0                       0.230638
+#define CS_MIDDLE_16000_A1                      -0.224232
+#define CS_MIDDLE_16000_A2                       0.000000
+#define CS_MIDDLE_16000_B1                      -0.960550
+#define CS_MIDDLE_16000_B2                       0.000000
+#define CS_MIDDLE_16000_SCALE                        15
+#define CS_SIDE_16000_A0                         0.499695
+#define CS_SIDE_16000_A1                        -0.355543
+#define CS_SIDE_16000_A2                        -0.144152
+#define CS_SIDE_16000_B1                        -1.050788
+#define CS_SIDE_16000_B2                         0.144104
+#define CS_SIDE_16000_SCALE                          14
+
+/* Stereo Enhancer coefficients for 22050Hz sample rate, scaled with 0.160781 */
+#define CS_MIDDLE_22050_A0                       0.228749
+#define CS_MIDDLE_22050_A1                      -0.224128
+#define CS_MIDDLE_22050_A2                       0.000000
+#define CS_MIDDLE_22050_B1                      -0.971262
+#define CS_MIDDLE_22050_B2                       0.000000
+#define CS_MIDDLE_22050_SCALE                        15
+#define CS_SIDE_22050_A0                          0.440112
+#define CS_SIDE_22050_A1                         -0.261096
+#define CS_SIDE_22050_A2                         -0.179016
+#define CS_SIDE_22050_B1                         -1.116786
+#define CS_SIDE_22050_B2                          0.182507
+#define CS_SIDE_22050_SCALE                          14
+
+/* Stereo Enhancer coefficients for 24000Hz sample rate, scaled with 0.161882 */
+#define CS_MIDDLE_24000_A0                         0.230395
+#define CS_MIDDLE_24000_A1                        -0.226117
+#define CS_MIDDLE_24000_A2                         0.000000
+#define CS_MIDDLE_24000_B1                        -0.973573
+#define CS_MIDDLE_24000_B2                         0.000000
+#define CS_MIDDLE_24000_SCALE                        15
+#define CS_SIDE_24000_A0                           0.414770
+#define CS_SIDE_24000_A1                          -0.287182
+#define CS_SIDE_24000_A2                          -0.127588
+#define CS_SIDE_24000_B1                          -1.229648
+#define CS_SIDE_24000_B2                           0.282177
+#define CS_SIDE_24000_SCALE                          14
+
+/* Stereo Enhancer coefficients for 32000Hz sample rate, scaled with 0.160322 */
+#define CS_MIDDLE_32000_A0                          0.228400
+#define CS_MIDDLE_32000_A1                         -0.225214
+#define CS_MIDDLE_32000_A2                          0.000000
+#define CS_MIDDLE_32000_B1                         -0.980126
+#define CS_MIDDLE_32000_B2                          0.000000
+#define CS_MIDDLE_32000_SCALE                        15
+#define CS_SIDE_32000_A0                            0.364579
+#define CS_SIDE_32000_A1                           -0.207355
+#define CS_SIDE_32000_A2                           -0.157224
+#define CS_SIDE_32000_B1                           -1.274231
+#define CS_SIDE_32000_B2                            0.312495
+#define CS_SIDE_32000_SCALE                          14
+
+/* Stereo Enhancer coefficients for 44100Hz sample rate, scaled with 0.163834 */
+#define CS_MIDDLE_44100_A0                     0.233593
+#define CS_MIDDLE_44100_A1                    -0.231225
+#define CS_MIDDLE_44100_A2                     0.000000
+#define CS_MIDDLE_44100_B1                    -0.985545
+#define CS_MIDDLE_44100_B2                     0.000000
+#define CS_MIDDLE_44100_SCALE                        15
+#define CS_SIDE_44100_A0                       0.284573
+#define CS_SIDE_44100_A1                      -0.258910
+#define CS_SIDE_44100_A2                      -0.025662
+#define CS_SIDE_44100_B1                      -1.572248
+#define CS_SIDE_44100_B2                       0.588399
+#define CS_SIDE_44100_SCALE                  14
+
+/* Stereo Enhancer coefficients for 48000Hz sample rate, scaled with 0.164402 */
+#define CS_MIDDLE_48000_A0                     0.234445
+#define CS_MIDDLE_48000_A1                    -0.232261
+#define CS_MIDDLE_48000_A2                     0.000000
+#define CS_MIDDLE_48000_B1                    -0.986713
+#define CS_MIDDLE_48000_B2                     0.000000
+#define CS_MIDDLE_48000_SCALE                        15
+#define CS_SIDE_48000_A0                     0.272606
+#define CS_SIDE_48000_A1                    -0.266952
+#define CS_SIDE_48000_A2                    -0.005654
+#define CS_SIDE_48000_B1                    -1.617141
+#define CS_SIDE_48000_B2                     0.630405
+#define CS_SIDE_48000_SCALE                          14
+
+#ifdef HIGHER_FS
+/* Stereo Enhancer coefficients for 96000Hz sample rate, scaled with  0.165*/
+/* high pass filter with cutoff frequency 102.18 Hz*/
+#define CS_MIDDLE_96000_A0                     0.235532
+#define CS_MIDDLE_96000_A1                    -0.234432
+#define CS_MIDDLE_96000_A2                     0.000000
+#define CS_MIDDLE_96000_B1                    -0.993334
+#define CS_MIDDLE_96000_B2                     0.000000
+#define CS_MIDDLE_96000_SCALE                        15
+/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
+#define CS_SIDE_96000_A0                     0.016727
+#define CS_SIDE_96000_A1                     0.000000
+#define CS_SIDE_96000_A2                    -0.016727
+#define CS_SIDE_96000_B1                    -1.793372
+#define CS_SIDE_96000_B2                     0.797236
+#define CS_SIDE_96000_SCALE                        14
+
+/* Stereo Enhancer coefficients for 192000Hz sample rate, scaled with  0.1689*/
+#define CS_MIDDLE_192000_A0                     0.241219
+#define CS_MIDDLE_192000_A1                    -0.240656
+#define CS_MIDDLE_192000_A2                     0.000000
+#define CS_MIDDLE_192000_B1                    -0.996661
+#define CS_MIDDLE_192000_B2                     0.000000
+#define CS_MIDDLE_192000_SCALE                        15
+/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
+#define CS_SIDE_192000_A0                     0.008991
+#define CS_SIDE_192000_A1                    -0.000000
+#define CS_SIDE_192000_A2                    -0.008991
+#define CS_SIDE_192000_B1                    -1.892509
+#define CS_SIDE_192000_B2                     0.893524
+#define CS_SIDE_192000_SCALE                       14
+#endif
+
+/************************************************************************************/
+/*                                                                                  */
+/* The Reverb Unit                                                                  */
+/*                                                                                  */
+/************************************************************************************/
+
+/* Reverb delay settings in samples */
+#define LVCS_STEREODELAY_CS_8KHZ                     93         /* Sample rate 8kS/s */
+#define LVCS_STEREODELAY_CS_11KHZ                   128         /* Sample rate 11kS/s */
+#define LVCS_STEREODELAY_CS_12KHZ                   139         /* Sample rate 12kS/s */
+#define LVCS_STEREODELAY_CS_16KHZ                   186         /* Sample rate 16kS/s */
+#define LVCS_STEREODELAY_CS_22KHZ                   256         /* Sample rate 22kS/s */
+#define LVCS_STEREODELAY_CS_24KHZ                   279         /* Sample rate 24kS/s */
+#define LVCS_STEREODELAY_CS_32KHZ                   372         /* Sample rate 32kS/s */
+#define LVCS_STEREODELAY_CS_44KHZ                   512         /* Sample rate 44kS/s */
+#define LVCS_STEREODELAY_CS_48KHZ                   512         /* Sample rate 48kS/s */
+
+/* Reverb coefficients for 8000 Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_8000_A0                          0.667271
+#define CS_REVERB_8000_A1                         -0.667271
+#define CS_REVERB_8000_A2                          0.000000
+#define CS_REVERB_8000_B1                         -0.668179
+#define CS_REVERB_8000_B2                          0.000000
+#define CS_REVERB_8000_SCALE                         15
+
+/* Reverb coefficients for 11025Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_11025_A0                     0.699638
+#define CS_REVERB_11025_A1                    -0.699638
+#define CS_REVERB_11025_A2                     0.000000
+#define CS_REVERB_11025_B1                    -0.749096
+#define CS_REVERB_11025_B2                     0.000000
+#define CS_REVERB_11025_SCALE                  15
+
+/* Reverb coefficients for 12000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_12000_A0                   0.706931
+#define CS_REVERB_12000_A1                  -0.706931
+#define CS_REVERB_12000_A2                   0.000000
+#define CS_REVERB_12000_B1                  -0.767327
+#define CS_REVERB_12000_B2                   0.000000
+#define CS_REVERB_12000_SCALE                15
+
+/* Reverb coefficients for 16000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_16000_A0                      0.728272
+#define CS_REVERB_16000_A1                     -0.728272
+#define CS_REVERB_16000_A2                      0.000000
+#define CS_REVERB_16000_B1                     -0.820679
+#define CS_REVERB_16000_B2                      0.000000
+#define CS_REVERB_16000_SCALE                        15
+
+/* Reverb coefficients for 22050Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_22050_A0                     0.516396
+#define CS_REVERB_22050_A1                     0.000000
+#define CS_REVERB_22050_A2                    -0.516396
+#define CS_REVERB_22050_B1                    -0.518512
+#define CS_REVERB_22050_B2                    -0.290990
+#define CS_REVERB_22050_SCALE                        15
+
+
+/* Reverb coefficients for 24000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_24000_A0                       0.479565
+#define CS_REVERB_24000_A1                       0.000000
+#define CS_REVERB_24000_A2                      -0.479565
+#define CS_REVERB_24000_B1                      -0.637745
+#define CS_REVERB_24000_B2                      -0.198912
+#define CS_REVERB_24000_SCALE                        15
+
+/* Reverb coefficients for 32000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_32000_A0                      0.380349
+#define CS_REVERB_32000_A1                      0.000000
+#define CS_REVERB_32000_A2                     -0.380349
+#define CS_REVERB_32000_B1                     -0.950873
+#define CS_REVERB_32000_B2                      0.049127
+#define CS_REVERB_32000_SCALE                        15
+
+/* Reverb coefficients for 44100Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_44100_A0                         0.297389
+#define CS_REVERB_44100_A1                         0.000000
+#define CS_REVERB_44100_A2                        -0.297389
+#define CS_REVERB_44100_B1                        -1.200423
+#define CS_REVERB_44100_B2                         0.256529
+#define CS_REVERB_44100_SCALE                        14
+
+/* Reverb coefficients for 48000Hz sample rate, scaled with 1.038030 */
+#define CS_REVERB_48000_A0                       0.278661
+#define CS_REVERB_48000_A1                       0.000000
+#define CS_REVERB_48000_A2                      -0.278661
+#define CS_REVERB_48000_B1                      -1.254993
+#define CS_REVERB_48000_B2                       0.303347
+#define CS_REVERB_48000_SCALE                        14
+
+#ifdef HIGHER_FS
+/* Reverb coefficients for 96000Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000*/
+#define CS_REVERB_96000_A0                       0.1602488
+#define CS_REVERB_96000_A1                       0.000000
+#define CS_REVERB_96000_A2                      -0.1602488
+#define CS_REVERB_96000_B1                      -1.585413
+#define CS_REVERB_96000_B2                       0.599377
+#define CS_REVERB_96000_SCALE                        14
+
+/* Reverb coefficients for 192000Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000*/
+#define CS_REVERB_192000_A0                       0.0878369
+#define CS_REVERB_192000_A1                       0.000000
+#define CS_REVERB_192000_A2                      -0.0878369
+#define CS_REVERB_192000_B1                      -1.7765764
+#define CS_REVERB_192000_B2                       0.7804076
+#define CS_REVERB_192000_SCALE                        14
+
+#endif
+
+
+/* Reverb Gain Settings */
+#define LVCS_HEADPHONE_DELAYGAIN               0.800000         /* Algorithm delay path gain */
+#define LVCS_HEADPHONE_OUTPUTGAIN              1.000000         /* Algorithm output gain */
+#define LVCS_HEADPHONE_PROCGAIN                   18403         /* Processed path gain */
+#define LVCS_HEADPHONE_UNPROCGAIN                 18403         /* Unprocessed path gain */
+#define LVCS_HEADPHONE_GAINCORRECT             1.009343         /* Delay mixer gain correction */
+
+/************************************************************************************/
+/*                                                                                  */
+/* The Equaliser                                                                    */
+/*                                                                                  */
+/************************************************************************************/
+
+/* Equaliser coefficients for 8000 Hz sample rate, \
+   CS scaled with 1.038497 and CSEX scaled with 0.775480 */
+#define CS_EQUALISER_8000_A0                     1.263312
+#define CS_EQUALISER_8000_A1                    -0.601748
+#define CS_EQUALISER_8000_A2                    -0.280681
+#define CS_EQUALISER_8000_B1                    -0.475865
+#define CS_EQUALISER_8000_B2                    -0.408154
+#define CS_EQUALISER_8000_SCALE                      14
+#define CSEX_EQUALISER_8000_A0                    0.943357
+#define CSEX_EQUALISER_8000_A1                   -0.449345
+#define CSEX_EQUALISER_8000_A2                   -0.209594
+#define CSEX_EQUALISER_8000_B1                   -0.475865
+#define CSEX_EQUALISER_8000_B2                   -0.408154
+#define CSEX_EQUALISER_8000_SCALE                    15
+
+/* Equaliser coefficients for 11025Hz sample rate, \
+   CS scaled with 1.027761 and CSEX scaled with 0.767463 */
+#define CS_EQUALISER_11025_A0                    1.101145
+#define CS_EQUALISER_11025_A1                    0.139020
+#define CS_EQUALISER_11025_A2                   -0.864423
+#define CS_EQUALISER_11025_B1                    0.024541
+#define CS_EQUALISER_11025_B2                   -0.908930
+#define CS_EQUALISER_11025_SCALE                     14
+#define CSEX_EQUALISER_11025_A0                    0.976058
+#define CSEX_EQUALISER_11025_A1                   -0.695326
+#define CSEX_EQUALISER_11025_A2                   -0.090809
+#define CSEX_EQUALISER_11025_B1                   -0.610594
+#define CSEX_EQUALISER_11025_B2                   -0.311149
+#define CSEX_EQUALISER_11025_SCALE                   15
+
+/* Equaliser coefficients for 12000Hz sample rate, \
+   CS scaled with 1.032521 and CSEX scaled with 0.771017 */
+#define CS_EQUALISER_12000_A0                      1.276661
+#define CS_EQUALISER_12000_A1                     -1.017519
+#define CS_EQUALISER_12000_A2                     -0.044128
+#define CS_EQUALISER_12000_B1                     -0.729616
+#define CS_EQUALISER_12000_B2                     -0.204532
+#define CS_EQUALISER_12000_SCALE                     14
+#define CSEX_EQUALISER_12000_A0                 1.007095
+#define CSEX_EQUALISER_12000_A1                -0.871912
+#define CSEX_EQUALISER_12000_A2                 0.023232
+#define CSEX_EQUALISER_12000_B1                -0.745857
+#define CSEX_EQUALISER_12000_B2                -0.189171
+#define CSEX_EQUALISER_12000_SCALE                   14
+
+/* Equaliser coefficients for 16000Hz sample rate, \
+   CS scaled with 1.031378 and CSEX scaled with 0.770164 */
+#define CS_EQUALISER_16000_A0                     1.281629
+#define CS_EQUALISER_16000_A1                    -1.075872
+#define CS_EQUALISER_16000_A2                    -0.041365
+#define CS_EQUALISER_16000_B1                    -0.725239
+#define CS_EQUALISER_16000_B2                    -0.224358
+#define CS_EQUALISER_16000_SCALE                     14
+#define CSEX_EQUALISER_16000_A0                  1.081091
+#define CSEX_EQUALISER_16000_A1                 -0.867183
+#define CSEX_EQUALISER_16000_A2                 -0.070247
+#define CSEX_EQUALISER_16000_B1                 -0.515121
+#define CSEX_EQUALISER_16000_B2                 -0.425893
+#define CSEX_EQUALISER_16000_SCALE                   14
+
+/* Equaliser coefficients for 22050Hz sample rate, \
+   CS scaled with 1.041576 and CSEX scaled with 0.777779 */
+#define CS_EQUALISER_22050_A0                   1.388605
+#define CS_EQUALISER_22050_A1                  -1.305799
+#define CS_EQUALISER_22050_A2                   0.039922
+#define CS_EQUALISER_22050_B1                  -0.719494
+#define CS_EQUALISER_22050_B2                  -0.243245
+#define CS_EQUALISER_22050_SCALE                     14
+#define CSEX_EQUALISER_22050_A0                   1.272910
+#define CSEX_EQUALISER_22050_A1                  -1.341014
+#define CSEX_EQUALISER_22050_A2                   0.167462
+#define CSEX_EQUALISER_22050_B1                  -0.614219
+#define CSEX_EQUALISER_22050_B2                  -0.345384
+#define CSEX_EQUALISER_22050_SCALE                   14
+
+/* Equaliser coefficients for 24000Hz sample rate, \
+   CS scaled with 1.034495 and CSEX scaled with 0.772491 */
+#define CS_EQUALISER_24000_A0                    1.409832
+#define CS_EQUALISER_24000_A1                   -1.456506
+#define CS_EQUALISER_24000_A2                    0.151410
+#define CS_EQUALISER_24000_B1                   -0.804201
+#define CS_EQUALISER_24000_B2                   -0.163783
+#define CS_EQUALISER_24000_SCALE                     14
+#define CSEX_EQUALISER_24000_A0                  1.299198
+#define CSEX_EQUALISER_24000_A1                 -1.452447
+#define CSEX_EQUALISER_24000_A2                  0.240489
+#define CSEX_EQUALISER_24000_B1                 -0.669303
+#define CSEX_EQUALISER_24000_B2                 -0.294984
+#define CSEX_EQUALISER_24000_SCALE                   14
+
+/* Equaliser coefficients for 32000Hz sample rate, \
+   CS scaled with 1.044559 and CSEX scaled with 0.780006 */
+#define CS_EQUALISER_32000_A0                     1.560988
+#define CS_EQUALISER_32000_A1                    -1.877724
+#define CS_EQUALISER_32000_A2                     0.389741
+#define CS_EQUALISER_32000_B1                    -0.907410
+#define CS_EQUALISER_32000_B2                    -0.070489
+#define CS_EQUALISER_32000_SCALE                     14
+#define CSEX_EQUALISER_32000_A0                  1.785049
+#define CSEX_EQUALISER_32000_A1                 -2.233497
+#define CSEX_EQUALISER_32000_A2                  0.526431
+#define CSEX_EQUALISER_32000_B1                 -0.445939
+#define CSEX_EQUALISER_32000_B2                 -0.522446
+#define CSEX_EQUALISER_32000_SCALE                   13
+
+/* Equaliser coefficients for 44100Hz sample rate, \
+   CS scaled with 1.022170 and CSEX scaled with 0.763288 */
+#define CS_EQUALISER_44100_A0                  1.623993
+#define CS_EQUALISER_44100_A1                 -2.270743
+#define CS_EQUALISER_44100_A2                  0.688829
+#define CS_EQUALISER_44100_B1                 -1.117190
+#define CS_EQUALISER_44100_B2                  0.130208
+#define CS_EQUALISER_44100_SCALE                     13
+#define CSEX_EQUALISER_44100_A0                   2.028315
+#define CSEX_EQUALISER_44100_A1                  -2.882459
+#define CSEX_EQUALISER_44100_A2                   0.904535
+#define CSEX_EQUALISER_44100_B1                  -0.593308
+#define CSEX_EQUALISER_44100_B2                  -0.385816
+#define CSEX_EQUALISER_44100_SCALE                   13
+
+/* Equaliser coefficients for 48000Hz sample rate, \
+   CS scaled with 1.018635 and CSEX scaled with 0.760648 */
+#define CS_EQUALISER_48000_A0                    1.641177
+#define CS_EQUALISER_48000_A1                   -2.364687
+#define CS_EQUALISER_48000_A2                    0.759910
+#define CS_EQUALISER_48000_B1                   -1.166774
+#define CS_EQUALISER_48000_B2                    0.178074
+#define CS_EQUALISER_48000_SCALE                     13
+#define CSEX_EQUALISER_48000_A0                  2.099655
+#define CSEX_EQUALISER_48000_A1                 -3.065220
+#define CSEX_EQUALISER_48000_A2                  1.010417
+#define CSEX_EQUALISER_48000_B1                 -0.634021
+#define CSEX_EQUALISER_48000_B2                 -0.347332
+#define CSEX_EQUALISER_48000_SCALE                   13
+
+
+#ifdef HIGHER_FS
+#define CS_EQUALISER_96000_A0                    1.784497
+#define CS_EQUALISER_96000_A1                   -3.001435
+#define CS_EQUALISER_96000_A2                    1.228422
+#define CS_EQUALISER_96000_B1                   -1.477804
+#define CS_EQUALISER_96000_B2                    0.481369
+#define CS_EQUALISER_96000_SCALE                     13
+#define CSEX_EQUALISER_96000_A0                  2.7573
+#define CSEX_EQUALISER_96000_A1                 -4.6721
+#define CSEX_EQUALISER_96000_A2                  1.9317
+#define CSEX_EQUALISER_96000_B1                 -0.971718
+#define CSEX_EQUALISER_96000_B2                 -0.021216
+#define CSEX_EQUALISER_96000_SCALE                   13
+
+#define CS_EQUALISER_192000_A0                    1.889582
+#define CS_EQUALISER_192000_A1                   -3.456140
+#define CS_EQUALISER_192000_A2                    1.569864
+#define CS_EQUALISER_192000_B1                   -1.700798
+#define CS_EQUALISER_192000_B2                    0.701824
+#define CS_EQUALISER_192000_SCALE                     13
+#define CSEX_EQUALISER_192000_A0                  3.4273
+#define CSEX_EQUALISER_192000_A1                 -6.2936
+#define CSEX_EQUALISER_192000_A2                  2.8720
+#define CSEX_EQUALISER_192000_B1                 -1.31074
+#define CSEX_EQUALISER_192000_B2                 0.31312
+#define CSEX_EQUALISER_192000_SCALE                   13
+#endif
+
+
+#define LVCS_HEADPHONE_SHIFT                          2              /* Output Shift */
+#define LVCS_HEADPHONE_SHIFTLOSS                  0.8477735          /* Output Shift loss */
+#define LVCS_HEADPHONE_GAIN                       0.2087465          /* Unprocessed path gain */
+#define LVCS_EX_HEADPHONE_SHIFT                       3              /* EX Output Shift */
+#define LVCS_EX_HEADPHONE_SHIFTLOSS               0.569225           /* EX Output Shift loss */
+#define LVCS_EX_HEADPHONE_GAIN                    0.07794425         /* EX Unprocessed path gain */
+#else
 /* Stereo Enhancer coefficients for 8000 Hz sample rate, scaled with 0.161258 */
 #define CS_MIDDLE_8000_A0                          7462         /* Floating point value 0.227720 */
 #define CS_MIDDLE_8000_A1                        (-7049)        /* Floating point value -0.215125 */
@@ -394,5 +850,6 @@
 #define LVCS_EX_HEADPHONE_SHIFT                       3              /* EX Output Shift */
 #define LVCS_EX_HEADPHONE_SHIFTLOSS               18600              /* EX Output Shift loss */
 #define LVCS_EX_HEADPHONE_GAIN                     5108              /* EX Unprocessed path gain */
-
 #endif
+#endif
+
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
index 1904e46..d4c7627 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
@@ -98,7 +98,13 @@
         /*
          * Scratch memory
          */
+#ifdef BUILD_FLOAT
+        /* Inplace processing */
+        ScratchSize = (LVM_UINT32) \
+                        (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT) * pCapabilities->MaxBlockSize);
+#else
         ScratchSize = (LVM_UINT32)(LVCS_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);     /* Inplace processing */
+#endif
         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;
@@ -190,6 +196,7 @@
     pLVCS_VolCorrectTable            = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
     pInstance->VolCorrect            = pLVCS_VolCorrectTable[0];
     pInstance->TransitionGain        = 0;
+
     /* These current and target values are intialized again in LVCS_Control.c */
     LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
     /* These current and target values are intialized again in LVCS_Control.c */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index f3adb8d..a97e4f0 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -95,10 +95,17 @@
 /* Volume correction structure */
 typedef struct
 {
+#ifdef BUILD_FLOAT
+    LVM_FLOAT   CompFull;                       /* Post CS compression 100% effect */
+    LVM_FLOAT   CompMin;                        /* Post CS compression 0% effect */
+    LVM_FLOAT   GainFull;                       /* CS gain correct 100% effect */
+    LVM_FLOAT   GainMin;                        /* CS gain correct 0% effect */
+#else
     LVM_INT16   CompFull;                       /* Post CS compression 100% effect */
     LVM_INT16   CompMin;                        /* Post CS compression 0% effect */
     LVM_INT16   GainFull;                       /* CS gain correct 100% effect */
     LVM_INT16   GainMin;                        /* CS gain correct 0% effect */
+#endif
 } LVCS_VolCorrect_t;
 
 /* Instance structure */
@@ -112,8 +119,13 @@
     /* Private parameters */
     LVCS_OutputDevice_en    OutputDevice;       /* Selected output device type */
     LVCS_VolCorrect_t       VolCorrect;         /* Volume correction settings */
+#ifndef BUILD_FLOAT
     LVM_INT16               TransitionGain;     /* Transition gain */
     LVM_INT16               CompressGain;       /* Last used compressor gain*/
+#else
+    LVM_FLOAT               TransitionGain;     /* Transition gain */
+    LVM_FLOAT               CompressGain;       /* Last used compressor gain*/
+#endif
 
     /* Sub-block configurations */
     LVCS_StereoEnhancer_t   StereoEnhancer;     /* Stereo enhancer configuration */
@@ -134,24 +146,35 @@
 /* Coefficient Structure */
 typedef struct
 {
+#ifdef BUILD_FLOAT
+    Biquad_FLOAT_Instance_t       EqualiserBiquadInstance;
+    Biquad_FLOAT_Instance_t       ReverbBiquadInstance;
+    Biquad_FLOAT_Instance_t       SEBiquadInstanceMid;
+    Biquad_FLOAT_Instance_t       SEBiquadInstanceSide;
+#else
     Biquad_Instance_t       EqualiserBiquadInstance;
     Biquad_Instance_t       ReverbBiquadInstance;
     Biquad_Instance_t       SEBiquadInstanceMid;
     Biquad_Instance_t       SEBiquadInstanceSide;
-
+#endif
 } LVCS_Coefficient_t;
 
 /* Data Structure */
 typedef struct
 {
+#ifdef BUILD_FLOAT
+    Biquad_2I_Order2_FLOAT_Taps_t EqualiserBiquadTaps;
+    Biquad_2I_Order2_FLOAT_Taps_t ReverbBiquadTaps;
+    Biquad_1I_Order1_FLOAT_Taps_t SEBiquadTapsMid;
+    Biquad_1I_Order2_FLOAT_Taps_t SEBiquadTapsSide;
+#else
     Biquad_2I_Order2_Taps_t EqualiserBiquadTaps;
     Biquad_2I_Order2_Taps_t ReverbBiquadTaps;
     Biquad_1I_Order1_Taps_t SEBiquadTapsMid;
     Biquad_1I_Order2_Taps_t SEBiquadTapsSide;
-
+#endif
 } LVCS_Data_t;
 
-
 void LVCS_TimerCallBack (   void* hInstance,
                             void* pCallBackParams,
                             LVM_INT32 CallbackParam);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
index 5d99461..3956d4d 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
@@ -66,7 +66,77 @@
 /* NOTES:                                                                           */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t              hInstance,
+                                     const LVM_FLOAT            *pInData,
+                                     LVM_FLOAT                  *pOutData,
+                                     LVM_UINT16                 NumSamples)
+{
+    const LVM_FLOAT     *pInput;
+    LVCS_Instance_t     *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVM_FLOAT           *pScratch;
+    LVCS_ReturnStatus_en err;
 
+    pScratch  = (LVM_FLOAT *) \
+                  pInstance->MemoryTable.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress;
+
+    /*
+     * Check if the processing is inplace
+     */
+    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;
+    }
+
+    /*
+     * Call the stereo enhancer
+     */
+    err = LVCS_StereoEnhancer(hInstance,              /* Instance handle */
+                              pInData,                    /* Pointer to the input data */
+                              pOutData,                   /* Pointer to the output data */
+                              NumSamples);                /* Number of samples to process */
+
+    /*
+     * Call the reverb generator
+     */
+    err = LVCS_ReverbGenerator(hInstance,             /* Instance handle */
+                               pOutData,                  /* Pointer to the input data */
+                               pOutData,                  /* Pointer to the output data */
+                               NumSamples);               /* Number of samples to process */
+    
+    /*
+     * Call the equaliser
+     */
+    err = LVCS_Equaliser(hInstance,                   /* Instance handle */
+                         pOutData,                        /* Pointer to the input data */
+                         NumSamples);                     /* Number of samples to process */
+
+    /*
+     * Call the bypass mixer
+     */
+    err = LVCS_BypassMixer(hInstance,                 /* Instance handle */
+                           pOutData,                      /* Pointer to the processed data */
+                           pInput,                        /* Pointer to the input (unprocessed) data */
+                           pOutData,                      /* Pointer to the output data */
+                           NumSamples);                   /* Number of samples to process */
+
+    if(err != LVCS_SUCCESS)
+    {
+        return err;
+    }
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_Process_CS(LVCS_Handle_t              hInstance,
                                      const LVM_INT16            *pInData,
                                      LVM_INT16                  *pOutData,
@@ -133,7 +203,7 @@
 
     return(LVCS_SUCCESS);
 }
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:                LVCS_Process                                            */
@@ -160,7 +230,170 @@
 /* NOTES:                                                                           */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t             hInstance,
+                                  const LVM_FLOAT           *pInData,
+                                  LVM_FLOAT                 *pOutData,
+                                  LVM_UINT16                NumSamples)
+{
 
+    LVCS_Instance_t *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVCS_ReturnStatus_en err;
+
+    /*
+     * Check the number of samples is not too large
+     */
+    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
+    {
+        return(LVCS_TOOMANYSAMPLES);
+    }
+
+    /*
+     * Check if the algorithm is enabled
+     */
+    if (pInstance->Params.OperatingMode != LVCS_OFF)
+    {
+        /*
+         * Call CS process function
+         */
+            err = LVCS_Process_CS(hInstance,
+                                  pInData,
+                                  pOutData,
+                                  NumSamples);
+            
+            
+        /*
+         * Compress to reduce expansion effect of Concert Sound and correct volume
+         * differences for difference settings. Not applied in test modes
+         */
+        if ((pInstance->Params.OperatingMode == LVCS_ON)&& \
+                                        (pInstance->Params.CompressorMode == LVM_MODE_ON))
+        {
+            LVM_FLOAT Gain = pInstance->VolCorrect.CompMin;
+            LVM_FLOAT Current1;
+
+            Current1 = LVC_Mixer_GetCurrent(&pInstance->BypassMix.Mixer_Instance.MixerStream[0]);
+            Gain = (LVM_FLOAT)(  pInstance->VolCorrect.CompMin
+                               - (((LVM_FLOAT)pInstance->VolCorrect.CompMin  * (Current1)))
+                               + (((LVM_FLOAT)pInstance->VolCorrect.CompFull * (Current1))));
+
+            if(NumSamples < LVCS_COMPGAINFRAME)
+            {
+                NonLinComp_Float(Gain,                    /* Compressor gain setting */
+                                 pOutData,
+                                 pOutData,
+                                 (LVM_INT32)(2 * NumSamples));
+            }
+            else
+            {
+                LVM_FLOAT  GainStep;
+                LVM_FLOAT  FinalGain;
+                LVM_INT16  SampleToProcess = NumSamples;
+                LVM_FLOAT  *pOutPtr;
+
+                /* Large changes in Gain can cause clicks in output
+                   Split data into small blocks and use interpolated gain values */
+
+                GainStep = (LVM_FLOAT)(((Gain-pInstance->CompressGain) * \
+                                                LVCS_COMPGAINFRAME) / NumSamples);
+
+                if((GainStep == 0) && (pInstance->CompressGain < Gain))
+                {
+                    GainStep = 1;
+                }
+                else
+                {
+                    if((GainStep == 0) && (pInstance->CompressGain > Gain))
+                    {
+                        GainStep = -1;
+                    }
+                }
+
+                FinalGain = Gain;
+                Gain = pInstance->CompressGain;
+                pOutPtr = pOutData;
+
+                while(SampleToProcess > 0)
+                {
+                    Gain = (LVM_FLOAT)(Gain + GainStep);
+                    if((GainStep > 0) && (FinalGain <= Gain))
+                    {
+                        Gain = FinalGain;
+                        GainStep = 0;
+                    }
+
+                    if((GainStep < 0) && (FinalGain > Gain))
+                    {
+                        Gain = FinalGain;
+                        GainStep = 0;
+                    }
+
+                    if(SampleToProcess > LVCS_COMPGAINFRAME)
+                    {
+                        NonLinComp_Float(Gain,                    /* Compressor gain setting */
+                                         pOutPtr,
+                                         pOutPtr,
+                                         (LVM_INT32)(2 * LVCS_COMPGAINFRAME));
+                        pOutPtr += (2 * LVCS_COMPGAINFRAME);
+                        SampleToProcess = (LVM_INT16)(SampleToProcess - LVCS_COMPGAINFRAME);
+                    }
+                    else
+                    {
+                        NonLinComp_Float(Gain,                    /* Compressor gain setting */
+                                         pOutPtr,
+                                         pOutPtr,
+                                         (LVM_INT32)(2 * SampleToProcess));
+                        SampleToProcess = 0;
+                    }
+
+                }
+            }
+
+            /* Store gain value*/
+            pInstance->CompressGain = Gain;
+        }
+
+
+        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
+
+            /*
+             * Re-init bypass mix when timer has completed
+             */
+            if ((pInstance->bTimerDone == LVM_TRUE) &&
+                (pInstance->BypassMix.Mixer_Instance.MixerStream[1].CallbackSet == 0))
+            {
+                err = LVCS_BypassMixInit(hInstance,
+                                         &pInstance->Params);
+
+                if(err != LVCS_SUCCESS)
+                {
+                    return err;
+                }
+
+            }
+            else{
+                LVM_Timer ( &pInstance->TimerInstance,
+                            (LVM_INT16)NumSamples);
+            }
+        }
+    }
+    else
+    {
+        if (pInData != pOutData)
+        {
+            /*
+             * 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 */
+        }
+    }
+
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_Process(LVCS_Handle_t             hInstance,
                                   const LVM_INT16           *pInData,
                                   LVM_INT16                 *pOutData,
@@ -321,13 +554,4 @@
 
     return(LVCS_SUCCESS);
 }
-
-
-
-
-
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
index ee257b8..1085101 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
@@ -57,7 +57,98 @@
 /*  2.  The numerator coefficients of the filter are negated to cause an inversion. */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t     hInstance,
+                                              LVCS_Params_t     *pParams)
+{
 
+    LVM_UINT16              Delay;
+    LVM_UINT16              Offset;
+    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVCS_ReverbGenerator_t  *pConfig   = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
+    LVCS_Data_t             *pData;
+    LVCS_Coefficient_t      *pCoefficients;
+    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;
+
+    /*
+     * Initialise the delay and filters if:
+     *  - the sample rate has changed
+     *  - the speaker type has changed to or from the mobile speaker
+     */
+    if(pInstance->Params.SampleRate != pParams->SampleRate )      /* Sample rate change test */
+
+    {
+        /*
+         * Setup the delay
+         */
+        Delay = (LVM_UINT16)LVCS_StereoDelayCS[(LVM_UINT16)pParams->SampleRate];
+
+
+        pConfig->DelaySize      = (LVM_INT16)(2 * Delay);
+        pConfig->DelayOffset    = 0;
+        LoadConst_Float(0,                                            /* Value */
+                        (LVM_FLOAT *)&pConfig->StereoSamples[0],      /* Destination */
+                        /* Number of words */
+                        (LVM_UINT16)(sizeof(pConfig->StereoSamples) / sizeof(LVM_FLOAT)));
+        /*
+         * Setup the filters
+         */
+        Offset = (LVM_UINT16)pParams->SampleRate;
+        pReverbCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_ReverbCoefTable[0];
+
+        /* Convert incoming coefficients to the required format/ordering */
+        Coeffs.A0 = (LVM_FLOAT)pReverbCoefTable[Offset].A0;
+        Coeffs.A1 = (LVM_FLOAT)pReverbCoefTable[Offset].A1;
+        Coeffs.A2 = (LVM_FLOAT)pReverbCoefTable[Offset].A2;
+        Coeffs.B1 = (LVM_FLOAT)-pReverbCoefTable[Offset].B1;
+        Coeffs.B2 = (LVM_FLOAT)-pReverbCoefTable[Offset].B2;
+
+        LoadConst_Float(0,                                 /* Value */
+                        (void *)&pData->ReverbBiquadTaps,  /* Destination Cast to void:
+                                                             no dereferencing in function*/
+                        /* Number of words */
+                        (LVM_UINT16)(sizeof(pData->ReverbBiquadTaps) / sizeof(LVM_FLOAT)));
+
+        BQ_2I_D16F16Css_TRC_WRA_01_Init(&pCoefficients->ReverbBiquadInstance,
+                                        &pData->ReverbBiquadTaps,
+                                        &Coeffs);
+
+        /* Callbacks */
+        switch(pReverbCoefTable[Offset].Scale)
+        {
+            case 14:
+                pConfig->pBiquadCallBack  = BQ_2I_D16F16C14_TRC_WRA_01;
+                break;
+            case 15:
+                pConfig->pBiquadCallBack  = BQ_2I_D16F16C15_TRC_WRA_01;
+                break;
+        }
+
+
+        /*
+         * Setup the mixer
+         */
+        pConfig->ProcGain = (LVM_UINT16)(HEADPHONEGAINPROC);
+        pConfig->UnprocGain  = (LVM_UINT16)(HEADPHONEGAINUNPROC);
+    }
+
+    if(pInstance->Params.ReverbLevel != pParams->ReverbLevel)
+    {
+        LVM_INT32   ReverbPercentage = 83886;      // 1 Percent Reverb i.e 1/100 in Q 23 format
+        ReverbPercentage *= pParams->ReverbLevel;  // Actual Reverb Level in Q 23 format
+        pConfig->ReverbLevel = ((LVM_FLOAT)(ReverbPercentage>>8)) / 32767.0f;
+    }
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t     hInstance,
                                               LVCS_Params_t     *pParams)
 {
@@ -140,7 +231,7 @@
 
     return(LVCS_SUCCESS);
 }
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:                LVCS_Reverb                                             */
@@ -179,7 +270,91 @@
 /*  2.  The Gain is combined with the LPF and incorporated in to the coefficients   */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t         hInstance,
+                                          const LVM_FLOAT       *pInData,
+                                          LVM_FLOAT             *pOutData,
+                                          LVM_UINT16            NumSamples)
+{
 
+    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVCS_ReverbGenerator_t  *pConfig   = (LVCS_ReverbGenerator_t *)&pInstance->Reverberation;
+    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;
+
+    /*
+     * Copy the data to the output in outplace processing
+     */
+    if (pInData != pOutData)
+    {
+        /*
+         * Reverb not required so just copy the data
+         */
+        Copy_Float((LVM_FLOAT *)pInData,                                       /* Source */
+                   (LVM_FLOAT *)pOutData,                                      /* Destination */
+                   (LVM_INT16)(2 * NumSamples));                                 /* Left and right */
+    }
+
+
+    /*
+     * Check if the reverb is required
+     */
+    /* Disable when CS4MS in stereo mode */
+    if (((pInstance->Params.SpeakerType == LVCS_HEADPHONE) || \
+         (pInstance->Params.SpeakerType == LVCS_EX_HEADPHONES) ||
+         (pInstance->Params.SourceFormat != LVCS_STEREO))  &&
+                                    /* For validation testing */
+        ((pInstance->Params.OperatingMode & LVCS_REVERBSWITCH) !=0))
+    {
+        /********************************************************************************/
+        /*                                                                              */
+        /* Copy the input data to scratch memory and filter it                          */
+        /*                                                                              */
+        /********************************************************************************/
+
+        /*
+         * Copy the input data to the scratch memory
+         */
+        Copy_Float((LVM_FLOAT *)pInData,                                     /* Source */
+                   (LVM_FLOAT *)pScratch,                                    /* Destination */
+                   (LVM_INT16)(2 * NumSamples));                               /* Left and right */
+
+        /*
+         * Filter the data
+         */
+        (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*)&pCoefficients->ReverbBiquadInstance,
+                                   (LVM_FLOAT *)pScratch,
+                                   (LVM_FLOAT *)pScratch,
+                                   (LVM_INT16)NumSamples);
+
+        Mult3s_Float( (LVM_FLOAT *)pScratch,
+                      pConfig->ReverbLevel,
+                      (LVM_FLOAT *)pScratch,
+                      (LVM_INT16)(2 * NumSamples));
+
+
+        /*
+         * Apply the delay mix
+         */
+        DelayMix_Float((LVM_FLOAT *)pScratch,
+                       &pConfig->StereoSamples[0],
+                       pConfig->DelaySize,
+                       pOutData,
+                       &pConfig->DelayOffset,
+                       (LVM_INT16)NumSamples);
+
+
+    }
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t         hInstance,
                                           const LVM_INT16       *pInData,
                                           LVM_INT16             *pOutData,
@@ -257,8 +432,4 @@
 
     return(LVCS_SUCCESS);
 }
-
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
index 6e026ff..69892b6 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -58,14 +58,20 @@
     LVM_INT16                   DelayOffset;
     LVM_INT16                   ProcGain;
     LVM_INT16                   UnprocGain;
+#ifndef BUILD_FLOAT
     LVM_INT16                    StereoSamples[2*LVCS_STEREODELAY_CS_48KHZ];
-
     /* Reverb Level */
     LVM_INT16                   ReverbLevel;
-
     /* Filter */
     void                        (*pBiquadCallBack) (Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
+#else
+    LVM_FLOAT                   StereoSamples[2 * LVCS_STEREODELAY_CS_48KHZ];
+    /* Reverb Level */
+    LVM_FLOAT                   ReverbLevel;
+    /* Filter */
+    void                        (*pBiquadCallBack) (Biquad_FLOAT_Instance_t*,
+                                                    LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
 } LVCS_ReverbGenerator_t;
 
 
@@ -77,12 +83,17 @@
 
 LVCS_ReturnStatus_en LVCS_ReverbGeneratorInit(LVCS_Handle_t     hInstance,
                                                  LVCS_Params_t  *pParams);
-
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t         hInstance,
+                                          const LVM_FLOAT       *pInput,
+                                          LVM_FLOAT             *pOutput,
+                                          LVM_UINT16            NumSamples);
+#else
 LVCS_ReturnStatus_en LVCS_ReverbGenerator(LVCS_Handle_t         hInstance,
                                           const LVM_INT16       *pInput,
                                           LVM_INT16             *pOutput,
                                           LVM_UINT16            NumSamples);
-
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
index b9b8b05..2992c35 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
@@ -49,7 +49,103 @@
 /* NOTES:                                                                           */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t       hInstance,
+                                        LVCS_Params_t       *pParams)
+{
 
+    LVM_UINT16              Offset;
+    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
+    LVCS_StereoEnhancer_t   *pConfig   = (LVCS_StereoEnhancer_t *)&pInstance->StereoEnhancer;
+    LVCS_Data_t             *pData;
+    LVCS_Coefficient_t      *pCoefficient;
+    FO_FLOAT_Coefs_t          CoeffsMid;
+    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;
+
+    /*
+     * If the sample rate or speaker type has changed update the filters
+     */
+    if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
+        (pInstance->Params.SpeakerType != pParams->SpeakerType))
+    {
+        /*
+         * Set the filter coefficients based on the sample rate
+         */
+        /* Mid filter */
+        Offset = (LVM_UINT16)pParams->SampleRate;
+
+        /* Convert incoming coefficients to the required format/ordering */
+        CoeffsMid.A0 = (LVM_FLOAT) LVCS_SEMidCoefTable[Offset].A0;
+        CoeffsMid.A1 = (LVM_FLOAT) LVCS_SEMidCoefTable[Offset].A1;
+        CoeffsMid.B1 = (LVM_FLOAT)-LVCS_SEMidCoefTable[Offset].B1;
+
+        /* Clear the taps */
+        LoadConst_Float(0,                                  /* Value */
+                        (void *)&pData->SEBiquadTapsMid,    /* Destination Cast to void:\
+                                                              no dereferencing in function*/
+                        /* Number of words */
+                        (LVM_UINT16)(sizeof(pData->SEBiquadTapsMid) / sizeof(LVM_FLOAT)));
+
+        FO_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceMid,
+                                        &pData->SEBiquadTapsMid,
+                                        &CoeffsMid);
+
+        /* Callbacks */
+        if(LVCS_SEMidCoefTable[Offset].Scale == 15)
+        {
+            pConfig->pBiquadCallBack_Mid  = FO_1I_D16F16C15_TRC_WRA_01;
+        }
+
+        Offset = (LVM_UINT16)(pParams->SampleRate);
+        pSESideCoefs = (BiquadA012B12CoefsSP_t*)&LVCS_SESideCoefTable[0];
+
+        /* Side filter */
+        /* Convert incoming coefficients to the required format/ordering */
+        CoeffsSide.A0 = (LVM_FLOAT) pSESideCoefs[Offset].A0;
+        CoeffsSide.A1 = (LVM_FLOAT) pSESideCoefs[Offset].A1;
+        CoeffsSide.A2 = (LVM_FLOAT) pSESideCoefs[Offset].A2;
+        CoeffsSide.B1 = (LVM_FLOAT)-pSESideCoefs[Offset].B1;
+        CoeffsSide.B2 = (LVM_FLOAT)-pSESideCoefs[Offset].B2;
+
+        /* Clear the taps */
+        LoadConst_Float(0,                                /* Value */
+                        (void *)&pData->SEBiquadTapsSide, /* Destination Cast to void:\
+                                                             no dereferencing in function*/
+                        /* Number of words */
+                        (LVM_UINT16)(sizeof(pData->SEBiquadTapsSide) / sizeof(LVM_FLOAT)));
+        /* Callbacks */
+        switch(pSESideCoefs[Offset].Scale)
+        {
+            case 14:
+                BQ_1I_D16F32Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide,
+                                                &pData->SEBiquadTapsSide,
+                                                &CoeffsSide);
+
+                pConfig->pBiquadCallBack_Side  = BQ_1I_D16F32C14_TRC_WRA_01;
+                break;
+            case 15:
+                BQ_1I_D16F16Css_TRC_WRA_01_Init(&pCoefficient->SEBiquadInstanceSide,
+                                                &pData->SEBiquadTapsSide,
+                                                &CoeffsSide);
+
+                pConfig->pBiquadCallBack_Side  = BQ_1I_D16F16C15_TRC_WRA_01;
+                break;
+        }
+
+    }
+
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t       hInstance,
                                         LVCS_Params_t       *pParams)
 {
@@ -138,7 +234,7 @@
 
     return(LVCS_SUCCESS);
 }
-
+#endif
 /************************************************************************************/
 /*                                                                                  */
 /* FUNCTION:                LVCS_StereoEnhance                                      */
@@ -177,7 +273,90 @@
 /*  1.  The side filter is not used in Mobile Speaker mode                          */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BUILD_FLOAT
+LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t          hInstance,
+                                         const LVM_FLOAT        *pInData,
+                                         LVM_FLOAT              *pOutData,
+                                         LVM_UINT16             NumSamples)
+{
 
+    LVCS_Instance_t         *pInstance = (LVCS_Instance_t  *)hInstance;
+    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;
+    /*
+     * Check if the Stereo Enhancer is enabled
+     */
+    if ((pInstance->Params.OperatingMode & LVCS_STEREOENHANCESWITCH) != 0)
+        {
+        /*
+         * Convert from stereo to middle and side
+         */
+        From2iToMS_Float(pInData,
+                         pScratch,
+                         pScratch + NumSamples,
+                         (LVM_INT16)NumSamples);
+
+        /*
+         * Apply filter to the middle signal
+         */
+        if (pInstance->OutputDevice == LVCS_HEADPHONE)
+        {
+            (pConfig->pBiquadCallBack_Mid)((Biquad_FLOAT_Instance_t*)\
+                                            &pCoefficient->SEBiquadInstanceMid,
+                                            (LVM_FLOAT *)pScratch,
+                                            (LVM_FLOAT *)pScratch,
+                                            (LVM_INT16)NumSamples);
+        }
+        else
+        {
+            Mult3s_Float(pScratch,              /* Source */
+                         (LVM_FLOAT)pConfig->MidGain,      /* Gain */
+                         pScratch,              /* Destination */
+                         (LVM_INT16)NumSamples);           /* Number of samples */
+        }
+
+        /*
+         * Apply the filter the side signal only in stereo mode for headphones
+         * and in all modes for mobile speakers
+         */
+        if (pInstance->Params.SourceFormat == LVCS_STEREO)
+        {
+            (pConfig->pBiquadCallBack_Side)((Biquad_FLOAT_Instance_t*) \
+                                            &pCoefficient->SEBiquadInstanceSide,
+                                            (LVM_FLOAT *)(pScratch + NumSamples),
+                                            (LVM_FLOAT *)(pScratch + NumSamples),
+                                            (LVM_INT16)NumSamples);
+        }
+
+        /*
+         * Convert from middle and side to stereo
+         */
+        MSTo2i_Sat_Float(pScratch,
+                         pScratch + NumSamples,
+                         pOutData,
+                         (LVM_INT16)NumSamples);
+
+    }
+    else
+    {
+        /*
+         * The stereo enhancer is disabled so just copy the data
+         */
+        Copy_Float((LVM_FLOAT *)pInData,           /* Source */
+                   (LVM_FLOAT *)pOutData,          /* Destination */
+                   (LVM_INT16)(2 * NumSamples));     /* Left and right */
+    }
+
+    return(LVCS_SUCCESS);
+}
+#else
 LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t          hInstance,
                                          const LVM_INT16        *pInData,
                                          LVM_INT16              *pOutData,
@@ -254,7 +433,4 @@
 
     return(LVCS_SUCCESS);
 }
-
-
-
-
+#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
index 15bc407..4125f24 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
@@ -43,18 +43,31 @@
 /* Stereo enhancer structure */
 typedef struct
 {
+
+#ifndef BUILD_FLOAT
     /*
      * Middle filter
      */
     void                    (*pBiquadCallBack_Mid)(Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
-
     /*
      * Side filter
      */
     void                    (*pBiquadCallBack_Side)(Biquad_Instance_t*, LVM_INT16*, LVM_INT16*, LVM_INT16);
+    LVM_UINT16              MidGain;            /* Middle gain in mobile speaker mode */
+#else
+    /*
+     * Middle filter
+     */
+    void                    (*pBiquadCallBack_Mid)(Biquad_FLOAT_Instance_t*,
+                                    LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
 
-      LVM_UINT16              MidGain;            /* Middle gain in mobile speaker mode */
-
+    /*
+     * Side filter
+     */
+    void                    (*pBiquadCallBack_Side)(Biquad_FLOAT_Instance_t*,
+                                    LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+    LVM_FLOAT              MidGain;            /* Middle gain in mobile speaker mode */
+#endif
 } LVCS_StereoEnhancer_t;
 
 
@@ -67,12 +80,17 @@
 LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t        hInstance,
                                         LVCS_Params_t        *pParams);
 
+#ifndef BUILD_FLOAT
 LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t        hInstance,
                                          const LVM_INT16    *pInData,
                                          LVM_INT16            *pOutData,
                                          LVM_UINT16            NumSamples);
-
-
+#else
+LVCS_ReturnStatus_en LVCS_StereoEnhancer(LVCS_Handle_t        hInstance,
+                                         const LVM_FLOAT    *pInData,
+                                         LVM_FLOAT            *pOutData,
+                                         LVM_UINT16            NumSamples);
+#endif
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
index 974de21..e154e29 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -71,7 +71,19 @@
     {CS_MIDDLE_48000_A0,        /* 48kS/s coefficients */
      CS_MIDDLE_48000_A1,
      CS_MIDDLE_48000_B1,
-     (LVM_UINT16 )CS_MIDDLE_48000_SCALE}};
+     (LVM_UINT16 )CS_MIDDLE_48000_SCALE}
+#ifdef HIGHER_FS
+    ,
+    {CS_MIDDLE_96000_A0,        /* 96kS/s coefficients */
+     CS_MIDDLE_96000_A1,
+     CS_MIDDLE_96000_B1,
+     (LVM_UINT16 )CS_MIDDLE_96000_SCALE},
+    {CS_MIDDLE_192000_A0,        /* 192kS/s coefficients */
+     CS_MIDDLE_192000_A1,
+     CS_MIDDLE_192000_B1,
+     (LVM_UINT16 )CS_MIDDLE_192000_SCALE}
+#endif
+    };
 
 /* Coefficient table for the side filter */
 const BiquadA012B12CoefsSP_t LVCS_SESideCoefTable[] = {
@@ -130,6 +142,21 @@
      CS_SIDE_48000_B1,
      CS_SIDE_48000_B2,
      (LVM_UINT16 )CS_SIDE_48000_SCALE}
+#ifdef HIGHER_FS
+     ,
+     {CS_SIDE_96000_A0,          /* 96kS/s coefficients */
+     CS_SIDE_96000_A1,
+     CS_SIDE_96000_A2,
+     CS_SIDE_96000_B1,
+     CS_SIDE_96000_B2,
+     (LVM_UINT16 )CS_SIDE_96000_SCALE},
+     {CS_SIDE_192000_A0,          /* 192kS/s coefficients */
+     CS_SIDE_192000_A1,
+     CS_SIDE_192000_A2,
+     CS_SIDE_192000_B1,
+     CS_SIDE_192000_B2,
+     (LVM_UINT16 )CS_SIDE_192000_SCALE}
+#endif
 };
 
 
@@ -195,6 +222,20 @@
      CS_EQUALISER_48000_B1,
      CS_EQUALISER_48000_B2,
      (LVM_UINT16 )CS_EQUALISER_48000_SCALE},
+#ifdef HIGHER_FS
+    {CS_EQUALISER_96000_A0,     /* 96kS/s coefficients */
+     CS_EQUALISER_96000_A1,
+     CS_EQUALISER_96000_A2,
+     CS_EQUALISER_96000_B1,
+     CS_EQUALISER_96000_B2,
+     (LVM_UINT16 )CS_EQUALISER_96000_SCALE},
+    {CS_EQUALISER_192000_A0,     /* 192kS/s coefficients */
+     CS_EQUALISER_192000_A1,
+     CS_EQUALISER_192000_A2,
+     CS_EQUALISER_192000_B1,
+     CS_EQUALISER_192000_B2,
+     (LVM_UINT16 )CS_EQUALISER_192000_SCALE},
+#endif
 
     /* Concert Sound EX Headphone coefficients */
     {CSEX_EQUALISER_8000_A0,    /* 8kS/s coefficients */
@@ -251,6 +292,21 @@
      CSEX_EQUALISER_48000_B1,
      CSEX_EQUALISER_48000_B2,
      (LVM_UINT16 )CSEX_EQUALISER_48000_SCALE}
+#ifdef HIGHER_FS
+    ,
+    {CSEX_EQUALISER_96000_A0,   /* 96kS/s coefficients */
+     CSEX_EQUALISER_96000_A1,
+     CSEX_EQUALISER_96000_A2,
+     CSEX_EQUALISER_96000_B1,
+     CSEX_EQUALISER_96000_B2,
+     (LVM_UINT16 )CSEX_EQUALISER_96000_SCALE},
+     {CSEX_EQUALISER_192000_A0,   /* 192kS/s coefficients */
+     CSEX_EQUALISER_192000_A1,
+     CSEX_EQUALISER_192000_A2,
+     CSEX_EQUALISER_192000_B1,
+     CSEX_EQUALISER_192000_B2,
+     (LVM_UINT16 )CSEX_EQUALISER_192000_SCALE}
+#endif
 };
 
 
@@ -334,6 +390,21 @@
      CS_REVERB_48000_B1,
      CS_REVERB_48000_B2,
      (LVM_UINT16 )CS_REVERB_48000_SCALE}
+#ifdef HIGHER_FS
+    ,
+    {CS_REVERB_96000_A0,            /* 96kS/s coefficients */
+     CS_REVERB_96000_A1,
+     CS_REVERB_96000_A2,
+     CS_REVERB_96000_B1,
+     CS_REVERB_96000_B2,
+     (LVM_UINT16 )CS_REVERB_96000_SCALE},
+     {CS_REVERB_192000_A0,            /* 192kS/s coefficients */
+     CS_REVERB_192000_A1,
+     CS_REVERB_192000_A2,
+     CS_REVERB_192000_B1,
+     CS_REVERB_192000_B2,
+     (LVM_UINT16 )CS_REVERB_192000_SCALE}
+#endif
 };
 
 
@@ -385,6 +456,24 @@
 /*                                                                                  */
 /************************************************************************************/
 const LVCS_VolCorrect_t LVCS_VolCorrectTable[] = {
+#ifdef BUILD_FLOAT
+    {0.433362f,          /* Headphone, stereo mode */
+     0.000000f,
+     1.000024f,
+     1.412640f},
+    {0.433362f,          /* EX Headphone, stereo mode */
+     0.000000f,
+     1.000024f,
+     1.412640f},
+    {1.000000f,         /* Headphone, mono mode */
+     0.000000f,
+     1.000024f,
+     1.412640f},
+    {1.000000f,         /* EX Headphone, mono mode */
+     0.000000f,
+     1.000024f,
+     1.412640f}
+#else
     {14200,          /* Headphone, stereo mode */
      0,
      4096,
@@ -401,6 +490,7 @@
      0,
      4096,
      5786}
+#endif
 };
 
 /************************************************************************************/
@@ -418,8 +508,25 @@
 #define LVCS_VOL_TC_Fs32000     32721       /* Floating point value 0.998565674 */
 #define LVCS_VOL_TC_Fs44100     32734       /* Floating point value 0.998962402 */
 #define LVCS_VOL_TC_Fs48000     32737       /* Floating point value 0.999053955 */
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVCS_VOL_TC_Fs96000     32751       /* Floating point value 0.999511703 */   /* Todo @ need to re check this value*/
+#define LVCS_VOL_TC_Fs192000    32763       /* Floating point value 0.999877925 */  /* Todo @ need to re check this value*/
+#endif
 
-
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_INT16 LVCS_VolumeTCTable[11] = {LVCS_VOL_TC_Fs8000,
+		                                  LVCS_VOL_TC_Fs11025,
+										  LVCS_VOL_TC_Fs12000,
+										  LVCS_VOL_TC_Fs16000,
+										  LVCS_VOL_TC_Fs22050,
+										  LVCS_VOL_TC_Fs24000,
+										  LVCS_VOL_TC_Fs32000,
+										  LVCS_VOL_TC_Fs44100,
+										  LVCS_VOL_TC_Fs48000,
+										  LVCS_VOL_TC_Fs96000,
+										  LVCS_VOL_TC_Fs192000
+};
+#else
 const LVM_INT16 LVCS_VolumeTCTable[9] = {LVCS_VOL_TC_Fs8000,
                                         LVCS_VOL_TC_Fs11025,
                                         LVCS_VOL_TC_Fs12000,
@@ -428,15 +535,30 @@
                                         LVCS_VOL_TC_Fs24000,
                                         LVCS_VOL_TC_Fs32000,
                                         LVCS_VOL_TC_Fs44100,
-                                        LVCS_VOL_TC_Fs48000};
+                                        LVCS_VOL_TC_Fs48000
+};
+#endif
 
 /************************************************************************************/
 /*                                                                                  */
 /*  Sample rate table                                                               */
 /*                                                                                  */
 /************************************************************************************/
-
-const LVM_INT32   LVCS_SampleRateTable[9] = {8000,
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+const LVM_INT32   LVCS_SampleRateTable[11] = {8000,
+		                                      11025,
+											  12000,
+											  16000,
+											  22050,
+											  24000,
+											  32000,
+											  44100,
+											  48000,
+											  96000,
+											  192000
+};
+#else
+const LVM_INT16   LVCS_SampleRateTable[9] = {8000,
                                             11025,
                                             12000,
                                             16000,
@@ -444,5 +566,6 @@
                                             24000,
                                             32000,
                                             44100,
-                                            48000};
-
+                                            48000
+};
+#endif
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index efd30fb..f106aae 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -10,7 +10,7 @@
 LOCAL_SRC_FILES:= \
 	Bundle/EffectBundle.cpp
 
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_MODULE:= libbundlewrapper
@@ -43,7 +43,7 @@
 LOCAL_SRC_FILES:= \
     Reverb/EffectReverb.cpp
 
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -DBUILD_FLOAT -DHIGHER_FS
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_MODULE:= libreverbwrapper
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index df6501b..4f1fed5 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -14,7 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#ifndef LVM_FLOAT
+typedef float LVM_FLOAT;
+#endif
 #define LOG_TAG "Bundle"
 #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array)[0])
 //#define LOG_NDEBUG 0
@@ -271,7 +273,10 @@
         pContext->pBundledContext->SamplesToExitCountVirt   = 0;
         pContext->pBundledContext->SamplesToExitCountBb     = 0;
         pContext->pBundledContext->SamplesToExitCountEq     = 0;
-
+#ifdef BUILD_FLOAT
+        pContext->pBundledContext->pInputBuffer             = NULL;
+        pContext->pBundledContext->pOutputBuffer            = NULL;
+#endif
         for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
             pContext->pBundledContext->bandGaindB[i] = EQNB_5BandSoftPresets[i];
         }
@@ -439,6 +444,14 @@
         if (pContext->pBundledContext->workBuffer != NULL) {
             free(pContext->pBundledContext->workBuffer);
         }
+#ifdef BUILD_FLOAT
+        if (pContext->pBundledContext->pInputBuffer != NULL) {
+            free(pContext->pBundledContext->pInputBuffer);
+        }
+        if (pContext->pBundledContext->pOutputBuffer != NULL) {
+            free(pContext->pBundledContext->pOutputBuffer);
+        }
+#endif
         delete pContext->pBundledContext;
         pContext->pBundledContext = LVM_NULL;
     }
@@ -695,7 +708,47 @@
     return 0;
 }   /* end LvmBundle_init */
 
+#ifdef BUILD_FLOAT
+/**********************************************************************************
+   FUNCTION INT16LTOFLOAT
+***********************************************************************************/
+// Todo: need to write function descriptor
+static void Int16ToFloat(const LVM_INT16 *src, LVM_FLOAT *dst, size_t n) {
+    size_t ii;
+    src += n-1;
+    dst += n-1;
+    for (ii = n; ii != 0; ii--) {
+        *dst = ((LVM_FLOAT)((LVM_INT16)*src)) / 32768.0f;
+        src--;
+        dst--;
+    }
+    return;
+}
+/**********************************************************************************
+   FUNCTION FLOATTOINT16_SAT
+***********************************************************************************/
+// Todo : Need to write function descriptor
+static void FloatToInt16_SAT(const LVM_FLOAT *src, LVM_INT16 *dst, size_t n) {
+    size_t ii;
+    LVM_INT32 temp;
 
+    src += n-1;
+    dst += n-1;
+    for (ii = n; ii != 0; ii--) {
+        temp = (LVM_INT32)((*src) * 32768.0f);
+        if (temp >= 32767) {
+            *dst = 32767;
+        } else if (temp <= -32768) {
+            *dst = -32768;
+        } else {
+            *dst = (LVM_INT16)temp;
+        }
+        src--;
+        dst--;
+    }
+    return;
+}
+#endif
 //----------------------------------------------------------------------------
 // LvmBundle_process()
 //----------------------------------------------------------------------------
@@ -713,7 +766,99 @@
 //  pOut:       pointer to updated stereo 16 bit output data
 //
 //----------------------------------------------------------------------------
+#ifdef BUILD_FLOAT
+int LvmBundle_process(LVM_INT16        *pIn,
+                      LVM_INT16        *pOut,
+                      int              frameCount,
+                      EffectContext    *pContext){
 
+
+    //LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
+    LVM_INT16               *pOutTmp;
+    LVM_FLOAT               *pInputBuff;
+    LVM_FLOAT               *pOutputBuff;
+
+    if (pContext->pBundledContext->pInputBuffer == NULL ||
+            pContext->pBundledContext->frameCount < frameCount) {
+        if (pContext->pBundledContext->pInputBuffer != NULL) {
+            free(pContext->pBundledContext->pInputBuffer);
+        }
+        pContext->pBundledContext->pInputBuffer = (LVM_FLOAT *)malloc(frameCount * \
+                                                                      sizeof(LVM_FLOAT) * FCC_2);
+    }
+
+    if (pContext->pBundledContext->pOutputBuffer == NULL ||
+            pContext->pBundledContext->frameCount < frameCount) {
+        if (pContext->pBundledContext->pOutputBuffer != NULL) {
+            free(pContext->pBundledContext->pOutputBuffer);
+        }
+        pContext->pBundledContext->pOutputBuffer = (LVM_FLOAT *)malloc(frameCount * \
+                                                                       sizeof(LVM_FLOAT) * FCC_2);
+    }
+
+    if ((pContext->pBundledContext->pInputBuffer == NULL) ||
+                                    (pContext->pBundledContext->pOutputBuffer == NULL)) {
+        ALOGV("LVM_ERROR : LvmBundle_process memory allocation for float buffer's failed");
+        return -EINVAL;
+    }
+
+    pInputBuff = pContext->pBundledContext->pInputBuffer;
+    pOutputBuff = pContext->pBundledContext->pOutputBuffer;
+
+    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE){
+        pOutTmp = pOut;
+    } else if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+        if (pContext->pBundledContext->frameCount != frameCount) {
+            if (pContext->pBundledContext->workBuffer != NULL) {
+                free(pContext->pBundledContext->workBuffer);
+            }
+            pContext->pBundledContext->workBuffer =
+                    (LVM_INT16 *)calloc(frameCount, sizeof(LVM_INT16) * FCC_2);
+            if (pContext->pBundledContext->workBuffer == NULL) {
+                return -ENOMEM;
+            }
+            pContext->pBundledContext->frameCount = frameCount;
+        }
+        pOutTmp = pContext->pBundledContext->workBuffer;
+    } else {
+        ALOGV("LVM_ERROR : LvmBundle_process invalid access mode");
+        return -EINVAL;
+    }
+
+    #ifdef LVM_PCM
+    fwrite(pIn, frameCount*sizeof(LVM_INT16) * FCC_2, 1, pContext->pBundledContext->PcmInPtr);
+    fflush(pContext->pBundledContext->PcmInPtr);
+    #endif
+
+    /* Converting input data from fixed point to float point */
+    Int16ToFloat(pIn, pInputBuff, frameCount * 2);
+
+    /* Process the samples */
+    LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
+                            pInputBuff,                           /* Input buffer */
+                            pOutputBuff,                          /* Output buffer */
+                            (LVM_UINT16)frameCount,               /* Number of samples to read */
+                            0);                                   /* Audo Time */
+
+    LVM_ERROR_CHECK(LvmStatus, "LVM_Process", "LvmBundle_process")
+    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+    /* Converting output data from float point to fixed point */
+    FloatToInt16_SAT(pOutputBuff, pOutTmp, (LVM_UINT16)frameCount * 2);
+    #ifdef LVM_PCM
+    fwrite(pOutTmp, frameCount*sizeof(LVM_INT16) * FCC_2, 1, pContext->pBundledContext->PcmOutPtr);
+    fflush(pContext->pBundledContext->PcmOutPtr);
+    #endif
+
+    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+        for (int i = 0; i < frameCount * 2; i++){
+            pOut[i] = clamp16((LVM_INT32)pOut[i] + (LVM_INT32)pOutTmp[i]);
+        }
+    }
+    return 0;
+}    /* end LvmBundle_process */
+#else
 int LvmBundle_process(LVM_INT16        *pIn,
                       LVM_INT16        *pOut,
                       int              frameCount,
@@ -771,7 +916,7 @@
     }
     return 0;
 }    /* end LvmBundle_process */
-
+#endif
 
 //----------------------------------------------------------------------------
 // EqualizerUpdateActiveParams()
@@ -1126,6 +1271,16 @@
         SampleRate = LVM_FS_48000;
         pContext->pBundledContext->SamplesPerSecond = 48000*2; // 2 secs Stereo
         break;
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 96000:
+        SampleRate = LVM_FS_96000;
+        pContext->pBundledContext->SamplesPerSecond = 96000*2; // 2 secs Stereo
+        break;
+    case 192000:
+        SampleRate = LVM_FS_192000;
+        pContext->pBundledContext->SamplesPerSecond = 192000*2; // 2 secs Stereo
+        break;
+#endif
     default:
         ALOGV("\tEffect_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
         return -EINVAL;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index ee604eb..cad89fd 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -103,6 +103,10 @@
     FILE                            *PcmInPtr;
     FILE                            *PcmOutPtr;
     #endif
+    #ifdef BUILD_FLOAT
+    LVM_FLOAT                       *pInputBuffer;
+    LVM_FLOAT                       *pOutputBuffer;
+    #endif
 };
 
 /* SessionContext : One session */
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 6d7d4cd..1717b49 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -14,7 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#ifndef LVM_FLOAT
+typedef float LVM_FLOAT;
+#endif
 #define LOG_TAG "Reverb"
 #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array)[0])
 //#define LOG_NDEBUG 0
@@ -152,6 +154,8 @@
     LVM_Fs_en                       SampleRate;
     LVM_INT32                       *InFrames32;
     LVM_INT32                       *OutFrames32;
+    size_t                          bufferSizeIn;
+    size_t                          bufferSizeOut;
     bool                            auxiliary;
     bool                            preset;
     uint16_t                        curPreset;
@@ -172,8 +176,11 @@
 
 #define REVERB_DEFAULT_PRESET REVERB_PRESET_NONE
 
-
+#ifdef BUILD_FLOAT
+#define REVERB_SEND_LEVEL   0.75f // 0.75 in 4.12 format
+#else
 #define REVERB_SEND_LEVEL   (0x0C00) // 0.75 in 4.12 format
+#endif
 #define REVERB_UNIT_VOLUME  (0x1000) // 1.0 in 4.12 format
 
 //--- local function prototypes
@@ -270,8 +277,15 @@
 
 
     // Allocate memory for reverb process (*2 is for STEREO)
-    pContext->InFrames32  = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
-    pContext->OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
+#ifdef BUILD_FLOAT
+    pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(float) * 2;
+    pContext->bufferSizeOut = pContext->bufferSizeIn;
+#else
+    pContext->bufferSizeIn = LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2;
+    pContext->bufferSizeOut = pContext->bufferSizeIn;
+#endif
+    pContext->InFrames32  = (LVM_INT32 *)malloc(pContext->bufferSizeIn);
+    pContext->OutFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeOut);
 
     ALOGV("\tEffectCreate %p, size %zu", pContext, sizeof(ReverbContext));
     ALOGV("\tEffectCreate end\n");
@@ -293,6 +307,8 @@
     #endif
     free(pContext->InFrames32);
     free(pContext->OutFrames32);
+    pContext->bufferSizeIn = 0;
+    pContext->bufferSizeOut = 0;
     Reverb_free(pContext);
     delete pContext;
     return 0;
@@ -389,6 +405,48 @@
 }
 #endif
 
+#ifdef BUILD_FLOAT
+/**********************************************************************************
+   FUNCTION INT16LTOFLOAT
+***********************************************************************************/
+// Todo: need to write function descriptor
+static void Int16ToFloat(const LVM_INT16 *src, LVM_FLOAT *dst, size_t n) {
+    size_t ii;
+    src += n-1;
+    dst += n-1;
+    for (ii = n; ii != 0; ii--) {
+        *dst = ((LVM_FLOAT)((LVM_INT16)*src)) / 32768.0f;
+        src--;
+        dst--;
+    }
+    return;
+}
+/**********************************************************************************
+   FUNCTION FLOATTOINT16_SAT
+***********************************************************************************/
+// Todo : Need to write function descriptor
+static void FloatToInt16_SAT(const LVM_FLOAT *src, LVM_INT16 *dst, size_t n) {
+    size_t ii;
+    LVM_INT32 temp;
+
+    src += n-1;
+    dst += n-1;
+    for (ii = n; ii != 0; ii--) {
+        temp = (LVM_INT32)((*src) * 32768.0f);
+        if (temp >= 32767) {
+            *dst = 32767;
+        } else if (temp <= -32768) {
+            *dst = -32768;
+        } else {
+            *dst = (LVM_INT16)temp;
+        }
+        src--;
+        dst--;
+    }
+    return;
+}
+#endif
+
 static inline int16_t clamp16(int32_t sample)
 {
     if ((sample>>15) ^ (sample>>31))
@@ -422,8 +480,31 @@
     LVM_INT16               samplesPerFrame = 1;
     LVREV_ReturnStatus_en   LvmStatus = LVREV_SUCCESS;              /* Function call status */
     LVM_INT16 *OutFrames16;
+#ifdef BUILD_FLOAT
+    LVM_FLOAT               *pInputBuff;
+    LVM_FLOAT               *pOutputBuff;
+#endif
 
-
+#ifdef BUILD_FLOAT
+    if (pContext->InFrames32 == NULL ||
+            pContext->bufferSizeIn < frameCount * sizeof(float) * 2) {
+        if (pContext->InFrames32 != NULL) {
+            free(pContext->InFrames32);
+        }
+        pContext->bufferSizeIn = frameCount * sizeof(float) * 2;
+        pContext->InFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeIn);
+    }
+    if (pContext->OutFrames32 == NULL ||
+            pContext->bufferSizeOut < frameCount * sizeof(float) * 2) {
+        if (pContext->OutFrames32 != NULL) {
+            free(pContext->OutFrames32);
+        }
+        pContext->bufferSizeOut = frameCount * sizeof(float) * 2;
+        pContext->OutFrames32 = (LVM_INT32 *)malloc(pContext->bufferSizeOut);
+    }
+    pInputBuff = (float *)pContext->InFrames32;
+    pOutputBuff = (float *)pContext->OutFrames32;
+#endif
     // Check that the input is either mono or stereo
     if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
         samplesPerFrame = 2;
@@ -449,49 +530,84 @@
         Reverb_LoadPreset(pContext);
     }
 
-
-
     // Convert to Input 32 bits
     if (pContext->auxiliary) {
+#ifdef BUILD_FLOAT
+        Int16ToFloat(pIn, pInputBuff, frameCount * samplesPerFrame);
+#else
         for(int i=0; i<frameCount*samplesPerFrame; i++){
             pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
         }
-    } else {
+#endif
+        } else {
         // insert reverb input is always stereo
         for (int i = 0; i < frameCount; i++) {
+#ifndef BUILD_FLOAT
             pContext->InFrames32[2*i] = (pIn[2*i] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
             pContext->InFrames32[2*i+1] = (pIn[2*i+1] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
+#else
+            pInputBuff[2 * i] = (LVM_FLOAT)pIn[2 * i] * REVERB_SEND_LEVEL / 32768.0f;
+            pInputBuff[2 * i + 1] = (LVM_FLOAT)pIn[2 * i + 1] * REVERB_SEND_LEVEL / 32768.0f;
+#endif
         }
     }
 
     if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
+#ifdef BUILD_FLOAT
+        memset(pOutputBuff, 0, frameCount * sizeof(LVM_FLOAT) * 2); //always stereo here
+#else
         memset(pContext->OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2); //always stereo here
+#endif
     } else {
         if(pContext->bEnabled == LVM_FALSE && pContext->SamplesToExitCount > 0) {
+#ifdef BUILD_FLOAT
+            memset(pInputBuff, 0, frameCount * sizeof(LVM_FLOAT) * samplesPerFrame);
+#else
             memset(pContext->InFrames32,0,frameCount * sizeof(LVM_INT32) * samplesPerFrame);
+#endif
             ALOGV("\tZeroing %d samples per frame at the end of call", samplesPerFrame);
         }
 
         /* Process the samples, producing a stereo output */
+#ifdef BUILD_FLOAT
+        LvmStatus = LVREV_Process(pContext->hInstance,      /* Instance handle */
+                                  pInputBuff,     /* Input buffer */
+                                  pOutputBuff,    /* Output buffer */
+                                  frameCount);              /* Number of samples to read */
+#else
         LvmStatus = LVREV_Process(pContext->hInstance,      /* Instance handle */
                                   pContext->InFrames32,     /* Input buffer */
                                   pContext->OutFrames32,    /* Output buffer */
                                   frameCount);              /* Number of samples to read */
-    }
+#endif
+        }
 
     LVM_ERROR_CHECK(LvmStatus, "LVREV_Process", "process")
     if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
 
     // Convert to 16 bits
     if (pContext->auxiliary) {
+#ifdef BUILD_FLOAT
+        FloatToInt16_SAT(pOutputBuff, OutFrames16, (size_t)frameCount * 2);
+#else
         for (int i=0; i < frameCount*2; i++) { //always stereo here
             OutFrames16[i] = clamp16(pContext->OutFrames32[i]>>8);
         }
-    } else {
-        for (int i=0; i < frameCount*2; i++) { //always stereo here
-            OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
-        }
+#endif
+        } else {
+#ifdef BUILD_FLOAT
+            for (int i = 0; i < frameCount * 2; i++) {//always stereo here
+                //pOutputBuff and OutFrames16 point to the same buffer, so better to
+                //accumulate in pInputBuff, which is available
+                pInputBuff[i] = pOutputBuff[i] + (LVM_FLOAT)pIn[i] / 32768.0f;
+            }
 
+            FloatToInt16_SAT(pInputBuff, OutFrames16, (size_t)frameCount * 2);
+#else
+            for (int i=0; i < frameCount*2; i++) { //always stereo here
+                OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
+            }
+#endif
         // apply volume with ramp if needed
         if ((pContext->leftVolume != pContext->prevLeftVolume ||
                 pContext->rightVolume != pContext->prevRightVolume) &&
@@ -644,6 +760,14 @@
     case 48000:
         SampleRate = LVM_FS_48000;
         break;
+#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 96000:
+        SampleRate = LVM_FS_96000;
+        break;
+    case 192000:
+        SampleRate = LVM_FS_192000;
+        break;
+#endif
     default:
         ALOGV("\rReverb_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
         return -EINVAL;
@@ -1011,7 +1135,7 @@
     //ALOGV("\tReverbGetRoomHfLevel() ActiveParams.LPFL %d, pContext->SavedHfLevel: %d, "
     //     "converted level: %d\n", ActiveParams.LPF, pContext->SavedHfLevel, level);
 
-    if(ActiveParams.LPF != level){
+    if((int16_t)ActiveParams.LPF != level){
         ALOGV("\tLVM_ERROR : (ignore at start up) ReverbGetRoomHfLevel() has wrong level -> %d %d\n",
                ActiveParams.Level, level);
     }
diff --git a/media/libheif/Android.bp b/media/libheif/Android.bp
new file mode 100644
index 0000000..7d5a4eb
--- /dev/null
+++ b/media/libheif/Android.bp
@@ -0,0 +1,23 @@
+cc_library_shared {
+    name: "libheif",
+
+    srcs: [
+        "HeifDecoderImpl.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libutils",
+        "libmedia",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    include_dirs: [],
+
+    export_include_dirs: ["include"],
+}
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
new file mode 100644
index 0000000..8b846be
--- /dev/null
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "HeifDecoderImpl"
+
+#include "HeifDecoderImpl.h"
+
+#include <stdio.h>
+
+#include <binder/IMemory.h>
+#include <drm/drm_framework_common.h>
+#include <media/IDataSource.h>
+#include <media/mediametadataretriever.h>
+#include <media/stagefright/MediaSource.h>
+#include <private/media/VideoFrame.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+
+HeifDecoder* createHeifDecoder() {
+    return new android::HeifDecoderImpl();
+}
+
+namespace android {
+
+/*
+ * HeifDataSource
+ *
+ * Proxies data requests over IDataSource interface from MediaMetadataRetriever
+ * to the HeifStream interface we received from the heif decoder client.
+ */
+class HeifDataSource : public BnDataSource {
+public:
+    /*
+     * Constructs HeifDataSource; will take ownership of |stream|.
+     */
+    HeifDataSource(HeifStream* stream)
+        : mStream(stream), mReadPos(0), mEOS(false) {}
+
+    ~HeifDataSource() override {}
+
+    /*
+     * Initializes internal resources.
+     */
+    bool init();
+
+    sp<IMemory> getIMemory() override { return mMemory; }
+    ssize_t readAt(off64_t offset, size_t size) override;
+    status_t getSize(off64_t* size) override ;
+    void close() {}
+    uint32_t getFlags() override { return 0; }
+    String8 toString() override { return String8("HeifDataSource"); }
+    sp<DecryptHandle> DrmInitialization(const char*) override {
+        return nullptr;
+    }
+
+private:
+    /*
+     * Buffer size for passing the read data to mediaserver. Set to 64K
+     * (which is what MediaDataSource Java API's jni implementation uses).
+     */
+    enum {
+        kBufferSize = 64 * 1024,
+    };
+    sp<IMemory> mMemory;
+    std::unique_ptr<HeifStream> mStream;
+    off64_t mReadPos;
+    bool mEOS;
+};
+
+bool HeifDataSource::init() {
+    sp<MemoryDealer> memoryDealer =
+            new MemoryDealer(kBufferSize, "HeifDataSource");
+    mMemory = memoryDealer->allocate(kBufferSize);
+    if (mMemory == nullptr) {
+        ALOGE("Failed to allocate shared memory!");
+        return false;
+    }
+    return true;
+}
+
+ssize_t HeifDataSource::readAt(off64_t offset, size_t size) {
+    ALOGV("readAt: offset=%lld, size=%zu", (long long)offset, size);
+
+    if (size == 0) {
+        return mEOS ? ERROR_END_OF_STREAM : 0;
+    }
+
+    if (offset < mReadPos) {
+        // try seek, then rewind/skip, fail if none worked
+        if (mStream->seek(offset)) {
+            ALOGV("readAt: seek to offset=%lld", (long long)offset);
+            mReadPos = offset;
+            mEOS = false;
+        } else if (mStream->rewind()) {
+            ALOGV("readAt: rewind to offset=0");
+            mReadPos = 0;
+            mEOS = false;
+        } else {
+            ALOGE("readAt: couldn't seek or rewind!");
+            mEOS = true;
+        }
+    }
+
+    if (mEOS) {
+        ALOGV("readAt: EOS");
+        return ERROR_END_OF_STREAM;
+    }
+
+    if (offset > mReadPos) {
+        // skipping
+        size_t skipSize = offset - mReadPos;
+        size_t bytesSkipped = mStream->read(nullptr, skipSize);
+        if (bytesSkipped <= skipSize) {
+            mReadPos += bytesSkipped;
+        }
+        if (bytesSkipped != skipSize) {
+            mEOS = true;
+            return ERROR_END_OF_STREAM;
+        }
+    }
+
+    if (size > kBufferSize) {
+        size = kBufferSize;
+    }
+    size_t bytesRead = mStream->read(mMemory->pointer(), size);
+    if (bytesRead > size || bytesRead == 0) {
+        // bytesRead is invalid
+        mEOS = true;
+        return ERROR_END_OF_STREAM;
+    } if (bytesRead < size) {
+        // read some bytes but not all, set EOS and return ERROR_END_OF_STREAM next time
+        mEOS = true;
+    }
+    mReadPos += bytesRead;
+    return bytesRead;
+}
+
+status_t HeifDataSource::getSize(off64_t* size) {
+    if (!mStream->hasLength()) {
+        *size = -1;
+        ALOGE("getSize: not supported!");
+        return ERROR_UNSUPPORTED;
+    }
+    *size = mStream->getLength();
+    ALOGV("getSize: size=%lld", (long long)*size);
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+HeifDecoderImpl::HeifDecoderImpl() :
+    // output color format should always be set via setOutputColor(), in case
+    // it's not, default to HAL_PIXEL_FORMAT_RGB_565.
+    mOutputColor(HAL_PIXEL_FORMAT_RGB_565),
+    mCurScanline(0) {
+}
+
+HeifDecoderImpl::~HeifDecoderImpl() {
+}
+
+bool HeifDecoderImpl::init(HeifStream* stream, HeifFrameInfo* frameInfo) {
+    sp<HeifDataSource> dataSource = new HeifDataSource(stream);
+    if (!dataSource->init()) {
+        return false;
+    }
+    mDataSource = dataSource;
+
+    mRetriever = new MediaMetadataRetriever();
+    status_t err = mRetriever->setDataSource(mDataSource, "video/mp4");
+    if (err != OK) {
+        ALOGE("failed to set data source!");
+
+        mRetriever.clear();
+        mDataSource.clear();
+        return false;
+    }
+    ALOGV("successfully set data source.");
+
+    const char* hasVideo = mRetriever->extractMetadata(METADATA_KEY_HAS_VIDEO);
+    if (!hasVideo || strcasecmp(hasVideo, "yes")) {
+        ALOGE("no video: %s", hasVideo ? hasVideo : "null");
+        return false;
+    }
+
+    mFrameMemory = mRetriever->getFrameAtTime(0,
+            IMediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
+            mOutputColor, true /*metaOnly*/);
+    if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) {
+        ALOGE("getFrameAtTime: videoFrame is a nullptr");
+        return false;
+    }
+
+    VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
+
+    ALOGV("Meta dimension %dx%d, display %dx%d, angle %d, iccSize %d",
+            videoFrame->mWidth,
+            videoFrame->mHeight,
+            videoFrame->mDisplayWidth,
+            videoFrame->mDisplayHeight,
+            videoFrame->mRotationAngle,
+            videoFrame->mIccSize);
+
+    if (frameInfo != nullptr) {
+        frameInfo->set(
+                videoFrame->mWidth,
+                videoFrame->mHeight,
+                videoFrame->mRotationAngle,
+                videoFrame->mBytesPerPixel,
+                videoFrame->mIccSize,
+                videoFrame->getFlattenedIccData());
+    }
+    return true;
+}
+
+bool HeifDecoderImpl::getEncodedColor(HeifEncodedColor* /*outColor*/) const {
+    ALOGW("getEncodedColor: not implemented!");
+    return false;
+}
+
+bool HeifDecoderImpl::setOutputColor(HeifColorFormat heifColor) {
+    switch(heifColor) {
+        case kHeifColorFormat_RGB565:
+        {
+            mOutputColor = HAL_PIXEL_FORMAT_RGB_565;
+            return true;
+        }
+        case kHeifColorFormat_RGBA_8888:
+        {
+            mOutputColor = HAL_PIXEL_FORMAT_RGBA_8888;
+            return true;
+        }
+        case kHeifColorFormat_BGRA_8888:
+        {
+            mOutputColor = HAL_PIXEL_FORMAT_BGRA_8888;
+            return true;
+        }
+        default:
+            break;
+    }
+    ALOGE("Unsupported output color format %d", heifColor);
+    return false;
+}
+
+bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {
+    mFrameMemory = mRetriever->getFrameAtTime(0,
+            IMediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, mOutputColor);
+    if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) {
+        ALOGE("getFrameAtTime: videoFrame is a nullptr");
+        return false;
+    }
+
+    VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
+    ALOGV("Decoded dimension %dx%d, display %dx%d, angle %d, rowbytes %d, size %d",
+            videoFrame->mWidth,
+            videoFrame->mHeight,
+            videoFrame->mDisplayWidth,
+            videoFrame->mDisplayHeight,
+            videoFrame->mRotationAngle,
+            videoFrame->mRowBytes,
+            videoFrame->mSize);
+
+    if (frameInfo != nullptr) {
+        frameInfo->set(
+                videoFrame->mWidth,
+                videoFrame->mHeight,
+                videoFrame->mRotationAngle,
+                videoFrame->mBytesPerPixel,
+                videoFrame->mIccSize,
+                videoFrame->getFlattenedIccData());
+    }
+    return true;
+}
+
+bool HeifDecoderImpl::getScanline(uint8_t* dst) {
+    if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) {
+        return false;
+    }
+    VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
+    if (mCurScanline >= videoFrame->mHeight) {
+        return false;
+    }
+    uint8_t* src = videoFrame->getFlattenedData() + videoFrame->mRowBytes * mCurScanline++;
+    memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mWidth);
+    return true;
+}
+
+size_t HeifDecoderImpl::skipScanlines(size_t count) {
+    if (mFrameMemory == nullptr || mFrameMemory->pointer() == nullptr) {
+        return 0;
+    }
+    VideoFrame* videoFrame = static_cast<VideoFrame*>(mFrameMemory->pointer());
+
+    uint32_t oldScanline = mCurScanline;
+    mCurScanline += count;
+    if (mCurScanline >= videoFrame->mHeight) {
+        mCurScanline = videoFrame->mHeight;
+    }
+    return (mCurScanline > oldScanline) ? (mCurScanline - oldScanline) : 0;
+}
+
+} // namespace android
diff --git a/media/libheif/HeifDecoderImpl.h b/media/libheif/HeifDecoderImpl.h
new file mode 100644
index 0000000..2f8f0f8
--- /dev/null
+++ b/media/libheif/HeifDecoderImpl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HEIF_DECODER_IMPL_
+#define _HEIF_DECODER_IMPL_
+
+#include "include/HeifDecoderAPI.h"
+#include <system/graphics.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class IDataSource;
+class IMemory;
+class MediaMetadataRetriever;
+
+/*
+ * An implementation of HeifDecoder based on Android's MediaMetadataRetriever.
+ */
+class HeifDecoderImpl : public HeifDecoder {
+public:
+
+    HeifDecoderImpl();
+    ~HeifDecoderImpl() override;
+
+    bool init(HeifStream* stream, HeifFrameInfo* frameInfo) override;
+
+    bool getEncodedColor(HeifEncodedColor* outColor) const override;
+
+    bool setOutputColor(HeifColorFormat heifColor) override;
+
+    bool decode(HeifFrameInfo* frameInfo) override;
+
+    bool getScanline(uint8_t* dst) override;
+
+    size_t skipScanlines(size_t count) override;
+
+private:
+    sp<IDataSource> mDataSource;
+    sp<MediaMetadataRetriever> mRetriever;
+    sp<IMemory> mFrameMemory;
+    android_pixel_format_t mOutputColor;
+    size_t mCurScanline;
+};
+
+} // namespace android
+
+#endif // _HEIF_DECODER_IMPL_
diff --git a/media/libheif/include/HeifDecoderAPI.h b/media/libheif/include/HeifDecoderAPI.h
new file mode 100644
index 0000000..5183c39
--- /dev/null
+++ b/media/libheif/include/HeifDecoderAPI.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HEIF_DECODER_API_
+#define _HEIF_DECODER_API_
+
+#include <memory>
+
+/*
+ * The output color pixel format of heif decoder.
+ */
+typedef enum {
+    kHeifColorFormat_RGB565     = 0,
+    kHeifColorFormat_RGBA_8888  = 1,
+    kHeifColorFormat_BGRA_8888  = 2,
+} HeifColorFormat;
+
+/*
+ * The color spaces encoded in the heif image.
+ */
+typedef enum {
+    kHeifEncodedColor_RGB = 0,
+    kHeifEncodedColor_YUV = 1,
+    kHeifEncodedColor_CMYK = 2,
+} HeifEncodedColor;
+
+/*
+ * Represents a color converted (RGB-based) video frame
+ */
+struct HeifFrameInfo
+{
+    HeifFrameInfo() :
+        mWidth(0), mHeight(0), mRotationAngle(0), mBytesPerPixel(0),
+        mIccSize(0), mIccData(nullptr) {}
+
+    // update the frame info, will make a copy of |iccData| internally
+    void set(uint32_t width, uint32_t height, int32_t rotation, uint32_t bpp,
+            uint32_t iccSize, uint8_t* iccData) {
+        mWidth = width;
+        mHeight = height;
+        mRotationAngle = rotation;
+        mBytesPerPixel = bpp;
+
+        if (mIccData != nullptr) {
+            mIccData.reset(nullptr);
+        }
+        mIccSize = iccSize;
+        if (iccSize > 0) {
+            mIccData.reset(new uint8_t[iccSize]);
+            if (mIccData.get() != nullptr) {
+                memcpy(mIccData.get(), iccData, iccSize);
+            } else {
+                mIccSize = 0;
+            }
+        }
+    }
+
+    // Intentional public access modifiers:
+    uint32_t mWidth;
+    uint32_t mHeight;
+    int32_t  mRotationAngle;           // Rotation angle, clockwise, should be multiple of 90
+    uint32_t mBytesPerPixel;           // Number of bytes for one pixel
+    uint32_t mIccSize;                 // Number of bytes in mIccData
+    std::unique_ptr<uint8_t> mIccData; // Actual ICC data, memory is owned by this structure
+};
+
+/*
+ * Abstract interface to provide data to HeifDecoder.
+ */
+struct HeifStream {
+    HeifStream() {}
+
+    virtual ~HeifStream() {}
+
+    /*
+     * Reads or skips size number of bytes. return the number of bytes actually
+     * read or skipped.
+     * If |buffer| == NULL, skip size bytes, return how many were skipped.
+     * If |buffer| != NULL, copy size bytes into buffer, return how many were copied.
+     */
+    virtual size_t read(void* buffer, size_t size) = 0;
+
+    /*
+     * Rewinds to the beginning of the stream. Returns true if the stream is known
+     * to be at the beginning after this call returns.
+     */
+    virtual bool rewind() = 0;
+
+    /*
+     * Seeks to an absolute position in the stream. If this cannot be done, returns false.
+     * If an attempt is made to seek past the end of the stream, the position will be set
+     * to the end of the stream.
+     */
+    virtual bool seek(size_t /*position*/) = 0;
+
+    /** Returns true if this stream can report its total length. */
+    virtual bool hasLength() const = 0;
+
+    /** Returns the total length of the stream. If this cannot be done, returns 0. */
+    virtual size_t getLength() const = 0;
+
+private:
+    HeifStream(const HeifFrameInfo&) = delete;
+    HeifStream& operator=(const HeifFrameInfo&) = delete;
+};
+
+/*
+ * Abstract interface to decode heif images from a HeifStream data source.
+ */
+struct HeifDecoder {
+    HeifDecoder() {}
+
+    virtual ~HeifDecoder() {}
+
+    /*
+     * Returns true if it successfully sets outColor to the encoded color,
+     * and false otherwise.
+     */
+    virtual bool getEncodedColor(HeifEncodedColor* outColor) const = 0;
+
+    /*
+     * Returns true if it successfully sets the output color format to color,
+     * and false otherwise.
+     */
+    virtual bool setOutputColor(HeifColorFormat color) = 0;
+
+    /*
+     * Returns true if it successfully initialize heif decoder with source,
+     * and false otherwise. |frameInfo| will be filled with information of
+     * the primary picture upon success and unmodified upon failure.
+     * Takes ownership of |stream| regardless of result.
+     */
+    virtual bool init(HeifStream* stream, HeifFrameInfo* frameInfo) = 0;
+
+    /*
+     * Decode the picture internally, returning whether it succeeded. |frameInfo|
+     * will be filled with information of the primary picture upon success and
+     * unmodified upon failure.
+     *
+     * After this succeeded, getScanline can be called to read the scanlines
+     * that were decoded.
+     */
+    virtual bool decode(HeifFrameInfo* frameInfo) = 0;
+
+    /*
+     * Read the next scanline (in top-down order), returns true upon success
+     * and false otherwise.
+     */
+    virtual bool getScanline(uint8_t* dst) = 0;
+
+    /*
+     * Skip the next |count| scanlines, returns true upon success and
+     * false otherwise.
+     */
+    virtual size_t skipScanlines(size_t count) = 0;
+
+private:
+    HeifDecoder(const HeifFrameInfo&) = delete;
+    HeifDecoder& operator=(const HeifFrameInfo&) = delete;
+};
+
+/*
+ * Creates a HeifDecoder. Returns a HeifDecoder instance upon success, or NULL
+ * if the creation has failed.
+ */
+HeifDecoder* createHeifDecoder();
+
+#endif // _HEIF_DECODER_API_
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index bbe97ee..a462f3a 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -2,11 +2,22 @@
     name: "libmedia_headers",
     vendor_available: true,
     export_include_dirs: ["include"],
+    header_libs:[
+        "libstagefright_headers",
+        "media_plugin_headers",
+    ],
+    export_header_lib_headers: [
+        "libstagefright_headers",
+        "media_plugin_headers",
+    ],
 }
 
 cc_library {
     name: "libmedia_helper",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
     cflags: [
         "-Werror",
@@ -34,6 +45,7 @@
         "IMediaCodecList.cpp",
         "IMediaCodecService.cpp",
         "IOMX.cpp",
+        "IOMXStore.cpp",
         "MediaCodecBuffer.cpp",
         "MediaCodecInfo.cpp",
         "MediaDefs.cpp",
@@ -69,14 +81,6 @@
         "libutils",
     ],
 
-    include_dirs: [
-        "frameworks/av/include", // for media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h
-        "frameworks/av/include/media",
-        "frameworks/native/include", // for media/hardware/MetadataBufferType.h
-        "frameworks/native/include/media/openmax",
-        "frameworks/av/media/libstagefright",
-    ],
-
     export_shared_lib_headers: [
         "android.hidl.memory@1.0",
         "android.hidl.token@1.0-utils",
@@ -120,6 +124,9 @@
 cc_library_shared {
     name: "libmedia_omx",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     defaults: ["libmedia_omx_defaults"],
 }
@@ -202,6 +209,7 @@
         "libicui18n",
         "libsonivox",
         "libmediadrm",
+        "libmedia_helper",
         "android.hidl.memory@1.0",
     ],
 
@@ -210,15 +218,10 @@
         "libc_malloc_debug_backtrace",
     ],
 
-    include_dirs: [
-        "frameworks/native/include/media/openmax",
-        "frameworks/av/include/media/",
-        "frameworks/av/media/libstagefright",
-    ],
-
     export_include_dirs: [
         "include",
     ],
+
     cflags: [
         "-Werror",
         "-Wno-error=deprecated-declarations",
diff --git a/media/libmedia/CharacterEncodingDetector.cpp b/media/libmedia/CharacterEncodingDetector.cpp
index 3020136..990d260 100644
--- a/media/libmedia/CharacterEncodingDetector.cpp
+++ b/media/libmedia/CharacterEncodingDetector.cpp
@@ -18,15 +18,15 @@
 #define LOG_TAG "CharacterEncodingDector"
 #include <utils/Log.h>
 
-#include <CharacterEncodingDetector.h>
+#include <media/CharacterEncodingDetector.h>
 #include "CharacterEncodingDetectorTables.h"
 
-#include "utils/Vector.h"
-#include "StringArray.h"
+#include <utils/Vector.h>
+#include <media/StringArray.h>
 
-#include "unicode/ucnv.h"
-#include "unicode/ucsdet.h"
-#include "unicode/ustring.h"
+#include <unicode/ucnv.h>
+#include <unicode/ucsdet.h>
+#include <unicode/ustring.h>
 
 namespace android {
 
@@ -85,6 +85,8 @@
         UErrorCode status = U_ZERO_ERROR;
         UCharsetDetector *csd = ucsdet_open(&status);
         const UCharsetMatch *ucm;
+        bool goodmatch = true;
+        int highest = 0;
 
         // try combined detection of artist/album/title etc.
         char buf[1024];
@@ -116,8 +118,6 @@
             ucsdet_setText(csd, buf, strlen(buf), &status);
             int32_t matches;
             const UCharsetMatch** ucma = ucsdet_detectAll(csd, &matches, &status);
-            bool goodmatch = true;
-            int highest = 0;
             const UCharsetMatch* bestCombinedMatch = getPreferred(buf, strlen(buf),
                     ucma, matches, &goodmatch, &highest);
 
@@ -180,8 +180,24 @@
                     !strcmp(name, "genre") ||
                     !strcmp(name, "album") ||
                     !strcmp(name, "title"))) {
-                // use encoding determined from the combination of artist/album/title etc.
-                enc = combinedenc;
+                if (!goodmatch && highest < 0) {
+                    // Give it one more chance if there is no good match.
+                    ALOGV("Trying to detect %s separately", name);
+                    int32_t matches;
+                    bool goodmatchSingle = true;
+                    int highestSingle = 0;
+                    ucsdet_setText(csd, s, inputLength, &status);
+                    const UCharsetMatch** ucma = ucsdet_detectAll(csd, &matches, &status);
+                    const UCharsetMatch* bestSingleMatch = getPreferred(s, inputLength,
+                            ucma, matches, &goodmatchSingle, &highestSingle);
+                    if (goodmatchSingle || highestSingle > highest)
+                        enc = ucsdet_getName(bestSingleMatch, &status);
+                    else
+                        enc = combinedenc;
+                } else {
+                    // use encoding determined from the combination of artist/album/title etc.
+                    enc = combinedenc;
+                }
             } else {
                 if (isPrintableAscii(s, inputLength)) {
                     enc = "UTF-8";
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index f08fabb..19b00f3 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -21,7 +21,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <android/media/ICas.h>
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 #include <media/IMediaExtractor.h>
@@ -117,12 +116,12 @@
         return NULL;
     }
 
-    virtual status_t setMediaCas(const sp<ICas> & cas) {
+    virtual status_t setMediaCas(const HInterfaceToken &casToken) {
         ALOGV("setMediaCas");
 
         Parcel data, reply;
         data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(cas));
+        data.writeByteVector(casToken);
 
         status_t err = remote()->transact(SETMEDIACAS, data, &reply);
         if (err != NO_ERROR) {
@@ -206,15 +205,14 @@
             ALOGV("setMediaCas");
             CHECK_INTERFACE(IMediaExtractor, data, reply);
 
-            sp<IBinder> casBinder;
-            status_t err = data.readNullableStrongBinder(&casBinder);
+            HInterfaceToken casToken;
+            status_t err = data.readByteVector(&casToken);
             if (err != NO_ERROR) {
-                ALOGE("Error reading cas from parcel");
+                ALOGE("Error reading casToken from parcel");
                 return err;
             }
-            sp<ICas> cas = interface_cast<ICas>(casBinder);
 
-            reply->writeInt32(setMediaCas(cas));
+            reply->writeInt32(setMediaCas(casToken));
             return OK;
         }
         default:
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 7058ee8..5ea2e8b 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -127,22 +127,32 @@
         return reply.readInt32();
     }
 
-    status_t setDataSource(const sp<IDataSource>& source)
+    status_t setDataSource(const sp<IDataSource>& source, const char *mime)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
         data.writeStrongBinder(IInterface::asBinder(source));
+
+        if (mime != NULL) {
+            data.writeInt32(1);
+            data.writeCString(mime);
+        } else {
+            data.writeInt32(0);
+        }
         remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
         return reply.readInt32();
     }
 
-    sp<IMemory> getFrameAtTime(int64_t timeUs, int option)
+    sp<IMemory> getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly)
     {
-        ALOGV("getTimeAtTime: time(%" PRId64 " us) and option(%d)", timeUs, option);
+        ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d) metaOnly(%d)",
+                timeUs, option, colorFormat, metaOnly);
         Parcel data, reply;
         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
         data.writeInt64(timeUs);
         data.writeInt32(option);
+        data.writeInt32(colorFormat);
+        data.writeInt32(metaOnly);
 #ifndef DISABLE_GROUP_SCHEDULE_HACK
         sendSchedPolicy(data);
 #endif
@@ -258,7 +268,12 @@
             if (source == NULL) {
                 reply->writeInt32(BAD_VALUE);
             } else {
-                reply->writeInt32(setDataSource(source));
+                int32_t hasMime = data.readInt32();
+                const char *mime = NULL;
+                if (hasMime) {
+                    mime = data.readCString();
+                }
+                reply->writeInt32(setDataSource(source, mime));
             }
             return NO_ERROR;
         } break;
@@ -266,11 +281,14 @@
             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
             int64_t timeUs = data.readInt64();
             int option = data.readInt32();
-            ALOGV("getTimeAtTime: time(%" PRId64 " us) and option(%d)", timeUs, option);
+            int colorFormat = data.readInt32();
+            bool metaOnly = (data.readInt32() != 0);
+            ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d), metaOnly(%d)",
+                    timeUs, option, colorFormat, metaOnly);
 #ifndef DISABLE_GROUP_SCHEDULE_HACK
             setSchedPolicy(data);
 #endif
-            sp<IMemory> bitmap = getFrameAtTime(timeUs, option);
+            sp<IMemory> bitmap = getFrameAtTime(timeUs, option, colorFormat, metaOnly);
             if (bitmap != 0) {  // Don't send NULL across the binder interface
                 reply->writeInt32(NO_ERROR);
                 reply->writeStrongBinder(IInterface::asBinder(bitmap));
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 43130eb..a073081 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -29,7 +29,7 @@
 #include <utils/NativeHandle.h>
 #include <gui/IGraphicBufferProducer.h>
 
-#include <omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxNode.h>
 #include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 
diff --git a/media/libmedia/IOMXStore.cpp b/media/libmedia/IOMXStore.cpp
new file mode 100644
index 0000000..4948f1a
--- /dev/null
+++ b/media/libmedia/IOMXStore.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2009 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 "IOMXStore"
+
+#include <utils/Log.h>
+
+#include <media/IOMX.h>
+#include <media/IOMXStore.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+#include <binder/Parcel.h>
+
+#include <vector>
+#include <string>
+
+namespace android {
+
+namespace {
+
+enum {
+    CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+    LIST_SERVICE_ATTRIBUTES,
+    GET_NODE_PREFIX,
+    LIST_ROLES,
+    GET_OMX,
+};
+
+// Forward declarations of std::vector<T> <-> Parcel conversion funcitons that
+// depend on writeToParcel() and readToParcel() for T <-> Parcel.
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p);
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p);
+
+// std::string <-> Parcel
+
+status_t writeToParcel(const std::string& s, Parcel* p) {
+    if (s.size() > INT32_MAX) {
+        return BAD_VALUE;
+    }
+    return p->writeByteArray(
+            s.size(), reinterpret_cast<const uint8_t*>(s.c_str()));
+}
+
+status_t readFromParcel(std::string* s, const Parcel& p) {
+    int32_t len;
+    status_t status = p.readInt32(&len);
+    if (status != NO_ERROR) {
+        return status;
+    } else if ((len < 0) || (static_cast<uint64_t>(len) > SIZE_MAX)) {
+        return BAD_VALUE;
+    }
+    s->resize(len);
+    if (len == 0) {
+        return NO_ERROR;
+    }
+    return p.read(static_cast<void*>(&s->front()), static_cast<size_t>(len));
+}
+
+// IOMXStore::Attribute <-> Parcel
+
+status_t writeToParcel(const IOMXStore::Attribute& a, Parcel* p) {
+    status_t status = writeToParcel(a.key, p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return writeToParcel(a.value, p);
+}
+
+status_t readFromParcel(IOMXStore::Attribute* a, const Parcel& p) {
+    status_t status = readFromParcel(&(a->key), p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return readFromParcel(&(a->value), p);
+}
+
+// IOMXStore::NodeInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::NodeInfo& n, Parcel* p) {
+    status_t status = writeToParcel(n.name, p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = writeToParcel(n.owner, p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return writeToParcel(n.attributes, p);
+}
+
+status_t readFromParcel(IOMXStore::NodeInfo* n, const Parcel& p) {
+    status_t status = readFromParcel(&(n->name), p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = readFromParcel(&(n->owner), p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return readFromParcel(&(n->attributes), p);
+}
+
+// IOMXStore::RoleInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::RoleInfo& r, Parcel* p) {
+    status_t status = writeToParcel(r.role, p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = writeToParcel(r.type, p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = p->writeBool(r.isEncoder);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = p->writeBool(r.preferPlatformNodes);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return writeToParcel(r.nodes, p);
+}
+
+status_t readFromParcel(IOMXStore::RoleInfo* r, const Parcel& p) {
+    status_t status = readFromParcel(&(r->role), p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = readFromParcel(&(r->type), p);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = p.readBool(&(r->isEncoder));
+    if (status != NO_ERROR) {
+        return status;
+    }
+    status = p.readBool(&(r->preferPlatformNodes));
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return readFromParcel(&(r->nodes), p);
+}
+
+// std::vector<NodeInfo> <-> Parcel
+// std::vector<RoleInfo> <-> Parcel
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p) {
+    status_t status = p->writeVectorSize(v);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    for (const T& x : v) {
+        status = writeToParcel(x, p);
+        if (status != NO_ERROR) {
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p) {
+    status_t status = p.resizeOutVector(v);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    for (T& x : *v) {
+        status = readFromParcel(&x, p);
+        if (status != NO_ERROR) {
+            return status;
+        }
+    }
+    return NO_ERROR;
+}
+
+} // unnamed namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BpOMXStore : public BpInterface<IOMXStore> {
+public:
+    explicit BpOMXStore(const sp<IBinder> &impl)
+        : BpInterface<IOMXStore>(impl) {
+    }
+
+    status_t listServiceAttributes(
+            std::vector<Attribute>* attributes) override {
+        Parcel data, reply;
+        status_t status;
+        status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(LIST_SERVICE_ATTRIBUTES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return readFromParcel(attributes, reply);
+    }
+
+    status_t getNodePrefix(std::string* prefix) override {
+        Parcel data, reply;
+        status_t status;
+        status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(GET_NODE_PREFIX, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return readFromParcel(prefix, reply);
+    }
+
+    status_t listRoles(std::vector<RoleInfo>* roleList) override {
+        Parcel data, reply;
+        status_t status;
+        status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(LIST_ROLES, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return readFromParcel(roleList, reply);
+    }
+
+    status_t getOmx(const std::string& name, sp<IOMX>* omx) override {
+        Parcel data, reply;
+        status_t status;
+        status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = writeToParcel(name, &data);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = remote()->transact(GET_OMX, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return reply.readStrongBinder(omx);
+    }
+
+};
+
+IMPLEMENT_META_INTERFACE(OMXStore, "android.hardware.IOMXStore");
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define CHECK_OMX_INTERFACE(interface, data, reply) \
+        do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
+            ALOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnOMXStore::onTransact(
+    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+    switch (code) {
+        case LIST_SERVICE_ATTRIBUTES: {
+            CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+            status_t status;
+            std::vector<Attribute> attributes;
+
+            status = listServiceAttributes(&attributes);
+            if (status != NO_ERROR) {
+                ALOGE("listServiceAttributes() fails with status %d",
+                        static_cast<int>(status));
+                return NO_ERROR;
+            }
+            status = writeToParcel(attributes, reply);
+            if (status != NO_ERROR) {
+                ALOGE("listServiceAttributes() fails to send reply");
+                return NO_ERROR;
+            }
+            return NO_ERROR;
+        }
+        case GET_NODE_PREFIX: {
+            CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+            status_t status;
+            std::string prefix;
+
+            status = getNodePrefix(&prefix);
+            if (status != NO_ERROR) {
+                ALOGE("getNodePrefix() fails with status %d",
+                        static_cast<int>(status));
+                return NO_ERROR;
+            }
+            status = writeToParcel(prefix, reply);
+            if (status != NO_ERROR) {
+                ALOGE("getNodePrefix() fails to send reply");
+                return NO_ERROR;
+            }
+            return NO_ERROR;
+        }
+        case LIST_ROLES: {
+            CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+            status_t status;
+            std::vector<RoleInfo> roleList;
+
+            status = listRoles(&roleList);
+            if (status != NO_ERROR) {
+                ALOGE("listRoles() fails with status %d",
+                        static_cast<int>(status));
+                return NO_ERROR;
+            }
+            status = writeToParcel(roleList, reply);
+            if (status != NO_ERROR) {
+                ALOGE("listRoles() fails to send reply");
+                return NO_ERROR;
+            }
+            return NO_ERROR;
+        }
+        case GET_OMX: {
+            CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+            status_t status;
+            std::string name;
+            sp<IOMX> omx;
+
+            status = readFromParcel(&name, data);
+            if (status != NO_ERROR) {
+                ALOGE("getOmx() fails to retrieve name");
+                return NO_ERROR;
+            }
+            status = getOmx(name, &omx);
+            if (status != NO_ERROR) {
+                ALOGE("getOmx() fails with status %d",
+                        static_cast<int>(status));
+                return NO_ERROR;
+            }
+            status = reply->writeStrongBinder(IInterface::asBinder(omx));
+            if (status != NO_ERROR) {
+                ALOGE("getOmx() fails to send reply");
+                return NO_ERROR;
+            }
+            return NO_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}  // namespace android
diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp
index 95f7d2e..9724fc1 100644
--- a/media/libmedia/IResourceManagerService.cpp
+++ b/media/libmedia/IResourceManagerService.cpp
@@ -19,7 +19,7 @@
 #define LOG_TAG "IResourceManagerService"
 #include <utils/Log.h>
 
-#include "media/IResourceManagerService.h"
+#include <media/IResourceManagerService.h>
 
 #include <binder/Parcel.h>
 
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index 9f803cb..028616b 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -20,8 +20,8 @@
 
 #include <media/mediascanner.h>
 
-#include "CharacterEncodingDetector.h"
-#include "StringArray.h"
+#include <media/CharacterEncodingDetector.h>
+#include <media/StringArray.h>
 
 namespace android {
 
diff --git a/media/libmedia/MidiDeviceInfo.cpp b/media/libmedia/MidiDeviceInfo.cpp
index 02efc5f..7588e00 100644
--- a/media/libmedia/MidiDeviceInfo.cpp
+++ b/media/libmedia/MidiDeviceInfo.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "MidiDeviceInfo"
 
-#include "MidiDeviceInfo.h"
+#include <media/MidiDeviceInfo.h>
 
 #include <binder/Parcel.h>
 #include <log/log.h>
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index faae954..4e5d67f 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -22,7 +22,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-#include "media/MidiIoWrapper.h"
+#include <media/MidiIoWrapper.h>
 
 static int readAt(void *handle, void *buffer, int pos, int size) {
     return ((android::MidiIoWrapper*)handle)->readAt(buffer, pos, size);
diff --git a/media/libmedia/StringArray.cpp b/media/libmedia/StringArray.cpp
index b2e5907..7868b85 100644
--- a/media/libmedia/StringArray.cpp
+++ b/media/libmedia/StringArray.cpp
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "StringArray.h"
+#include <media/StringArray.h>
 
 namespace android {
 
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index a6eba86..e6c8f9c 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -375,7 +375,7 @@
 audio_channel_mask_t channelMaskFromString(const std::string &literalChannels)
 {
     audio_channel_mask_t channels;
-    if (!OutputChannelConverter::fromString(literalChannels, channels) ||
+    if (!OutputChannelConverter::fromString(literalChannels, channels) &&
             !InputChannelConverter::fromString(literalChannels, channels)) {
         return AUDIO_CHANNEL_INVALID;
     }
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index e031765..5d25e4d 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -39,6 +39,11 @@
 
 struct DrmSessionClientInterface;
 
+inline bool operator==(const Vector<uint8_t> &l, const Vector<uint8_t> &r) {
+    if (l.size() != r.size()) return false;
+    return memcmp(l.array(), r.array(), l.size()) == 0;
+}
+
 struct DrmHal : public BnDrm,
              public IBinder::DeathRecipient,
              public IDrmPluginListener {
@@ -161,6 +166,9 @@
     const Vector<sp<IDrmFactory>> mFactories;
     sp<IDrmPlugin> mPlugin;
 
+    Vector<Vector<uint8_t>> mOpenSessions;
+    void closeOpenSessions();
+
     /**
      * mInitCheck is:
      *   NO_INIT if a plugin hasn't been created yet
@@ -175,6 +183,11 @@
 
     void writeByteArray(Parcel &obj, const hidl_vec<uint8_t>& array);
 
+    void reportMetrics() const;
+    status_t getPropertyStringInternal(String8 const &name, String8 &value) const;
+    status_t getPropertyByteArrayInternal(String8 const &name,
+                                          Vector<uint8_t> &value) const;
+
     DISALLOW_EVIL_CONSTRUCTORS(DrmHal);
 };
 
diff --git a/media/libmedia/include/media/IDataSource.h b/media/libmedia/include/media/IDataSource.h
index 655f337..3858f78 100644
--- a/media/libmedia/include/media/IDataSource.h
+++ b/media/libmedia/include/media/IDataSource.h
@@ -35,7 +35,9 @@
     // Get the memory that readAt writes into.
     virtual sp<IMemory> getIMemory() = 0;
     // Read up to |size| bytes into the memory returned by getIMemory(). Returns
-    // the number of bytes read, or -1 on error. |size| must not be larger than
+    // the number of bytes read, or negative value on error (eg.
+    // ERROR_END_OF_STREAM indicating EOS. This is needed by CallbackDataSource
+    // to properly handle reading of last chunk). |size| must not be larger than
     // the buffer.
     virtual ssize_t readAt(off64_t offset, size_t size) = 0;
     // Get the size, or -1 if the size is unknown.
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
index ab40f53..1e13b65 100644
--- a/media/libmedia/include/media/IMediaExtractor.h
+++ b/media/libmedia/include/media/IMediaExtractor.h
@@ -20,14 +20,12 @@
 
 #include <media/IMediaSource.h>
 #include <media/stagefright/DataSource.h>
+#include <vector>
 
 namespace android {
 
 class MetaData;
-namespace media {
-class ICas;
-};
-using namespace media;
+typedef std::vector<uint8_t> HInterfaceToken;
 
 class IMediaExtractor : public IInterface {
 public:
@@ -65,7 +63,7 @@
     // for DRM
     virtual char* getDrmTrackInfo(size_t trackID, int *len)  = 0;
 
-    virtual status_t setMediaCas(const sp<ICas> &cas) = 0;
+    virtual status_t setMediaCas(const HInterfaceToken &casToken) = 0;
 
     virtual void setUID(uid_t uid)  = 0;
 
diff --git a/media/libmedia/include/media/IMediaMetadataRetriever.h b/media/libmedia/include/media/IMediaMetadataRetriever.h
index c90f254..ea95161 100644
--- a/media/libmedia/include/media/IMediaMetadataRetriever.h
+++ b/media/libmedia/include/media/IMediaMetadataRetriever.h
@@ -19,13 +19,12 @@
 #define ANDROID_IMEDIAMETADATARETRIEVER_H
 
 #include <binder/IInterface.h>
-#include <binder/Parcel.h>
 #include <binder/IMemory.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 
 namespace android {
-
+class Parcel;
 class IDataSource;
 struct IMediaHTTPService;
 
@@ -41,8 +40,10 @@
             const KeyedVector<String8, String8> *headers = NULL) = 0;
 
     virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
-    virtual status_t        setDataSource(const sp<IDataSource>& dataSource) = 0;
-    virtual sp<IMemory>     getFrameAtTime(int64_t timeUs, int option) = 0;
+    virtual status_t        setDataSource(
+            const sp<IDataSource>& dataSource, const char *mime) = 0;
+    virtual sp<IMemory>     getFrameAtTime(
+            int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
     virtual sp<IMemory>     extractAlbumArt() = 0;
     virtual const char*     extractMetadata(int keyCode) = 0;
 };
diff --git a/media/libmedia/include/media/IOMX.h b/media/libmedia/include/media/IOMX.h
index 9a0ada1..d868860 100644
--- a/media/libmedia/include/media/IOMX.h
+++ b/media/libmedia/include/media/IOMX.h
@@ -29,8 +29,8 @@
 #include <media/hardware/MetadataBufferType.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 
-#include <OMX_Core.h>
-#include <OMX_Video.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_Video.h>
 
 namespace android {
 
diff --git a/media/libmedia/include/media/IOMXStore.h b/media/libmedia/include/media/IOMXStore.h
new file mode 100644
index 0000000..f739c3b
--- /dev/null
+++ b/media/libmedia/include/media/IOMXStore.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IOMXSTORE_H_
+
+#define ANDROID_IOMXSTORE_H_
+
+#include <media/IOMX.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+
+#include <vector>
+#include <string>
+
+/*
+#include <OMX_Core.h>
+#include <OMX_Video.h>
+*/
+
+namespace android {
+
+using hardware::media::omx::V1_0::IOmxStore;
+
+class IOMXStore : public IInterface {
+public:
+    DECLARE_META_INTERFACE(OMXStore);
+
+    struct Attribute {
+        std::string key;
+        std::string value;
+    };
+
+    struct NodeInfo {
+        std::string name;
+        std::string owner;
+        std::vector<Attribute> attributes;
+    };
+
+    struct RoleInfo {
+        std::string role;
+        std::string type;
+        bool isEncoder;
+        bool preferPlatformNodes;
+        std::vector<NodeInfo> nodes;
+    };
+
+    virtual status_t listServiceAttributes(
+            std::vector<Attribute>* attributes) = 0;
+
+    virtual status_t getNodePrefix(std::string* prefix) = 0;
+
+    virtual status_t listRoles(std::vector<RoleInfo>* roleList) = 0;
+
+    virtual status_t getOmx(const std::string& name, sp<IOMX>* omx) = 0;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BnOMXStore : public BnInterface<IOMXStore> {
+public:
+    virtual status_t onTransact(
+            uint32_t code, const Parcel &data, Parcel *reply,
+            uint32_t flags = 0);
+};
+
+}  // namespace android
+
+#endif  // ANDROID_IOMX_H_
diff --git a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
index a5e1350..257002d 100644
--- a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
+++ b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
@@ -41,8 +41,9 @@
             const KeyedVector<String8, String8> *headers = NULL) = 0;
 
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0;
-    virtual status_t setDataSource(const sp<DataSource>& source) = 0;
-    virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
+    virtual status_t setDataSource(const sp<DataSource>& source, const char *mime) = 0;
+    virtual VideoFrame* getFrameAtTime(
+            int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
     virtual MediaAlbumArt* extractAlbumArt() = 0;
     virtual const char* extractMetadata(int keyCode) = 0;
 };
@@ -54,7 +55,9 @@
     MediaMetadataRetrieverInterface() {}
 
     virtual             ~MediaMetadataRetrieverInterface() {}
-    virtual VideoFrame* getFrameAtTime(int64_t /*timeUs*/, int /*option*/) { return NULL; }
+    virtual VideoFrame* getFrameAtTime(
+            int64_t /*timeUs*/, int /*option*/, int /*colorFormat*/, bool /*metaOnly*/)
+    { return NULL; }
     virtual MediaAlbumArt* extractAlbumArt() { return NULL; }
     virtual const char* extractMetadata(int /*keyCode*/) { return NULL; }
 };
diff --git a/media/libmedia/include/media/PluginMetricsReporting.h b/media/libmedia/include/media/PluginMetricsReporting.h
new file mode 100644
index 0000000..4a5a363
--- /dev/null
+++ b/media/libmedia/include/media/PluginMetricsReporting.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLUGIN_METRICS_REPORTING_H_
+
+#define PLUGIN_METRICS_REPORTING_H_
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics,
+                                const String8& vendorName,
+                                const String8& description);
+
+}  // namespace android
+
+#endif  // PLUGIN_METRICS_REPORTING_H_
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 8ed07ee..65c266b 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -76,8 +76,10 @@
             const KeyedVector<String8, String8> *headers = NULL);
 
     status_t setDataSource(int fd, int64_t offset, int64_t length);
-    status_t setDataSource(const sp<IDataSource>& dataSource);
-    sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
+    status_t setDataSource(
+            const sp<IDataSource>& dataSource, const char *mime = NULL);
+    sp<IMemory> getFrameAtTime(int64_t timeUs, int option,
+            int colorFormat = HAL_PIXEL_FORMAT_RGB_565, bool metaOnly = false);
     sp<IMemory> extractAlbumArt();
     const char* extractMetadata(int keyCode);
 
diff --git a/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
similarity index 100%
rename from include/media/omx/1.0/Conversion.h
rename to media/libmedia/include/media/omx/1.0/Conversion.h
diff --git a/include/media/omx/1.0/WGraphicBufferSource.h b/media/libmedia/include/media/omx/1.0/WGraphicBufferSource.h
similarity index 100%
rename from include/media/omx/1.0/WGraphicBufferSource.h
rename to media/libmedia/include/media/omx/1.0/WGraphicBufferSource.h
diff --git a/include/media/omx/1.0/WOmx.h b/media/libmedia/include/media/omx/1.0/WOmx.h
similarity index 100%
rename from include/media/omx/1.0/WOmx.h
rename to media/libmedia/include/media/omx/1.0/WOmx.h
diff --git a/include/media/omx/1.0/WOmxBufferSource.h b/media/libmedia/include/media/omx/1.0/WOmxBufferSource.h
similarity index 98%
rename from include/media/omx/1.0/WOmxBufferSource.h
rename to media/libmedia/include/media/omx/1.0/WOmxBufferSource.h
index 86322da..086f648 100644
--- a/include/media/omx/1.0/WOmxBufferSource.h
+++ b/media/libmedia/include/media/omx/1.0/WOmxBufferSource.h
@@ -21,7 +21,7 @@
 #include <hidl/Status.h>
 
 #include <binder/Binder.h>
-#include <OMXFenceParcelable.h>
+#include <media/OMXFenceParcelable.h>
 
 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
 #include <android/BnOMXBufferSource.h>
diff --git a/include/media/omx/1.0/WOmxNode.h b/media/libmedia/include/media/omx/1.0/WOmxNode.h
similarity index 100%
rename from include/media/omx/1.0/WOmxNode.h
rename to media/libmedia/include/media/omx/1.0/WOmxNode.h
diff --git a/include/media/omx/1.0/WOmxObserver.h b/media/libmedia/include/media/omx/1.0/WOmxObserver.h
similarity index 100%
rename from include/media/omx/1.0/WOmxObserver.h
rename to media/libmedia/include/media/omx/1.0/WOmxObserver.h
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 08a9e6a..7d27d57 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -130,7 +130,7 @@
 }
 
 status_t MediaMetadataRetriever::setDataSource(
-    const sp<IDataSource>& dataSource)
+    const sp<IDataSource>& dataSource, const char *mime)
 {
     ALOGV("setDataSource(IDataSource)");
     Mutex::Autolock _l(mLock);
@@ -138,18 +138,20 @@
         ALOGE("retriever is not initialized");
         return INVALID_OPERATION;
     }
-    return mRetriever->setDataSource(dataSource);
+    return mRetriever->setDataSource(dataSource, mime);
 }
 
-sp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option)
+sp<IMemory> MediaMetadataRetriever::getFrameAtTime(
+        int64_t timeUs, int option, int colorFormat, bool metaOnly)
 {
-    ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d)", timeUs, option);
+    ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d) colorFormat(%d) metaOnly(%d)",
+            timeUs, option, colorFormat, metaOnly);
     Mutex::Autolock _l(mLock);
     if (mRetriever == 0) {
         ALOGE("retriever is not initialized");
         return NULL;
     }
-    return mRetriever->getFrameAtTime(timeUs, option);
+    return mRetriever->getFrameAtTime(timeUs, option, colorFormat, metaOnly);
 }
 
 const char* MediaMetadataRetriever::extractMetadata(int keyCode)
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 0a9f791..6da1ec1 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -245,8 +245,12 @@
     if (sInitComplete)
         return;
 
-    registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
-    registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
+    IFactory* factory = new NuPlayerFactory();
+    if (registerFactory_l(factory, NU_PLAYER) != OK)
+        delete factory;
+    factory = new TestPlayerFactory();
+    if (registerFactory_l(factory, TEST_PLAYER) != OK)
+        delete factory;
 
     sInitComplete = true;
 }
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 942a8fc..496db0d 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -77,7 +77,7 @@
 #include "TestPlayerStub.h"
 #include "nuplayer/NuPlayerDriver.h"
 
-#include <OMX.h>
+#include <media/stagefright/omx/OMX.h>
 
 #include "HDCP.h"
 #include "HTTPBase.h"
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 793f476..5a468f3 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -175,7 +175,7 @@
 }
 
 status_t MetadataRetrieverClient::setDataSource(
-        const sp<IDataSource>& source)
+        const sp<IDataSource>& source, const char *mime)
 {
     ALOGV("setDataSource(IDataSource)");
     Mutex::Autolock lock(mLock);
@@ -186,16 +186,18 @@
     ALOGV("player type = %d", playerType);
     sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
     if (p == NULL) return NO_INIT;
-    status_t ret = p->setDataSource(dataSource);
+    status_t ret = p->setDataSource(dataSource, mime);
     if (ret == NO_ERROR) mRetriever = p;
     return ret;
 }
 
 Mutex MetadataRetrieverClient::sLock;
 
-sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
+sp<IMemory> MetadataRetrieverClient::getFrameAtTime(
+        int64_t timeUs, int option, int colorFormat, bool metaOnly)
 {
-    ALOGV("getFrameAtTime: time(%lld us) option(%d)", (long long)timeUs, option);
+    ALOGV("getFrameAtTime: time(%lld us) option(%d) colorFormat(%d), metaOnly(%d)",
+            (long long)timeUs, option, colorFormat, metaOnly);
     Mutex::Autolock lock(mLock);
     Mutex::Autolock glock(sLock);
     mThumbnail.clear();
@@ -203,12 +205,13 @@
         ALOGE("retriever is not initialized");
         return NULL;
     }
-    VideoFrame *frame = mRetriever->getFrameAtTime(timeUs, option);
+    VideoFrame *frame = mRetriever->getFrameAtTime(
+            timeUs, option, colorFormat, metaOnly);
     if (frame == NULL) {
         ALOGE("failed to capture a video frame");
         return NULL;
     }
-    size_t size = sizeof(VideoFrame) + frame->mSize;
+    size_t size = frame->getFlattenedSize();
     sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient");
     if (heap == NULL) {
         ALOGE("failed to create MemoryDealer");
@@ -222,16 +225,7 @@
         return NULL;
     }
     VideoFrame *frameCopy = static_cast<VideoFrame *>(mThumbnail->pointer());
-    frameCopy->mWidth = frame->mWidth;
-    frameCopy->mHeight = frame->mHeight;
-    frameCopy->mDisplayWidth = frame->mDisplayWidth;
-    frameCopy->mDisplayHeight = frame->mDisplayHeight;
-    frameCopy->mSize = frame->mSize;
-    frameCopy->mRotationAngle = frame->mRotationAngle;
-    ALOGV("rotation: %d", frameCopy->mRotationAngle);
-    frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame);
-    memcpy(frameCopy->mData, frame->mData, frame->mSize);
-    frameCopy->mData = 0;
+    frameCopy->copyFlattened(*frame);
     delete frame;  // Fix memory leakage
     return mThumbnail;
 }
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index fe7547c..c78cd4b 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -49,8 +49,9 @@
             const KeyedVector<String8, String8> *headers);
 
     virtual status_t                setDataSource(int fd, int64_t offset, int64_t length);
-    virtual status_t                setDataSource(const sp<IDataSource>& source);
-    virtual sp<IMemory>             getFrameAtTime(int64_t timeUs, int option);
+    virtual status_t                setDataSource(const sp<IDataSource>& source, const char *mime);
+    virtual sp<IMemory>             getFrameAtTime(
+            int64_t timeUs, int option, int colorFormat, bool metaOnly);
     virtual sp<IMemory>             extractAlbumArt();
     virtual const char*             extractMetadata(int keyCode);
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6a09227..df36046 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1171,7 +1171,7 @@
                 if (mSource != nullptr) {
                     if (audio) {
                         if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
-                                || mSurface == NULL) {
+                                || mSurface == NULL || mVideoDecoder == NULL) {
                             // When both audio and video have error, or this stream has only audio
                             // which has error, notify client of error.
                             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
@@ -1182,7 +1182,7 @@
                         mAudioDecoderError = true;
                     } else {
                         if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
-                                || mAudioSink == NULL) {
+                                || mAudioSink == NULL || mAudioDecoder == NULL) {
                             // When both audio and video have error, or this stream has only video
                             // which has error, notify client of error.
                             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 8fe255b..ac187cc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -343,7 +343,7 @@
             format, mSurface, crypto, 0 /* flags */);
 
     if (err != OK) {
-        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
+        ALOGE("Failed to configure [%s] decoder (err=%d)", mComponentName.c_str(), err);
         mCodec->release();
         mCodec.clear();
         handleError(err);
@@ -372,7 +372,7 @@
 
     err = mCodec->start();
     if (err != OK) {
-        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
+        ALOGE("Failed to start [%s] decoder (err=%d)", mComponentName.c_str(), err);
         mCodec->release();
         mCodec.clear();
         handleError(err);
@@ -460,6 +460,12 @@
     if (notifyComplete) {
         mResumePending = true;
     }
+
+    if (mCodec == NULL) {
+        ALOGE("[%s] onResume without a valid codec", mComponentName.c_str());
+        handleError(NO_INIT);
+        return;
+    }
     mCodec->start();
 }
 
@@ -481,7 +487,7 @@
     }
 
     if (err != OK) {
-        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
+        ALOGE("failed to flush [%s] (err=%d)", mComponentName.c_str(), err);
         handleError(err);
         // finish with posting kWhatFlushCompleted.
         // we attempt to release the buffers even if flush fails.
@@ -530,7 +536,7 @@
     releaseAndResetMediaBuffers();
 
     if (err != OK) {
-        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
+        ALOGE("failed to release [%s] (err=%d)", mComponentName.c_str(), err);
         handleError(err);
         // finish with posting kWhatShutdownCompleted.
     }
@@ -631,10 +637,17 @@
         return false;
     }
 
+    if (mCodec == NULL) {
+        ALOGE("[%s] handleAnInputBuffer without a valid codec", mComponentName.c_str());
+        handleError(NO_INIT);
+        return false;
+    }
+
     sp<MediaCodecBuffer> buffer;
     mCodec->getInputBuffer(index, &buffer);
 
     if (buffer == NULL) {
+        ALOGE("[%s] handleAnInputBuffer, failed to get input buffer", mComponentName.c_str());
         handleError(UNKNOWN_ERROR);
         return false;
     }
@@ -697,11 +710,18 @@
         size_t size,
         int64_t timeUs,
         int32_t flags) {
+    if (mCodec == NULL) {
+        ALOGE("[%s] handleAnOutputBuffer without a valid codec", mComponentName.c_str());
+        handleError(NO_INIT);
+        return false;
+    }
+
 //    CHECK_LT(bufferIx, mOutputBuffers.size());
     sp<MediaCodecBuffer> buffer;
     mCodec->getOutputBuffer(index, &buffer);
 
     if (buffer == NULL) {
+        ALOGE("[%s] handleAnOutputBuffer, failed to get output buffer", mComponentName.c_str());
         handleError(UNKNOWN_ERROR);
         return false;
     }
@@ -949,6 +969,12 @@
 }
 
 bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
+    if (mCodec == NULL) {
+        ALOGE("[%s] onInputBufferFetched without a valid codec", mComponentName.c_str());
+        handleError(NO_INIT);
+        return false;
+    }
+
     size_t bufferIx;
     CHECK(msg->findSize("buffer-ix", &bufferIx));
     CHECK_LT(bufferIx, mInputBuffers.size());
@@ -979,7 +1005,7 @@
         }
 
         if (streamErr != ERROR_END_OF_STREAM) {
-            ALOGE("Stream error for %s (err=%d), EOS %s queued",
+            ALOGE("Stream error for [%s] (err=%d), EOS %s queued",
                     mComponentName.c_str(),
                     streamErr,
                     err == OK ? "successfully" : "unsuccessfully");
@@ -1073,7 +1099,7 @@
         } // no cryptInfo
 
         if (err != OK) {
-            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for %s (err=%d, %s)",
+            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for [%s] (err=%d, %s)",
                     (cryptInfo != NULL ? "Secure" : ""),
                     mComponentName.c_str(), err, errorDetailMsg.c_str());
             handleError(err);
@@ -1102,7 +1128,9 @@
         }
     }
 
-    if (msg->findInt32("render", &render) && render) {
+    if (mCodec == NULL) {
+        err = NO_INIT;
+    } else if (msg->findInt32("render", &render) && render) {
         int64_t timestampNs;
         CHECK(msg->findInt64("timestampNs", &timestampNs));
         err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
@@ -1111,7 +1139,7 @@
         err = mCodec->releaseOutputBuffer(bufferIx);
     }
     if (err != OK) {
-        ALOGE("failed to release output buffer for %s (err=%d)",
+        ALOGE("failed to release output buffer for [%s] (err=%d)",
                 mComponentName.c_str(), err);
         handleError(err);
     }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index ad788f7..0fc1aa7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -639,11 +639,6 @@
         notifyListener_l(MEDIA_STOPPED);
     }
 
-    if (property_get_bool("persist.debug.sf.stats", false)) {
-        Vector<String16> args;
-        dump(-1, args);
-    }
-
     mState = STATE_RESET_IN_PROGRESS;
     mPlayer->resetAsync();
 
@@ -935,7 +930,10 @@
                     // don't send completion event when looping
                     return;
                 }
-
+                if (property_get_bool("persist.debug.sf.stats", false)) {
+                    Vector<String16> args;
+                    dump(-1, args);
+                }
                 mPlayer->pause();
                 mState = STATE_PAUSED;
             }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 758db1f..483a9ff 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -840,7 +840,7 @@
         return;
     }
 
-    notifyEOS(true /* audio */, ERROR_END_OF_STREAM);
+    notifyEOS_l(true /* audio */, ERROR_END_OF_STREAM);
 }
 
 size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
@@ -917,10 +917,10 @@
             if (mAudioSink->needsTrailingPadding()) {
                 postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
             }
-            ALOGV("fillAudioBuffer: notifyEOS "
+            ALOGV("fillAudioBuffer: notifyEOS_l "
                     "mNumFramesWritten:%u  finalResult:%d  postEOSDelay:%lld",
                     mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs);
-            notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
+            notifyEOS_l(true /* audio */, entry->mFinalResult, postEOSDelayUs);
         }
     }
     return sizeCopied;
@@ -1408,6 +1408,11 @@
 }
 
 void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
+    Mutex::Autolock autoLock(mLock);
+    notifyEOS_l(audio, finalResult, delayUs);
+}
+
+void NuPlayer::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs) {
     if (audio && delayUs > 0) {
         sp<AMessage> msg = new AMessage(kWhatEOS, this);
         msg->setInt32("audioEOSGeneration", mAudioEOSGeneration);
@@ -1420,6 +1425,11 @@
     notify->setInt32("audio", static_cast<int32_t>(audio));
     notify->setInt32("finalResult", finalResult);
     notify->post(delayUs);
+
+    if (audio) {
+        // Video might outlive audio. Clear anchor to enable video only case.
+        mAnchorTimeMediaUs = -1;
+    }
 }
 
 void NuPlayer::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index e6850b5..f58b79c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -275,6 +275,7 @@
     void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> &notify);
 
     void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
+    void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0);
     void notifyFlushComplete(bool audio);
     void notifyPosition();
     void notifyVideoLateBy(int64_t lateByUs);
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index f511876..4220b77 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -1,15 +1,51 @@
+
+cc_defaults {
+    name: "libnbaio_mono_defaults",
+    srcs: [
+        "MonoPipe.cpp",
+        "MonoPipeReader.cpp",
+        "NBAIO.cpp",
+    ],
+    header_libs: [
+        "libaudioclient_headers",
+        "libaudio_system_headers",
+        "libmedia_headers",
+    ],
+    export_header_lib_headers: [
+        "libaudioclient_headers",
+        "libmedia_headers",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+        "libutils",
+    ],
+
+    export_include_dirs: ["include_mono"],
+}
+
+// libnbaio_mono is the part of libnbaio that is available for vendors to use. Vendor modules can't
+// link against libnbaio and system modules can't link against libnbaio_mono. The rest of libnbaio
+// pulls in too many other dependencies.
+cc_library_shared {
+    name: "libnbaio_mono",
+    vendor: true,
+    defaults: ["libnbaio_mono_defaults"],
+}
+
 cc_library_shared {
     name: "libnbaio",
+    defaults: ["libnbaio_mono_defaults"],
     srcs: [
         "AudioBufferProviderSource.cpp",
         "AudioStreamInSource.cpp",
         "AudioStreamOutSink.cpp",
-        "MonoPipe.cpp",
-        "MonoPipeReader.cpp",
-        "NBAIO.cpp",
         "NBLog.cpp",
+        "PerformanceAnalysis.cpp",
         "Pipe.cpp",
         "PipeReader.cpp",
+        "ReportPerformance.cpp",
         "SourceAudioBufferProvider.cpp",
     ],
 
@@ -24,8 +60,8 @@
         "libaudioutils",
         "libbinder",
         "libcutils",
-        "libutils",
         "liblog",
+        "libutils",
     ],
 
     cflags: [
@@ -35,7 +71,5 @@
 
     include_dirs: ["system/media/audio_utils/include"],
 
-    local_include_dirs: ["include"],
-
     export_include_dirs: ["include"],
 }
diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp
index cbff87d..8564899 100644
--- a/media/libnbaio/AudioStreamOutSink.cpp
+++ b/media/libnbaio/AudioStreamOutSink.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include <utils/Log.h>
+#include <audio_utils/clock.h>
 #include <media/audiohal/StreamHalInterface.h>
 #include <media/nbaio/AudioStreamOutSink.h>
 
@@ -82,8 +83,7 @@
         return INVALID_OPERATION;
     }
     timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position64;
-    timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
-            time.tv_sec * 1000000000LL + time.tv_nsec;
+    timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = audio_utils_ns_from_timespec(&time);
     return OK;
 }
 
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index ebb90c8..2f639d2 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -18,14 +18,14 @@
 * Documentation: Workflow summary for histogram data processing:
 * For more details on FIFO, please see system/media/audio_utils; doxygen
 * TODO: add this documentation to doxygen once it is further developed
-* 1) writing the data to a buffer
-* onWork
+* 1) Writing buffer period timestamp to the circular buffer
+* onWork()
 *     Called every period length (e.g., 4ms)
 *     Calls LOG_HIST_TS
 * LOG_HIST_TS
-*     Hashes file name and line number
-*     calls NBLOG::Writer::logHistTS once
-* NBLOG::Writer::logHistTS
+*     Hashes file name and line number, and writes single timestamp to buffer
+*     calls NBLOG::Writer::logEventHistTS once
+* NBLOG::Writer::logEventHistTS
 *     calls NBLOG::Writer::log on hash and current timestamp
 *     time is in CLOCK_MONOTONIC converted to ns
 * NBLOG::Writer::log(Event, const void*, size_t)
@@ -44,6 +44,8 @@
 * ssize_t audio_utils_fifo_reader::obtain
 *     Determines readable buffer section via pointer arithmetic on reader
 *     and writer pointers
+* Similarly, LOG_AUDIO_STATE() is called by onStateChange whenever audio is
+* turned on or off, and writes this notification to the FIFO.
 *
 * 2) reading the data from shared memory
 * Thread::threadloop()
@@ -51,6 +53,7 @@
 * NBLog::MergeThread::threadLoop()
 *     calls NBLog::Merger::merge
 * NBLog::Merger::merge
+*     Merges snapshots sorted by timestamp
 *     for each reader in vector of class NamedReader,
 *     callsNamedReader::reader()->getSnapshot
 *     TODO: check whether the rest of this function is relevant
@@ -59,11 +62,12 @@
 *     calls mFifoReader->obtain to find readable data
 *     sets snapshot.begin() and .end() iterators to boundaries of valid entries
 *     moves the fifo reader index to after the last entry read
-*     in this case, the buffer is in shared memory. in (3), the buffer is private
+*     in this case, the buffer is in shared memory. in (4), the buffer is private
 *
 * 3) reading the data from private buffer
 * MediaLogService::dump
-*     calls NBLog::Reader::dump(int) on instance of subclass mergeReader
+*     calls NBLog::Reader::dump(CONSOLE)
+*     The private buffer contains all logs for all readers in shared memory
 * NBLog::Reader::dump(int)
 *     calls getSnapshot on the current reader
 *     calls dump(int, size_t, Snapshot)
@@ -72,9 +76,10 @@
 *     (string, timestamp, etc...)
 *     In the case of EVENT_HISTOGRAM_ENTRY_TS, adds a list of timestamp sequences
 *     (histogram entry) to NBLog::mHists
-*     In the case of EVENT_HISTOGRAM_FLUSH, calls drawHistogram on each element in
-*     the list and erases it
-*     TODO: when do these events occur?
+*     TODO: add every HISTOGRAM_ENTRY_TS to two
+*     circular buffers: one short-term and one long-term (can add even longer-term
+*     structures in the future). When dump is called, print everything currently
+*     in the buffer.
 * NBLog::drawHistogram
 *     input: timestamp array
 *     buckets this to a histogram and prints
@@ -82,7 +87,7 @@
 */
 
 #define LOG_TAG "NBLog"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #include <algorithm>
 #include <climits>
@@ -102,6 +107,8 @@
 #include <new>
 #include <audio_utils/roundup.h>
 #include <media/nbaio/NBLog.h>
+#include <media/nbaio/PerformanceAnalysis.h>
+#include <media/nbaio/ReportPerformance.h>
 // #include <utils/CallStack.h> // used to print callstack
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -134,7 +141,7 @@
     switch (type) {
     case EVENT_START_FMT:
         return std::make_unique<FormatEntry>(FormatEntry(ptr));
-    case EVENT_HISTOGRAM_FLUSH:
+    case EVENT_AUDIO_STATE:
     case EVENT_HISTOGRAM_ENTRY_TS:
         return std::make_unique<HistogramEntry>(HistogramEntry(ptr));
     default:
@@ -513,7 +520,7 @@
     log(EVENT_HASH, &hash, sizeof(hash));
 }
 
-void NBLog::Writer::logHistTS(log_hash_t hash)
+void NBLog::Writer::logEventHistTs(Event event, log_hash_t hash)
 {
     if (!mEnabled) {
         return;
@@ -522,22 +529,7 @@
     data.hash = hash;
     data.ts = get_monotonic_ns();
     if (data.ts > 0) {
-        log(EVENT_HISTOGRAM_ENTRY_TS, &data, sizeof(data));
-    } else {
-        ALOGE("Failed to get timestamp");
-    }
-}
-
-void NBLog::Writer::logHistFlush(log_hash_t hash)
-{
-    if (!mEnabled) {
-        return;
-    }
-    HistTsEntry data;
-    data.hash = hash;
-    data.ts = get_monotonic_ns();
-    if (data.ts > 0) {
-        log(EVENT_HISTOGRAM_FLUSH, &data, sizeof(data));
+        log(event, &data, sizeof(data));
     } else {
         ALOGE("Failed to get timestamp");
     }
@@ -771,15 +763,15 @@
                                                            NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS};
 const std::set<NBLog::Event> NBLog::Reader::endingTypes   {NBLog::Event::EVENT_END_FMT,
                                                            NBLog::Event::EVENT_HISTOGRAM_ENTRY_TS,
-                                                           NBLog::Event::EVENT_HISTOGRAM_FLUSH};
+                                                           NBLog::Event::EVENT_AUDIO_STATE};
+
 NBLog::Reader::Reader(const void *shared, size_t size)
     : mShared((/*const*/ Shared *) shared), /*mIMemory*/
       mFd(-1), mIndent(0),
       mFifo(mShared != NULL ?
         new audio_utils_fifo(size, sizeof(uint8_t),
             mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
-      mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL),
-      findGlitch(false)
+      mFifoReader(mFifo != NULL ? new audio_utils_fifo_reader(*mFifo) : NULL)
 {
 }
 
@@ -795,39 +787,6 @@
     delete mFifo;
 }
 
-inline static int deltaMs(int64_t ns1, int64_t ns2) {
-    return (ns2 - ns1) / (1000 * 1000);
-}
-
-// Produces a log warning if the timing of recent buffer periods caused a glitch
-// Computes sum of running window of three buffer periods
-// Checks whether the buffer periods leave enough CPU time for the next one
-// e.g. if a buffer period is expected to be 4 ms and a buffer requires 3 ms of CPU time,
-// here are some glitch cases:
-// 4 + 4 + 6 ; 5 + 4 + 5; 2 + 2 + 10
-// TODO: develop this code to track changes in histogram distribution in addition
-// to / instead of glitches
-void NBLog::Reader::alertIfGlitch(const std::vector<int64_t> &samples) {
-    //TODO: measure kPeriodLen and kRatio from the data as they may change.
-    static const int kPeriodLen = 4; // current period length is ideally 4 ms
-    static const double kRatio = 0.75; // estimate of CPU time as ratio of period length
-    // DAC processing time for 4 ms buffer
-    static const int kPeriodTime = static_cast<int>(round(kPeriodLen * kRatio));
-    static const int kNumBuff = 3; // number of buffers considered in local history
-    std::deque<int> periods(kNumBuff, kPeriodLen);
-    for (size_t i = 2; i < samples.size(); ++i) { // skip first time entry
-        periods.push_front(deltaMs(samples[i - 1], samples[i]));
-        periods.pop_back();
-        // TODO: check that all glitch cases are covered
-        if (std::accumulate(periods.begin(), periods.end(), 0) > kNumBuff * kPeriodLen +
-            kPeriodLen - kPeriodTime) {
-                ALOGW("A glitch occurred");
-                periods.assign(kNumBuff, kPeriodLen);
-        }
-    }
-    return;
-}
-
 const uint8_t *NBLog::Reader::findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
                                             const std::set<Event> &types) {
     while (back + Entry::kPreviousLengthOffset >= front) {
@@ -911,61 +870,17 @@
 
 }
 
-// writes sample deltas to file, either truncating or appending
-inline void writeHistToFile(const std::vector<int64_t> &samples, bool append) {
-    // name of file on audioserver
-    static const char* const kName = (char *)"/data/misc/audioserver/sample_results.txt";
-    // stores deltas between the samples
-    std::vector<int64_t> intervals;
-    for (size_t i = 1; i < samples.size(); ++i) {
-        intervals.push_back(deltaMs(samples[i - 1], samples[i]));
-    }
-    if (intervals.empty()) return;
-    // Deletes maximum value in a histogram. Temp quick fix.
-    // FIXME: need to find root cause of approx. 35th element from the end
-    // consistently being an outlier in the first histogram of a flush
-    // ALOGW("%" PRId64 "before", (int64_t) *(std::max_element(intervals.begin(), intervals.end())));
-    intervals.erase(std::max_element(intervals.begin(), intervals.end()));
-    // ALOGW("%" PRId64 "after", (int64_t) *(std::max_element(intervals.begin(), intervals.end())));
-    std::ofstream ofs;
-    ofs.open(kName, append ? std::ios::app : std::ios::trunc);
-    if (!ofs) {
-        ALOGW("couldn't open file %s", kName);
-        return;
-    }
-    for (size_t i = 0; i < intervals.size(); ++i) {
-        ofs << intervals[i] << "\n";
-    }
-    ofs.close();
-}
-
+// TODO: move this to PerformanceAnalysis
+// TODO: make call to dump periodic so that data in shared FIFO does not get overwritten
 void NBLog::Reader::dump(int fd, size_t indent, NBLog::Reader::Snapshot &snapshot)
 {
-  //  CallStack cs(LOG_TAG);
-#if 0
-    struct timespec ts;
-    time_t maxSec = -1;
-    while (entry - start >= (int) Entry::kOverhead) {
-        if (prevEntry - start < 0 || !prevEntry.hasConsistentLength()) {
-            break;
-        }
-        if (prevEntry->type == EVENT_TIMESTAMP) {
-            if (prevEntry->length != sizeof(struct timespec)) {
-                // corrupt
-                break;
-            }
-            prevEntry.copyData((uint8_t*) &ts);
-            if (ts.tv_sec > maxSec) {
-                maxSec = ts.tv_sec;
-            }
-        }
-        --entry;
-        --prevEntry;
-    }
-#endif
     mFd = fd;
     mIndent = indent;
     String8 timestamp, body;
+    // FIXME: this is not thread safe
+    // TODO: need a separate instance of performanceAnalysis for each thread
+    // used to store data and to call analysis functions
+    static ReportPerformance::PerformanceAnalysis performanceAnalysis;
     size_t lost = snapshot.lost() + (snapshot.begin() - EntryIterator(snapshot.data()));
     if (lost > 0) {
         body.appendFormat("warning: lost %zu bytes worth of events", lost);
@@ -973,85 +888,9 @@
         //      log to push it out.  Consider keeping the timestamp/body between calls to copyEntryDataAt().
         dumpLine(timestamp, body);
     }
-#if 0
-    size_t width = 1;
-    while (maxSec >= 10) {
-        ++width;
-        maxSec /= 10;
-    }
-    if (maxSec >= 0) {
-        timestamp.appendFormat("[%*s]", (int) width + 4, "");
-    }
-    bool deferredTimestamp = false;
-#endif
 
     for (auto entry = snapshot.begin(); entry != snapshot.end();) {
         switch (entry->type) {
-#if 0
-        case EVENT_STRING:
-            body.appendFormat("%.*s", (int) entry.length(), entry.data());
-            break;
-        case EVENT_TIMESTAMP: {
-            // already checked that length == sizeof(struct timespec);
-            entry.copyData((const uint8_t*) &ts);
-            long prevNsec = ts.tv_nsec;
-            long deltaMin = LONG_MAX;
-            long deltaMax = -1;
-            long deltaTotal = 0;
-            auto aux(entry);
-            for (;;) {
-                ++aux;
-                if (end - aux >= 0 || aux.type() != EVENT_TIMESTAMP) {
-                    break;
-                }
-                struct timespec tsNext;
-                aux.copyData((const uint8_t*) &tsNext);
-                if (tsNext.tv_sec != ts.tv_sec) {
-                    break;
-                }
-                long delta = tsNext.tv_nsec - prevNsec;
-                if (delta < 0) {
-                    break;
-                }
-                if (delta < deltaMin) {
-                    deltaMin = delta;
-                }
-                if (delta > deltaMax) {
-                    deltaMax = delta;
-                }
-                deltaTotal += delta;
-                prevNsec = tsNext.tv_nsec;
-            }
-            size_t n = (aux - entry) / (sizeof(struct timespec) + 3 /*Entry::kOverhead?*/);
-            if (deferredTimestamp) {
-                dumpLine(timestamp, body);
-                deferredTimestamp = false;
-            }
-            timestamp.clear();
-            if (n >= kSquashTimestamp) {
-                timestamp.appendFormat("[%d.%03d to .%.03d by .%.03d to .%.03d]",
-                        (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
-                        (int) ((ts.tv_nsec + deltaTotal) / 1000000),
-                        (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
-                entry = aux;
-                // advance = 0;
-                break;
-            }
-            timestamp.appendFormat("[%d.%03d]", (int) ts.tv_sec,
-                    (int) (ts.tv_nsec / 1000000));
-            deferredTimestamp = true;
-            }
-            break;
-        case EVENT_INTEGER:
-            appendInt(&body, entry.data());
-            break;
-        case EVENT_FLOAT:
-            appendFloat(&body, entry.data());
-            break;
-        case EVENT_PID:
-            appendPID(&body, entry.data(), entry.length());
-            break;
-#endif
         case EVENT_START_FMT:
             entry = handleFormat(FormatEntry(entry), &timestamp, &body);
             break;
@@ -1063,40 +902,12 @@
             memcpy(&hash, &(data->hash), sizeof(hash));
             int64_t ts;
             memcpy(&ts, &data->ts, sizeof(ts));
-            const std::pair<log_hash_t, int> key(hash, data->author);
-            // TODO might want to filter excessively high outliers, which are usually caused
-            // by the thread being inactive.
-            mHists[key].push_back(ts);
+            performanceAnalysis.logTsEntry(ts);
             ++entry;
             break;
         }
-        // draws histograms stored in global Reader::mHists and erases them
-        case EVENT_HISTOGRAM_FLUSH: {
-            HistogramEntry histEntry(entry);
-            // Log timestamp
-            // Timestamp of call to drawHistogram, not when audio was generated
-            const int64_t ts = histEntry.timestamp();
-            timestamp.clear();
-            timestamp.appendFormat("[%d.%03d]", (int) (ts / (1000 * 1000 * 1000)),
-                            (int) ((ts / (1000 * 1000)) % 1000));
-            // Log histograms
-            setFindGlitch(true);
-            body.appendFormat("Histogram flush - ");
-            handleAuthor(histEntry, &body);
-            for (auto hist = mHists.begin(); hist != mHists.end();) {
-                if (hist->first.second == histEntry.author()) {
-                    body.appendFormat("%X", (int)hist->first.first);
-                    if (findGlitch) {
-                        alertIfGlitch(hist->second);
-                    }
-                    // set file to empty and write data for all histograms in this set
-                    writeHistToFile(hist->second, hist != mHists.begin());
-                    drawHistogram(&body, hist->second, true, indent);
-                    hist = mHists.erase(hist);
-                } else {
-                    ++hist;
-                }
-            }
+        case EVENT_AUDIO_STATE: {
+            performanceAnalysis.handleStateChange();
             ++entry;
             break;
         }
@@ -1110,10 +921,10 @@
             ++entry;
             break;
         }
-
-        if (!body.isEmpty()) {
-            dumpLine(timestamp, body);
-        }
+    }
+    performanceAnalysis.reportPerformance(&body);
+    if (!body.isEmpty()) {
+        dumpLine(timestamp, body);
     }
 }
 
@@ -1139,16 +950,6 @@
     return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
 }
 
-void NBLog::Reader::setFindGlitch(bool s)
-{
-    findGlitch = s;
-}
-
-bool NBLog::Reader::isFindGlitch() const
-{
-    return findGlitch;
-}
-
 // ---------------------------------------------------------------------------
 
 void NBLog::appendTimestamp(String8 *body, const void *data) {
@@ -1283,126 +1084,6 @@
     return arg;
 }
 
-static int widthOf(int x) {
-    int width = 0;
-    while (x > 0) {
-        ++width;
-        x /= 10;
-    }
-    return width;
-}
-
-static std::map<int, int> buildBuckets(const std::vector<int64_t> &samples) {
-    // TODO allow buckets of variable resolution
-    std::map<int, int> buckets;
-    for (size_t i = 1; i < samples.size(); ++i) {
-        ++buckets[deltaMs(samples[i - 1], samples[i])];
-    }
-    return buckets;
-}
-
-static inline uint32_t log2(uint32_t x) {
-    // This works for x > 0
-    return 31 - __builtin_clz(x);
-}
-
-// TODO put this function in separate file. Make it return a std::string instead of modifying body
-/*
-Example output:
-[54.234] Histogram flush - AudioOut_D:
-Histogram 33640BF1
-            [ 1][ 1][ 1][ 3][54][69][ 1][ 2][ 1]
-        64|                      []
-        32|                  []  []
-        16|                  []  []
-         8|                  []  []
-         4|                  []  []
-         2|______________[]__[]__[]______[]____
-              4   5   6   8   9  10  11  13  15
-Notice that all values that fall in the same row have the same height (65 and 127 are displayed
-identically). That's why exact counts are added at the top.
-*/
-void NBLog::Reader::drawHistogram(String8 *body,
-                                  const std::vector<int64_t> &samples,
-                                  bool logScale,
-                                  int indent,
-                                  int maxHeight) {
-    // this avoids some corner cases
-    if (samples.size() <= 1) {
-        return;
-    }
-    // temp code for debugging the outlier timestamp
-    const int kMaxMs = 100;
-    for (size_t i = 1; i < samples.size()-1; ++i) {
-        const int currDelta = deltaMs(samples[i - 1], samples[i]);
-        if (currDelta > kMaxMs) {
-            body->appendFormat("\nlocation: %zu, size: %zu, pos from end: %zu, %d\t", i,
-                           samples.size(), samples.size() - i, currDelta);
-        }
-    }
-    // FIXME: as can be seen when printing the values, the outlier timestamps typically occur
-    // in the first histogram 35 to 38 indices from the end (most often 35).
-    // TODO: build histogram buckets earlier and discard timestamps to save memory
-    std::map<int, int> buckets = buildBuckets(samples);
-    // TODO consider changing all ints to uint32_t or uint64_t
-
-    // underscores and spaces length corresponds to maximum width of histogram
-    static const int kLen = 40;
-    std::string underscores(kLen, '-');
-    std::string spaces(kLen, ' ');
-
-    auto it = buckets.begin();
-    int maxDelta = it->first;
-    int maxCount = it->second;
-    // Compute maximum values
-    while (++it != buckets.end()) {
-        if (it->first > maxDelta) {
-            maxDelta = it->first;
-        }
-        if (it->second > maxCount) {
-            maxCount = it->second;
-        }
-    }
-    int height = logScale ? log2(maxCount) + 1 : maxCount; // maxCount > 0, safe to call log2
-    const int leftPadding = widthOf(logScale ? pow(2, height) : maxCount);
-    const int colWidth = std::max(std::max(widthOf(maxDelta) + 1, 3), leftPadding + 2);
-    int scalingFactor = 1;
-    // scale data if it exceeds maximum height
-    if (height > maxHeight) {
-        scalingFactor = (height + maxHeight) / maxHeight;
-        height /= scalingFactor;
-    }
-    body->appendFormat("\n%*s", leftPadding + 11, "Occurrences");
-    // write histogram label line with bucket values
-    body->appendFormat("\n%*s", indent, " ");
-    body->appendFormat("%*s", leftPadding, " ");
-    for (auto const &x : buckets) {
-        body->appendFormat("%*d", colWidth, x.second);
-    }
-    // write histogram ascii art
-    body->appendFormat("\n%*s", indent, " ");
-    for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
-        const int value = logScale ? (1 << row) : row;
-        body->appendFormat("%.*s", leftPadding, spaces.c_str());
-        for (auto const &x : buckets) {
-          body->appendFormat("%.*s%s", colWidth - 1, spaces.c_str(), x.second < value ? " " : "|");
-        }
-        body->appendFormat("\n%*s", indent, " ");
-    }
-    // print x-axis
-    const int columns = static_cast<int>(buckets.size());
-    body->appendFormat("%*c", leftPadding, ' ');
-    body->appendFormat("%.*s", (columns + 1) * colWidth, underscores.c_str());
-    body->appendFormat("\n%*s", indent, " ");
-
-    // write footer with bucket labels
-    body->appendFormat("%*s", leftPadding, " ");
-    for (auto const &x : buckets) {
-        body->appendFormat("%*d", colWidth, x.first);
-    }
-    body->appendFormat("%.*s%s", colWidth, spaces.c_str(), "ms\n");
-}
-
 NBLog::Merger::Merger(const void *shared, size_t size):
       mShared((Shared *) shared),
       mFifo(mShared != NULL ?
diff --git a/media/libnbaio/OWNERS b/media/libnbaio/OWNERS
new file mode 100644
index 0000000..f9cb567
--- /dev/null
+++ b/media/libnbaio/OWNERS
@@ -0,0 +1 @@
+gkasten@google.com
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnbaio/PerformanceAnalysis.cpp
new file mode 100644
index 0000000..fb3bddc
--- /dev/null
+++ b/media/libnbaio/PerformanceAnalysis.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#define LOG_TAG "PerformanceAnalysis"
+// #define LOG_NDEBUG 0
+
+#include <algorithm>
+#include <climits>
+#include <deque>
+#include <iostream>
+#include <math.h>
+#include <numeric>
+#include <vector>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <time.h>
+#include <new>
+#include <audio_utils/roundup.h>
+#include <media/nbaio/NBLog.h>
+#include <media/nbaio/PerformanceAnalysis.h>
+#include <media/nbaio/ReportPerformance.h>
+// #include <utils/CallStack.h> // used to print callstack
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <queue>
+#include <utility>
+
+namespace android {
+
+namespace ReportPerformance {
+
+PerformanceAnalysis::PerformanceAnalysis() {
+    // These variables will be (FIXME) learned from the data
+    kPeriodMs = 4; // typical buffer period (mode)
+    // average number of Ms spent processing buffer
+    kPeriodMsCPU = static_cast<int>(kPeriodMs * kRatio);
+}
+
+// converts a time series into a map. key: buffer period length. value: count
+static std::map<int, int> buildBuckets(const std::vector<int64_t> &samples) {
+    // TODO allow buckets of variable resolution
+    std::map<int, int> buckets;
+    for (size_t i = 1; i < samples.size(); ++i) {
+        ++buckets[deltaMs(samples[i - 1], samples[i])];
+    }
+    return buckets;
+}
+
+static int widthOf(int x) {
+    int width = 0;
+    while (x > 0) {
+        ++width;
+        x /= 10;
+    }
+    return width;
+}
+
+// Given a series of audio processing wakeup timestamps,
+// buckets the time intervals into a histogram, searches for
+// outliers, analyzes the outlier series for unexpectedly
+// small or large values and stores these as peaks, and flushes
+// the timestamp series from memory.
+void PerformanceAnalysis::processAndFlushTimeStampSeries() {
+    // 1) analyze the series to store all outliers and their exact timestamps:
+    storeOutlierData(mTimeStampSeries);
+
+    // 2) detect peaks in the outlier series
+    detectPeaks();
+
+    // 3) compute its histogram, append to mRecentHists and clear the time series
+    mRecentHists.emplace_back(static_cast<timestamp>(mTimeStampSeries[0]),
+                              buildBuckets(mTimeStampSeries));
+    // do not let mRecentHists exceed capacity
+    // ALOGD("mRecentHists size: %d", static_cast<int>(mRecentHists.size()));
+    if (mRecentHists.size() >= kRecentHistsCapacity) {
+        //  ALOGD("popped back mRecentHists");
+        mRecentHists.pop_front();
+    }
+    mTimeStampSeries.clear();
+}
+
+// forces short-term histogram storage to avoid adding idle audio time interval
+// to buffer period data
+void PerformanceAnalysis::handleStateChange() {
+    ALOGD("handleStateChange");
+    processAndFlushTimeStampSeries();
+    return;
+}
+
+// Takes a single buffer period timestamp entry information and stores it in a
+// temporary series of timestamps. Once the series is full, the data is analyzed,
+// stored, and emptied.
+void PerformanceAnalysis::logTsEntry(int64_t ts) {
+    // TODO might want to filter excessively high outliers, which are usually caused
+    // by the thread being inactive.
+    // Store time series data for each reader in order to bucket it once there
+    // is enough data. Then, write to recentHists as a histogram.
+    mTimeStampSeries.push_back(ts);
+    // if length of the time series has reached kShortHistSize samples,
+    // analyze the data and flush the timestamp series from memory
+    if (mTimeStampSeries.size() >= kShortHistSize) {
+        processAndFlushTimeStampSeries();
+    }
+}
+
+// When the short-term histogram array mRecentHists has reached capacity,
+// merge histograms for data compression and store them in mLongTermHists
+// clears mRecentHists
+// TODO: have logTsEntry write directly to mLongTermHists, discard mRecentHists,
+// start a new histogram when a peak occurs
+void PerformanceAnalysis::processAndFlushRecentHists() {
+
+    // Buckets is used to aggregate short-term histograms.
+    Histogram buckets;
+    timestamp startingTs = mRecentHists[0].first;
+
+    for (const auto &shortHist: mRecentHists) {
+        // If the time between starting and ending timestamps has reached the maximum,
+        // add the current histogram (buckets) to the long-term histogram buffer,
+        // clear buckets, and start a new long-term histogram aggregation process.
+        if (deltaMs(startingTs, shortHist.first) >= kMaxHistTimespanMs) {
+            mLongTermHists.emplace_back(startingTs, std::move(buckets));
+            buckets.clear();
+            startingTs = shortHist.first;
+            // When memory is full, delete oldest histogram
+            // TODO use a circular buffer
+            if (mLongTermHists.size() >= kLongTermHistsCapacity) {
+                mLongTermHists.pop_front();
+            }
+        }
+
+        // add current histogram to buckets
+        for (const auto &countPair : shortHist.second) {
+            buckets[countPair.first] += countPair.second;
+        }
+    }
+    mRecentHists.clear();
+    // TODO: decide when/where to call writeToFile
+    // TODO: add a thread-specific extension to the file name
+    static const char* const kName = (const char *) "/data/misc/audioserver/sample_results.txt";
+    writeToFile(mOutlierData, mLongTermHists, kName, false);
+}
+
+// Given a series of outlier intervals (mOutlier data),
+// looks for changes in distribution (peaks), which can be either positive or negative.
+// The function sets the mean to the starting value and sigma to 0, and updates
+// them as long as no peak is detected. When a value is more than 'threshold'
+// standard deviations from the mean, a peak is detected and the mean and sigma
+// are set to the peak value and 0.
+void PerformanceAnalysis::detectPeaks() {
+    if (mOutlierData.empty()) {
+        return;
+    }
+
+    // compute mean of the distribution. Used to check whether a value is large
+    const double kTypicalDiff = std::accumulate(
+        mOutlierData.begin(), mOutlierData.end(), 0,
+        [](auto &a, auto &b){return a + b.first;}) / mOutlierData.size();
+    // ALOGD("typicalDiff %f", kTypicalDiff);
+
+    // iterator at the beginning of a sequence, or updated to the most recent peak
+    std::deque<std::pair<uint64_t, uint64_t>>::iterator start = mOutlierData.begin();
+    // the mean and standard deviation are updated every time a peak is detected
+    // initialize first time. The mean from the previous sequence is stored
+    // for the next sequence. Here, they are initialized for the first time.
+    if (mPeakDetectorMean < 0) {
+        mPeakDetectorMean = static_cast<double>(start->first);
+        mPeakDetectorSd = 0;
+    }
+    auto sqr = [](auto x){ return x * x; };
+    for (auto it = mOutlierData.begin(); it != mOutlierData.end(); ++it) {
+        // no surprise occurred:
+        // the new element is a small number of standard deviations from the mean
+        if ((fabs(it->first - mPeakDetectorMean) < kStddevThreshold * mPeakDetectorSd) ||
+             // or: right after peak has been detected, the delta is smaller than average
+            (mPeakDetectorSd == 0 && fabs(it->first - mPeakDetectorMean) < kTypicalDiff)) {
+            // update the mean and sd:
+            // count number of elements (distance between start interator and current)
+            const int kN = std::distance(start, it) + 1;
+            // usual formulas for mean and sd
+            mPeakDetectorMean = std::accumulate(start, it + 1, 0.0,
+                                   [](auto &a, auto &b){return a + b.first;}) / kN;
+            mPeakDetectorSd = sqrt(std::accumulate(start, it + 1, 0.0,
+                      [=](auto &a, auto &b){ return a + sqr(b.first - mPeakDetectorMean);})) /
+                      ((kN > 1)? kN - 1 : kN); // kN - 1: mean is correlated with variance
+        }
+        // surprising value: store peak timestamp and reset mean, sd, and start iterator
+        else {
+            mPeakTimestamps.emplace_back(it->second);
+            // TODO: remove pop_front once a circular buffer is in place
+            if (mPeakTimestamps.size() >= kPeakSeriesSize) {
+                mPeakTimestamps.pop_front();
+            }
+            mPeakDetectorMean = static_cast<double>(it->first);
+            mPeakDetectorSd = 0;
+            start = it;
+        }
+    }
+    return;
+}
+
+// Called by LogTsEntry. The input is a vector of timestamps.
+// Finds outliers and writes to mOutlierdata.
+// Each value in mOutlierdata consists of: <outlier timestamp, time elapsed since previous outlier>.
+// e.g. timestamps (ms) 1, 4, 5, 16, 18, 28 will produce pairs (4, 5), (13, 18).
+// This function is applied to the time series before it is converted into a histogram.
+void PerformanceAnalysis::storeOutlierData(const std::vector<int64_t> &timestamps) {
+    if (timestamps.size() < 1) {
+        return;
+    }
+    // first pass: need to initialize
+    if (mElapsed == 0) {
+        mPrevNs = timestamps[0];
+    }
+    for (const auto &ts: timestamps) {
+        const uint64_t diffMs = static_cast<uint64_t>(deltaMs(mPrevNs, ts));
+        if (diffMs >= static_cast<uint64_t>(kOutlierMs)) {
+            mOutlierData.emplace_back(mElapsed, static_cast<uint64_t>(mPrevNs));
+            // Remove oldest value if the vector is full
+            // TODO: remove pop_front once circular buffer is in place
+            // FIXME: make sure kShortHistSize is large enough that that data will never be lost
+            // before being written to file or to a FIFO
+            if (mOutlierData.size() >= kOutlierSeriesSize) {
+                mOutlierData.pop_front();
+            }
+            mElapsed = 0;
+        }
+        mElapsed += diffMs;
+        mPrevNs = ts;
+    }
+}
+
+
+// FIXME: delete this temporary test code, recycled for various new functions
+void PerformanceAnalysis::testFunction() {
+    // produces values (4: 5000000), (13: 18000000)
+    // ns timestamps of buffer periods
+    const std::vector<int64_t>kTempTestData = {1000000, 4000000, 5000000,
+                                               16000000, 18000000, 28000000};
+    PerformanceAnalysis::storeOutlierData(kTempTestData);
+    for (const auto &outlier: mOutlierData) {
+        ALOGE("PerformanceAnalysis test %lld: %lld",
+              static_cast<long long>(outlier.first), static_cast<long long>(outlier.second));
+    }
+    detectPeaks();
+}
+
+// TODO Make it return a std::string instead of modifying body --> is this still relevant?
+// TODO consider changing all ints to uint32_t or uint64_t
+// TODO: move this to ReportPerformance, probably make it a friend function of PerformanceAnalysis
+void PerformanceAnalysis::reportPerformance(String8 *body, int maxHeight) {
+    if (mRecentHists.size() < 1) {
+        ALOGD("reportPerformance: mRecentHists is empty");
+        return;
+    }
+    ALOGD("reportPerformance: hists size %d", static_cast<int>(mRecentHists.size()));
+    // TODO: more elaborate data analysis
+    std::map<int, int> buckets;
+    for (const auto &shortHist: mRecentHists) {
+        for (const auto &countPair : shortHist.second) {
+            buckets[countPair.first] += countPair.second;
+        }
+    }
+
+    // underscores and spaces length corresponds to maximum width of histogram
+    static const int kLen = 40;
+    std::string underscores(kLen, '_');
+    std::string spaces(kLen, ' ');
+
+    auto it = buckets.begin();
+    int maxDelta = it->first;
+    int maxCount = it->second;
+    // Compute maximum values
+    while (++it != buckets.end()) {
+        if (it->first > maxDelta) {
+            maxDelta = it->first;
+        }
+        if (it->second > maxCount) {
+            maxCount = it->second;
+        }
+    }
+    int height = log2(maxCount) + 1; // maxCount > 0, safe to call log2
+    const int leftPadding = widthOf(1 << height);
+    const int colWidth = std::max(std::max(widthOf(maxDelta) + 1, 3), leftPadding + 2);
+    int scalingFactor = 1;
+    // scale data if it exceeds maximum height
+    if (height > maxHeight) {
+        scalingFactor = (height + maxHeight) / maxHeight;
+        height /= scalingFactor;
+    }
+    body->appendFormat("\n%*s", leftPadding + 11, "Occurrences");
+    // write histogram label line with bucket values
+    body->appendFormat("\n%s", " ");
+    body->appendFormat("%*s", leftPadding, " ");
+    for (auto const &x : buckets) {
+        body->appendFormat("%*d", colWidth, x.second);
+    }
+    // write histogram ascii art
+    body->appendFormat("\n%s", " ");
+    for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
+        const int value = 1 << row;
+        body->appendFormat("%.*s", leftPadding, spaces.c_str());
+        for (auto const &x : buckets) {
+          body->appendFormat("%.*s%s", colWidth - 1, spaces.c_str(), x.second < value ? " " : "|");
+        }
+        body->appendFormat("\n%s", " ");
+    }
+    // print x-axis
+    const int columns = static_cast<int>(buckets.size());
+    body->appendFormat("%*c", leftPadding, ' ');
+    body->appendFormat("%.*s", (columns + 1) * colWidth, underscores.c_str());
+    body->appendFormat("\n%s", " ");
+
+    // write footer with bucket labels
+    body->appendFormat("%*s", leftPadding, " ");
+    for (auto const &x : buckets) {
+        body->appendFormat("%*d", colWidth, x.first);
+    }
+    body->appendFormat("%.*s%s", colWidth, spaces.c_str(), "ms\n");
+
+    // Now report glitches
+    body->appendFormat("\ntime elapsed between glitches and glitch timestamps\n");
+    for (const auto &outlier: mOutlierData) {
+        body->appendFormat("%lld: %lld\n", static_cast<long long>(outlier.first),
+                           static_cast<long long>(outlier.second));
+    }
+
+}
+
+
+// Produces a log warning if the timing of recent buffer periods caused a glitch
+// Computes sum of running window of three buffer periods
+// Checks whether the buffer periods leave enough CPU time for the next one
+// e.g. if a buffer period is expected to be 4 ms and a buffer requires 3 ms of CPU time,
+// here are some glitch cases:
+// 4 + 4 + 6 ; 5 + 4 + 5; 2 + 2 + 10
+// TODO: develop this code to track changes in histogram distribution in addition
+// to / instead of glitches.
+void PerformanceAnalysis::alertIfGlitch(const std::vector<int64_t> &samples) {
+    std::deque<int> periods(kNumBuff, kPeriodMs);
+    for (size_t i = 2; i < samples.size(); ++i) { // skip first time entry
+        periods.push_front(deltaMs(samples[i - 1], samples[i]));
+        periods.pop_back();
+        // TODO: check that all glitch cases are covered
+        if (std::accumulate(periods.begin(), periods.end(), 0) > kNumBuff * kPeriodMs +
+            kPeriodMs - kPeriodMsCPU) {
+                ALOGW("A glitch occurred");
+                periods.assign(kNumBuff, kPeriodMs);
+        }
+    }
+    return;
+}
+
+} // namespace ReportPerformance
+
+}   // namespace android
diff --git a/media/libnbaio/ReportPerformance.cpp b/media/libnbaio/ReportPerformance.cpp
new file mode 100644
index 0000000..dc50ada
--- /dev/null
+++ b/media/libnbaio/ReportPerformance.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ReportPerformance"
+
+#include <fstream>
+#include <iostream>
+#include <queue>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <utility>
+#include <media/nbaio/NBLog.h>
+#include <media/nbaio/PerformanceAnalysis.h>
+#include <media/nbaio/ReportPerformance.h>
+// #include <utils/CallStack.h> // used to print callstack
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+namespace android {
+
+namespace ReportPerformance {
+
+// Writes outlier intervals, timestamps, and histograms spanning long time intervals to a file.
+// TODO: format the data efficiently and write different types of data to different files
+void writeToFile(std::deque<std::pair<outlierInterval, timestamp>> &outlierData,
+                                    std::deque<std::pair<timestamp, Histogram>> &hists,
+                                    const char * kName,
+                                    bool append) {
+    ALOGD("writing performance data to file");
+    if (outlierData.empty() || hists.empty()) {
+        return;
+    }
+
+    std::ofstream ofs;
+    ofs.open(kName, append ? std::ios::app : std::ios::trunc);
+    if (!ofs.is_open()) {
+        ALOGW("couldn't open file %s", kName);
+        return;
+    }
+    ofs << "Outlier data: interval and timestamp\n";
+    for (const auto &outlier : outlierData) {
+        ofs << outlier.first << ": " << outlier.second << "\n";
+    }
+    ofs << "Histogram data\n";
+    for (const auto &hist : hists) {
+        ofs << "\ttimestamp\n";
+        ofs << hist.first << "\n";
+        ofs << "\tbuckets and counts\n";
+        for (const auto &bucket : hist.second) {
+            ofs << bucket.first << ": " << bucket.second << "\n";
+        }
+    }
+    ofs.close();
+}
+
+} // namespace ReportPerformance
+
+}   // namespace android
diff --git a/media/libnbaio/include/AudioBufferProviderSource.h b/media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
similarity index 98%
rename from media/libnbaio/include/AudioBufferProviderSource.h
rename to media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
index 4747dcf..71182bb 100644
--- a/media/libnbaio/include/AudioBufferProviderSource.h
+++ b/media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
@@ -19,8 +19,8 @@
 #ifndef ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
 #define ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
 
-#include "NBAIO.h"
 #include <media/AudioBufferProvider.h>
+#include <media/nbaio/NBAIO.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/AudioStreamInSource.h b/media/libnbaio/include/media/nbaio/AudioStreamInSource.h
similarity index 98%
rename from media/libnbaio/include/AudioStreamInSource.h
rename to media/libnbaio/include/media/nbaio/AudioStreamInSource.h
index 508e0fe..8a3ffbe 100644
--- a/media/libnbaio/include/AudioStreamInSource.h
+++ b/media/libnbaio/include/media/nbaio/AudioStreamInSource.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_AUDIO_STREAM_IN_SOURCE_H
 #define ANDROID_AUDIO_STREAM_IN_SOURCE_H
 
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/AudioStreamOutSink.h b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
similarity index 98%
rename from media/libnbaio/include/AudioStreamOutSink.h
rename to media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
index 56a2a38..348b4f8 100644
--- a/media/libnbaio/include/AudioStreamOutSink.h
+++ b/media/libnbaio/include/media/nbaio/AudioStreamOutSink.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_AUDIO_STREAM_OUT_SINK_H
 #define ANDROID_AUDIO_STREAM_OUT_SINK_H
 
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/LibsndfileSink.h b/media/libnbaio/include/media/nbaio/LibsndfileSink.h
similarity index 97%
rename from media/libnbaio/include/LibsndfileSink.h
rename to media/libnbaio/include/media/nbaio/LibsndfileSink.h
index 97a57e03..535e3f5 100644
--- a/media/libnbaio/include/LibsndfileSink.h
+++ b/media/libnbaio/include/media/nbaio/LibsndfileSink.h
@@ -17,7 +17,8 @@
 #ifndef ANDROID_AUDIO_LIBSNDFILE_SINK_H
 #define ANDROID_AUDIO_LIBSNDFILE_SINK_H
 
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
+
 #include "sndfile.h"
 
 // Implementation of NBAIO_Sink that wraps a libsndfile opened in SFM_WRITE mode
diff --git a/media/libnbaio/include/LibsndfileSource.h b/media/libnbaio/include/media/nbaio/LibsndfileSource.h
similarity index 97%
rename from media/libnbaio/include/LibsndfileSource.h
rename to media/libnbaio/include/media/nbaio/LibsndfileSource.h
index 4fbdb4b..bc6aa9d 100644
--- a/media/libnbaio/include/LibsndfileSource.h
+++ b/media/libnbaio/include/media/nbaio/LibsndfileSource.h
@@ -17,7 +17,8 @@
 #ifndef ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
 #define ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
 
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
+
 #include "sndfile.h"
 
 // Implementation of NBAIO_Source that wraps a libsndfile opened in SFM_READ mode
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/media/nbaio/NBLog.h
similarity index 95%
rename from media/libnbaio/include/NBLog.h
rename to media/libnbaio/include/media/nbaio/NBLog.h
index 785b9c2..3e48ee1 100644
--- a/media/libnbaio/include/NBLog.h
+++ b/media/libnbaio/include/media/nbaio/NBLog.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
 #include <utils/threads.h>
 
 #include <map>
+#include <deque>
 #include <set>
 #include <vector>
 
@@ -43,8 +44,6 @@
 class Writer;
 class Reader;
 
-private:
-
 enum Event : uint8_t {
     EVENT_RESERVED,
     EVENT_STRING,               // ASCII string, not NUL-terminated
@@ -59,12 +58,13 @@
     EVENT_HASH,                 // unique HASH of log origin, originates from hash of file name
                                 // and line number
     EVENT_HISTOGRAM_ENTRY_TS,   // single datum for timestamp histogram
-    EVENT_HISTOGRAM_FLUSH,      // show histogram on log
+    EVENT_AUDIO_STATE,          // audio on/off event: logged upon FastMixer::onStateChange() call
     EVENT_END_FMT,              // end of logFormat argument list
 
     EVENT_UPPER_BOUND,          // to check for invalid events
 };
 
+private:
 
 // ---------------------------------------------------------------------------
 // API for handling format entry operations
@@ -248,6 +248,8 @@
     int author;
 }; //TODO __attribute__((packed));
 
+using StateTsEntryWithAuthor = HistTsEntryWithAuthor;
+
 struct HistIntEntry {
     log_hash_t hash;
     int value;
@@ -341,8 +343,7 @@
     virtual void    logStart(const char *fmt);
     virtual void    logEnd();
     virtual void    logHash(log_hash_t hash);
-    virtual void    logHistTS(log_hash_t hash);
-    virtual void    logHistFlush(log_hash_t hash);
+    virtual void    logEventHistTs(Event event, log_hash_t hash);
 
     virtual bool    isEnabled() const;
 
@@ -407,6 +408,7 @@
 public:
 
     // A snapshot of a readers buffer
+    // This is raw data. No analysis has been done on it
     class Snapshot {
     public:
         Snapshot() : mData(NULL), mLost(0) {}
@@ -443,20 +445,17 @@
 
     virtual ~Reader();
 
-    void alertIfGlitch(const std::vector<int64_t> &samples);
-
     // get snapshot of readers fifo buffer, effectively consuming the buffer
     std::unique_ptr<Snapshot> getSnapshot();
     // dump a particular snapshot of the reader
+    // TODO: move dump to PerformanceAnalysis. Model/view/controller design
     void     dump(int fd, size_t indent, Snapshot & snap);
     // dump the current content of the reader's buffer (call getSnapshot() and previous dump())
     void     dump(int fd, size_t indent = 0);
     bool     isIMemory(const sp<IMemory>& iMemory) const;
-    // if findGlitch is true, log warning when buffer periods caused glitch
-    void     setFindGlitch(bool s);
-    bool     isFindGlitch() const;
 
 private:
+
     static const std::set<Event> startingTypes;
     static const std::set<Event> endingTypes;
     /*const*/ Shared* const mShared;    // raw pointer to shared memory, actually const but not
@@ -469,10 +468,6 @@
     audio_utils_fifo_reader * const mFifoReader;    // used to read from FIFO,
                                                     // non-NULL unless constructor fails
 
-    // each pair contains a sequence of timestamps (one histogram's worth)
-    // pair's log_hash_t is the hash of the source code location where the timestamp was taken
-    // pair's int points to the Reader that originated the entry
-    std::map<std::pair<log_hash_t, int>, std::vector<int64_t>> mHists;
     // TODO: it might be clearer, instead of a direct map from source location to vector of
     // timestamps, if we instead first mapped from source location to an object that
     // represented that location. And one_of its fields would be a vector of timestamps.
@@ -485,17 +480,12 @@
     // dummy method for handling absent author entry
     virtual void handleAuthor(const AbstractEntry& /*fmtEntry*/, String8* /*body*/) {}
 
-    static void drawHistogram(String8 *body, const std::vector<int64_t> &samples,
-                              bool logScale, int indent = 0, int maxHeight = 10);
-
     // Searches for the last entry of type <type> in the range [front, back)
     // back has to be entry-aligned. Returns nullptr if none enconuntered.
     static const uint8_t *findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,
                                          const std::set<Event> &types);
 
     static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps
-
-    bool findGlitch; // alert if a local buffer period sequence caused an audio glitch
 };
 
 // Wrapper for a reader with a name. Contains a pointer to the reader and a pointer to the name
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
new file mode 100644
index 0000000..b0dc148
--- /dev/null
+++ b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Non-blocking event logger intended for safe communication between processes via shared memory
+
+#ifndef ANDROID_MEDIA_PERFORMANCEANALYSIS_H
+#define ANDROID_MEDIA_PERFORMANCEANALYSIS_H
+
+#include <map>
+#include <deque>
+#include <vector>
+#include "NBLog.h"
+#include "ReportPerformance.h"
+
+namespace android {
+
+namespace ReportPerformance {
+
+class PerformanceAnalysis {
+    // This class stores and analyzes audio processing wakeup timestamps from NBLog
+    // FIXME: currently, all performance data is stored in deques. Need to add a mutex.
+    // FIXME: continue this way until analysis is done in a separate thread. Then, use
+    // the fifo writer utilities.
+public:
+
+    PerformanceAnalysis();
+
+    // Given a series of audio processing wakeup timestamps,
+    // compresses and and analyzes the data, and flushes
+    // the timestamp series from memory.
+    void processAndFlushTimeStampSeries();
+
+    // Called when an audio on/off event is read from the buffer,
+    // e.g. EVENT_AUDIO_STATE.
+    // calls flushTimeStampSeries on the data up to the event,
+    // effectively discarding the idle audio time interval
+    void handleStateChange();
+
+    // When the short-term histogram array mRecentHists has reached capacity,
+    // merges histograms for data compression and stores them in mLongTermHists
+    void processAndFlushRecentHists();
+
+    // Writes wakeup timestamp entry to log and runs analysis
+    // TODO: make this thread safe. Each thread should have its own instance
+    // of PerformanceAnalysis.
+    void logTsEntry(timestamp_raw ts);
+
+    // FIXME: make peakdetector and storeOutlierData a single function
+    // Input: mOutlierData. Looks at time elapsed between outliers
+    // finds significant changes in the distribution
+    // writes timestamps of significant changes to mPeakTimestamps
+    void detectPeaks();
+
+    // runs analysis on timestamp series before it is converted to a histogram
+    // finds outliers
+    // writes to mOutlierData <time elapsed since previous outlier, outlier timestamp>
+    void storeOutlierData(const std::vector<timestamp_raw> &timestamps);
+
+    // input: series of short histograms. Generates a string of analysis of the buffer periods
+    // TODO: WIP write more detailed analysis
+    // FIXME: move this data visualization to a separate class. Model/view/controller
+    void reportPerformance(String8 *body, int maxHeight = 10);
+
+    // TODO: delete this. temp for testing
+    void testFunction();
+
+    // This function used to detect glitches in a time series
+    // TODO incorporate this into the analysis (currently unused)
+    void alertIfGlitch(const std::vector<timestamp_raw> &samples);
+
+private:
+
+    // stores outlier analysis: <elapsed time between outliers in ms, outlier timestamp>
+    std::deque<std::pair<outlierInterval, timestamp>> mOutlierData;
+
+    // stores each timestamp at which a peak was detected
+    // a peak is a moment at which the average outlier interval changed significantly
+    std::deque<timestamp> mPeakTimestamps;
+
+    // TODO: turn these into circular buffers for better data flow
+    // FIFO of small histograms
+    // stores fixed-size short buffer period histograms with timestamp of first sample
+    std::deque<std::pair<timestamp, Histogram>> mRecentHists;
+
+    // FIFO of small histograms
+    // stores fixed-size long-term buffer period histograms with timestamp of first sample
+    std::deque<std::pair<timestamp, Histogram>> mLongTermHists;
+
+    // vector of timestamps, collected from NBLog for a (TODO) specific thread
+    // when a vector reaches its maximum size, the data is processed and flushed
+    std::vector<timestamp_raw> mTimeStampSeries;
+
+    static const int kMsPerSec = 1000;
+
+    // Parameters used when detecting outliers
+    // TODO: learn some of these from the data, delete unused ones
+    // FIXME: decide whether to make kPeriodMs static.
+    static const int kNumBuff = 3; // number of buffers considered in local history
+    int kPeriodMs; // current period length is ideally 4 ms
+    static const int kOutlierMs = 7; // values greater or equal to this cause glitches
+    // DAC processing time for 4 ms buffer
+    static constexpr double kRatio = 0.75; // estimate of CPU time as ratio of period length
+    int kPeriodMsCPU; // compute based on kPeriodLen and kRatio
+
+    // Peak detection: number of standard deviations from mean considered a significant change
+    static const int kStddevThreshold = 5;
+
+    // capacity allocated to data structures
+    // TODO: adjust all of these values
+    static const int kRecentHistsCapacity = 100; // number of short-term histograms stored in memory
+    static const int kShortHistSize = 50; // number of samples in a short-term histogram
+    static const int kOutlierSeriesSize = 100; // number of values stored in outlier array
+    static const int kPeakSeriesSize = 100; // number of values stored in peak array
+    static const int kLongTermHistsCapacity = 20; // number of long-term histogram stored in memory
+    // maximum elapsed time between first and last timestamp of a long-term histogram
+    static const int kMaxHistTimespanMs = 5 * kMsPerSec;
+
+    // these variables are stored in-class to ensure continuity while analyzing the timestamp
+    // series one short sequence at a time: the variables are not re-initialized every time.
+    // FIXME: create inner class for these variables and decide which other ones to add to it
+    double mPeakDetectorMean = -1;
+    double mPeakDetectorSd = -1;
+    // variables for storeOutlierData
+    uint64_t mElapsed = 0;
+    int64_t mPrevNs = -1;
+
+};
+
+} // namespace ReportPerformance
+
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_PERFORMANCEANALYSIS_H
diff --git a/media/libnbaio/include/Pipe.h b/media/libnbaio/include/media/nbaio/Pipe.h
similarity index 98%
rename from media/libnbaio/include/Pipe.h
rename to media/libnbaio/include/media/nbaio/Pipe.h
index 58b9750..0431976 100644
--- a/media/libnbaio/include/Pipe.h
+++ b/media/libnbaio/include/media/nbaio/Pipe.h
@@ -18,7 +18,7 @@
 #define ANDROID_AUDIO_PIPE_H
 
 #include <audio_utils/fifo.h>
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/PipeReader.h b/media/libnbaio/include/media/nbaio/PipeReader.h
similarity index 100%
rename from media/libnbaio/include/PipeReader.h
rename to media/libnbaio/include/media/nbaio/PipeReader.h
diff --git a/media/libnbaio/include/media/nbaio/ReportPerformance.h b/media/libnbaio/include/media/nbaio/ReportPerformance.h
new file mode 100644
index 0000000..27d2810
--- /dev/null
+++ b/media/libnbaio/include/media/nbaio/ReportPerformance.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_REPORTPERFORMANCE_H
+#define ANDROID_MEDIA_REPORTPERFORMANCE_H
+
+#include <deque>
+#include <map>
+#include <vector>
+
+namespace android {
+
+// This class is used by reportPerformance function
+// TODO move reportPerformance function to ReportPerformance.cpp
+class String8;
+
+namespace ReportPerformance {
+
+// stores a histogram: key: observed buffer period. value: count
+// TODO: unsigned, unsigned
+using Histogram = std::map<int, int>;
+
+using outlierInterval = uint64_t;
+// int64_t timestamps are converted to uint64_t in PerformanceAnalysis::storeOutlierData,
+// and all analysis functions use uint64_t.
+using timestamp = uint64_t;
+using timestamp_raw = int64_t;
+
+// FIXME: decide whether to use 64 or 32 bits
+// TODO: the code has a mix of typedef and using. Standardize to one or the other.
+typedef uint64_t log_hash_t;
+
+static inline int deltaMs(int64_t ns1, int64_t ns2) {
+    return (ns2 - ns1) / (1000 * 1000);
+}
+
+static inline uint32_t log2(uint32_t x) {
+    // This works for x > 0
+    return 31 - __builtin_clz(x);
+}
+
+// Writes outlier intervals, timestamps, and histograms spanning long time
+// intervals to a file.
+void writeToFile(std::deque<std::pair<outlierInterval, timestamp>> &outlierData,
+                 std::deque<std::pair<timestamp, Histogram>> &hists,
+                 const char * kName,
+                 bool append);
+
+} // namespace ReportPerformance
+
+}   // namespace android
+
+#endif  // ANDROID_MEDIA_REPORTPERFORMANCE_H
diff --git a/media/libnbaio/include/SourceAudioBufferProvider.h b/media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
similarity index 98%
rename from media/libnbaio/include/SourceAudioBufferProvider.h
rename to media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
index ae49903..cc2d019 100644
--- a/media/libnbaio/include/SourceAudioBufferProvider.h
+++ b/media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
@@ -19,7 +19,7 @@
 #ifndef ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
 #define ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
 
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
 #include <media/ExtendedAudioBufferProvider.h>
 
 namespace android {
diff --git a/media/libnbaio/include/MonoPipe.h b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
similarity index 98%
rename from media/libnbaio/include/MonoPipe.h
rename to media/libnbaio/include_mono/media/nbaio/MonoPipe.h
index 60ae92e..c51d0fe 100644
--- a/media/libnbaio/include/MonoPipe.h
+++ b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
@@ -20,7 +20,7 @@
 #include <time.h>
 #include <audio_utils/fifo.h>
 #include <media/SingleStateQueue.h>
-#include "NBAIO.h"
+#include <media/nbaio/NBAIO.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/MonoPipeReader.h b/media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
similarity index 100%
rename from media/libnbaio/include/MonoPipeReader.h
rename to media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
diff --git a/media/libnbaio/include/NBAIO.h b/media/libnbaio/include_mono/media/nbaio/NBAIO.h
similarity index 100%
rename from media/libnbaio/include/NBAIO.h
rename to media/libnbaio/include_mono/media/nbaio/NBAIO.h
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 1f98e8d..d4ec30d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -49,18 +49,18 @@
 
 #include <hidlmemory/mapping.h>
 
-#include <OMX_AudioExt.h>
-#include <OMX_VideoExt.h>
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-#include <OMX_AsString.h>
+#include <media/openmax/OMX_AudioExt.h>
+#include <media/openmax/OMX_VideoExt.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/openmax/OMX_AsString.h>
 
 #include "include/avc_utils.h"
 #include "include/ACodecBufferChannel.h"
 #include "include/DataConverter.h"
 #include "include/SecureBuffer.h"
 #include "include/SharedMemoryBuffer.h"
-#include "omx/OMXUtils.h"
+#include <media/stagefright/omx/OMXUtils.h>
 
 #include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
@@ -4843,9 +4843,9 @@
                             rect.nTop < 0 ||
                             rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
                             rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
-                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
+                            ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
                                     rect.nLeft, rect.nTop,
-                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
+                                    rect.nWidth, rect.nHeight,
                                     videoDef->nFrameWidth, videoDef->nFrameHeight);
                             return BAD_VALUE;
                         }
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index 0d9696f..3c7ae3e 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -20,7 +20,7 @@
 
 #include <numeric>
 
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
 #include <binder/MemoryDealer.h>
 #include <media/openmax/OMX_Core.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -34,8 +34,11 @@
 #include "include/SharedMemoryBuffer.h"
 
 namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
 using BufferInfo = ACodecBufferChannel::BufferInfo;
 using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
 
@@ -114,74 +117,97 @@
         return -ENOENT;
     }
 
-    ICrypto::DestinationBuffer destination;
+    native_handle_t *secureHandle = NULL;
     if (secure) {
         sp<SecureBuffer> secureData =
                 static_cast<SecureBuffer *>(it->mCodecBuffer.get());
-        destination.mType = secureData->getDestinationType();
-        if (destination.mType != ICrypto::kDestinationTypeNativeHandle) {
+        if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
             return BAD_VALUE;
         }
-        destination.mHandle =
-                static_cast<native_handle_t *>(secureData->getDestinationPointer());
-    } else {
-        destination.mType = ICrypto::kDestinationTypeSharedMemory;
-        destination.mSharedMemory = mDecryptDestination;
+        secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
     }
-
-    ICrypto::SourceBuffer source;
-    source.mSharedMemory = it->mSharedEncryptedBuffer;
-    source.mHeapSeqNum = mHeapSeqNum;
-
     ssize_t result = -1;
     if (mCrypto != NULL) {
+        ICrypto::DestinationBuffer destination;
+        if (secure) {
+            destination.mType = ICrypto::kDestinationTypeNativeHandle;
+            destination.mHandle = secureHandle;
+        } else {
+            destination.mType = ICrypto::kDestinationTypeSharedMemory;
+            destination.mSharedMemory = mDecryptDestination;
+        }
+
+        ICrypto::SourceBuffer source;
+        source.mSharedMemory = it->mSharedEncryptedBuffer;
+        source.mHeapSeqNum = mHeapSeqNum;
+
         result = mCrypto->decrypt(key, iv, mode, pattern,
                 source, it->mClientBuffer->offset(),
                 subSamples, numSubSamples, destination, errorDetailMsg);
-    } else {
-        DescrambleInfo descrambleInfo;
-        descrambleInfo.dstType = destination.mType ==
-                ICrypto::kDestinationTypeSharedMemory ?
-                DescrambleInfo::kDestinationTypeVmPointer :
-                DescrambleInfo::kDestinationTypeNativeHandle;
-        descrambleInfo.scramblingControl = key != NULL ?
-                (DescramblerPlugin::ScramblingControl)key[0] :
-                DescramblerPlugin::kScrambling_Unscrambled;
-        descrambleInfo.numSubSamples = numSubSamples;
-        descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples;
-        descrambleInfo.srcMem = it->mSharedEncryptedBuffer;
-        descrambleInfo.srcOffset = 0;
-        descrambleInfo.dstPtr = NULL;
-        descrambleInfo.dstOffset = 0;
-
-        int32_t descrambleResult = -1;
-        Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult);
-
-        if (status.isOk()) {
-            result = descrambleResult;
-        }
 
         if (result < 0) {
-            ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd",
-                    status.exceptionCode(), status.transactionError(), result);
-        } else {
-            ALOGV("descramble succeeded, result=%zd", result);
+            return result;
         }
 
-        if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) {
-            memcpy(destination.mSharedMemory->pointer(),
+        if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+            memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
+        }
+    } else {
+        // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
+        // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
+        hidl_vec<SubSample> hidlSubSamples;
+        hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
+
+        ssize_t offset;
+        size_t size;
+        it->mSharedEncryptedBuffer->getMemory(&offset, &size);
+        hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
+                .heapBase = mHidlMemory,
+                .offset = (uint64_t) offset,
+                .size = size
+        };
+
+        DestinationBuffer dstBuffer;
+        if (secure) {
+            dstBuffer.type = BufferType::NATIVE_HANDLE;
+            dstBuffer.secureMemory = hidl_handle(secureHandle);
+        } else {
+            dstBuffer.type = BufferType::SHARED_MEMORY;
+            dstBuffer.nonsecureMemory = srcBuffer;
+        }
+
+        Status status = Status::OK;
+        hidl_string detailedError;
+
+        auto returnVoid = mDescrambler->descramble(
+                key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
+                hidlSubSamples,
+                srcBuffer,
+                0,
+                dstBuffer,
+                0,
+                [&status, &result, &detailedError] (
+                        Status _status, uint32_t _bytesWritten,
+                        const hidl_string& _detailedError) {
+                    status = _status;
+                    result = (ssize_t)_bytesWritten;
+                    detailedError = _detailedError;
+                });
+
+        if (!returnVoid.isOk() || status != Status::OK || result < 0) {
+            ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
+                    returnVoid.description().c_str(), status, result);
+            return UNKNOWN_ERROR;
+        }
+
+        ALOGV("descramble succeeded, %zd bytes", result);
+
+        if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+            memcpy(it->mCodecBuffer->base(),
                     (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result);
         }
     }
 
-    if (result < 0) {
-        return result;
-    }
-
-    if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
-        memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
-    }
-
     it->mCodecBuffer->setRange(0, result);
 
     // Copy metadata from client to codec buffer.
@@ -275,10 +301,21 @@
         int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
         if (seqNum >= 0) {
             mHeapSeqNum = seqNum;
-            ALOGD("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
+            ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
         } else {
             mHeapSeqNum = -1;
-            ALOGD("setHeap failed, setting mHeapSeqNum=-1");
+            ALOGE("setHeap failed, setting mHeapSeqNum=-1");
+        }
+    } else if (mDescrambler != nullptr) {
+        sp<IMemoryHeap> heap = dealer->getMemoryHeap();
+        native_handle_t* nativeHandle = native_handle_create(1, 0);
+        if (nativeHandle != nullptr) {
+            int fd = heap->getHeapID();
+            nativeHandle->data[0] = fd;
+            mHidlMemory = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize());
+            ALOGV("created hidl_memory for descrambler");
+        } else {
+            ALOGE("failed to create hidl_memory for descrambler");
         }
     }
     return dealer;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 6cc1ace..348abf8 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -17,6 +17,7 @@
         "AudioPlayer.cpp",
         "AudioSource.cpp",
         "BufferImpl.cpp",
+        "CodecBase.cpp",
         "CallbackDataSource.cpp",
         "CameraSource.cpp",
         "CameraSourceTimeLapse.cpp",
@@ -29,6 +30,7 @@
         "FrameRenderTracker.cpp",
         "HTTPBase.cpp",
         "HevcUtils.cpp",
+        "ItemTable.cpp",
         "JPEGSource.cpp",
         "MP3Extractor.cpp",
         "MPEG2TSWriter.cpp",
@@ -67,11 +69,6 @@
         "avc_utils.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/native/include/media/openmax",
-        "frameworks/native/include/media/hardware",
-    ],
-
     shared_libs: [
         "libaudioutils",
         "libbinder",
@@ -98,14 +95,17 @@
         "libmedia_helper",
         "libstagefright_flacdec",
         "libstagefright_foundation",
+        "libstagefright_xmlparser",
         "libdl",
         "libRScpp",
         "libhidlbase",
         "libhidlmemory",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "android.hidl.token@1.0-utils",
+        "android.hardware.cas@1.0",
+        "android.hardware.cas.native@1.0",
         "android.hardware.media.omx@1.0",
-        "libstagefright_xmlparser@1.0",
     ],
 
     static_libs: [
@@ -173,4 +173,5 @@
     "timedtext",
     "webm",
     "wifi-display",
+    "xmlparser",
 ]
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index 4309372..6dfe2de 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -127,10 +127,6 @@
 }
 
 ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) {
-    if (size >= kCacheSize) {
-        return mSource->readAt(offset, data, size);
-    }
-
     // Check if the cache satisfies the read.
     if (mCachedOffset <= offset
             && offset < (off64_t) (mCachedOffset + mCachedSize)) {
@@ -154,6 +150,9 @@
         }
     }
 
+    if (size >= kCacheSize) {
+        return mSource->readAt(offset, data, size);
+    }
 
     // Fill the cache and copy to the caller.
     const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize);
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
new file mode 100644
index 0000000..d0610b2
--- /dev/null
+++ b/media/libstagefright/CodecBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecBase"
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/CodecBase.h>
+#include <utils/Log.h>
+
+namespace android {
+
+void BufferChannelBase::setCrypto(const sp<ICrypto> &crypto) {
+    mCrypto = crypto;
+}
+
+void BufferChannelBase::setDescrambler(const sp<IDescrambler> &descrambler) {
+    mDescrambler = descrambler;
+}
+
+} // namespace android
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index a5760d1..c22053e 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -92,6 +92,48 @@
     return true;
 }
 
+bool DataSource::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
+    if (size == 2) {
+        return getUInt16(offset, x);
+    }
+    if (size == 1) {
+        uint8_t tmp;
+        if (readAt(offset, &tmp, 1) == 1) {
+            *x = tmp;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool DataSource::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
+    if (size == 4) {
+        return getUInt32(offset, x);
+    }
+    if (size == 2) {
+        uint16_t tmp;
+        if (getUInt16(offset, &tmp)) {
+            *x = tmp;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool DataSource::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
+    if (size == 8) {
+        return getUInt64(offset, x);
+    }
+    if (size == 4) {
+        uint32_t tmp;
+        if (getUInt32(offset, &tmp)) {
+            *x = tmp;
+            return true;
+        }
+    }
+    return false;
+}
+
 status_t DataSource::getSize(off64_t *size) {
     *size = 0;
 
diff --git a/media/libstagefright/FrameRenderTracker.cpp b/media/libstagefright/FrameRenderTracker.cpp
index 917870f..1aa3bad 100644
--- a/media/libstagefright/FrameRenderTracker.cpp
+++ b/media/libstagefright/FrameRenderTracker.cpp
@@ -88,7 +88,9 @@
 
 status_t FrameRenderTracker::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
     // ensure monotonic timestamps
-    if (mLastRenderTimeNs >= systemNano) {
+    if (mLastRenderTimeNs > systemNano ||
+        // EOS is normally marked on the last frame
+        (mLastRenderTimeNs == systemNano && mediaTimeUs != INT64_MAX)) {
         ALOGW("[%s] Ignoring out of order/stale system nano %lld for media time %lld from codec.",
                 mComponentName.c_str(), (long long)systemNano, (long long)mediaTimeUs);
         return BAD_VALUE;
diff --git a/media/libstagefright/ItemTable.cpp b/media/libstagefright/ItemTable.cpp
new file mode 100644
index 0000000..b7ff21b
--- /dev/null
+++ b/media/libstagefright/ItemTable.cpp
@@ -0,0 +1,1544 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ItemTable"
+//#define LOG_NDEBUG 0
+
+#include <include/ItemTable.h>
+#include <media/MediaDefs.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/Utils.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <utils/Log.h>
+
+namespace android {
+
+namespace heif {
+
+/////////////////////////////////////////////////////////////////////
+//
+//  struct to keep track of one image item
+//
+
+struct ImageItem {
+    friend struct ItemReference;
+    friend struct ItemProperty;
+
+    ImageItem() : ImageItem(0) {}
+    ImageItem(uint32_t _type) : type(_type),
+            rows(0), columns(0), width(0), height(0), rotation(0),
+            offset(0), size(0), nextTileIndex(0) {}
+
+    bool isGrid() const {
+        return type == FOURCC('g', 'r', 'i', 'd');
+    }
+
+    status_t getNextTileItemId(uint32_t *nextTileItemId, bool reset) {
+        if (reset) {
+            nextTileIndex = 0;
+        }
+        if (nextTileIndex >= dimgRefs.size()) {
+            return ERROR_END_OF_STREAM;
+        }
+        *nextTileItemId = dimgRefs[nextTileIndex++];
+        return OK;
+    }
+
+    uint32_t type;
+    int32_t rows;
+    int32_t columns;
+    int32_t width;
+    int32_t height;
+    int32_t rotation;
+    off64_t offset;
+    size_t size;
+    sp<ABuffer> hvcc;
+    sp<ABuffer> icc;
+
+    Vector<uint32_t> thumbnails;
+    Vector<uint32_t> dimgRefs;
+    size_t nextTileIndex;
+};
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//  ISO boxes
+//
+
+struct Box {
+protected:
+    Box(const sp<DataSource> source, uint32_t type) :
+        mDataSource(source), mType(type) {}
+
+    virtual ~Box() {}
+
+    virtual status_t onChunkData(
+            uint32_t /*type*/, off64_t /*offset*/, size_t /*size*/) {
+        return OK;
+    }
+
+    inline uint32_t type() const { return mType; }
+
+    inline sp<DataSource> source() const { return mDataSource; }
+
+    status_t parseChunk(off64_t *offset);
+
+    status_t parseChunks(off64_t offset, size_t size);
+
+private:
+    sp<DataSource> mDataSource;
+    uint32_t mType;
+};
+
+status_t Box::parseChunk(off64_t *offset) {
+    if (*offset < 0) {
+        ALOGE("b/23540914");
+        return ERROR_MALFORMED;
+    }
+    uint32_t hdr[2];
+    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
+        return ERROR_IO;
+    }
+    uint64_t chunk_size = ntohl(hdr[0]);
+    int32_t chunk_type = ntohl(hdr[1]);
+    off64_t data_offset = *offset + 8;
+
+    if (chunk_size == 1) {
+        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
+            return ERROR_IO;
+        }
+        chunk_size = ntoh64(chunk_size);
+        data_offset += 8;
+
+        if (chunk_size < 16) {
+            // The smallest valid chunk is 16 bytes long in this case.
+            return ERROR_MALFORMED;
+        }
+    } else if (chunk_size == 0) {
+        // This shouldn't happen since we should never be top level
+        ALOGE("invalid chunk size 0 for non-top level box");
+        return ERROR_MALFORMED;
+    } else if (chunk_size < 8) {
+        // The smallest valid chunk is 8 bytes long.
+        ALOGE("invalid chunk size: %lld", (long long)chunk_size);
+        return ERROR_MALFORMED;
+    }
+
+    char chunk[5];
+    MakeFourCCString(chunk_type, chunk);
+    ALOGV("chunk: %s @ %lld", chunk, (long long)*offset);
+
+    off64_t chunk_data_size = chunk_size - (data_offset - *offset);
+    if (chunk_data_size < 0) {
+        ALOGE("b/23540914");
+        return ERROR_MALFORMED;
+    }
+
+    status_t err = onChunkData(chunk_type, data_offset, chunk_data_size);
+
+    if (err != OK) {
+        return err;
+    }
+    *offset += chunk_size;
+    return OK;
+}
+
+status_t Box::parseChunks(off64_t offset, size_t size) {
+    off64_t stopOffset = offset + size;
+    while (offset < stopOffset) {
+        status_t err = parseChunk(&offset);
+        if (err != OK) {
+            return err;
+        }
+    }
+    if (offset != stopOffset) {
+        return ERROR_MALFORMED;
+    }
+    return OK;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+struct FullBox : public Box {
+protected:
+    FullBox(const sp<DataSource> source, uint32_t type) :
+        Box(source, type), mVersion(0), mFlags(0) {}
+
+    inline uint8_t version() const { return mVersion; }
+
+    inline uint32_t flags() const { return mFlags; }
+
+    status_t parseFullBoxHeader(off64_t *offset, size_t *size);
+
+private:
+    uint8_t mVersion;
+    uint32_t mFlags;
+};
+
+status_t FullBox::parseFullBoxHeader(off64_t *offset, size_t *size) {
+    if (*size < 4) {
+        return ERROR_MALFORMED;
+    }
+    if (!source()->readAt(*offset, &mVersion, 1)) {
+        return ERROR_IO;
+    }
+    if (!source()->getUInt24(*offset + 1, &mFlags)) {
+        return ERROR_IO;
+    }
+    *offset += 4;
+    *size -= 4;
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//  PrimaryImage box
+//
+
+struct PitmBox : public FullBox {
+    PitmBox(const sp<DataSource> source) :
+        FullBox(source, FOURCC('p', 'i', 't', 'm')) {}
+
+    status_t parse(off64_t offset, size_t size, uint32_t *primaryItemId);
+};
+
+status_t PitmBox::parse(off64_t offset, size_t size, uint32_t *primaryItemId) {
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    size_t itemIdSize = (version() == 0) ? 2 : 4;
+    if (size < itemIdSize) {
+        return ERROR_MALFORMED;
+    }
+    uint32_t itemId;
+    if (!source()->getUInt32Var(offset, &itemId, itemIdSize)) {
+        return ERROR_IO;
+    }
+
+    ALOGV("primary id %d", itemId);
+    *primaryItemId = itemId;
+
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//  ItemLocation related boxes
+//
+
+struct ExtentEntry {
+    uint64_t extentIndex;
+    uint64_t extentOffset;
+    uint64_t extentLength;
+};
+
+struct ItemLoc {
+    ItemLoc() : ItemLoc(0, 0, 0, 0) {}
+    ItemLoc(uint32_t item_id, uint16_t construction_method,
+            uint16_t data_reference_index, uint64_t base_offset) :
+        itemId(item_id),
+        constructionMethod(construction_method),
+        dataReferenceIndex(data_reference_index),
+        baseOffset(base_offset) {}
+
+    void addExtent(const ExtentEntry& extent) {
+        extents.push_back(extent);
+    }
+
+    status_t getLoc(off64_t *offset, size_t *size,
+            off64_t idatOffset, size_t idatSize) const {
+        // TODO: fix extent handling, fix constructionMethod = 2
+        CHECK(extents.size() == 1);
+        if (constructionMethod == 0) {
+            *offset = baseOffset + extents[0].extentOffset;
+            *size = extents[0].extentLength;
+            return OK;
+        } else if (constructionMethod == 1) {
+            if (baseOffset + extents[0].extentOffset + extents[0].extentLength
+                    > idatSize) {
+                return ERROR_MALFORMED;
+            }
+            *offset = baseOffset + extents[0].extentOffset + idatOffset;
+            *size = extents[0].extentLength;
+            return OK;
+        }
+        return ERROR_UNSUPPORTED;
+    }
+
+    // parsed info
+    uint32_t itemId;
+    uint16_t constructionMethod;
+    uint16_t dataReferenceIndex;
+    off64_t baseOffset;
+    Vector<ExtentEntry> extents;
+};
+
+struct IlocBox : public FullBox {
+    IlocBox(const sp<DataSource> source, KeyedVector<uint32_t, ItemLoc> *itemLocs) :
+        FullBox(source, FOURCC('i', 'l', 'o', 'c')),
+        mItemLocs(itemLocs), mHasConstructMethod1(false) {}
+
+    status_t parse(off64_t offset, size_t size);
+
+    bool hasConstructMethod1() { return mHasConstructMethod1; }
+
+private:
+    static bool isSizeFieldValid(uint32_t offset_size) {
+        return offset_size == 0 || offset_size == 4 || offset_size == 8;
+    }
+    KeyedVector<uint32_t, ItemLoc> *mItemLocs;
+    bool mHasConstructMethod1;
+};
+
+status_t IlocBox::parse(off64_t offset, size_t size) {
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+    if (version() > 2) {
+        ALOGE("%s: invalid version %d", __FUNCTION__, version());
+        return ERROR_MALFORMED;
+    }
+
+    if (size < 2) {
+        return ERROR_MALFORMED;
+    }
+    uint8_t offset_size;
+    if (!source()->readAt(offset++, &offset_size, 1)) {
+        return ERROR_IO;
+    }
+    uint8_t length_size = (offset_size & 0xF);
+    offset_size >>= 4;
+
+    uint8_t base_offset_size;
+    if (!source()->readAt(offset++, &base_offset_size, 1)) {
+        return ERROR_IO;
+    }
+    uint8_t index_size = 0;
+    if (version() == 1 || version() == 2) {
+        index_size = (base_offset_size & 0xF);
+    }
+    base_offset_size >>= 4;
+    size -= 2;
+
+    if (!isSizeFieldValid(offset_size)
+            || !isSizeFieldValid(length_size)
+            || !isSizeFieldValid(base_offset_size)
+            || !isSizeFieldValid((index_size))) {
+        ALOGE("%s: offset size not valid: %d, %d, %d, %d", __FUNCTION__,
+                offset_size, length_size, base_offset_size, index_size);
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t item_count;
+    size_t itemFieldSize = version() < 2 ? 2 : 4;
+    if (size < itemFieldSize) {
+        return ERROR_MALFORMED;
+    }
+    if (!source()->getUInt32Var(offset, &item_count, itemFieldSize)) {
+        return ERROR_IO;
+    }
+
+    ALOGV("item_count %lld", (long long) item_count);
+    offset += itemFieldSize;
+    size -= itemFieldSize;
+
+    for (size_t i = 0; i < item_count; i++) {
+        uint32_t item_id;
+        if (!source()->getUInt32Var(offset, &item_id, itemFieldSize)) {
+            return ERROR_IO;
+        }
+        ALOGV("item[%zu]: id %lld", i, (long long)item_id);
+        offset += itemFieldSize;
+
+        uint8_t construction_method = 0;
+        if (version() == 1 || version() == 2) {
+            uint8_t buf[2];
+            if (!source()->readAt(offset, buf, 2)) {
+                return ERROR_IO;
+            }
+            construction_method = (buf[1] & 0xF);
+            ALOGV("construction_method %d", construction_method);
+            if (construction_method == 1) {
+                mHasConstructMethod1 = true;
+            }
+
+            offset += 2;
+        }
+
+        uint16_t data_reference_index;
+        if (!source()->getUInt16(offset, &data_reference_index)) {
+            return ERROR_IO;
+        }
+        ALOGV("data_reference_index %d", data_reference_index);
+        if (data_reference_index != 0) {
+            // we don't support reference to other files
+            return ERROR_UNSUPPORTED;
+        }
+        offset += 2;
+
+        uint64_t base_offset = 0;
+        if (base_offset_size != 0) {
+            if (!source()->getUInt64Var(offset, &base_offset, base_offset_size)) {
+                return ERROR_IO;
+            }
+            offset += base_offset_size;
+        }
+        ALOGV("base_offset %lld", (long long) base_offset);
+
+        ssize_t index = mItemLocs->add(item_id, ItemLoc(
+                item_id, construction_method, data_reference_index, base_offset));
+        ItemLoc &item = mItemLocs->editValueAt(index);
+
+        uint16_t extent_count;
+        if (!source()->getUInt16(offset, &extent_count)) {
+            return ERROR_IO;
+        }
+        ALOGV("extent_count %d", extent_count);
+
+        if (extent_count > 1 && (offset_size == 0 || length_size == 0)) {
+            // if the item is dividec into more than one extents, offset and
+            // length must be present.
+            return ERROR_MALFORMED;
+        }
+        offset += 2;
+
+        for (size_t j = 0; j < extent_count; j++) {
+            uint64_t extent_index = 1; // default=1
+            if ((version() == 1 || version() == 2) && (index_size > 0)) {
+                if (!source()->getUInt64Var(offset, &extent_index, index_size)) {
+                    return ERROR_IO;
+                }
+                // TODO: add support for this mode
+                offset += index_size;
+                ALOGV("extent_index %lld", (long long)extent_index);
+            }
+
+            uint64_t extent_offset = 0; // default=0
+            if (offset_size > 0) {
+                if (!source()->getUInt64Var(offset, &extent_offset, offset_size)) {
+                    return ERROR_IO;
+                }
+                offset += offset_size;
+            }
+            ALOGV("extent_offset %lld", (long long)extent_offset);
+
+            uint64_t extent_length = 0; // this indicates full length of file
+            if (length_size > 0) {
+                if (!source()->getUInt64Var(offset, &extent_length, length_size)) {
+                    return ERROR_IO;
+                }
+                offset += length_size;
+            }
+            ALOGV("extent_length %lld", (long long)extent_length);
+
+            item.addExtent({ extent_index, extent_offset, extent_length });
+        }
+    }
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//  ItemReference related boxes
+//
+
+struct ItemReference : public Box, public RefBase {
+    ItemReference(const sp<DataSource> source, uint32_t type, uint32_t itemIdSize) :
+        Box(source, type), mItemId(0), mRefIdSize(itemIdSize) {}
+
+    status_t parse(off64_t offset, size_t size);
+
+    uint32_t itemId() { return mItemId; }
+
+    void apply(KeyedVector<uint32_t, ImageItem> &itemIdToImageMap) const {
+        ssize_t imageIndex = itemIdToImageMap.indexOfKey(mItemId);
+
+        // ignore non-image items
+        if (imageIndex < 0) {
+            return;
+        }
+
+        ALOGV("attach reference type 0x%x to item id %d)", type(), mItemId);
+
+        if (type() == FOURCC('d', 'i', 'm', 'g')) {
+            ImageItem &image = itemIdToImageMap.editValueAt(imageIndex);
+            if (!image.dimgRefs.empty()) {
+                ALOGW("dimgRefs if not clean!");
+            }
+            image.dimgRefs.appendVector(mRefs);
+        } else if (type() == FOURCC('t', 'h', 'm', 'b')) {
+            for (size_t i = 0; i < mRefs.size(); i++) {
+                imageIndex = itemIdToImageMap.indexOfKey(mRefs[i]);
+
+                // ignore non-image items
+                if (imageIndex < 0) {
+                    continue;
+                }
+                ALOGV("Image item id %d uses thumbnail item id %d", mRefs[i], mItemId);
+                ImageItem &image = itemIdToImageMap.editValueAt(imageIndex);
+                if (!image.thumbnails.empty()) {
+                    ALOGW("already has thumbnails!");
+                }
+                image.thumbnails.push_back(mItemId);
+            }
+        } else {
+            ALOGW("ignoring unsupported ref type 0x%x", type());
+        }
+    }
+
+private:
+    uint32_t mItemId;
+    uint32_t mRefIdSize;
+    Vector<uint32_t> mRefs;
+
+    DISALLOW_EVIL_CONSTRUCTORS(ItemReference);
+};
+
+status_t ItemReference::parse(off64_t offset, size_t size) {
+    if (size < mRefIdSize + 2) {
+        return ERROR_MALFORMED;
+    }
+    if (!source()->getUInt32Var(offset, &mItemId, mRefIdSize)) {
+        return ERROR_IO;
+    }
+    offset += mRefIdSize;
+
+    uint16_t count;
+    if (!source()->getUInt16(offset, &count)) {
+        return ERROR_IO;
+    }
+    offset += 2;
+    size -= (mRefIdSize + 2);
+
+    if (size < count * mRefIdSize) {
+        return ERROR_MALFORMED;
+    }
+
+    for (size_t i = 0; i < count; i++) {
+        uint32_t refItemId;
+        if (!source()->getUInt32Var(offset, &refItemId, mRefIdSize)) {
+            return ERROR_IO;
+        }
+        offset += mRefIdSize;
+        mRefs.push_back(refItemId);
+        ALOGV("item id %d: referencing item id %d", mItemId, refItemId);
+    }
+
+    return OK;
+}
+
+struct IrefBox : public FullBox {
+    IrefBox(const sp<DataSource> source, Vector<sp<ItemReference> > *itemRefs) :
+        FullBox(source, FOURCC('i', 'r', 'e', 'f')), mRefIdSize(0), mItemRefs(itemRefs) {}
+
+    status_t parse(off64_t offset, size_t size);
+
+protected:
+    status_t onChunkData(uint32_t type, off64_t offset, size_t size) override;
+
+private:
+    uint32_t mRefIdSize;
+    Vector<sp<ItemReference> > *mItemRefs;
+};
+
+status_t IrefBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    mRefIdSize = (version() == 0) ? 2 : 4;
+    return parseChunks(offset, size);
+}
+
+status_t IrefBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
+    sp<ItemReference> itemRef = new ItemReference(source(), type, mRefIdSize);
+
+    status_t err = itemRef->parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+    mItemRefs->push_back(itemRef);
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//  ItemProperty related boxes
+//
+
+struct AssociationEntry {
+    uint32_t itemId;
+    bool essential;
+    uint16_t index;
+};
+
+struct ItemProperty : public RefBase {
+    ItemProperty() {}
+
+    virtual void attachTo(ImageItem &/*image*/) const {
+        ALOGW("Unrecognized property");
+    }
+    virtual status_t parse(off64_t /*offset*/, size_t /*size*/) {
+        ALOGW("Unrecognized property");
+        return OK;
+    }
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(ItemProperty);
+};
+
+struct IspeBox : public FullBox, public ItemProperty {
+    IspeBox(const sp<DataSource> source) :
+        FullBox(source, FOURCC('i', 's', 'p', 'e')), mWidth(0), mHeight(0) {}
+
+    status_t parse(off64_t offset, size_t size) override;
+
+    void attachTo(ImageItem &image) const override {
+        image.width = mWidth;
+        image.height = mHeight;
+    }
+
+private:
+    uint32_t mWidth;
+    uint32_t mHeight;
+};
+
+status_t IspeBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    if (size < 8) {
+        return ERROR_MALFORMED;
+    }
+    if (!source()->getUInt32(offset, &mWidth)
+            || !source()->getUInt32(offset + 4, &mHeight)) {
+        return ERROR_IO;
+    }
+    ALOGV("property ispe: %dx%d", mWidth, mHeight);
+
+    return OK;
+}
+
+struct HvccBox : public Box, public ItemProperty {
+    HvccBox(const sp<DataSource> source) :
+        Box(source, FOURCC('h', 'v', 'c', 'C')) {}
+
+    status_t parse(off64_t offset, size_t size) override;
+
+    void attachTo(ImageItem &image) const override {
+        image.hvcc = mHVCC;
+    }
+
+private:
+    sp<ABuffer> mHVCC;
+};
+
+status_t HvccBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    mHVCC = new ABuffer(size);
+
+    if (mHVCC->data() == NULL) {
+        ALOGE("b/28471206");
+        return NO_MEMORY;
+    }
+
+    if (source()->readAt(offset, mHVCC->data(), size) < (ssize_t)size) {
+        return ERROR_IO;
+    }
+
+    ALOGV("property hvcC");
+
+    return OK;
+}
+
+struct IrotBox : public Box, public ItemProperty {
+    IrotBox(const sp<DataSource> source) :
+        Box(source, FOURCC('i', 'r', 'o', 't')), mAngle(0) {}
+
+    status_t parse(off64_t offset, size_t size) override;
+
+    void attachTo(ImageItem &image) const override {
+        image.rotation = mAngle * 90;
+    }
+
+private:
+    uint8_t mAngle;
+};
+
+status_t IrotBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    if (size < 1) {
+        return ERROR_MALFORMED;
+    }
+    if (source()->readAt(offset, &mAngle, 1) != 1) {
+        return ERROR_IO;
+    }
+    mAngle &= 0x3;
+    ALOGV("property irot: %d", mAngle);
+
+    return OK;
+}
+
+struct ColrBox : public Box, public ItemProperty {
+    ColrBox(const sp<DataSource> source) :
+        Box(source, FOURCC('c', 'o', 'l', 'r')) {}
+
+    status_t parse(off64_t offset, size_t size) override;
+
+    void attachTo(ImageItem &image) const override {
+        image.icc = mICCData;
+    }
+
+private:
+    sp<ABuffer> mICCData;
+};
+
+status_t ColrBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    if (size < 4) {
+        return ERROR_MALFORMED;
+    }
+    uint32_t colour_type;
+    if (!source()->getUInt32(offset, &colour_type)) {
+        return ERROR_IO;
+    }
+    offset += 4;
+    size -= 4;
+    if (colour_type == FOURCC('n', 'c', 'l', 'x')) {
+        return OK;
+    }
+    if ((colour_type != FOURCC('r', 'I', 'C', 'C')) &&
+        (colour_type != FOURCC('p', 'r', 'o', 'f'))) {
+        return ERROR_MALFORMED;
+    }
+
+    mICCData = new ABuffer(size);
+    if (mICCData->data() == NULL) {
+        ALOGE("b/28471206");
+        return NO_MEMORY;
+    }
+
+    if (source()->readAt(offset, mICCData->data(), size) != (ssize_t)size) {
+        return ERROR_IO;
+    }
+
+    ALOGV("property Colr: size %zd", size);
+    return OK;
+}
+
+struct IpmaBox : public FullBox {
+    IpmaBox(const sp<DataSource> source, Vector<AssociationEntry> *associations) :
+        FullBox(source, FOURCC('i', 'p', 'm', 'a')), mAssociations(associations) {}
+
+    status_t parse(off64_t offset, size_t size);
+private:
+    Vector<AssociationEntry> *mAssociations;
+};
+
+status_t IpmaBox::parse(off64_t offset, size_t size) {
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    if (size < 4) {
+        return ERROR_MALFORMED;
+    }
+    uint32_t entryCount;
+    if (!source()->getUInt32(offset, &entryCount)) {
+        return ERROR_IO;
+    }
+    offset += 4;
+    size -= 4;
+
+    for (size_t k = 0; k < entryCount; ++k) {
+        uint32_t itemId = 0;
+        size_t itemIdSize = (version() < 1) ? 2 : 4;
+
+        if (size < itemIdSize + 1) {
+            return ERROR_MALFORMED;
+        }
+
+        if (!source()->getUInt32Var(offset, &itemId, itemIdSize)) {
+            return ERROR_IO;
+        }
+        offset += itemIdSize;
+        size -= itemIdSize;
+
+        uint8_t associationCount;
+        if (!source()->readAt(offset, &associationCount, 1)) {
+            return ERROR_IO;
+        }
+        offset++;
+        size--;
+
+        for (size_t i = 0; i < associationCount; ++i) {
+            size_t propIndexSize = (flags() & 1) ? 2 : 1;
+            if (size < propIndexSize) {
+                return ERROR_MALFORMED;
+            }
+            uint16_t propIndex;
+            if (!source()->getUInt16Var(offset, &propIndex, propIndexSize)) {
+                return ERROR_IO;
+            }
+            offset += propIndexSize;
+            size -= propIndexSize;
+            uint16_t bitmask = (1 << (8 * propIndexSize - 1));
+            AssociationEntry entry = {
+                    .itemId = itemId,
+                    .essential = !!(propIndex & bitmask),
+                    .index = (uint16_t) (propIndex & ~bitmask)
+            };
+
+            ALOGV("item id %d associated to property %d (essential %d)",
+                    itemId, entry.index, entry.essential);
+
+            mAssociations->push_back(entry);
+        }
+    }
+
+    return OK;
+}
+
+struct IpcoBox : public Box {
+    IpcoBox(const sp<DataSource> source, Vector<sp<ItemProperty> > *properties) :
+        Box(source, FOURCC('i', 'p', 'c', 'o')), mItemProperties(properties) {}
+
+    status_t parse(off64_t offset, size_t size);
+protected:
+    status_t onChunkData(uint32_t type, off64_t offset, size_t size) override;
+
+private:
+    Vector<sp<ItemProperty> > *mItemProperties;
+};
+
+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
+    mItemProperties->push_back(new ItemProperty());
+    return parseChunks(offset, size);
+}
+
+status_t IpcoBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
+    sp<ItemProperty> itemProperty;
+    switch(type) {
+        case FOURCC('h', 'v', 'c', 'C'):
+        {
+            itemProperty = new HvccBox(source());
+            break;
+        }
+        case FOURCC('i', 's', 'p', 'e'):
+        {
+            itemProperty = new IspeBox(source());
+            break;
+        }
+        case FOURCC('i', 'r', 'o', 't'):
+        {
+            itemProperty = new IrotBox(source());
+            break;
+        }
+        case FOURCC('c', 'o', 'l', 'r'):
+        {
+            itemProperty = new ColrBox(source());
+            break;
+        }
+        default:
+        {
+            // push dummy to maintain correct item property index
+            itemProperty = new ItemProperty();
+            break;
+        }
+    }
+    status_t err = itemProperty->parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+    mItemProperties->push_back(itemProperty);
+    return OK;
+}
+
+struct IprpBox : public Box {
+    IprpBox(const sp<DataSource> source,
+            Vector<sp<ItemProperty> > *properties,
+            Vector<AssociationEntry> *associations) :
+        Box(source, FOURCC('i', 'p', 'r', 'p')),
+        mProperties(properties), mAssociations(associations) {}
+
+    status_t parse(off64_t offset, size_t size);
+protected:
+    status_t onChunkData(uint32_t type, off64_t offset, size_t size) override;
+
+private:
+    Vector<sp<ItemProperty> > *mProperties;
+    Vector<AssociationEntry> *mAssociations;
+};
+
+status_t IprpBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    status_t err = parseChunks(offset, size);
+    if (err != OK) {
+        return err;
+    }
+    return OK;
+}
+
+status_t IprpBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
+    switch(type) {
+        case FOURCC('i', 'p', 'c', 'o'):
+        {
+            IpcoBox ipcoBox(source(), mProperties);
+            return ipcoBox.parse(offset, size);
+        }
+        case FOURCC('i', 'p', 'm', 'a'):
+        {
+            IpmaBox ipmaBox(source(), mAssociations);
+            return ipmaBox.parse(offset, size);
+        }
+        default:
+        {
+            ALOGW("Unrecognized box.");
+            break;
+        }
+    }
+    return OK;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//  ItemInfo related boxes
+//
+struct ItemInfo {
+    uint32_t itemId;
+    uint32_t itemType;
+};
+
+struct InfeBox : public FullBox {
+    InfeBox(const sp<DataSource> source) :
+        FullBox(source, FOURCC('i', 'n', 'f', 'e')) {}
+
+    status_t parse(off64_t offset, size_t size, ItemInfo *itemInfo);
+
+private:
+    bool parseNullTerminatedString(off64_t *offset, size_t *size, String8 *out);
+};
+
+bool InfeBox::parseNullTerminatedString(
+        off64_t *offset, size_t *size, String8 *out) {
+    char tmp[256];
+    size_t len = 0;
+    off64_t newOffset = *offset;
+    off64_t stopOffset = *offset + *size;
+    while (newOffset < stopOffset) {
+        if (!source()->readAt(newOffset++, &tmp[len], 1)) {
+            return false;
+        }
+        if (tmp[len] == 0) {
+            out->append(tmp, len);
+
+            *offset = newOffset;
+            *size = stopOffset - newOffset;
+
+            return true;
+        }
+        if (++len >= sizeof(tmp)) {
+            out->append(tmp, len);
+            len = 0;
+        }
+    }
+    return false;
+}
+
+status_t InfeBox::parse(off64_t offset, size_t size, ItemInfo *itemInfo) {
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    if (version() == 0 || version() == 1) {
+        if (size < 4) {
+            return ERROR_MALFORMED;
+        }
+        uint16_t item_id;
+        if (!source()->getUInt16(offset, &item_id)) {
+            return ERROR_IO;
+        }
+        ALOGV("item_id %d", item_id);
+        uint16_t item_protection_index;
+        if (!source()->getUInt16(offset + 2, &item_protection_index)) {
+            return ERROR_IO;
+        }
+        offset += 4;
+        size -= 4;
+
+        String8 item_name;
+        if (!parseNullTerminatedString(&offset, &size, &item_name)) {
+            return ERROR_MALFORMED;
+        }
+
+        String8 content_type;
+        if (!parseNullTerminatedString(&offset, &size, &content_type)) {
+            return ERROR_MALFORMED;
+        }
+
+        String8 content_encoding;
+        if (!parseNullTerminatedString(&offset, &size, &content_encoding)) {
+            return ERROR_MALFORMED;
+        }
+
+        if (version() == 1) {
+            uint32_t extension_type;
+            if (!source()->getUInt32(offset, &extension_type)) {
+                return ERROR_IO;
+            }
+            offset++;
+            size--;
+            // TODO: handle this case
+        }
+    } else { // version >= 2
+        uint32_t item_id;
+        size_t itemIdSize = (version() == 2) ? 2 : 4;
+        if (size < itemIdSize + 6) {
+            return ERROR_MALFORMED;
+        }
+        if (!source()->getUInt32Var(offset, &item_id, itemIdSize)) {
+            return ERROR_IO;
+        }
+        ALOGV("item_id %d", item_id);
+        offset += itemIdSize;
+        uint16_t item_protection_index;
+        if (!source()->getUInt16(offset, &item_protection_index)) {
+            return ERROR_IO;
+        }
+        ALOGV("item_protection_index %d", item_protection_index);
+        offset += 2;
+        uint32_t item_type;
+        if (!source()->getUInt32(offset, &item_type)) {
+            return ERROR_IO;
+        }
+
+        itemInfo->itemId = item_id;
+        itemInfo->itemType = item_type;
+
+        char itemTypeString[5];
+        MakeFourCCString(item_type, itemTypeString);
+        ALOGV("item_type %s", itemTypeString);
+        offset += 4;
+        size -= itemIdSize + 6;
+
+        String8 item_name;
+        if (!parseNullTerminatedString(&offset, &size, &item_name)) {
+            return ERROR_MALFORMED;
+        }
+        ALOGV("item_name %s", item_name.c_str());
+
+        if (item_type == FOURCC('m', 'i', 'm', 'e')) {
+            String8 content_type;
+            if (!parseNullTerminatedString(&offset, &size, &content_type)) {
+                return ERROR_MALFORMED;
+            }
+
+            String8 content_encoding;
+            if (!parseNullTerminatedString(&offset, &size, &content_encoding)) {
+                return ERROR_MALFORMED;
+            }
+        } else if (item_type == FOURCC('u', 'r', 'i', ' ')) {
+            String8 item_uri_type;
+            if (!parseNullTerminatedString(&offset, &size, &item_uri_type)) {
+                return ERROR_MALFORMED;
+            }
+        }
+    }
+    return OK;
+}
+
+struct IinfBox : public FullBox {
+    IinfBox(const sp<DataSource> source, Vector<ItemInfo> *itemInfos) :
+        FullBox(source, FOURCC('i', 'i', 'n', 'f')),
+        mItemInfos(itemInfos), mHasGrids(false) {}
+
+    status_t parse(off64_t offset, size_t size);
+
+    bool hasGrids() { return mHasGrids; }
+
+protected:
+    status_t onChunkData(uint32_t type, off64_t offset, size_t size) override;
+
+private:
+    Vector<ItemInfo> *mItemInfos;
+    bool mHasGrids;
+};
+
+status_t IinfBox::parse(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    status_t err = parseFullBoxHeader(&offset, &size);
+    if (err != OK) {
+        return err;
+    }
+
+    size_t entryCountSize = version() == 0 ? 2 : 4;
+    if (size < entryCountSize) {
+        return ERROR_MALFORMED;
+    }
+    uint32_t entry_count;
+    if (!source()->getUInt32Var(offset, &entry_count, entryCountSize)) {
+        return ERROR_IO;
+    }
+    ALOGV("entry_count %d", entry_count);
+
+    off64_t stopOffset = offset + size;
+    offset += entryCountSize;
+    for (size_t i = 0; i < entry_count && offset < stopOffset; i++) {
+        ALOGV("entry %zu", i);
+        status_t err = parseChunk(&offset);
+        if (err != OK) {
+            return err;
+        }
+    }
+    if (offset != stopOffset) {
+        return ERROR_MALFORMED;
+    }
+
+    return OK;
+}
+
+status_t IinfBox::onChunkData(uint32_t type, off64_t offset, size_t size) {
+    if (type != FOURCC('i', 'n', 'f', 'e')) {
+        return OK;
+    }
+
+    InfeBox infeBox(source());
+    ItemInfo itemInfo;
+    status_t err = infeBox.parse(offset, size, &itemInfo);
+    if (err != OK) {
+        return err;
+    }
+    mItemInfos->push_back(itemInfo);
+    mHasGrids |= (itemInfo.itemType == FOURCC('g', 'r', 'i', 'd'));
+    return OK;
+}
+
+//////////////////////////////////////////////////////////////////
+
+ItemTable::ItemTable(const sp<DataSource> &source)
+    : mDataSource(source),
+      mPrimaryItemId(0),
+      mIdatOffset(0),
+      mIdatSize(0),
+      mImageItemsValid(false),
+      mCurrentImageIndex(0) {
+    mRequiredBoxes.insert('iprp');
+    mRequiredBoxes.insert('iloc');
+    mRequiredBoxes.insert('pitm');
+    mRequiredBoxes.insert('iinf');
+}
+
+ItemTable::~ItemTable() {}
+
+status_t ItemTable::parse(uint32_t type, off64_t data_offset, size_t chunk_data_size) {
+    switch(type) {
+        case FOURCC('i', 'l', 'o', 'c'):
+        {
+            return parseIlocBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('i', 'i', 'n', 'f'):
+        {
+            return parseIinfBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('i', 'p', 'r', 'p'):
+        {
+            return parseIprpBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('p', 'i', 't', 'm'):
+        {
+            return parsePitmBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('i', 'd', 'a', 't'):
+        {
+            return parseIdatBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('i', 'r', 'e', 'f'):
+        {
+            return parseIrefBox(data_offset, chunk_data_size);
+        }
+        case FOURCC('i', 'p', 'r', 'o'):
+        {
+            ALOGW("ipro box not supported!");
+            break;
+        }
+        default:
+        {
+            ALOGW("unrecognized box type: 0x%x", type);
+            break;
+        }
+    }
+    return ERROR_UNSUPPORTED;
+}
+
+status_t ItemTable::parseIlocBox(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    IlocBox ilocBox(mDataSource, &mItemLocs);
+    status_t err = ilocBox.parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+
+    if (ilocBox.hasConstructMethod1()) {
+        mRequiredBoxes.insert('idat');
+    }
+
+    return buildImageItemsIfPossible('iloc');
+}
+
+status_t ItemTable::parseIinfBox(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    IinfBox iinfBox(mDataSource, &mItemInfos);
+    status_t err = iinfBox.parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+
+    if (iinfBox.hasGrids()) {
+        mRequiredBoxes.insert('iref');
+    }
+
+    return buildImageItemsIfPossible('iinf');
+}
+
+status_t ItemTable::parsePitmBox(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    PitmBox pitmBox(mDataSource);
+    status_t err = pitmBox.parse(offset, size, &mPrimaryItemId);
+    if (err != OK) {
+        return err;
+    }
+
+    return buildImageItemsIfPossible('pitm');
+}
+
+status_t ItemTable::parseIprpBox(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    IprpBox iprpBox(mDataSource, &mItemProperties, &mAssociations);
+    status_t err = iprpBox.parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+
+    return buildImageItemsIfPossible('iprp');
+}
+
+status_t ItemTable::parseIdatBox(off64_t offset, size_t size) {
+    ALOGV("%s: idat offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    // only remember the offset and size of idat box for later use
+    mIdatOffset = offset;
+    mIdatSize = size;
+
+    return buildImageItemsIfPossible('idat');
+}
+
+status_t ItemTable::parseIrefBox(off64_t offset, size_t size) {
+    ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
+
+    IrefBox irefBox(mDataSource, &mItemReferences);
+    status_t err = irefBox.parse(offset, size);
+    if (err != OK) {
+        return err;
+    }
+
+    return buildImageItemsIfPossible('iref');
+}
+
+status_t ItemTable::buildImageItemsIfPossible(uint32_t type) {
+    if (mImageItemsValid) {
+        return OK;
+    }
+
+    mBoxesSeen.insert(type);
+
+    // need at least 'iprp', 'iloc', 'pitm', 'iinf';
+    // need 'idat' if any items used construction_method of 2;
+    // need 'iref' if there are grids.
+    if (!std::includes(
+            mBoxesSeen.begin(), mBoxesSeen.end(),
+            mRequiredBoxes.begin(), mRequiredBoxes.end())) {
+        return OK;
+    }
+
+    ALOGV("building image table...");
+
+    for (size_t i = 0; i < mItemInfos.size(); i++) {
+        const ItemInfo &info = mItemInfos[i];
+
+
+        // ignore non-image items
+        if (info.itemType != FOURCC('g', 'r', 'i', 'd') &&
+            info.itemType != FOURCC('h', 'v', 'c', '1')) {
+            continue;
+        }
+
+        ssize_t imageIndex = mItemIdToImageMap.indexOfKey(info.itemId);
+        if (imageIndex >= 0) {
+            ALOGW("ignoring duplicate image item id %d", info.itemId);
+            continue;
+        }
+
+        ssize_t ilocIndex = mItemLocs.indexOfKey(info.itemId);
+        if (ilocIndex < 0) {
+            ALOGE("iloc missing for image item id %d", info.itemId);
+            continue;
+        }
+        const ItemLoc &iloc = mItemLocs[ilocIndex];
+
+        off64_t offset;
+        size_t size;
+        if (iloc.getLoc(&offset, &size, mIdatOffset, mIdatSize) != OK) {
+            return ERROR_MALFORMED;
+        }
+
+        ImageItem image(info.itemType);
+
+        ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
+
+        if (image.isGrid()) {
+            if (size > 12) {
+                return ERROR_MALFORMED;
+            }
+            uint8_t buf[12];
+            if (!mDataSource->readAt(offset, buf, size)) {
+                return ERROR_IO;
+            }
+
+            image.rows = buf[2] + 1;
+            image.columns = buf[3] + 1;
+
+            ALOGV("rows %d, columans %d", image.rows, image.columns);
+        } else {
+            image.offset = offset;
+            image.size = size;
+        }
+        mItemIdToImageMap.add(info.itemId, image);
+    }
+
+    for (size_t i = 0; i < mAssociations.size(); i++) {
+        attachProperty(mAssociations[i]);
+    }
+
+    for (size_t i = 0; i < mItemReferences.size(); i++) {
+        mItemReferences[i]->apply(mItemIdToImageMap);
+    }
+
+    mImageItemsValid = true;
+    return OK;
+}
+
+void ItemTable::attachProperty(const AssociationEntry &association) {
+    ssize_t imageIndex = mItemIdToImageMap.indexOfKey(association.itemId);
+
+    // ignore non-image items
+    if (imageIndex < 0) {
+        return;
+    }
+
+    uint16_t propertyIndex = association.index;
+    if (propertyIndex >= mItemProperties.size()) {
+        ALOGW("Ignoring invalid property index %d", propertyIndex);
+        return;
+    }
+
+    ALOGV("attach property %d to item id %d)",
+            propertyIndex, association.itemId);
+
+    mItemProperties[propertyIndex]->attachTo(
+            mItemIdToImageMap.editValueAt(imageIndex));
+}
+
+sp<MetaData> ItemTable::getImageMeta() {
+    if (!mImageItemsValid) {
+        return NULL;
+    }
+
+    ssize_t imageIndex = mItemIdToImageMap.indexOfKey(mPrimaryItemId);
+    if (imageIndex < 0) {
+        ALOGE("Primary item id %d not found!", mPrimaryItemId);
+        return NULL;
+    }
+
+    ALOGV("primary image index %zu", imageIndex);
+
+    const ImageItem *image = &mItemIdToImageMap[imageIndex];
+
+    sp<MetaData> meta = new MetaData;
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+
+    ALOGV("setting image size %dx%d", image->width, image->height);
+    meta->setInt32(kKeyWidth, image->width);
+    meta->setInt32(kKeyHeight, image->height);
+    if (image->rotation != 0) {
+        meta->setInt32(kKeyRotation, image->rotation);
+    }
+    meta->setInt32(kKeyMaxInputSize, image->width * image->height * 1.5);
+
+    if (!image->thumbnails.empty()) {
+        ssize_t thumbnailIndex = mItemIdToImageMap.indexOfKey(image->thumbnails[0]);
+        if (thumbnailIndex >= 0) {
+            const ImageItem &thumbnail = mItemIdToImageMap[thumbnailIndex];
+
+            meta->setInt32(kKeyThumbnailWidth, thumbnail.width);
+            meta->setInt32(kKeyThumbnailHeight, thumbnail.height);
+            meta->setData(kKeyThumbnailHVCC, kTypeHVCC,
+                    thumbnail.hvcc->data(), thumbnail.hvcc->size());
+            ALOGV("thumbnail meta: %dx%d, index %zd",
+                    thumbnail.width, thumbnail.height, thumbnailIndex);
+        } else {
+            ALOGW("Referenced thumbnail does not exist!");
+        }
+    }
+
+    if (image->isGrid()) {
+        ssize_t tileIndex = mItemIdToImageMap.indexOfKey(image->dimgRefs[0]);
+        if (tileIndex < 0) {
+            return NULL;
+        }
+        meta->setInt32(kKeyGridRows, image->rows);
+        meta->setInt32(kKeyGridCols, image->columns);
+
+        image = &mItemIdToImageMap.editValueAt(tileIndex);
+    }
+
+    if (image->hvcc == NULL) {
+        ALOGE("hvcc is missing!");
+        return NULL;
+    }
+    meta->setData(kKeyHVCC, kTypeHVCC, image->hvcc->data(), image->hvcc->size());
+
+    if (image->icc != NULL) {
+        meta->setData(kKeyIccProfile, 0, image->icc->data(), image->icc->size());
+    }
+    return meta;
+}
+
+uint32_t ItemTable::countImages() const {
+    return mImageItemsValid ? mItemIdToImageMap.size() : 0;
+}
+
+status_t ItemTable::findPrimaryImage(uint32_t *imageIndex) {
+    if (!mImageItemsValid) {
+        return INVALID_OPERATION;
+    }
+
+    ssize_t index = mItemIdToImageMap.indexOfKey(mPrimaryItemId);
+    if (index < 0) {
+        return ERROR_MALFORMED;
+    }
+
+    *imageIndex = index;
+    return OK;
+}
+
+status_t ItemTable::findThumbnail(uint32_t *imageIndex) {
+    if (!mImageItemsValid) {
+        return INVALID_OPERATION;
+    }
+
+    ssize_t primaryIndex = mItemIdToImageMap.indexOfKey(mPrimaryItemId);
+    if (primaryIndex < 0) {
+        ALOGE("Primary item id %d not found!", mPrimaryItemId);
+        return ERROR_MALFORMED;
+    }
+
+    const ImageItem &primaryImage = mItemIdToImageMap[primaryIndex];
+    if (primaryImage.thumbnails.empty()) {
+        ALOGW("Using primary in place of thumbnail.");
+        *imageIndex = primaryIndex;
+        return OK;
+    }
+
+    ssize_t thumbnailIndex = mItemIdToImageMap.indexOfKey(
+            primaryImage.thumbnails[0]);
+    if (thumbnailIndex < 0) {
+        ALOGE("Thumbnail item id %d not found!", primaryImage.thumbnails[0]);
+        return ERROR_MALFORMED;
+    }
+
+    *imageIndex = thumbnailIndex;
+    return OK;
+}
+
+status_t ItemTable::getImageOffsetAndSize(
+        uint32_t *imageIndex, off64_t *offset, size_t *size) {
+    if (!mImageItemsValid) {
+        return INVALID_OPERATION;
+    }
+
+    if (imageIndex != NULL) {
+        if (*imageIndex >= mItemIdToImageMap.size()) {
+            ALOGE("Bad image index!");
+            return BAD_VALUE;
+        }
+        mCurrentImageIndex = *imageIndex;
+    }
+
+    ImageItem &image = mItemIdToImageMap.editValueAt(mCurrentImageIndex);
+    if (image.isGrid()) {
+        uint32_t tileItemId;
+        status_t err = image.getNextTileItemId(&tileItemId, imageIndex != NULL);
+        if (err != OK) {
+            return err;
+        }
+        ssize_t tileImageIndex = mItemIdToImageMap.indexOfKey(tileItemId);
+        if (tileImageIndex < 0) {
+            return ERROR_END_OF_STREAM;
+        }
+        *offset = mItemIdToImageMap[tileImageIndex].offset;
+        *size = mItemIdToImageMap[tileImageIndex].size;
+    } else {
+        if (imageIndex == NULL) {
+            // For single images, we only allow it to be read once, after that
+            // it's EOS.  New image index must be requested each time.
+            return ERROR_END_OF_STREAM;
+        }
+        *offset = mItemIdToImageMap[mCurrentImageIndex].offset;
+        *size = mItemIdToImageMap[mCurrentImageIndex].size;
+    }
+
+    return OK;
+}
+
+} // namespace heif
+
+}  // namespace android
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index a14d05e..5ef0f56 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -19,6 +19,7 @@
 
 #include <ctype.h>
 #include <inttypes.h>
+#include <memory>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,6 +28,7 @@
 
 #include "include/MPEG4Extractor.h"
 #include "include/SampleTable.h"
+#include "include/ItemTable.h"
 #include "include/ESDS.h"
 
 #include <media/stagefright/foundation/ABitReader.h>
@@ -35,6 +37,7 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/ColorUtils.h>
+#include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
@@ -71,7 +74,8 @@
                 const sp<SampleTable> &sampleTable,
                 Vector<SidxEntry> &sidx,
                 const Trex *trex,
-                off64_t firstMoofOffset);
+                off64_t firstMoofOffset,
+                const sp<ItemTable> &itemTable);
     virtual status_t init();
 
     virtual status_t start(MetaData *params = NULL);
@@ -133,6 +137,9 @@
 
     uint8_t *mSrcBuffer;
 
+    bool mIsHEIF;
+    sp<ItemTable> mItemTable;
+
     size_t parseNALSize(const uint8_t *data) const;
     status_t parseChunk(off64_t *offset);
     status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
@@ -284,45 +291,6 @@
 
 static const bool kUseHexDump = false;
 
-static void hexdump(const void *_data, size_t size) {
-    const uint8_t *data = (const uint8_t *)_data;
-    size_t offset = 0;
-    while (offset < size) {
-        printf("0x%04zx  ", offset);
-
-        size_t n = size - offset;
-        if (n > 16) {
-            n = 16;
-        }
-
-        for (size_t i = 0; i < 16; ++i) {
-            if (i == 8) {
-                printf(" ");
-            }
-
-            if (offset + i < size) {
-                printf("%02x ", data[offset + i]);
-            } else {
-                printf("   ");
-            }
-        }
-
-        printf(" ");
-
-        for (size_t i = 0; i < n; ++i) {
-            if (isprint(data[offset + i])) {
-                printf("%c", data[offset + i]);
-            } else {
-                printf(".");
-            }
-        }
-
-        printf("\n");
-
-        offset += 16;
-    }
-}
-
 static const char *FourCC2MIME(uint32_t fourcc) {
     switch (fourcc) {
         case FOURCC('m', 'p', '4', 'a'):
@@ -377,6 +345,7 @@
       mInitCheck(NO_INIT),
       mHeaderTimescale(0),
       mIsQT(false),
+      mIsHEIF(false),
       mFirstTrack(NULL),
       mLastTrack(NULL),
       mFileMetaData(new MetaData),
@@ -511,14 +480,6 @@
     return track->meta;
 }
 
-static void MakeFourCCString(uint32_t x, char *s) {
-    s[0] = x >> 24;
-    s[1] = (x >> 16) & 0xff;
-    s[2] = (x >> 8) & 0xff;
-    s[3] = x & 0xff;
-    s[4] = '\0';
-}
-
 status_t MPEG4Extractor::readMetaData() {
     if (mInitCheck != NO_INIT) {
         return mInitCheck;
@@ -528,7 +489,8 @@
     status_t err;
     bool sawMoovOrSidx = false;
 
-    while (!(sawMoovOrSidx && (mMdatFound || mMoofFound))) {
+    while (!((sawMoovOrSidx && (mMdatFound || mMoofFound)) ||
+            (mIsHEIF && (mItemTable != NULL) && mItemTable->isValid()))) {
         off64_t orig_offset = offset;
         err = parseChunk(&offset, 0);
 
@@ -580,6 +542,29 @@
         mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize);
         free(buf);
     }
+
+    if (mIsHEIF) {
+        sp<MetaData> meta = mItemTable->getImageMeta();
+        if (meta == NULL) {
+            return ERROR_MALFORMED;
+        }
+
+        Track *track = mLastTrack;
+        if (track != NULL) {
+            ALOGW("track is set before metadata is fully processed");
+        } else {
+            track = new Track;
+            track->next = NULL;
+            mFirstTrack = mLastTrack = track;
+        }
+
+        track->meta = meta;
+        track->meta->setInt32(kKeyTrackID, 0);
+        track->includes_expensive_metadata = false;
+        track->skipTrack = false;
+        track->timescale = 0;
+    }
+
     return mInitCheck;
 }
 
@@ -966,8 +951,9 @@
                     }
                 }
 
-                if (mLastTrack == NULL)
+                if (mLastTrack == NULL) {
                     return ERROR_MALFORMED;
+                }
 
                 mLastTrack->sampleTable = new SampleTable(mDataSource);
             }
@@ -1139,8 +1125,9 @@
             original_fourcc = ntohl(original_fourcc);
             ALOGV("read original format: %d", original_fourcc);
 
-            if (mLastTrack == NULL)
+            if (mLastTrack == NULL) {
                 return ERROR_MALFORMED;
+            }
 
             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
             uint32_t num_channels = 0;
@@ -1580,8 +1567,9 @@
         case FOURCC('s', 't', 'c', 'o'):
         case FOURCC('c', 'o', '6', '4'):
         {
-            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
+            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
                 return ERROR_MALFORMED;
+            }
 
             status_t err =
                 mLastTrack->sampleTable->setChunkOffsetParams(
@@ -1617,8 +1605,9 @@
         case FOURCC('s', 't', 's', 'z'):
         case FOURCC('s', 't', 'z', '2'):
         {
-            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
+            if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
                 return ERROR_MALFORMED;
+            }
 
             status_t err =
                 mLastTrack->sampleTable->setSampleSizeParams(
@@ -1776,35 +1765,49 @@
         {
             *offset += chunk_size;
 
-            // Best case the total data length inside "\xA9xyz" box
-            // would be 8, for instance "\xA9xyz" + "\x00\x04\x15\xc7" + "0+0/",
-            // where "\x00\x04" is the text string length with value = 4,
-            // "\0x15\xc7" is the language code = en, and "0+0" is a
+            // Best case the total data length inside "\xA9xyz" box would
+            // be 9, for instance "\xA9xyz" + "\x00\x05\x15\xc7" + "+0+0/",
+            // where "\x00\x05" is the text string length with value = 5,
+            // "\0x15\xc7" is the language code = en, and "+0+0/" is a
             // location (string) value with longitude = 0 and latitude = 0.
-            if (chunk_data_size < 8) {
+            // Since some devices encountered in the wild omit the trailing
+            // slash, we'll allow that.
+            if (chunk_data_size < 8) { // 8 instead of 9 to allow for missing /
                 return ERROR_MALFORMED;
             }
 
-            // Worst case the location string length would be 18,
-            // for instance +90.0000-180.0000, without the trailing "/" and
-            // the string length + language code, and some devices include
-            // an additional 8 bytes of altitude, e.g. +007.186
-            char buffer[18 + 8];
-
-            // Substracting 5 from the data size is because the text string length +
-            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
-            off64_t location_length = chunk_data_size - 5;
-            if (location_length >= (off64_t) sizeof(buffer)) {
-                return ERROR_MALFORMED;
-            }
-
-            if (mDataSource->readAt(
-                        data_offset + 4, buffer, location_length) < location_length) {
+            uint16_t len;
+            if (!mDataSource->getUInt16(data_offset, &len)) {
                 return ERROR_IO;
             }
 
-            buffer[location_length] = '\0';
-            mFileMetaData->setCString(kKeyLocation, buffer);
+            // allow "+0+0" without trailing slash
+            if (len < 4 || len > chunk_data_size - 4) {
+                return ERROR_MALFORMED;
+            }
+            // The location string following the language code is formatted
+            // according to ISO 6709:2008 (https://en.wikipedia.org/wiki/ISO_6709).
+            // Allocate 2 extra bytes, in case we need to add a trailing slash,
+            // and to add a terminating 0.
+            std::unique_ptr<char[]> buffer(new (std::nothrow) char[len+2]());
+            if (!buffer) {
+                return NO_MEMORY;
+            }
+
+            if (mDataSource->readAt(
+                        data_offset + 4, &buffer[0], len) < len) {
+                return ERROR_IO;
+            }
+
+            len = strlen(&buffer[0]);
+            if (len < 4) {
+                return ERROR_MALFORMED;
+            }
+            // Add a trailing slash if there wasn't one.
+            if (buffer[len - 1] != '/') {
+                buffer[len] = '/';
+            }
+            mFileMetaData->setCString(kKeyLocation, &buffer[0]);
             break;
         }
 
@@ -2020,6 +2023,28 @@
             break;
         }
 
+        case FOURCC('i', 'l', 'o', 'c'):
+        case FOURCC('i', 'i', 'n', 'f'):
+        case FOURCC('i', 'p', 'r', 'p'):
+        case FOURCC('p', 'i', 't', 'm'):
+        case FOURCC('i', 'd', 'a', 't'):
+        case FOURCC('i', 'r', 'e', 'f'):
+        case FOURCC('i', 'p', 'r', 'o'):
+        {
+            if (mIsHEIF) {
+                if (mItemTable == NULL) {
+                    mItemTable = new ItemTable(mDataSource);
+                }
+                status_t err = mItemTable->parse(
+                        chunk_type, data_offset, chunk_data_size);
+                if (err != OK) {
+                    return err;
+                }
+            }
+            *offset += chunk_size;
+            break;
+        }
+
         case FOURCC('m', 'e', 'a', 'n'):
         case FOURCC('n', 'a', 'm', 'e'):
         case FOURCC('d', 'a', 't', 'a'):
@@ -2367,6 +2392,7 @@
 
             off64_t stop_offset = *offset + chunk_size;
             uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
+            std::set<uint32_t> brandSet;
             for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
                 if (i == 1) {
                     // Skip this index, it refers to the minorVersion,
@@ -2380,10 +2406,15 @@
                 }
 
                 brand = ntohl(brand);
-                if (brand == FOURCC('q', 't', ' ', ' ')) {
-                    mIsQT = true;
-                    break;
-                }
+                brandSet.insert(brand);
+            }
+
+            if (brandSet.count(FOURCC('q', 't', ' ', ' ')) > 0) {
+                mIsQT = true;
+            } else if (brandSet.count(FOURCC('m', 'i', 'f', '1')) > 0
+                    && brandSet.count(FOURCC('h', 'e', 'i', 'c')) > 0) {
+                mIsHEIF = true;
+                ALOGV("identified HEIF image");
             }
 
             *offset = stop_offset;
@@ -3332,7 +3363,7 @@
 
     sp<MPEG4Source> source =  new MPEG4Source(this,
             track->meta, mDataSource, track->timescale, track->sampleTable,
-            mSidxEntries, trex, mMoofOffset);
+            mSidxEntries, trex, mMoofOffset, mItemTable);
     if (source->init() != OK) {
         return NULL;
     }
@@ -3721,7 +3752,8 @@
         const sp<SampleTable> &sampleTable,
         Vector<SidxEntry> &sidx,
         const Trex *trex,
-        off64_t firstMoofOffset)
+        off64_t firstMoofOffset,
+        const sp<ItemTable> &itemTable)
     : mOwner(owner),
       mFormat(format),
       mDataSource(dataSource),
@@ -3746,7 +3778,9 @@
       mGroup(NULL),
       mBuffer(NULL),
       mWantsNALFragments(false),
-      mSrcBuffer(NULL) {
+      mSrcBuffer(NULL),
+      mIsHEIF(itemTable != NULL),
+      mItemTable(itemTable) {
 
     memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
 
@@ -4521,77 +4555,93 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-        uint32_t findFlags = 0;
-        switch (mode) {
-            case ReadOptions::SEEK_PREVIOUS_SYNC:
-                findFlags = SampleTable::kFlagBefore;
-                break;
-            case ReadOptions::SEEK_NEXT_SYNC:
-                findFlags = SampleTable::kFlagAfter;
-                break;
-            case ReadOptions::SEEK_CLOSEST_SYNC:
-            case ReadOptions::SEEK_CLOSEST:
-                findFlags = SampleTable::kFlagClosest;
-                break;
-            default:
-                CHECK(!"Should not be here.");
-                break;
-        }
+        if (mIsHEIF) {
+            CHECK(mSampleTable == NULL);
+            CHECK(mItemTable != NULL);
 
-        uint32_t sampleIndex;
-        status_t err = mSampleTable->findSampleAtTime(
-                seekTimeUs, 1000000, mTimescale,
-                &sampleIndex, findFlags);
-
-        if (mode == ReadOptions::SEEK_CLOSEST) {
-            // We found the closest sample already, now we want the sync
-            // sample preceding it (or the sample itself of course), even
-            // if the subsequent sync sample is closer.
-            findFlags = SampleTable::kFlagBefore;
-        }
-
-        uint32_t syncSampleIndex;
-        if (err == OK) {
-            err = mSampleTable->findSyncSampleNear(
-                    sampleIndex, &syncSampleIndex, findFlags);
-        }
-
-        uint32_t sampleTime;
-        if (err == OK) {
-            err = mSampleTable->getMetaDataForSample(
-                    sampleIndex, NULL, NULL, &sampleTime);
-        }
-
-        if (err != OK) {
-            if (err == ERROR_OUT_OF_RANGE) {
-                // An attempt to seek past the end of the stream would
-                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
-                // this all the way to the MediaPlayer would cause abnormal
-                // termination. Legacy behaviour appears to be to behave as if
-                // we had seeked to the end of stream, ending normally.
-                err = ERROR_END_OF_STREAM;
+            status_t err;
+            if (seekTimeUs >= 0) {
+                err = mItemTable->findPrimaryImage(&mCurrentSampleIndex);
+            } else {
+                err = mItemTable->findThumbnail(&mCurrentSampleIndex);
             }
-            ALOGV("end of stream");
-            return err;
-        }
+            if (err != OK) {
+                return err;
+            }
+        } else {
+            uint32_t findFlags = 0;
+            switch (mode) {
+                case ReadOptions::SEEK_PREVIOUS_SYNC:
+                    findFlags = SampleTable::kFlagBefore;
+                    break;
+                case ReadOptions::SEEK_NEXT_SYNC:
+                    findFlags = SampleTable::kFlagAfter;
+                    break;
+                case ReadOptions::SEEK_CLOSEST_SYNC:
+                case ReadOptions::SEEK_CLOSEST:
+                    findFlags = SampleTable::kFlagClosest;
+                    break;
+                default:
+                    CHECK(!"Should not be here.");
+                    break;
+            }
 
-        if (mode == ReadOptions::SEEK_CLOSEST) {
-            targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
-        }
+            uint32_t sampleIndex;
+            status_t err = mSampleTable->findSampleAtTime(
+                    seekTimeUs, 1000000, mTimescale,
+                    &sampleIndex, findFlags);
+
+            if (mode == ReadOptions::SEEK_CLOSEST) {
+                // We found the closest sample already, now we want the sync
+                // sample preceding it (or the sample itself of course), even
+                // if the subsequent sync sample is closer.
+                findFlags = SampleTable::kFlagBefore;
+            }
+
+            uint32_t syncSampleIndex;
+            if (err == OK) {
+                err = mSampleTable->findSyncSampleNear(
+                        sampleIndex, &syncSampleIndex, findFlags);
+            }
+
+            uint32_t sampleTime;
+            if (err == OK) {
+                err = mSampleTable->getMetaDataForSample(
+                        sampleIndex, NULL, NULL, &sampleTime);
+            }
+
+            if (err != OK) {
+                if (err == ERROR_OUT_OF_RANGE) {
+                    // An attempt to seek past the end of the stream would
+                    // normally cause this ERROR_OUT_OF_RANGE error. Propagating
+                    // this all the way to the MediaPlayer would cause abnormal
+                    // termination. Legacy behaviour appears to be to behave as if
+                    // we had seeked to the end of stream, ending normally.
+                    err = ERROR_END_OF_STREAM;
+                }
+                ALOGV("end of stream");
+                return err;
+            }
+
+            if (mode == ReadOptions::SEEK_CLOSEST) {
+                targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
+            }
 
 #if 0
-        uint32_t syncSampleTime;
-        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
-                    syncSampleIndex, NULL, NULL, &syncSampleTime));
+            uint32_t syncSampleTime;
+            CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
+                        syncSampleIndex, NULL, NULL, &syncSampleTime));
 
-        ALOGI("seek to time %lld us => sample at time %lld us, "
-             "sync sample at time %lld us",
-             seekTimeUs,
-             sampleTime * 1000000ll / mTimescale,
-             syncSampleTime * 1000000ll / mTimescale);
+            ALOGI("seek to time %lld us => sample at time %lld us, "
+                 "sync sample at time %lld us",
+                 seekTimeUs,
+                 sampleTime * 1000000ll / mTimescale,
+                 syncSampleTime * 1000000ll / mTimescale);
 #endif
 
-        mCurrentSampleIndex = syncSampleIndex;
+            mCurrentSampleIndex = syncSampleIndex;
+        }
+
         if (mBuffer != NULL) {
             mBuffer->release();
             mBuffer = NULL;
@@ -4608,9 +4658,19 @@
     if (mBuffer == NULL) {
         newBuffer = true;
 
-        status_t err =
-            mSampleTable->getMetaDataForSample(
+        status_t err;
+        if (!mIsHEIF) {
+            err = mSampleTable->getMetaDataForSample(
                     mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
+        } else {
+            err = mItemTable->getImageOffsetAndSize(
+                    options && options->getSeekTo(&seekTimeUs, &mode) ?
+                            &mCurrentSampleIndex : NULL, &offset, &size);
+
+            cts = stts = 0;
+            isSyncSample = 0;
+            ALOGV("image offset %lld, size %zu", (long long)offset, size);
+        }
 
         if (err != OK) {
             return err;
@@ -5180,7 +5240,8 @@
         || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
         || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
         || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
-        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
+        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)
+        || !memcmp(header, "ftypmif1", 8) || !memcmp(header, "ftypheic", 8)) {
         *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
         *confidence = 0.4;
 
@@ -5209,6 +5270,8 @@
 
         FOURCC('3', 'g', '2', 'a'),  // 3GPP2
         FOURCC('3', 'g', '2', 'b'),
+        FOURCC('m', 'i', 'f', '1'),  // HEIF image
+        FOURCC('h', 'e', 'i', 'c'),  // HEIF image
     };
 
     for (size_t i = 0;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index bd71632..98d101a 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -23,7 +23,8 @@
 #include "include/SharedMemoryBuffer.h"
 #include "include/SoftwareRenderer.h"
 
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+
 #include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 51f1ba3..640cb82 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
 #define LOG_TAG "NuMediaExtractor"
 #include <utils/Log.h>
 
@@ -35,7 +35,6 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
-#include <android/media/ICas.h>
 
 namespace android {
 
@@ -83,8 +82,8 @@
         return ERROR_UNSUPPORTED;
     }
 
-    if (mCas != NULL) {
-        mImpl->setMediaCas(mCas);
+    if (!mCasToken.empty()) {
+        mImpl->setMediaCas(mCasToken);
     }
 
     status_t err = updateDurationAndBitrate();
@@ -119,8 +118,8 @@
         return ERROR_UNSUPPORTED;
     }
 
-    if (mCas != NULL) {
-        mImpl->setMediaCas(mCas);
+    if (!mCasToken.empty()) {
+        mImpl->setMediaCas(mCasToken);
     }
 
     err = updateDurationAndBitrate();
@@ -149,8 +148,8 @@
         return ERROR_UNSUPPORTED;
     }
 
-    if (mCas != NULL) {
-        mImpl->setMediaCas(mCas);
+    if (!mCasToken.empty()) {
+        mImpl->setMediaCas(mCasToken);
     }
 
     err = updateDurationAndBitrate();
@@ -161,24 +160,36 @@
     return err;
 }
 
-status_t NuMediaExtractor::setMediaCas(const sp<ICas> &cas) {
-    ALOGV("setMediaCas: cas=%p", cas.get());
+static String8 arrayToString(const std::vector<uint8_t> &array) {
+    String8 result;
+    for (size_t i = 0; i < array.size(); i++) {
+        result.appendFormat("%02x ", array[i]);
+    }
+    if (result.isEmpty()) {
+        result.append("(null)");
+    }
+    return result;
+}
+
+status_t NuMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
+    ALOGV("setMediaCas: casToken={%s}", arrayToString(casToken).c_str());
 
     Mutex::Autolock autoLock(mLock);
 
-    if (cas == NULL) {
+    if (casToken.empty()) {
         return BAD_VALUE;
     }
 
+    mCasToken = casToken;
+
     if (mImpl != NULL) {
-        mImpl->setMediaCas(cas);
+        mImpl->setMediaCas(casToken);
         status_t err = updateDurationAndBitrate();
         if (err != OK) {
             return err;
         }
     }
 
-    mCas = cas;
     return OK;
 }
 
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index f0c27ac..4ff2bfe 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -85,7 +85,8 @@
     status_t status;
     if (fd < 0) {
         // couldn't open it locally, maybe the media server can?
-        status = mRetriever->setDataSource(NULL /* httpService */, path);
+        sp<IMediaHTTPService> nullService;
+        status = mRetriever->setDataSource(nullService, path);
     } else {
         status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL);
         close(fd);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 03dc9df..f36ff97 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -121,12 +121,12 @@
 }
 
 status_t StagefrightMetadataRetriever::setDataSource(
-        const sp<DataSource>& source) {
+        const sp<DataSource>& source, const char *mime) {
     ALOGV("setDataSource(DataSource)");
 
     clearMetadata();
     mSource = source;
-    mExtractor = MediaExtractor::Create(mSource);
+    mExtractor = MediaExtractor::Create(mSource, mime);
 
     if (mExtractor == NULL) {
         ALOGE("Failed to instantiate a MediaExtractor.");
@@ -137,17 +137,164 @@
     return OK;
 }
 
+static VideoFrame *allocVideoFrame(
+        const sp<MetaData> &trackMeta, int32_t width, int32_t height, int32_t bpp, bool metaOnly) {
+    int32_t rotationAngle;
+    if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
+        rotationAngle = 0;  // By default, no rotation
+    }
+
+    uint32_t type;
+    const void *iccData;
+    size_t iccSize;
+    if (!trackMeta->findData(kKeyIccProfile, &type, &iccData, &iccSize)){
+        iccData = NULL;
+        iccSize = 0;
+    }
+
+    int32_t sarWidth, sarHeight;
+    int32_t displayWidth, displayHeight;
+    if (trackMeta->findInt32(kKeySARWidth, &sarWidth)
+            && trackMeta->findInt32(kKeySARHeight, &sarHeight)
+            && sarHeight != 0) {
+        displayWidth = (width * sarWidth) / sarHeight;
+        displayHeight = height;
+    } else if (trackMeta->findInt32(kKeyDisplayWidth, &displayWidth)
+                && trackMeta->findInt32(kKeyDisplayHeight, &displayHeight)
+                && displayWidth > 0 && displayHeight > 0
+                && width > 0 && height > 0) {
+        ALOGV("found display size %dx%d", displayWidth, displayHeight);
+    } else {
+        displayWidth = width;
+        displayHeight = height;
+    }
+
+    return new VideoFrame(width, height, displayWidth, displayHeight,
+            rotationAngle, bpp, !metaOnly, iccData, iccSize);
+}
+
+static bool getDstColorFormat(android_pixel_format_t colorFormat,
+        OMX_COLOR_FORMATTYPE *omxColorFormat, int32_t *bpp) {
+    switch (colorFormat) {
+        case HAL_PIXEL_FORMAT_RGB_565:
+        {
+            *omxColorFormat = OMX_COLOR_Format16bitRGB565;
+            *bpp = 2;
+            return true;
+        }
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        {
+            *omxColorFormat = OMX_COLOR_Format32BitRGBA8888;
+            *bpp = 4;
+            return true;
+        }
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        {
+            *omxColorFormat = OMX_COLOR_Format32bitBGRA8888;
+            *bpp = 4;
+            return true;
+        }
+        default:
+        {
+            ALOGE("Unsupported color format: %d", colorFormat);
+            break;
+        }
+    }
+    return false;
+}
+
 static VideoFrame *extractVideoFrame(
         const AString &componentName,
         const sp<MetaData> &trackMeta,
         const sp<IMediaSource> &source,
         int64_t frameTimeUs,
-        int seekMode) {
-
+        int seekMode,
+        int colorFormat,
+        bool metaOnly) {
     sp<MetaData> format = source->getFormat();
 
+    MediaSource::ReadOptions::SeekMode mode =
+            static_cast<MediaSource::ReadOptions::SeekMode>(seekMode);
+    if (seekMode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC ||
+        seekMode > MediaSource::ReadOptions::SEEK_CLOSEST) {
+        ALOGE("Unknown seek mode: %d", seekMode);
+        return NULL;
+    }
+
+    int32_t dstBpp;
+    OMX_COLOR_FORMATTYPE dstFormat;
+    if (!getDstColorFormat(
+            (android_pixel_format_t)colorFormat, &dstFormat, &dstBpp)) {
+        return NULL;
+    }
+
+    if (metaOnly) {
+        int32_t width, height;
+        CHECK(trackMeta->findInt32(kKeyWidth, &width));
+        CHECK(trackMeta->findInt32(kKeyHeight, &height));
+        return allocVideoFrame(trackMeta, width, height, dstBpp, true);
+    }
+
+    MediaSource::ReadOptions options;
+    sp<MetaData> overrideMeta;
+    if (frameTimeUs < 0) {
+        uint32_t type;
+        const void *data;
+        size_t size;
+        int64_t thumbNailTime;
+        int32_t thumbnailWidth, thumbnailHeight;
+
+        // if we have a stand-alone thumbnail, set up the override meta,
+        // and set seekTo time to -1.
+        if (trackMeta->findInt32(kKeyThumbnailWidth, &thumbnailWidth)
+         && trackMeta->findInt32(kKeyThumbnailHeight, &thumbnailHeight)
+         && trackMeta->findData(kKeyThumbnailHVCC, &type, &data, &size)){
+            overrideMeta = new MetaData(*trackMeta);
+            overrideMeta->setInt32(kKeyWidth, thumbnailWidth);
+            overrideMeta->setInt32(kKeyHeight, thumbnailHeight);
+            overrideMeta->setData(kKeyHVCC, type, data, size);
+            thumbNailTime = -1ll;
+            ALOGV("thumbnail: %dx%d", thumbnailWidth, thumbnailHeight);
+        } else if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)
+                || thumbNailTime < 0) {
+            thumbNailTime = 0;
+        }
+
+        options.setSeekTo(thumbNailTime, mode);
+    } else {
+        options.setSeekTo(frameTimeUs, mode);
+    }
+
+    int32_t gridRows = 1, gridCols = 1;
+    int32_t numTiles = 1, tilesDecoded = 0;
+    if (overrideMeta == NULL) {
+        // check if we're dealing with a tiled heif
+        if (trackMeta->findInt32(kKeyGridRows, &gridRows) && gridRows > 0
+         && trackMeta->findInt32(kKeyGridCols, &gridCols) && gridCols > 0) {
+            int32_t width, height;
+            CHECK(trackMeta->findInt32(kKeyWidth, &width));
+            CHECK(trackMeta->findInt32(kKeyHeight, &height));
+
+            if ((width % gridCols == 0) && (height % gridRows == 0)) {
+                width /= gridCols;
+                height /= gridRows;
+                numTiles = gridCols * gridRows;
+
+                ALOGV("tile: %dx%d, numTiles %d", width, height, numTiles);
+
+                overrideMeta = new MetaData(*trackMeta);
+                overrideMeta->setInt32(kKeyWidth, width);
+                overrideMeta->setInt32(kKeyHeight, height);
+            }
+        }
+        if (overrideMeta == NULL) {
+            gridRows = gridCols = numTiles = 1;
+            overrideMeta = trackMeta;
+        }
+    }
+
     sp<AMessage> videoFormat;
-    if (convertMetaDataToMessage(trackMeta, &videoFormat) != OK) {
+    if (convertMetaDataToMessage(overrideMeta, &videoFormat) != OK) {
         ALOGE("b/23680780");
         ALOGW("Failed to convert meta data to message");
         return NULL;
@@ -160,7 +307,8 @@
     // input and output ports, if seeking to a sync frame. NOTE: This request may
     // fail if component requires more than that for decoding.
     bool isSeekingClosest = (seekMode == MediaSource::ReadOptions::SEEK_CLOSEST);
-    if (!isSeekingClosest) {
+    bool decodeSingleFrame = !isSeekingClosest && (numTiles == 1);
+    if (decodeSingleFrame) {
         videoFormat->setInt32("android._num-input-buffers", 1);
         videoFormat->setInt32("android._num-output-buffers", 1);
     }
@@ -190,30 +338,6 @@
         return NULL;
     }
 
-    MediaSource::ReadOptions options;
-    if (seekMode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC ||
-        seekMode > MediaSource::ReadOptions::SEEK_CLOSEST) {
-
-        ALOGE("Unknown seek mode: %d", seekMode);
-        decoder->release();
-        return NULL;
-    }
-
-    MediaSource::ReadOptions::SeekMode mode =
-            static_cast<MediaSource::ReadOptions::SeekMode>(seekMode);
-
-    int64_t thumbNailTime;
-    if (frameTimeUs < 0) {
-        if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)
-                || thumbNailTime < 0) {
-            thumbNailTime = 0;
-        }
-        options.setSeekTo(thumbNailTime, mode);
-    } else {
-        thumbNailTime = -1;
-        options.setSeekTo(frameTimeUs, mode);
-    }
-
     err = source->start();
     if (err != OK) {
         ALOGW("source failed to start: %d (%s)", err, asString(err));
@@ -258,6 +382,8 @@
     bool firstSample = true;
     int64_t targetTimeUs = -1ll;
 
+    VideoFrame *frame = NULL;
+
     do {
         size_t inputIndex = -1;
         int64_t ptsUs = 0ll;
@@ -282,6 +408,9 @@
             if (err != OK) {
                 ALOGW("Input Error or EOS");
                 haveMoreInputs = false;
+                if (err == ERROR_END_OF_STREAM) {
+                    err = OK;
+                }
                 break;
             }
             if (firstSample && isSeekingClosest) {
@@ -293,6 +422,7 @@
             if (mediaBuffer->range_length() > codecBuffer->capacity()) {
                 ALOGE("buffer size (%zu) too large for codec input size (%zu)",
                         mediaBuffer->range_length(), codecBuffer->capacity());
+                haveMoreInputs = false;
                 err = BAD_VALUE;
             } else {
                 codecBuffer->setRange(0, mediaBuffer->range_length());
@@ -301,19 +431,20 @@
                 memcpy(codecBuffer->data(),
                         (const uint8_t*)mediaBuffer->data() + mediaBuffer->range_offset(),
                         mediaBuffer->range_length());
-                if (isAvcOrHevc && IsIDR(codecBuffer) && !isSeekingClosest) {
-                    // Only need to decode one IDR frame, unless we're seeking with CLOSEST
-                    // option, in which case we need to actually decode to targetTimeUs.
-                    haveMoreInputs = false;
-                    flags |= MediaCodec::BUFFER_FLAG_EOS;
-                }
             }
 
             mediaBuffer->release();
             break;
         }
 
-        if (err == OK && inputIndex < inputBuffers.size()) {
+        if (haveMoreInputs && inputIndex < inputBuffers.size()) {
+            if (isAvcOrHevc && IsIDR(codecBuffer) && decodeSingleFrame) {
+                // Only need to decode one IDR frame, unless we're seeking with CLOSEST
+                // option, in which case we need to actually decode to targetTimeUs.
+                haveMoreInputs = false;
+                flags |= MediaCodec::BUFFER_FLAG_EOS;
+            }
+
             ALOGV("QueueInput: size=%zu ts=%" PRId64 " us flags=%x",
                     codecBuffer->size(), ptsUs, flags);
             err = decoder->queueInputBuffer(
@@ -352,11 +483,70 @@
                 } else if (err == OK) {
                     // If we're seeking with CLOSEST option and obtained a valid targetTimeUs
                     // from the extractor, decode to the specified frame. Otherwise we're done.
-                    done = (targetTimeUs < 0ll) || (timeUs >= targetTimeUs);
                     ALOGV("Received an output buffer, timeUs=%lld", (long long)timeUs);
-                    if (!done) {
-                        err = decoder->releaseOutputBuffer(index);
+                    sp<MediaCodecBuffer> videoFrameBuffer = outputBuffers.itemAt(index);
+
+                    int32_t width, height;
+                    CHECK(outputFormat != NULL);
+                    CHECK(outputFormat->findInt32("width", &width));
+                    CHECK(outputFormat->findInt32("height", &height));
+
+                    int32_t crop_left, crop_top, crop_right, crop_bottom;
+                    if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
+                        crop_left = crop_top = 0;
+                        crop_right = width - 1;
+                        crop_bottom = height - 1;
                     }
+
+                    if (frame == NULL) {
+                        frame = allocVideoFrame(
+                                overrideMeta,
+                                (crop_right - crop_left + 1) * gridCols,
+                                (crop_bottom - crop_top + 1) * gridRows,
+                                dstBpp,
+                                false /*metaOnly*/);
+                    }
+
+                    int32_t srcFormat;
+                    CHECK(outputFormat->findInt32("color-format", &srcFormat));
+
+                    ColorConverter converter((OMX_COLOR_FORMATTYPE)srcFormat, dstFormat);
+
+                    int32_t dstLeft, dstTop, dstRight, dstBottom;
+                    if (numTiles == 1) {
+                        dstLeft = crop_left;
+                        dstTop = crop_top;
+                        dstRight = crop_right;
+                        dstBottom = crop_bottom;
+                    } else {
+                        dstLeft = tilesDecoded % gridCols * width;
+                        dstTop = tilesDecoded / gridCols * height;
+                        dstRight = dstLeft + width - 1;
+                        dstBottom = dstTop + height - 1;
+                    }
+
+                    if (converter.isValid()) {
+                        err = converter.convert(
+                                (const uint8_t *)videoFrameBuffer->data(),
+                                width, height,
+                                crop_left, crop_top, crop_right, crop_bottom,
+                                frame->mData,
+                                frame->mWidth,
+                                frame->mHeight,
+                                dstLeft, dstTop, dstRight, dstBottom);
+                    } else {
+                        ALOGE("Unable to convert from format 0x%08x to 0x%08x",
+                                srcFormat, dstFormat);
+
+                        err = ERROR_UNSUPPORTED;
+                    }
+
+                    done = (targetTimeUs < 0ll) || (timeUs >= targetTimeUs);
+                    if (numTiles > 1) {
+                        tilesDecoded++;
+                        done &= (tilesDecoded >= numTiles);
+                    }
+                    err = decoder->releaseOutputBuffer(index);
                 } else {
                     ALOGW("Received error %d (%s) instead of output", err, asString(err));
                     done = true;
@@ -366,102 +556,11 @@
         }
     } while (err == OK && !done);
 
-    if (err != OK || size <= 0 || outputFormat == NULL) {
-        ALOGE("Failed to decode thumbnail frame");
-        source->stop();
-        decoder->release();
-        return NULL;
-    }
-
-    ALOGV("successfully decoded video frame.");
-    sp<MediaCodecBuffer> videoFrameBuffer = outputBuffers.itemAt(index);
-
-    if (thumbNailTime >= 0) {
-        if (timeUs != thumbNailTime) {
-            AString mime;
-            CHECK(outputFormat->findString("mime", &mime));
-
-            ALOGV("thumbNailTime = %lld us, timeUs = %lld us, mime = %s",
-                    (long long)thumbNailTime, (long long)timeUs, mime.c_str());
-        }
-    }
-
-    int32_t width, height;
-    CHECK(outputFormat->findInt32("width", &width));
-    CHECK(outputFormat->findInt32("height", &height));
-
-    int32_t crop_left, crop_top, crop_right, crop_bottom;
-    if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
-        crop_left = crop_top = 0;
-        crop_right = width - 1;
-        crop_bottom = height - 1;
-    }
-
-    int32_t rotationAngle;
-    if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
-        rotationAngle = 0;  // By default, no rotation
-    }
-
-    VideoFrame *frame = new VideoFrame;
-    frame->mWidth = crop_right - crop_left + 1;
-    frame->mHeight = crop_bottom - crop_top + 1;
-    frame->mDisplayWidth = frame->mWidth;
-    frame->mDisplayHeight = frame->mHeight;
-    frame->mSize = frame->mWidth * frame->mHeight * 2;
-    frame->mData = new uint8_t[frame->mSize];
-    frame->mRotationAngle = rotationAngle;
-
-    int32_t sarWidth, sarHeight;
-    if (trackMeta->findInt32(kKeySARWidth, &sarWidth)
-            && trackMeta->findInt32(kKeySARHeight, &sarHeight)
-            && sarHeight != 0) {
-        frame->mDisplayWidth = (frame->mDisplayWidth * sarWidth) / sarHeight;
-    } else {
-        int32_t width, height;
-        if (trackMeta->findInt32(kKeyDisplayWidth, &width)
-                && trackMeta->findInt32(kKeyDisplayHeight, &height)
-                && frame->mDisplayWidth > 0 && frame->mDisplayHeight > 0
-                && width > 0 && height > 0) {
-            if (frame->mDisplayHeight * (int64_t)width / height > (int64_t)frame->mDisplayWidth) {
-                frame->mDisplayHeight =
-                        (int32_t)(height * (int64_t)frame->mDisplayWidth / width);
-            } else {
-                frame->mDisplayWidth =
-                        (int32_t)(frame->mDisplayHeight * (int64_t)width / height);
-            }
-            ALOGV("thumbNail width and height are overridden to %d x %d",
-                    frame->mDisplayWidth, frame->mDisplayHeight);
-        }
-    }
-
-    int32_t srcFormat;
-    CHECK(outputFormat->findInt32("color-format", &srcFormat));
-
-    ColorConverter converter((OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565);
-
-    if (converter.isValid()) {
-        err = converter.convert(
-                (const uint8_t *)videoFrameBuffer->data(),
-                width, height,
-                crop_left, crop_top, crop_right, crop_bottom,
-                frame->mData,
-                frame->mWidth,
-                frame->mHeight,
-                0, 0, frame->mWidth - 1, frame->mHeight - 1);
-    } else {
-        ALOGE("Unable to convert from format 0x%08x to RGB565", srcFormat);
-
-        err = ERROR_UNSUPPORTED;
-    }
-
-    videoFrameBuffer.clear();
     source->stop();
-    decoder->releaseOutputBuffer(index);
     decoder->release();
 
     if (err != OK) {
-        ALOGE("Colorconverter failed to convert frame.");
-
+        ALOGE("failed to get video frame (err %d)", err);
         delete frame;
         frame = NULL;
     }
@@ -470,9 +569,10 @@
 }
 
 VideoFrame *StagefrightMetadataRetriever::getFrameAtTime(
-        int64_t timeUs, int option) {
+        int64_t timeUs, int option, int colorFormat, bool metaOnly) {
 
-    ALOGV("getFrameAtTime: %" PRId64 " us option: %d", timeUs, option);
+    ALOGV("getFrameAtTime: %" PRId64 " us option: %d colorFormat: %d, metaOnly: %d",
+            timeUs, option, colorFormat, metaOnly);
 
     if (mExtractor.get() == NULL) {
         ALOGV("no extractor.");
@@ -540,8 +640,8 @@
 
     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
         const AString &componentName = matchingCodecs[i];
-        VideoFrame *frame =
-            extractVideoFrame(componentName, trackMeta, source, timeUs, option);
+        VideoFrame *frame = extractVideoFrame(
+                componentName, trackMeta, source, timeUs, option, colorFormat, metaOnly);
 
         if (frame != NULL) {
             return frame;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 0aea8e1..a3bda5d 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1874,5 +1874,13 @@
     return result;
 }
 
+void MakeFourCCString(uint32_t x, char *s) {
+    s[0] = x >> 24;
+    s[1] = (x >> 16) & 0xff;
+    s[2] = (x >> 8) & 0xff;
+    s[3] = x & 0xff;
+    s[4] = '\0';
+}
+
 }  // namespace android
 
diff --git a/media/libstagefright/codecs/aacdec/Android.bp b/media/libstagefright/codecs/aacdec/Android.bp
index 6e04c1e..1daaf49 100644
--- a/media/libstagefright/codecs/aacdec/Android.bp
+++ b/media/libstagefright/codecs/aacdec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_aacdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "SoftAAC2.cpp",
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 9fbdb72..e0c0c32 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -218,6 +218,30 @@
 OMX_ERRORTYPE SoftAAC2::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch ((OMX_U32) index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAac:
         {
             OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
@@ -342,6 +366,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingAAC)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAac:
         {
             const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index a1cf285..73a3965 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -17,7 +17,7 @@
 #ifndef SOFT_AAC_2_H_
 #define SOFT_AAC_2_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 #include "aacdecoder_lib.h"
 #include "DrcPresModeWrap.h"
diff --git a/media/libstagefright/codecs/aacenc/Android.bp b/media/libstagefright/codecs/aacenc/Android.bp
index 1a7ffca..4b478ea 100644
--- a/media/libstagefright/codecs/aacenc/Android.bp
+++ b/media/libstagefright/codecs/aacenc/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_aacenc",
+    vendor_available: true,
 
     srcs: [
         "basic_op/basicop2.c",
@@ -111,6 +112,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_aacenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftAACEncoder2.cpp"],
 
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder.h b/media/libstagefright/codecs/aacenc/SoftAACEncoder.h
index 981cbbb..e64c1b7 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder.h
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AAC_ENCODER_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 struct VO_AUDIO_CODECAPI;
 struct VO_MEM_OPERATOR;
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
index 123fd25..681dcf2 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AAC_ENCODER_2_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 #include "aacenc_lib.h"
 
diff --git a/media/libstagefright/codecs/amrnb/common/Android.bp b/media/libstagefright/codecs/amrnb/common/Android.bp
index c5ac558..5177593 100644
--- a/media/libstagefright/codecs/amrnb/common/Android.bp
+++ b/media/libstagefright/codecs/amrnb/common/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_amrnb_common",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "src/add.cpp",
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index 996183b..a61fb57 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_amrnbdec",
+    vendor_available: true,
 
     srcs: [
         "src/a_refl.cpp",
@@ -55,13 +56,20 @@
     //    ],
     //},
 
-    shared_libs: ["libstagefright_amrnb_common"],
+    shared_libs: [
+        "libstagefright_amrnb_common",
+        "liblog",
+    ],
 }
 
 //###############################################################################
 
 cc_library_shared {
     name: "libstagefright_soft_amrdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftAMR.cpp"],
 
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index 7553153..b7e84ec 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -143,6 +143,30 @@
 OMX_ERRORTYPE SoftAMR::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingAMR : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAmr:
         {
             OMX_AUDIO_PARAM_AMRTYPE *amrParams =
@@ -236,6 +260,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingAMR)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAmr:
         {
             const OMX_AUDIO_PARAM_AMRTYPE *aacParams =
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.h b/media/libstagefright/codecs/amrnb/dec/SoftAMR.h
index 758d6ac..869b81d 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.h
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AMR_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index af0f8c2..04ed07f 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_amrnbenc",
+    vendor_available: true,
 
     srcs: [
         "src/amrencode.cpp",
@@ -83,6 +84,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_amrnbenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftAMRNBEncoder.cpp"],
 
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h
index 50178c4..c73e4dd 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AMRNB_ENCODER_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/libstagefright/codecs/amrwb/Android.bp
index e261c04..b932ccc 100644
--- a/media/libstagefright/codecs/amrwb/Android.bp
+++ b/media/libstagefright/codecs/amrwb/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_amrwbdec",
+    vendor_available: true,
 
     srcs: [
         "src/agc2_amr_wb.cpp",
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 5c5a122..d337cde 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_amrwbenc",
+    vendor_available: true,
 
     srcs: [
         "src/autocorr.c",
@@ -144,6 +145,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_amrwbenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftAMRWBEncoder.cpp"],
 
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h
index d0c1dab..8950a8c 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AMRWB_ENCODER_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 #include "voAMRWB.h"
 
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 6b996a7..3fa8d7f 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_avcdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     static_libs: ["libavcdec"],
     srcs: ["SoftAVCDec.cpp"],
@@ -12,7 +16,7 @@
     ],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.h b/media/libstagefright/codecs/avcdec/SoftAVCDec.h
index 18b7556..679ed3e 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.h
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.h
@@ -18,7 +18,7 @@
 
 #define SOFT_H264_DEC_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 #include <sys/time.h>
 
 namespace android {
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 49021a9..6c4311b 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_avcenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     static_libs: ["libavcenc"],
     srcs: ["SoftAVCEnc.cpp"],
@@ -13,7 +17,7 @@
     ],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libutils",
         "liblog",
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index b1af17b..326207b 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -27,7 +27,6 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
 #include <OMX_IndexExt.h>
 #include <OMX_VideoExt.h>
 
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index 818e4a1..a43cdf1 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -21,7 +21,7 @@
 #include <media/stagefright/foundation/ABase.h>
 #include <utils/Vector.h>
 
-#include "SoftVideoEncoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/common/Android.bp b/media/libstagefright/codecs/common/Android.bp
index 021e6af..3726922 100644
--- a/media/libstagefright/codecs/common/Android.bp
+++ b/media/libstagefright/codecs/common/Android.bp
@@ -1,5 +1,9 @@
 cc_library {
     name: "libstagefright_enc_common",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["cmnMemory.c"],
 
diff --git a/media/libstagefright/codecs/flac/dec/Android.bp b/media/libstagefright/codecs/flac/dec/Android.bp
index 6ac264d..5652594 100644
--- a/media/libstagefright/codecs/flac/dec/Android.bp
+++ b/media/libstagefright/codecs/flac/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_flacdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "SoftFlacDecoder.cpp",
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
index c09081d..4a21c34 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
@@ -18,7 +18,7 @@
 #define SOFT_FLAC_DECODER_H
 
 #include "FLACDecoder.h"
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/flac/enc/Android.bp b/media/libstagefright/codecs/flac/enc/Android.bp
index d1413f6..6197157 100644
--- a/media/libstagefright/codecs/flac/enc/Android.bp
+++ b/media/libstagefright/codecs/flac/enc/Android.bp
@@ -22,7 +22,7 @@
     },
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
@@ -32,5 +32,9 @@
     static_libs: ["libFLAC"],
 
     name: "libstagefright_soft_flacenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
 }
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
index 6027f76..f4f0655 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
@@ -18,7 +18,7 @@
 
 #define SOFT_FLAC_ENC_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 #include "FLAC/stream_encoder.h"
 
diff --git a/media/libstagefright/codecs/g711/dec/Android.bp b/media/libstagefright/codecs/g711/dec/Android.bp
index b78b689..0e6f468 100644
--- a/media/libstagefright/codecs/g711/dec/Android.bp
+++ b/media/libstagefright/codecs/g711/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_g711dec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftG711.cpp"],
 
@@ -9,7 +13,7 @@
     ],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libutils",
         "liblog",
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index f7c0429..7a4cca9 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -105,6 +105,30 @@
 OMX_ERRORTYPE SoftG711::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingG711 : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -173,6 +197,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingG711)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamStandardComponentRole:
         {
             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.h b/media/libstagefright/codecs/g711/dec/SoftG711.h
index 16b6340..3ece246 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.h
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.h
@@ -18,7 +18,7 @@
 
 #define SOFT_G711_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/gsm/dec/Android.bp b/media/libstagefright/codecs/gsm/dec/Android.bp
index 8e86ad6..7be86a4 100644
--- a/media/libstagefright/codecs/gsm/dec/Android.bp
+++ b/media/libstagefright/codecs/gsm/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_gsmdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftGSM.cpp"],
 
@@ -23,7 +27,7 @@
     },
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libutils",
         "liblog",
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 11999b4..d777229 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -105,6 +105,30 @@
 OMX_ERRORTYPE SoftGSM::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingGSMFR : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -164,6 +188,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingGSMFR)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamStandardComponentRole:
         {
             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.h b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
index 0303dea..ef86915 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.h
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.h
@@ -18,7 +18,7 @@
 
 #define SOFT_GSM_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 extern "C" {
 #include "gsm.h"
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index cd75c97..3fd1652 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_hevcdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     static_libs: ["libhevcdec"],
     srcs: ["SoftHEVC.cpp"],
@@ -22,7 +26,7 @@
     },
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.h b/media/libstagefright/codecs/hevcdec/SoftHEVC.h
index e7c2127..5800490 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.h
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.h
@@ -18,7 +18,7 @@
 
 #define SOFT_HEVC_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 #include <sys/time.h>
 
 namespace android {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index 04ea075..2619131 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -1,5 +1,7 @@
 cc_library_static {
     name: "libstagefright_m4vh263dec",
+    vendor_available: true,
+    shared_libs: ["liblog"],
 
     srcs: [
         "src/adaptive_smooth_no_mmx.cpp",
@@ -66,6 +68,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mpeg4dec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftMPEG4.cpp"],
 
@@ -87,7 +93,7 @@
     static_libs: ["libstagefright_m4vh263dec"],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
index 4114e7d..e399ac9 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
@@ -18,7 +18,7 @@
 
 #define SOFT_MPEG4_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 
 struct tagvideoDecControls;
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index da5b162..919b9d4 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_m4vh263enc",
+    vendor_available: true,
 
     srcs: [
         "src/bitstream_io.cpp",
@@ -52,6 +53,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mpeg4enc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftMPEG4Encoder.cpp"],
 
@@ -75,7 +80,7 @@
     static_libs: ["libstagefright_m4vh263enc"],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libutils",
         "liblog",
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 6d4cb69..7b90a01 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -29,7 +29,6 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
 
 #include "SoftMPEG4Encoder.h"
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
index ae8cb6f..00f2dd3 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
@@ -19,7 +19,7 @@
 
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/foundation/ABase.h>
-#include "SoftVideoEncoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
 #include "mp4enc_api.h"
 
 
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 0d0a2c6..b2e8f9b 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -1,5 +1,6 @@
 cc_library_static {
     name: "libstagefright_mp3dec",
+    vendor_available: true,
 
     srcs: [
         "src/pvmp3_normalize.cpp",
@@ -77,6 +78,10 @@
 
 cc_library_shared {
     name: "libstagefright_soft_mp3dec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftMP3.cpp"],
 
@@ -102,7 +107,7 @@
     },
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 3def1f0..2364684 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -134,6 +134,30 @@
 OMX_ERRORTYPE SoftMP3::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingMP3 : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -208,6 +232,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingMP3)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 3bfa6c7..976fd00 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -18,7 +18,7 @@
 
 #define SOFT_MP3_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 struct tPVMP3DecoderExternal;
 
diff --git a/media/libstagefright/codecs/mpeg2dec/Android.bp b/media/libstagefright/codecs/mpeg2dec/Android.bp
index 0144581..ed51797 100644
--- a/media/libstagefright/codecs/mpeg2dec/Android.bp
+++ b/media/libstagefright/codecs/mpeg2dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_mpeg2dec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     static_libs: ["libmpeg2dec"],
     srcs: ["SoftMPEG2.cpp"],
@@ -12,7 +16,7 @@
     ],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index 9a69226..9d5f342 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -789,7 +789,7 @@
 
             if (s_dec_op.u4_output_present) {
                 ssize_t timeStampIdx;
-                outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
+                outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
 
                 timeStampIdx = getMinTimestampIdx(mTimeStamps, mTimeStampsValid);
                 if (timeStampIdx < 0) {
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h
index 6729a54..338fc30 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h
@@ -18,7 +18,7 @@
 
 #define SOFT_MPEG2_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 #include <sys/time.h>
 
 namespace android {
diff --git a/media/libstagefright/codecs/on2/dec/Android.bp b/media/libstagefright/codecs/on2/dec/Android.bp
index c4242c2..249ab92 100644
--- a/media/libstagefright/codecs/on2/dec/Android.bp
+++ b/media/libstagefright/codecs/on2/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_vpxdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftVPX.cpp"],
 
@@ -11,7 +15,7 @@
     static_libs: ["libvpx"],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
index 84cf79c..d6bb902 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.h
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -18,7 +18,7 @@
 
 #define SOFT_VPX_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 
 #include "vpx/vpx_decoder.h"
 #include "vpx/vpx_codec.h"
diff --git a/media/libstagefright/codecs/on2/enc/Android.bp b/media/libstagefright/codecs/on2/enc/Android.bp
index 114c1be..0284719 100644
--- a/media/libstagefright/codecs/on2/enc/Android.bp
+++ b/media/libstagefright/codecs/on2/enc/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_vpxenc",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "SoftVPXEncoder.cpp",
@@ -26,7 +30,7 @@
     static_libs: ["libvpx"],
 
     shared_libs: [
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
index 86dfad7..dd86d36 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
@@ -18,7 +18,7 @@
 
 #define SOFT_VPX_ENCODER_H_
 
-#include "SoftVideoEncoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
 
 #include <OMX_VideoExt.h>
 #include <OMX_IndexExt.h>
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
index b8c1807..fad988b 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
@@ -18,7 +18,7 @@
 
 #define SOFT_AVC_H_
 
-#include "SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 #include <utils/KeyedVector.h>
 
 #include "H264SwDecApi.h"
diff --git a/media/libstagefright/codecs/opus/dec/Android.bp b/media/libstagefright/codecs/opus/dec/Android.bp
index 5d9c4c8..d7569a9 100644
--- a/media/libstagefright/codecs/opus/dec/Android.bp
+++ b/media/libstagefright/codecs/opus/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_opusdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftOpus.cpp"],
 
@@ -10,13 +14,15 @@
 
     shared_libs: [
         "libopus",
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
         "liblog",
     ],
 
+    cflags: ["-Werror"],
+
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 2ac6ce0..813004b 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -62,6 +62,7 @@
       mSeekPreRoll(0),
       mAnchorTimeUs(0),
       mNumFramesOutput(0),
+      mHaveEOS(false),
       mOutputPortSettingsChange(NONE) {
     initPorts();
     CHECK_EQ(initDecoder(), (status_t)OK);
@@ -129,6 +130,31 @@
 OMX_ERRORTYPE SoftOpus::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch ((int)index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS :
+                       OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAndroidOpus:
         {
             OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
@@ -212,6 +238,30 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding !=
+                           (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioAndroidOpus:
         {
             const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
@@ -335,7 +385,31 @@
     return static_cast<double>(ns) * kRate / 1000000000;
 }
 
-void SoftOpus::onQueueFilled(OMX_U32 portIndex) {
+void SoftOpus::handleEOS() {
+    List<BufferInfo *> &inQueue = getPortQueue(0);
+    List<BufferInfo *> &outQueue = getPortQueue(1);
+    CHECK(!inQueue.empty() && !outQueue.empty());
+
+    BufferInfo *outInfo = *outQueue.begin();
+    OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+    outHeader->nFilledLen = 0;
+    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+    mHaveEOS = true;
+
+    outQueue.erase(outQueue.begin());
+    outInfo->mOwnedByUs = false;
+    notifyFillBufferDone(outHeader);
+
+    BufferInfo *inInfo = *inQueue.begin();
+    OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+    inQueue.erase(inQueue.begin());
+    inInfo->mOwnedByUs = false;
+    notifyEmptyBufferDone(inHeader);
+
+    ++mInputBufferCount;
+}
+
+void SoftOpus::onQueueFilled(OMX_U32 /* portIndex */) {
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
@@ -343,104 +417,108 @@
         return;
     }
 
-    if (portIndex == 0 && mInputBufferCount < 3) {
-        BufferInfo *info = *inQueue.begin();
-        OMX_BUFFERHEADERTYPE *header = info->mHeader;
-
-        const uint8_t *data = header->pBuffer + header->nOffset;
-        size_t size = header->nFilledLen;
-
-        if (mInputBufferCount == 0) {
-            CHECK(mHeader == NULL);
-            mHeader = new OpusHeader();
-            memset(mHeader, 0, sizeof(*mHeader));
-            if (!ParseOpusHeader(data, size, mHeader)) {
-                ALOGV("Parsing Opus Header failed.");
-                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                return;
-            }
-
-            uint8_t channel_mapping[kMaxChannels] = {0};
-            if (mHeader->channels <= kMaxChannelsWithDefaultLayout) {
-                memcpy(&channel_mapping,
-                       kDefaultOpusChannelLayout,
-                       kMaxChannelsWithDefaultLayout);
-            } else {
-                memcpy(&channel_mapping,
-                       mHeader->stream_map,
-                       mHeader->channels);
-            }
-
-            int status = OPUS_INVALID_STATE;
-            mDecoder = opus_multistream_decoder_create(kRate,
-                                                       mHeader->channels,
-                                                       mHeader->num_streams,
-                                                       mHeader->num_coupled,
-                                                       channel_mapping,
-                                                       &status);
-            if (!mDecoder || status != OPUS_OK) {
-                ALOGV("opus_multistream_decoder_create failed status=%s",
-                      opus_strerror(status));
-                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                return;
-            }
-            status =
-                opus_multistream_decoder_ctl(mDecoder,
-                                             OPUS_SET_GAIN(mHeader->gain_db));
-            if (status != OPUS_OK) {
-                ALOGV("Failed to set OPUS header gain; status=%s",
-                      opus_strerror(status));
-                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                return;
-            }
-        } else if (mInputBufferCount == 1) {
-            mCodecDelay = ns_to_samples(
-                              *(reinterpret_cast<int64_t*>(header->pBuffer +
-                                                           header->nOffset)),
-                              kRate);
-            mSamplesToDiscard = mCodecDelay;
-        } else {
-            mSeekPreRoll = ns_to_samples(
-                               *(reinterpret_cast<int64_t*>(header->pBuffer +
-                                                            header->nOffset)),
-                               kRate);
-            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-            mOutputPortSettingsChange = AWAITING_DISABLED;
-        }
-
-        inQueue.erase(inQueue.begin());
-        info->mOwnedByUs = false;
-        notifyEmptyBufferDone(header);
-        ++mInputBufferCount;
-        return;
-    }
-
-    while (!inQueue.empty() && !outQueue.empty()) {
+    while (!mHaveEOS && !inQueue.empty() && !outQueue.empty()) {
         BufferInfo *inInfo = *inQueue.begin();
         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
 
-        // Ignore CSD re-submissions.
-        if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+        if (mInputBufferCount < 3) {
+            const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
+            size_t size = inHeader->nFilledLen;
+
+            if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && size == 0) {
+                handleEOS();
+                return;
+            }
+
+            if (mInputBufferCount == 0) {
+                CHECK(mHeader == NULL);
+                mHeader = new OpusHeader();
+                memset(mHeader, 0, sizeof(*mHeader));
+                if (!ParseOpusHeader(data, size, mHeader)) {
+                    ALOGV("Parsing Opus Header failed.");
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    return;
+                }
+
+                uint8_t channel_mapping[kMaxChannels] = {0};
+                if (mHeader->channels <= kMaxChannelsWithDefaultLayout) {
+                    memcpy(&channel_mapping,
+                           kDefaultOpusChannelLayout,
+                           kMaxChannelsWithDefaultLayout);
+                } else {
+                    memcpy(&channel_mapping,
+                           mHeader->stream_map,
+                           mHeader->channels);
+                }
+
+                int status = OPUS_INVALID_STATE;
+                mDecoder = opus_multistream_decoder_create(kRate,
+                                                           mHeader->channels,
+                                                           mHeader->num_streams,
+                                                           mHeader->num_coupled,
+                                                           channel_mapping,
+                                                           &status);
+                if (!mDecoder || status != OPUS_OK) {
+                    ALOGV("opus_multistream_decoder_create failed status=%s",
+                          opus_strerror(status));
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    return;
+                }
+                status =
+                    opus_multistream_decoder_ctl(mDecoder,
+                                                 OPUS_SET_GAIN(mHeader->gain_db));
+                if (status != OPUS_OK) {
+                    ALOGV("Failed to set OPUS header gain; status=%s",
+                          opus_strerror(status));
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    return;
+                }
+            } else if (mInputBufferCount == 1) {
+                mCodecDelay = ns_to_samples(
+                                  *(reinterpret_cast<int64_t*>(inHeader->pBuffer +
+                                                               inHeader->nOffset)),
+                                  kRate);
+                mSamplesToDiscard = mCodecDelay;
+            } else {
+                mSeekPreRoll = ns_to_samples(
+                                   *(reinterpret_cast<int64_t*>(inHeader->pBuffer +
+                                                                inHeader->nOffset)),
+                                   kRate);
+                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                mOutputPortSettingsChange = AWAITING_DISABLED;
+            }
+
+            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+                handleEOS();
+                return;
+            }
+
             inQueue.erase(inQueue.begin());
             inInfo->mOwnedByUs = false;
             notifyEmptyBufferDone(inHeader);
-            return;
+            ++mInputBufferCount;
+
+            continue;
+        }
+
+        // Ignore CSD re-submissions.
+        if (mInputBufferCount >= 3 && (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+                handleEOS();
+                return;
+            }
+
+            inQueue.erase(inQueue.begin());
+            inInfo->mOwnedByUs = false;
+            notifyEmptyBufferDone(inHeader);
+            continue;
         }
 
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
 
         if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && inHeader->nFilledLen == 0) {
-            inQueue.erase(inQueue.begin());
-            inInfo->mOwnedByUs = false;
-            notifyEmptyBufferDone(inHeader);
-
-            outHeader->nFilledLen = 0;
-            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-
-            outQueue.erase(outQueue.begin());
-            outInfo->mOwnedByUs = false;
-            notifyFillBufferDone(outHeader);
+            handleEOS();
             return;
         }
 
@@ -490,7 +568,6 @@
         }
 
         outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
-        outHeader->nFlags = 0;
 
         outHeader->nTimeStamp = mAnchorTimeUs +
                                 (mNumFramesOutput * 1000000ll) /
@@ -499,22 +576,20 @@
         mNumFramesOutput += numFrames;
 
         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
-            inHeader->nFilledLen = 0;
+            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+            mHaveEOS = true;
         } else {
-            inInfo->mOwnedByUs = false;
-            inQueue.erase(inQueue.begin());
-            inInfo = NULL;
-            notifyEmptyBufferDone(inHeader);
-            inHeader = NULL;
+            outHeader->nFlags = 0;
         }
 
+        inInfo->mOwnedByUs = false;
+        inQueue.erase(inQueue.begin());
+        notifyEmptyBufferDone(inHeader);
+        ++mInputBufferCount;
+
         outInfo->mOwnedByUs = false;
         outQueue.erase(outQueue.begin());
-        outInfo = NULL;
         notifyFillBufferDone(outHeader);
-        outHeader = NULL;
-
-        ++mInputBufferCount;
     }
 }
 
@@ -526,6 +601,7 @@
         opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
         mAnchorTimeUs = 0;
         mSamplesToDiscard = mSeekPreRoll;
+        mHaveEOS = false;
     }
 }
 
@@ -542,6 +618,7 @@
     }
 
     mOutputPortSettingsChange = NONE;
+    mHaveEOS = false;
 }
 
 void SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.h b/media/libstagefright/codecs/opus/dec/SoftOpus.h
index 97f6561..91cafa1 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.h
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.h
@@ -23,7 +23,7 @@
 
 #define SOFT_OPUS_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 struct OpusMSDecoder;
 
@@ -75,6 +75,7 @@
     int64_t mSamplesToDiscard;
     int64_t mAnchorTimeUs;
     int64_t mNumFramesOutput;
+    bool mHaveEOS;
 
     enum {
         NONE,
@@ -85,6 +86,7 @@
     void initPorts();
     status_t initDecoder();
     bool isConfigured() const;
+    void handleEOS();
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftOpus);
 };
diff --git a/media/libstagefright/codecs/raw/Android.bp b/media/libstagefright/codecs/raw/Android.bp
index c64027b..1bd75c6 100644
--- a/media/libstagefright/codecs/raw/Android.bp
+++ b/media/libstagefright/codecs/raw/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_rawdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftRaw.cpp"],
 
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index acb2b37..1a527b3 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -60,7 +60,7 @@
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 32 * 1024;
+    def.nBufferSize = 64 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -78,7 +78,7 @@
     def.eDir = OMX_DirOutput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 32 * 1024;
+    def.nBufferSize = 64 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -100,6 +100,28 @@
 OMX_ERRORTYPE SoftRaw::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding = OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
@@ -153,6 +175,26 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->eEncoding != OMX_AUDIO_CodingPCM) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioPcm:
         {
             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
diff --git a/media/libstagefright/codecs/raw/SoftRaw.h b/media/libstagefright/codecs/raw/SoftRaw.h
index 80906b4..ebc2741 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.h
+++ b/media/libstagefright/codecs/raw/SoftRaw.h
@@ -18,7 +18,7 @@
 
 #define SOFT_RAW_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 struct tPVMP4AudioDecoderExternal;
 
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.bp b/media/libstagefright/codecs/vorbis/dec/Android.bp
index 1a4de60..fedfb67 100644
--- a/media/libstagefright/codecs/vorbis/dec/Android.bp
+++ b/media/libstagefright/codecs/vorbis/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_soft_vorbisdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: ["SoftVorbis.cpp"],
 
@@ -10,7 +14,7 @@
 
     shared_libs: [
         "libvorbisidec",
-        "libmedia",
+        "libmedia_omx",
         "libstagefright_omx",
         "libstagefright_foundation",
         "libutils",
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 14dd250..8912f8a 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -129,6 +129,30 @@
 OMX_ERRORTYPE SoftVorbis::internalGetParameter(
         OMX_INDEXTYPE index, OMX_PTR params) {
     switch (index) {
+        case OMX_IndexParamAudioPortFormat:
+        {
+            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if (formatParams->nIndex > 0) {
+                return OMX_ErrorNoMore;
+            }
+
+            formatParams->eEncoding =
+                (formatParams->nPortIndex == 0)
+                    ? OMX_AUDIO_CodingVORBIS : OMX_AUDIO_CodingPCM;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioVorbis:
         {
             OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
@@ -221,6 +245,29 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPortFormat:
+        {
+            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
+            if (formatParams->nPortIndex > 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            if ((formatParams->nPortIndex == 0
+                        && formatParams->eEncoding != OMX_AUDIO_CodingVORBIS)
+                || (formatParams->nPortIndex == 1
+                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+                return OMX_ErrorUndefined;
+            }
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioVorbis:
         {
             const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
@@ -262,7 +309,33 @@
     oggpack_readinit(bits, ref);
 }
 
-void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
+void SoftVorbis::handleEOS() {
+    List<BufferInfo *> &inQueue = getPortQueue(0);
+    List<BufferInfo *> &outQueue = getPortQueue(1);
+
+    CHECK(!inQueue.empty() && !outQueue.empty());
+
+    mSawInputEos = true;
+
+    BufferInfo *outInfo = *outQueue.begin();
+    OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+    outHeader->nFilledLen = 0;
+    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+    outQueue.erase(outQueue.begin());
+    outInfo->mOwnedByUs = false;
+    notifyFillBufferDone(outHeader);
+    mSignalledOutputEos = true;
+
+    BufferInfo *inInfo = *inQueue.begin();
+    OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+    inQueue.erase(inQueue.begin());
+    inInfo->mOwnedByUs = false;
+    notifyEmptyBufferDone(inHeader);
+    ++mInputBufferCount;
+}
+
+void SoftVorbis::onQueueFilled(OMX_U32 /* portIndex */) {
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
@@ -270,69 +343,7 @@
         return;
     }
 
-    if (portIndex == 0 && mInputBufferCount < 2) {
-        BufferInfo *info = *inQueue.begin();
-        OMX_BUFFERHEADERTYPE *header = info->mHeader;
-
-        const uint8_t *data = header->pBuffer + header->nOffset;
-        size_t size = header->nFilledLen;
-        if (size < 7) {
-            ALOGE("Too small input buffer: %zu bytes", size);
-            android_errorWriteLog(0x534e4554, "27833616");
-            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            mSignalledError = true;
-            return;
-        }
-
-        ogg_buffer buf;
-        ogg_reference ref;
-        oggpack_buffer bits;
-
-        makeBitReader(
-                (const uint8_t *)data + 7, size - 7,
-                &buf, &ref, &bits);
-
-        if (mInputBufferCount == 0) {
-            CHECK(mVi == NULL);
-            mVi = new vorbis_info;
-            vorbis_info_init(mVi);
-
-            int ret = _vorbis_unpack_info(mVi, &bits);
-            if (ret != 0) {
-                notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
-                mSignalledError = true;
-                return;
-            }
-        } else {
-            int ret = _vorbis_unpack_books(mVi, &bits);
-            if (ret != 0) {
-                notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
-                mSignalledError = true;
-                return;
-            }
-
-            CHECK(mState == NULL);
-            mState = new vorbis_dsp_state;
-            CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
-
-            if (mVi->rate != kDefaultSamplingRate ||
-                    mVi->channels != kDefaultChannelCount) {
-                ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
-                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-                mOutputPortSettingsChange = AWAITING_DISABLED;
-            }
-        }
-
-        inQueue.erase(inQueue.begin());
-        info->mOwnedByUs = false;
-        notifyEmptyBufferDone(header);
-
-        ++mInputBufferCount;
-
-        return;
-    }
-
-    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+    while (!mSignalledOutputEos && (!inQueue.empty() || mSawInputEos) && !outQueue.empty()) {
         BufferInfo *inInfo = NULL;
         OMX_BUFFERHEADERTYPE *inHeader = NULL;
         if (!inQueue.empty()) {
@@ -346,6 +357,73 @@
         int32_t numPageSamples = 0;
 
         if (inHeader) {
+            if (mInputBufferCount < 2) {
+                const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
+                size_t size = inHeader->nFilledLen;
+
+                if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && size == 0) {
+                    handleEOS();
+                    return;
+                }
+
+                if (size < 7) {
+                    ALOGE("Too small input buffer: %zu bytes", size);
+                    android_errorWriteLog(0x534e4554, "27833616");
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    mSignalledError = true;
+                    return;
+                }
+
+                ogg_buffer buf;
+                ogg_reference ref;
+                oggpack_buffer bits;
+
+                makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
+
+                if (mInputBufferCount == 0) {
+                    CHECK(mVi == NULL);
+                    mVi = new vorbis_info;
+                    vorbis_info_init(mVi);
+
+                    int ret = _vorbis_unpack_info(mVi, &bits);
+                    if (ret != 0) {
+                        notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
+                        mSignalledError = true;
+                        return;
+                    }
+                } else {
+                    int ret = _vorbis_unpack_books(mVi, &bits);
+                    if (ret != 0) {
+                        notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
+                        mSignalledError = true;
+                        return;
+                    }
+
+                    CHECK(mState == NULL);
+                    mState = new vorbis_dsp_state;
+                    CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
+
+                    if (mVi->rate != kDefaultSamplingRate ||
+                            mVi->channels != kDefaultChannelCount) {
+                        ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
+                        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                        mOutputPortSettingsChange = AWAITING_DISABLED;
+                    }
+                }
+
+                if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+                    handleEOS();
+                    return;
+                }
+
+                inQueue.erase(inQueue.begin());
+                inInfo->mOwnedByUs = false;
+                notifyEmptyBufferDone(inHeader);
+                ++mInputBufferCount;
+
+                continue;
+            }
+
             if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
                 mSawInputEos = true;
             }
@@ -359,8 +437,7 @@
                     return;
                 }
                 memcpy(&numPageSamples,
-                       inHeader->pBuffer
-                        + inHeader->nOffset + inHeader->nFilledLen - 4,
+                       inHeader->pBuffer + inHeader->nOffset + inHeader->nFilledLen - 4,
                        sizeof(numPageSamples));
 
                 if (inHeader->nOffset == 0) {
@@ -399,6 +476,14 @@
         int numFrames = 0;
 
         outHeader->nFlags = 0;
+
+        if (mState == nullptr || mVi == nullptr) {
+            notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL);
+            mSignalledError = true;
+            ALOGE("onQueueFilled, input does not have CSD");
+            return;
+        }
+
         int err = vorbis_dsp_synthesis(mState, &pack, 1);
         if (err != 0) {
             // FIXME temporary workaround for log spam
@@ -448,18 +533,13 @@
         if (inHeader) {
             inInfo->mOwnedByUs = false;
             inQueue.erase(inQueue.begin());
-            inInfo = NULL;
             notifyEmptyBufferDone(inHeader);
-            inHeader = NULL;
+            ++mInputBufferCount;
         }
 
         outInfo->mOwnedByUs = false;
         outQueue.erase(outQueue.begin());
-        outInfo = NULL;
         notifyFillBufferDone(outHeader);
-        outHeader = NULL;
-
-        ++mInputBufferCount;
     }
 }
 
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
index 30d137b..5ff8ea4 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
@@ -18,7 +18,7 @@
 
 #define SOFT_VORBIS_H_
 
-#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 
 struct vorbis_dsp_state;
 struct vorbis_info;
@@ -72,6 +72,7 @@
     void initPorts();
     status_t initDecoder();
     bool isConfigured() const;
+    void handleEOS();
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftVorbis);
 };
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index 3ca7cc0..0982006 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/MediaErrors.h>
 
 #include "libyuv/convert_from.h"
+#include "libyuv/video_common.h"
 
 #define USE_LIBYUV
 
@@ -41,17 +42,17 @@
 }
 
 bool ColorConverter::isValid() const {
-    if (mDstFormat != OMX_COLOR_Format16bitRGB565) {
-        return false;
-    }
-
     switch (mSrcFormat) {
         case OMX_COLOR_FormatYUV420Planar:
+            return mDstFormat == OMX_COLOR_Format16bitRGB565
+                    || mDstFormat == OMX_COLOR_Format32BitRGBA8888
+                    || mDstFormat == OMX_COLOR_Format32bitBGRA8888;
+
         case OMX_COLOR_FormatCbYCrY:
         case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
         case OMX_COLOR_FormatYUV420SemiPlanar:
         case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
-            return true;
+            return mDstFormat == OMX_COLOR_Format16bitRGB565;
 
         default:
             return false;
@@ -62,14 +63,43 @@
         void *bits,
         size_t width, size_t height,
         size_t cropLeft, size_t cropTop,
-        size_t cropRight, size_t cropBottom)
+        size_t cropRight, size_t cropBottom,
+        OMX_COLOR_FORMATTYPE colorFromat)
     : mBits(bits),
+      mColorFormat(colorFromat),
       mWidth(width),
       mHeight(height),
       mCropLeft(cropLeft),
       mCropTop(cropTop),
       mCropRight(cropRight),
       mCropBottom(cropBottom) {
+    switch(mColorFormat) {
+    case OMX_COLOR_Format16bitRGB565:
+        mBpp = 2;
+        mStride = 2 * mWidth;
+        break;
+
+    case OMX_COLOR_Format32bitBGRA8888:
+    case OMX_COLOR_Format32BitRGBA8888:
+        mBpp = 4;
+        mStride = 4 * mWidth;
+        break;
+
+    case OMX_COLOR_FormatYUV420Planar:
+    case OMX_COLOR_FormatCbYCrY:
+    case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+        mBpp = 1;
+        mStride = mWidth;
+        break;
+
+    default:
+        ALOGE("Unsupported color format %d", mColorFormat);
+        mBpp = 1;
+        mStride = mWidth;
+        break;
+    }
 }
 
 size_t ColorConverter::BitmapParams::cropWidth() const {
@@ -89,19 +119,15 @@
         size_t dstWidth, size_t dstHeight,
         size_t dstCropLeft, size_t dstCropTop,
         size_t dstCropRight, size_t dstCropBottom) {
-    if (mDstFormat != OMX_COLOR_Format16bitRGB565) {
-        return ERROR_UNSUPPORTED;
-    }
-
     BitmapParams src(
             const_cast<void *>(srcBits),
             srcWidth, srcHeight,
-            srcCropLeft, srcCropTop, srcCropRight, srcCropBottom);
+            srcCropLeft, srcCropTop, srcCropRight, srcCropBottom, mSrcFormat);
 
     BitmapParams dst(
             dstBits,
             dstWidth, dstHeight,
-            dstCropLeft, dstCropTop, dstCropRight, dstCropBottom);
+            dstCropLeft, dstCropTop, dstCropRight, dstCropBottom, mDstFormat);
 
     status_t err;
 
@@ -212,26 +238,104 @@
         return ERROR_UNSUPPORTED;
     }
 
-    uint16_t *dst_ptr = (uint16_t *)dst.mBits
-        + dst.mCropTop * dst.mWidth + dst.mCropLeft;
+    uint8_t *dst_ptr = (uint8_t *)dst.mBits
+        + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp;
 
     const uint8_t *src_y =
-        (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft;
+        (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft;
 
     const uint8_t *src_u =
-        (const uint8_t *)src_y + src.mWidth * src.mHeight
-        + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2;
+        (const uint8_t *)src.mBits + src.mStride * src.mHeight
+        + (src.mCropTop / 2) * (src.mStride / 2) + (src.mCropLeft / 2);
 
     const uint8_t *src_v =
-        src_u + (src.mWidth / 2) * (src.mHeight / 2);
+        src_u + (src.mStride / 2) * (src.mHeight / 2);
 
+    switch (mDstFormat) {
+    case OMX_COLOR_Format16bitRGB565:
+        libyuv::I420ToRGB565(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight());
+        break;
 
-    libyuv::I420ToRGB565(src_y, src.mWidth, src_u, src.mWidth / 2, src_v, src.mWidth / 2,
-            (uint8 *)dst_ptr, dst.mWidth * 2, dst.mWidth, dst.mHeight);
+    case OMX_COLOR_Format32BitRGBA8888:
+        libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ABGR);
+        break;
+
+    case OMX_COLOR_Format32bitBGRA8888:
+        libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2,
+                (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ARGB);
+        break;
+
+    default:
+        return ERROR_UNSUPPORTED;
+    }
 
     return OK;
 }
 
+void ColorConverter::writeToDst(
+        void *dst_ptr, uint8_t *kAdjustedClip, bool uncropped,
+        signed r1, signed g1, signed b1,
+        signed r2, signed g2, signed b2) {
+    switch (mDstFormat) {
+    case OMX_COLOR_Format16bitRGB565:
+    {
+        uint32_t rgb1 =
+            ((kAdjustedClip[r1] >> 3) << 11)
+            | ((kAdjustedClip[g1] >> 2) << 5)
+            | (kAdjustedClip[b1] >> 3);
+
+        if (uncropped) {
+            uint32_t rgb2 =
+                ((kAdjustedClip[r2] >> 3) << 11)
+                | ((kAdjustedClip[g2] >> 2) << 5)
+                | (kAdjustedClip[b2] >> 3);
+
+            *(uint32_t *)dst_ptr = (rgb2 << 16) | rgb1;
+        } else {
+            *(uint16_t *)dst_ptr = rgb1;
+        }
+        break;
+    }
+    case OMX_COLOR_Format32BitRGBA8888:
+    {
+        ((uint32_t *)dst_ptr)[0] =
+                (kAdjustedClip[r1])
+                | (kAdjustedClip[g1] << 8)
+                | (kAdjustedClip[b1] << 16)
+                | (0xFF << 24);
+
+        if (uncropped) {
+            ((uint32_t *)dst_ptr)[1] =
+                    (kAdjustedClip[r2])
+                    | (kAdjustedClip[g2] << 8)
+                    | (kAdjustedClip[b2] << 16)
+                    | (0xFF << 24);
+        }
+        break;
+    }
+    case OMX_COLOR_Format32bitBGRA8888:
+    {
+        ((uint32_t *)dst_ptr)[0] =
+                (kAdjustedClip[b1])
+                | (kAdjustedClip[g1] << 8)
+                | (kAdjustedClip[r1] << 16)
+                | (0xFF << 24);
+
+        if (uncropped) {
+            ((uint32_t *)dst_ptr)[1] =
+                    (kAdjustedClip[b2])
+                    | (kAdjustedClip[g2] << 8)
+                    | (kAdjustedClip[r2] << 16)
+                    | (0xFF << 24);
+        }
+        break;
+    }
+    default:
+        break;
+    }
+}
 status_t ColorConverter::convertYUV420Planar(
         const BitmapParams &src, const BitmapParams &dst) {
     if (!((src.mCropLeft & 1) == 0
@@ -242,18 +346,18 @@
 
     uint8_t *kAdjustedClip = initClip();
 
-    uint16_t *dst_ptr = (uint16_t *)dst.mBits
-        + dst.mCropTop * dst.mWidth + dst.mCropLeft;
+    uint8_t *dst_ptr = (uint8_t *)dst.mBits
+        + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp;
 
     const uint8_t *src_y =
-        (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft;
+        (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft;
 
     const uint8_t *src_u =
-        (const uint8_t *)src_y + src.mWidth * src.mHeight
-        + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2;
+        (const uint8_t *)src.mBits + src.mStride * src.mHeight
+        + (src.mCropTop / 2) * (src.mStride / 2) + src.mCropLeft / 2;
 
     const uint8_t *src_v =
-        src_u + (src.mWidth / 2) * (src.mHeight / 2);
+        src_u + (src.mStride / 2) * (src.mHeight / 2);
 
     for (size_t y = 0; y < src.cropHeight(); ++y) {
         for (size_t x = 0; x < src.cropWidth(); x += 2) {
@@ -296,31 +400,19 @@
             signed g2 = (tmp2 + v_g + u_g) / 256;
             signed r2 = (tmp2 + v_r) / 256;
 
-            uint32_t rgb1 =
-                ((kAdjustedClip[r1] >> 3) << 11)
-                | ((kAdjustedClip[g1] >> 2) << 5)
-                | (kAdjustedClip[b1] >> 3);
-
-            uint32_t rgb2 =
-                ((kAdjustedClip[r2] >> 3) << 11)
-                | ((kAdjustedClip[g2] >> 2) << 5)
-                | (kAdjustedClip[b2] >> 3);
-
-            if (x + 1 < src.cropWidth()) {
-                *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1;
-            } else {
-                dst_ptr[x] = rgb1;
-            }
+            bool uncropped = x + 1 < src.cropWidth();
+            (void)writeToDst(dst_ptr + x * dst.mBpp,
+                    kAdjustedClip, uncropped, r1, g1, b1, r2, g2, b2);
         }
 
-        src_y += src.mWidth;
+        src_y += src.mStride;
 
         if (y & 1) {
-            src_u += src.mWidth / 2;
-            src_v += src.mWidth / 2;
+            src_u += src.mStride / 2;
+            src_v += src.mStride / 2;
         }
 
-        dst_ptr += dst.mWidth;
+        dst_ptr += dst.mStride;
     }
 
     return OK;
diff --git a/media/libstagefright/data/media_codecs_google_video.xml b/media/libstagefright/data/media_codecs_google_video.xml
index ce164a2..a127843 100644
--- a/media/libstagefright/data/media_codecs_google_video.xml
+++ b/media/libstagefright/data/media_codecs_google_video.xml
@@ -34,20 +34,21 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="OMX.google.h264.decoder" type="video/avc">
-            <!-- profiles and levels:  ProfileHigh : Level41 -->
-            <Limit name="size" min="16x16" max="1920x1088" />
+            <!-- profiles and levels:  ProfileHigh : Level52 -->
+            <Limit name="size" min="2x2" max="4096x4096" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="blocks-per-second" range="1-244800" />
-            <Limit name="bitrate" range="1-12000000" />
+            <Limit name="block-count" range="1-32768" /> <!-- max 4096x2048 -->
+            <Limit name="blocks-per-second" range="1-1966080" />
+            <Limit name="bitrate" range="1-48000000" />
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="OMX.google.hevc.decoder" type="video/hevc">
             <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
-            <Limit name="size" min="2x2" max="2048x2048" />
+            <Limit name="size" min="2x2" max="4096x4096" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="8x8" />
-            <Limit name="block-count" range="1-139264" />
+            <Limit name="block-count" range="1-196608" /> <!-- max 4096x3072 -->
             <Limit name="blocks-per-second" range="1-2000000" />
             <Limit name="bitrate" range="1-10000000" />
             <Feature name="adaptive-playback" />
@@ -56,6 +57,7 @@
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
+            <Limit name="block-count" range="1-16384" />
             <Limit name="blocks-per-second" range="1-1000000" />
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="adaptive-playback" />
@@ -64,6 +66,7 @@
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
+            <Limit name="block-count" range="1-16384" />
             <Limit name="blocks-per-second" range="1-500000" />
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="adaptive-playback" />
@@ -79,10 +82,11 @@
         </MediaCodec>
         <MediaCodec name="OMX.google.h264.encoder" type="video/avc">
             <!-- profiles and levels:  ProfileBaseline : Level41 -->
-            <Limit name="size" min="16x16" max="1920x1088" />
+            <Limit name="size" min="16x16" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="blocks-per-second" range="1-244800" />
+            <Limit name="block-count" range="1-8192" /> <!-- max 2048x1024 -->
+            <Limit name="blocks-per-second" range="1-245760" />
             <Limit name="bitrate" range="1-12000000" />
             <Feature name="intra-refresh" />
         </MediaCodec>
@@ -98,6 +102,9 @@
             <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <!-- 2016 devices can encode at about 10fps at this block count -->
+            <Limit name="block-count" range="1-16384" />
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
@@ -105,6 +112,9 @@
             <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
+            <Limit name="block-size" value="16x16" />
+            <!-- 2016 devices can encode at about 8fps at this block count -->
+            <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
diff --git a/media/libstagefright/data/media_codecs_google_video_le.xml b/media/libstagefright/data/media_codecs_google_video_le.xml
index 034a038..d7c6570 100644
--- a/media/libstagefright/data/media_codecs_google_video_le.xml
+++ b/media/libstagefright/data/media_codecs_google_video_le.xml
@@ -34,22 +34,22 @@
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="OMX.google.h264.decoder" type="video/avc">
-            <!-- profiles and levels:  ProfileBaseline : Level51 -->
+            <!-- profiles and levels:  ProfileHigh : Level51 -->
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="block-count" range="1-8160" />
-            <Limit name="blocks-per-second" range="1-489600" />
+            <Limit name="block-count" range="1-16384" />
+            <Limit name="blocks-per-second" range="1-491520" />
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="adaptive-playback" />
         </MediaCodec>
         <MediaCodec name="OMX.google.hevc.decoder" type="video/hevc">
             <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
-            <Limit name="size" min="2x2" max="1280x1280" />
+            <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="8x8" />
-            <Limit name="block-count" range="1-139264" />
-            <Limit name="blocks-per-second" range="1-432000" />
+            <Limit name="block-count" range="1-65536" />
+            <Limit name="blocks-per-second" range="1-491520" />
             <Limit name="bitrate" range="1-5000000" />
             <Feature name="adaptive-playback" />
         </MediaCodec>
@@ -57,7 +57,7 @@
             <Limit name="size" min="2x2" max="2048x2048" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="block-count" range="1-8160" />
+            <Limit name="block-count" range="1-8192" /> <!-- max 2048x1024 -->
             <Limit name="blocks-per-second" range="1-500000" />
             <Limit name="bitrate" range="1-40000000" />
             <Feature name="adaptive-playback" />
@@ -66,7 +66,7 @@
             <Limit name="size" min="2x2" max="1280x1280" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="block-count" range="1-3600" />
+            <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
             <Limit name="blocks-per-second" range="1-108000" />
             <Limit name="bitrate" range="1-5000000" />
             <Feature name="adaptive-playback" />
@@ -81,12 +81,14 @@
             <Limit name="bitrate" range="1-128000" />
         </MediaCodec>
         <MediaCodec name="OMX.google.h264.encoder" type="video/avc">
-            <!-- profiles and levels:  ProfileBaseline : Level2 -->
-            <Limit name="size" min="16x16" max="896x896" />
-            <Limit name="alignment" value="16x16" />
+            <!-- profiles and levels:  ProfileBaseline : Level3 -->
+            <Limit name="size" min="16x16" max="1808x1808" />
+            <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="16x16" />
-            <Limit name="blocks-per-second" range="1-11880" />
+            <Limit name="block-count" range="1-1620" />
+            <Limit name="blocks-per-second" range="1-40500" />
             <Limit name="bitrate" range="1-2000000" />
+            <Feature name="intra-refresh" />
         </MediaCodec>
         <MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es">
             <!-- profiles and levels:  ProfileCore : Level2 -->
@@ -100,7 +102,8 @@
             <!-- profiles and levels:  ProfileMain : Level_Version0-3 -->
             <Limit name="size" min="2x2" max="1280x1280" />
             <Limit name="alignment" value="2x2" />
-            <Limit name="block-count" range="1-3600" />
+            <Limit name="block-size" value="16x16" />
+            <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
             <Limit name="bitrate" range="1-20000000" />
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 284c25f..1b9fe0f 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -1,5 +1,9 @@
 cc_library_shared {
     name: "libstagefright_flacdec",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "FLACDecoder.cpp",
@@ -31,4 +35,5 @@
         "libstagefright_foundation",
         "libutils",
     ],
+    header_libs: ["libmedia_headers"],
 }
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 91462c8..221af1d 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -1,7 +1,15 @@
+cc_library_headers {
+    name: "libstagefright_foundation_headers",
+    export_include_dirs: ["include"],
+    vendor_available: true,
+}
+
 cc_library_shared {
     name: "libstagefright_foundation",
     vendor_available: true,
-
+    vndk: {
+        enabled: true,
+    },
     include_dirs: [
         "frameworks/av/include",
         "frameworks/native/include",
@@ -11,12 +19,13 @@
         "include/media/stagefright/foundation",
     ],
 
-    export_include_dirs: [
-        "include",
-    ],
-
     header_libs: [
         "libhardware_headers",
+        "libstagefright_foundation_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libstagefright_foundation_headers",
     ],
 
     export_shared_lib_headers: [
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 0da2e81..f253a52 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -30,6 +30,8 @@
 
 namespace android {
 
+using hardware::hidl_memory;
+
 /**
  * BufferChannelBase implementation for ACodec.
  */
@@ -117,6 +119,7 @@
     sp<MemoryDealer> mDealer;
     sp<IMemory> mDecryptDestination;
     int32_t mHeapSeqNum;
+    hidl_memory mHidlMemory;
 
     // These should only be accessed via std::atomic_* functions.
     //
diff --git a/media/libstagefright/include/ItemTable.h b/media/libstagefright/include/ItemTable.h
new file mode 100644
index 0000000..5a6af5e
--- /dev/null
+++ b/media/libstagefright/include/ItemTable.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ITEM_TABLE_H_
+#define ITEM_TABLE_H_
+
+#include <set>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class DataSource;
+class MetaData;
+
+namespace heif {
+
+struct AssociationEntry;
+struct ImageItem;
+struct ItemLoc;
+struct ItemInfo;
+struct ItemProperty;
+struct ItemReference;
+
+/*
+ * ItemTable keeps track of all image items (including coded images, grids and
+ * tiles) inside a HEIF still image (ISO/IEC FDIS 23008-12.2:2017(E)).
+ */
+
+class ItemTable : public RefBase {
+public:
+    explicit ItemTable(const sp<DataSource> &source);
+
+    status_t parse(uint32_t type, off64_t offset, size_t size);
+
+    bool isValid() { return mImageItemsValid; }
+    sp<MetaData> getImageMeta();
+    uint32_t countImages() const;
+    status_t findPrimaryImage(uint32_t *imageIndex);
+    status_t findThumbnail(uint32_t *thumbnailIndex);
+    status_t getImageOffsetAndSize(
+            uint32_t *imageIndex, off64_t *offset, size_t *size);
+
+protected:
+    ~ItemTable();
+
+private:
+    sp<DataSource> mDataSource;
+
+    KeyedVector<uint32_t, ItemLoc> mItemLocs;
+    Vector<ItemInfo> mItemInfos;
+    Vector<AssociationEntry> mAssociations;
+    Vector<sp<ItemProperty> > mItemProperties;
+    Vector<sp<ItemReference> > mItemReferences;
+
+    uint32_t mPrimaryItemId;
+    off64_t mIdatOffset;
+    size_t mIdatSize;
+
+    std::set<uint32_t> mRequiredBoxes;
+    std::set<uint32_t> mBoxesSeen;
+
+    bool mImageItemsValid;
+    uint32_t mCurrentImageIndex;
+    KeyedVector<uint32_t, ImageItem> mItemIdToImageMap;
+
+    status_t parseIlocBox(off64_t offset, size_t size);
+    status_t parseIinfBox(off64_t offset, size_t size);
+    status_t parsePitmBox(off64_t offset, size_t size);
+    status_t parseIprpBox(off64_t offset, size_t size);
+    status_t parseIdatBox(off64_t offset, size_t size);
+    status_t parseIrefBox(off64_t offset, size_t size);
+
+    void attachProperty(const AssociationEntry &association);
+    status_t buildImageItemsIfPossible(uint32_t type);
+
+    DISALLOW_EVIL_CONSTRUCTORS(ItemTable);
+};
+
+} // namespace heif
+} // namespace android
+
+#endif  // ITEM_TABLE_H_
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index 2a75298..ac93b5e 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -45,7 +45,7 @@
 
     virtual sp<MetaData> getMetaData();
 
-    virtual status_t setMediaCas(const sp<ICas> &cas) override;
+    virtual status_t setMediaCas(const HInterfaceToken &casToken) override;
 
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG2TSExtractor"; }
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index f847119..4a4c538 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -28,11 +28,14 @@
 #include <utils/String8.h>
 
 namespace android {
-
 struct AMessage;
 class DataSource;
 class SampleTable;
 class String8;
+namespace heif {
+class ItemTable;
+}
+using heif::ItemTable;
 
 struct SidxEntry {
     size_t mSize;
@@ -97,6 +100,7 @@
     status_t mInitCheck;
     uint32_t mHeaderTimescale;
     bool mIsQT;
+    bool mIsHEIF;
 
     Track *mFirstTrack, *mLastTrack;
 
@@ -134,6 +138,8 @@
     SINF *mFirstSINF;
 
     bool mIsDrm;
+    sp<ItemTable> mItemTable;
+
     status_t parseDrmSINF(off64_t *offset, off64_t data_offset);
 
     status_t parseTrackHeader(off64_t data_offset, off64_t data_size);
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index b7ac718..277eb3e 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -38,9 +38,9 @@
             const KeyedVector<String8, String8> *headers);
 
     virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
-    virtual status_t setDataSource(const sp<DataSource>& source);
+    virtual status_t setDataSource(const sp<DataSource>& source, const char *mime);
 
-    virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);
+    virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly);
     virtual MediaAlbumArt *extractAlbumArt();
     virtual const char *extractMetadata(int keyCode);
 
diff --git a/media/libstagefright/include/media/stagefright/CameraSource.h b/media/libstagefright/include/media/stagefright/CameraSource.h
index 2aaa884..d6149c0 100644
--- a/media/libstagefright/include/media/stagefright/CameraSource.h
+++ b/media/libstagefright/include/media/stagefright/CameraSource.h
@@ -29,7 +29,7 @@
 #include <utils/List.h>
 #include <utils/RefBase.h>
 #include <utils/String16.h>
-#include <MetadataBufferType.h>
+#include <media/hardware/MetadataBufferType.h>
 
 namespace android {
 
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 0dd77ba..6245ccb 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -24,27 +24,31 @@
 
 #define STRINGIFY_ENUMS
 
-#include <media/ICrypto.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/hardware/HardwareAPI.h>
 #include <media/IOMX.h>
 #include <media/MediaCodecInfo.h>
-#include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <media/stagefright/foundation/ColorUtils.h>
-#include <media/hardware/HardwareAPI.h>
-
+#include <media/stagefright/MediaErrors.h>
+#include <system/graphics.h>
 #include <utils/NativeHandle.h>
 
-#include <system/graphics.h>
-#include <android/media/IDescrambler.h>
-
 namespace android {
-using namespace media;
 class BufferChannelBase;
 struct BufferProducerWrapper;
 class MediaCodecBuffer;
 struct PersistentSurface;
 struct RenderedFrameInfo;
 class Surface;
+struct ICrypto;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
 
 struct CodecBase : public AHandler, /* static */ ColorUtils {
     /**
@@ -256,13 +260,9 @@
         mCallback = std::move(callback);
     }
 
-    inline void setCrypto(const sp<ICrypto> &crypto) {
-        mCrypto = crypto;
-    }
+    void setCrypto(const sp<ICrypto> &crypto);
 
-    inline void setDescrambler(const sp<IDescrambler> &descrambler) {
-        mDescrambler = descrambler;
-    }
+    void setDescrambler(const sp<IDescrambler> &descrambler);
 
     /**
      * Queue an input buffer into the buffer channel.
diff --git a/media/libstagefright/include/media/stagefright/ColorConverter.h b/media/libstagefright/include/media/stagefright/ColorConverter.h
index 270c809..7ac9b37 100644
--- a/media/libstagefright/include/media/stagefright/ColorConverter.h
+++ b/media/libstagefright/include/media/stagefright/ColorConverter.h
@@ -49,14 +49,17 @@
                 void *bits,
                 size_t width, size_t height,
                 size_t cropLeft, size_t cropTop,
-                size_t cropRight, size_t cropBottom);
+                size_t cropRight, size_t cropBottom,
+                OMX_COLOR_FORMATTYPE colorFromat);
 
         size_t cropWidth() const;
         size_t cropHeight() const;
 
         void *mBits;
+        OMX_COLOR_FORMATTYPE mColorFormat;
         size_t mWidth, mHeight;
         size_t mCropLeft, mCropTop, mCropRight, mCropBottom;
+        size_t mBpp, mStride;
     };
 
     OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat;
@@ -82,6 +85,10 @@
     status_t convertTIYUV420PackedSemiPlanar(
             const BitmapParams &src, const BitmapParams &dst);
 
+    void writeToDst(void *dst_ptr, uint8_t *kAdjustedClip, bool uncropped,
+            signed r1, signed g1, signed b1,
+            signed r2, signed g2, signed b2);
+
     ColorConverter(const ColorConverter &);
     ColorConverter &operator=(const ColorConverter &);
 };
diff --git a/media/libstagefright/include/media/stagefright/DataSource.h b/media/libstagefright/include/media/stagefright/DataSource.h
index 63eccea..bd863ba 100644
--- a/media/libstagefright/include/media/stagefright/DataSource.h
+++ b/media/libstagefright/include/media/stagefright/DataSource.h
@@ -73,6 +73,11 @@
     bool getUInt32(off64_t offset, uint32_t *x);
     bool getUInt64(off64_t offset, uint64_t *x);
 
+    // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
+    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size);
+    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size);
+    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size);
+
     // Reads in "count" entries of type T into vector *x.
     // Returns true if "count" entries can be read.
     // If fewer than "count" entries can be read, return false. In this case,
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 4140266..209fe12 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -47,10 +47,13 @@
 struct PersistentSurface;
 class SoftwareRenderer;
 class Surface;
-namespace media {
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
 
 struct MediaCodec : public AHandler {
     enum ConfigureFlags {
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 2e663ec..6a5c6b6 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -79,6 +79,26 @@
     HEARTBEAT_ERROR_BASE = -3000,
     ERROR_HEARTBEAT_TERMINATE_REQUESTED                     = HEARTBEAT_ERROR_BASE,
 
+    // CAS-related error codes
+    CAS_ERROR_BASE = -4000,
+
+    ERROR_CAS_UNKNOWN                        = CAS_ERROR_BASE,
+    ERROR_CAS_NO_LICENSE                     = CAS_ERROR_BASE - 1,
+    ERROR_CAS_LICENSE_EXPIRED                = CAS_ERROR_BASE - 2,
+    ERROR_CAS_SESSION_NOT_OPENED             = CAS_ERROR_BASE - 3,
+    ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED   = CAS_ERROR_BASE - 4,
+    ERROR_CAS_DECRYPT                        = CAS_ERROR_BASE - 5,
+    ERROR_CAS_CANNOT_HANDLE                  = CAS_ERROR_BASE - 6,
+    ERROR_CAS_TAMPER_DETECTED                = CAS_ERROR_BASE - 7,
+    ERROR_CAS_NOT_PROVISIONED                = CAS_ERROR_BASE - 8,
+    ERROR_CAS_DEVICE_REVOKED                 = CAS_ERROR_BASE - 9,
+    ERROR_CAS_RESOURCE_BUSY                  = CAS_ERROR_BASE - 10,
+    ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = CAS_ERROR_BASE - 11,
+    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 11,
+
+    ERROR_CAS_VENDOR_MAX                     = CAS_ERROR_BASE - 500,
+    ERROR_CAS_VENDOR_MIN                     = CAS_ERROR_BASE - 999,
+
     // NDK Error codes
     // frameworks/av/include/ndk/NdkMediaError.h
     // from -10000 (0xFFFFD8F0 - 0xFFFFD8EC)
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index a856b2b..f12160b 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -23,10 +23,6 @@
 #include <media/MediaAnalyticsItem.h>
 
 namespace android {
-namespace media {
-class ICas;
-};
-using namespace media;
 class DataSource;
 struct MediaSource;
 class MetaData;
@@ -70,7 +66,7 @@
     }
     virtual void setUID(uid_t /*uid*/) {
     }
-    virtual status_t setMediaCas(const sp<ICas>& /*cas*/) override {
+    virtual status_t setMediaCas(const HInterfaceToken &/*casToken*/) override {
         return INVALID_OPERATION;
     }
 
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
index 9676b97..65ad3e4 100644
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ b/media/libstagefright/include/media/stagefright/MetaData.h
@@ -38,6 +38,8 @@
     kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
     kKeySARWidth          = 'sarW',  // int32_t, sampleAspectRatio width
     kKeySARHeight         = 'sarH',  // int32_t, sampleAspectRatio height
+    kKeyThumbnailWidth    = 'thbW',  // int32_t, thumbnail width
+    kKeyThumbnailHeight   = 'thbH',  // int32_t, thumbnail height
 
     // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
     kKeyCropRect          = 'crop',
@@ -58,6 +60,7 @@
     kKeyAACProfile        = 'aacp',  // int32_t
     kKeyAVCC              = 'avcc',  // raw data
     kKeyHVCC              = 'hvcc',  // raw data
+    kKeyThumbnailHVCC     = 'thvc',  // raw data
     kKeyD263              = 'd263',  // raw data
     kKeyVorbisInfo        = 'vinf',  // raw data
     kKeyVorbisBooks       = 'vboo',  // raw data
@@ -209,6 +212,10 @@
                                    // color Matrix, value defined by ColorAspects.MatrixCoeffs.
     kKeyTemporalLayerId  = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
     kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
+
+    kKeyGridRows         = 'rows', // int32_t, HEIF grid rows
+    kKeyGridCols         = 'clms', // int32_t, HEIF grid columns
+    kKeyIccProfile       = 'prof', // raw data
 };
 
 enum {
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 3e3cc17..6a93bd5 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -28,10 +28,6 @@
 #include <utils/Vector.h>
 
 namespace android {
-namespace media {
-class ICas;
-}
-using namespace media;
 
 struct ABuffer;
 struct AMessage;
@@ -64,7 +60,7 @@
 
     status_t setDataSource(const sp<DataSource> &datasource);
 
-    status_t setMediaCas(const sp<ICas> &cas);
+    status_t setMediaCas(const HInterfaceToken &casToken);
 
     size_t countTracks() const;
     status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
@@ -115,7 +111,7 @@
     sp<DataSource> mDataSource;
 
     sp<IMediaExtractor> mImpl;
-    sp<ICas> mCas;
+    HInterfaceToken mCasToken;
 
     Vector<TrackInfo> mSelectedTracks;
     int64_t mTotalBitrate;  // in bits/sec
diff --git a/media/libstagefright/include/media/stagefright/SurfaceMediaSource.h b/media/libstagefright/include/media/stagefright/SurfaceMediaSource.h
index d38c337..d1677fa 100644
--- a/media/libstagefright/include/media/stagefright/SurfaceMediaSource.h
+++ b/media/libstagefright/include/media/stagefright/SurfaceMediaSource.h
@@ -25,7 +25,7 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MediaBuffer.h>
 
-#include <MetadataBufferType.h>
+#include <media/hardware/MetadataBufferType.h>
 
 #include "foundation/ABase.h"
 
diff --git a/media/libstagefright/include/media/stagefright/Utils.h b/media/libstagefright/include/media/stagefright/Utils.h
index 88a416a..77cbd4c 100644
--- a/media/libstagefright/include/media/stagefright/Utils.h
+++ b/media/libstagefright/include/media/stagefright/Utils.h
@@ -95,7 +95,7 @@
 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */);
 
 AString nameForFd(int fd);
-
+void MakeFourCCString(uint32_t x, char *s);
 }  // namespace android
 
 #endif  // UTILS_H_
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 31edb21..a256a4d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,8 +23,8 @@
 #include "ESQueue.h"
 #include "include/avc_utils.h"
 
-#include <android/media/IDescrambler.h>
-#include <binder/MemoryDealer.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <cutils/native_handle.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -41,8 +41,12 @@
 #include <inttypes.h>
 
 namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_memory;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
 
 // I want the expression "y" evaluated even if verbose logging is off.
 #define MY_LOGV(x, y) \
@@ -203,6 +207,7 @@
     sp<AMessage> mSampleAesKeyItem;
     sp<IMemory> mMem;
     sp<MemoryDealer> mDealer;
+    hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
     sp<ABuffer> mDescrambledBuffer;
     List<SubSampleInfo> mSubSamples;
     sp<IDescrambler> mDescrambler;
@@ -235,7 +240,7 @@
 
     // Ensure internal buffers can hold specified size, and will re-allocate
     // as needed.
-    void ensureBufferCapacity(size_t size);
+    bool ensureBufferCapacity(size_t size);
 
     DISALLOW_EVIL_CONSTRUCTORS(Stream);
 };
@@ -807,9 +812,9 @@
     mQueue = NULL;
 }
 
-void ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
+bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
     if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
-        return;
+        return true;
     }
 
     ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
@@ -837,6 +842,26 @@
         mMem = newMem;
         mDealer = newDealer;
         mDescrambledBuffer = newScrambledBuffer;
+
+        ssize_t offset;
+        size_t size;
+        sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
+        if (heap == NULL) {
+            return false;
+        }
+        native_handle_t* nativeHandle = native_handle_create(1, 0);
+        if (!nativeHandle) {
+            ALOGE("[stream %d] failed to create native handle", mElementaryPID);
+            return false;
+        }
+        nativeHandle->data[0] = heap->getHeapID();
+        mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
+                hidl_handle(nativeHandle), heap->getSize());
+        mDescramblerSrcBuffer.offset = (uint64_t) offset;
+        mDescramblerSrcBuffer.size = (uint64_t) size;
+
+        ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
+                mElementaryPID, offset, size);
     } else {
         // Align to multiples of 64K.
         neededSize = (neededSize + 65535) & ~65535;
@@ -850,6 +875,7 @@
         newBuffer->setRange(0, 0);
     }
     mBuffer = newBuffer;
+    return true;
 }
 
 status_t ATSParser::Stream::parse(
@@ -923,7 +949,9 @@
     }
 
     size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
-    ensureBufferCapacity(neededSize);
+    if (!ensureBufferCapacity(neededSize)) {
+        return NO_MEMORY;
+    }
 
     memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
     mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
@@ -1365,47 +1393,59 @@
         memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
         mDescrambledBuffer->setRange(0, descrambleBytes);
 
-        sp<ABuffer> subSamples = new ABuffer(
-                sizeof(DescramblerPlugin::SubSample) * descrambleSubSamples);
-
-        DescrambleInfo info;
-        info.dstType = DescrambleInfo::kDestinationTypeVmPointer;
-        info.scramblingControl = (DescramblerPlugin::ScramblingControl)sctrl;
-        info.numSubSamples = descrambleSubSamples;
-        info.subSamples = (DescramblerPlugin::SubSample *)subSamples->data();
-        info.srcMem = mMem;
-        info.srcOffset = 0;
-        info.dstPtr = NULL; // in-place descrambling into srcMem
-        info.dstOffset = 0;
+        hidl_vec<SubSample> subSamples;
+        subSamples.resize(descrambleSubSamples);
 
         int32_t i = 0;
         for (auto it = mSubSamples.begin();
                 it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
             if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
-                info.subSamples[i].mNumBytesOfClearData = 0;
-                info.subSamples[i].mNumBytesOfEncryptedData = it->subSampleSize;
+                subSamples[i].numBytesOfClearData = 0;
+                subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
             } else {
-                info.subSamples[i].mNumBytesOfClearData = it->subSampleSize;
-                info.subSamples[i].mNumBytesOfEncryptedData = 0;
+                subSamples[i].numBytesOfClearData = it->subSampleSize;
+                subSamples[i].numBytesOfEncryptedData = 0;
             }
         }
+
+        uint64_t srcOffset = 0, dstOffset = 0;
         // If scrambled at PES-level, PES header should be skipped
         if (pesScramblingControl != 0) {
-            info.srcOffset = info.dstOffset = pesOffset;
-            info.subSamples[0].mNumBytesOfEncryptedData -= pesOffset;
+            srcOffset = dstOffset = pesOffset;
+            subSamples[0].numBytesOfEncryptedData -= pesOffset;
         }
 
-        int32_t result;
-        Status status = mDescrambler->descramble(info, &result);
+        Status status = Status::OK;
+        uint32_t bytesWritten = 0;
+        hidl_string detailedError;
 
-        if (!status.isOk()) {
-            ALOGE("[stream %d] descramble failed, exceptionCode=%d",
-                    mElementaryPID, status.exceptionCode());
+        DestinationBuffer dstBuffer;
+        dstBuffer.type = BufferType::SHARED_MEMORY;
+        dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
+
+        auto returnVoid = mDescrambler->descramble(
+                (ScramblingControl) sctrl,
+                subSamples,
+                mDescramblerSrcBuffer,
+                srcOffset,
+                dstBuffer,
+                dstOffset,
+                [&status, &bytesWritten, &detailedError] (
+                        Status _status, uint32_t _bytesWritten,
+                        const hidl_string& _detailedError) {
+                    status = _status;
+                    bytesWritten = _bytesWritten;
+                    detailedError = _detailedError;
+                });
+
+        if (!returnVoid.isOk()) {
+            ALOGE("[stream %d] descramble failed, trans=%s",
+                    mElementaryPID, returnVoid.description().c_str());
             return UNKNOWN_ERROR;
         }
 
         ALOGV("[stream %d] descramble succeeded, %d bytes",
-                mElementaryPID, result);
+                mElementaryPID, bytesWritten);
         memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
     }
 
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 374e011..41c19cd 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -29,11 +29,13 @@
 #include <vector>
 
 namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace V1_0 {
+struct ICas;
+}}}
+using hardware::cas::V1_0::ICas;
+
 class ABitReader;
 struct ABuffer;
 struct AnotherPacketSource;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index 96eb5bf..21259c4 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -35,5 +35,8 @@
     shared_libs: [
         "libcrypto",
         "libmedia",
+        "libhidlmemory",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.memory@1.0",
     ],
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/libstagefright/mpeg2ts/CasManager.cpp
index 047b1b3..9ff4521 100644
--- a/media/libstagefright/mpeg2ts/CasManager.cpp
+++ b/media/libstagefright/mpeg2ts/CasManager.cpp
@@ -18,15 +18,19 @@
 #define LOG_TAG "CasManager"
 #include "CasManager.h"
 
-#include <android/media/ICas.h>
-#include <android/media/IDescrambler.h>
-#include <android/media/IMediaCasService.h>
-#include <binder/IServiceManager.h>
+#include <android/hardware/cas/1.0/ICas.h>
+#include <android/hardware/cas/1.0/IMediaCasService.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <hidl/HidlSupport.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <utils/Log.h>
 
 namespace android {
-using binder::Status;
+
+using hardware::hidl_vec;
+using hardware::Return;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
 
 struct ATSParser::CasManager::ProgramCasManager : public RefBase {
     ProgramCasManager(unsigned programNumber, const CADescriptor &descriptor);
@@ -125,45 +129,60 @@
          const sp<ICas>& cas,
          PidToSessionMap &sessionMap,
          CasSession *session) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> casServiceBinder = sm->getService(String16("media.cas"));
-    sp<IMediaCasService> casService =
-            interface_cast<IMediaCasService>(casServiceBinder);
-
+    sp<IMediaCasService> casService = IMediaCasService::getService("default");
     if (casService == NULL) {
         ALOGE("Cannot obtain IMediaCasService");
         return NO_INIT;
     }
 
+    Status status;
     sp<IDescrambler> descrambler;
+    sp<IDescramblerBase> descramblerBase;
+    Return<Status> returnStatus(Status::OK);
+    Return<sp<IDescramblerBase> > returnDescrambler(NULL);
     std::vector<uint8_t> sessionId;
     const CADescriptor &descriptor = session->mCADescriptor;
 
-    Status status = cas->openSession(&sessionId);
-    if (!status.isOk()) {
-        ALOGE("Failed to open session: exception=%d, error=%d",
-                status.exceptionCode(), status.serviceSpecificErrorCode());
+    auto returnVoid = cas->openSession(
+            [&status, &sessionId] (Status _status, const hidl_vec<uint8_t>& _sessionId) {
+                status = _status;
+                sessionId = _sessionId;
+            });
+    if (!returnVoid.isOk() || status != Status::OK) {
+        ALOGE("Failed to open session: trans=%s, status=%d",
+                returnVoid.description().c_str(), status);
         goto l_fail;
     }
 
-    cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
-    if (!status.isOk()) {
-        ALOGE("Failed to set private data: exception=%d, error=%d",
-                status.exceptionCode(), status.serviceSpecificErrorCode());
+    returnStatus = cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
+    if (!returnStatus.isOk() || returnStatus != Status::OK) {
+        ALOGE("Failed to set private data: trans=%s, status=%d",
+                returnStatus.description().c_str(), (Status)returnStatus);
         goto l_fail;
     }
 
-    status = casService->createDescrambler(descriptor.mSystemID, &descrambler);
-    if (!status.isOk() || descrambler == NULL) {
-        ALOGE("Failed to create descrambler: : exception=%d, error=%d",
-                status.exceptionCode(), status.serviceSpecificErrorCode());
+    returnDescrambler = casService->createDescrambler(descriptor.mSystemID);
+    if (!returnDescrambler.isOk()) {
+        ALOGE("Failed to create descrambler: trans=%s",
+                returnDescrambler.description().c_str());
+        goto l_fail;
+    }
+    descramblerBase = (sp<IDescramblerBase>) returnDescrambler;
+    if (descramblerBase == NULL) {
+        ALOGE("Failed to create descrambler: null ptr");
         goto l_fail;
     }
 
-    status = descrambler->setMediaCasSession(sessionId);
-    if (!status.isOk()) {
-        ALOGE("Failed to init descrambler: : exception=%d, error=%d",
-                status.exceptionCode(), status.serviceSpecificErrorCode());
+    returnStatus = descramblerBase->setMediaCasSession(sessionId);
+    if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+        ALOGE("Failed to init descrambler: : trans=%s, status=%d",
+                returnStatus.description().c_str(), (Status) returnStatus);
+        goto l_fail;
+    }
+
+    descrambler = IDescrambler::castFrom(descramblerBase);
+    if (descrambler == NULL) {
+        ALOGE("Failed to cast from IDescramblerBase to IDescrambler");
         goto l_fail;
     }
 
@@ -177,8 +196,8 @@
     if (!sessionId.empty()) {
         cas->closeSession(sessionId);
     }
-    if (descrambler != NULL) {
-        descrambler->release();
+    if (descramblerBase != NULL) {
+        descramblerBase->release();
     }
     return NO_INIT;
 }
@@ -316,11 +335,12 @@
     if (index < 0) {
         return false;
     }
-    MediaCas::ParcelableCasData ecm(br->data(), br->numBitsLeft() / 8);
-    Status status = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
-    if (!status.isOk()) {
-        ALOGE("Failed to process ECM: exception=%d, error=%d",
-                status.exceptionCode(), status.serviceSpecificErrorCode());
+    hidl_vec<uint8_t> ecm;
+    ecm.setToExternal((uint8_t*)br->data(), br->numBitsLeft() / 8);
+    auto returnStatus = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
+    if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+        ALOGE("Failed to process ECM: trans=%s, status=%d",
+                returnStatus.description().c_str(), (Status) returnStatus);
     }
     return true; // handled
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.h b/media/libstagefright/mpeg2ts/CasManager.h
index 8088dec..81f6546 100644
--- a/media/libstagefright/mpeg2ts/CasManager.h
+++ b/media/libstagefright/mpeg2ts/CasManager.h
@@ -21,10 +21,13 @@
 #include <set>
 
 namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-}
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
 
 struct ATSParser::CasManager : public RefBase {
     CasManager();
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index c3f1274..9d684e0 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -38,8 +38,13 @@
 #include "AnotherPacketSource.h"
 #include "ATSParser.h"
 
+#include <hidl/HybridInterface.h>
+#include <android/hardware/cas/1.0/ICas.h>
+
 namespace android {
 
+using hardware::cas::V1_0::ICas;
+
 static const size_t kTSPacketSize = 188;
 static const int kMaxDurationReadSize = 250000LL;
 static const int kMaxDurationRetry = 6;
@@ -156,7 +161,10 @@
                     || !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
 }
 
-status_t MPEG2TSExtractor::setMediaCas(const sp<ICas> &cas) {
+status_t MPEG2TSExtractor::setMediaCas(const HInterfaceToken &casToken) {
+    HalToken halToken;
+    halToken.setToExternal((uint8_t*)casToken.data(), casToken.size());
+    sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
     ALOGD("setMediaCas: %p", cas.get());
 
     status_t err = mParser->setMediaCas(cas);
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index 789379a..dfab3b0 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -19,20 +19,19 @@
 
 #include <android-base/logging.h>
 #include <gui/IGraphicBufferProducer.h>
-#include <OMX_Core.h>
-#include <OMX_AsString.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_AsString.h>
 
-#include "../OMXUtils.h"
-#include "../OMXMaster.h"
-#include "../GraphicBufferSource.h"
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/GraphicBufferSource.h>
 
-#include "WOmxNode.h"
-#include "WOmxObserver.h"
-#include "WGraphicBufferProducer.h"
-#include "WGraphicBufferSource.h"
-#include "Conversion.h"
-
-#include "Omx.h"
+#include <media/stagefright/omx/1.0/WOmxNode.h>
+#include <media/stagefright/omx/1.0/WOmxObserver.h>
+#include <media/stagefright/omx/1.0/WGraphicBufferProducer.h>
+#include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
+#include <media/stagefright/omx/1.0/Omx.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/OmxStore.cpp b/media/libstagefright/omx/1.0/OmxStore.cpp
index 0e37af9..a82625a 100644
--- a/media/libstagefright/omx/1.0/OmxStore.cpp
+++ b/media/libstagefright/omx/1.0/OmxStore.cpp
@@ -19,8 +19,8 @@
 
 #include <android-base/logging.h>
 
-#include "Conversion.h"
-#include "OmxStore.h"
+#include <media/stagefright/omx/1.0/Conversion.h>
+#include <media/stagefright/omx/1.0/OmxStore.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp b/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp
index acda060..fcf1092 100644
--- a/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp
+++ b/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp
@@ -18,9 +18,9 @@
 
 #include <android-base/logging.h>
 
-#include "WGraphicBufferProducer.h"
-#include "WProducerListener.h"
-#include "Conversion.h"
+#include <media/stagefright/omx/1.0/WGraphicBufferProducer.h>
+#include <media/stagefright/omx/1.0/WProducerListener.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
 #include <system/window.h>
 
 namespace android {
@@ -64,10 +64,9 @@
     sp<Fence> fence;
     ::android::FrameEventHistoryDelta outTimestamps;
     status_t status = mBase->dequeueBuffer(
-            &slot, &fence,
-            width, height,
-            static_cast<::android::PixelFormat>(format), usage,
-            getFrameTimestamps ? &outTimestamps : nullptr);
+        &slot, &fence, width, height,
+        static_cast<::android::PixelFormat>(format), usage, nullptr,
+        getFrameTimestamps ? &outTimestamps : nullptr);
     hidl_handle tFence;
     FrameEventHistoryDelta tOutTimestamps;
 
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
index d8540f8..3697429 100644
--- a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
@@ -17,15 +17,14 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "TWGraphicBufferSource"
 
+#include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
+#include <media/stagefright/omx/1.0/WOmxNode.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
+#include <media/stagefright/omx/OMXUtils.h>
 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-
-#include "omx/OMXUtils.h"
-#include "WGraphicBufferSource.h"
-#include "WOmxNode.h"
-#include "Conversion.h"
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WOmxBufferSource.cpp b/media/libstagefright/omx/1.0/WOmxBufferSource.cpp
index 803283a..c8c963f 100644
--- a/media/libstagefright/omx/1.0/WOmxBufferSource.cpp
+++ b/media/libstagefright/omx/1.0/WOmxBufferSource.cpp
@@ -16,8 +16,8 @@
 
 #include <utils/String8.h>
 
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/stagefright/omx/1.0/WOmxBufferSource.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WOmxNode.cpp b/media/libstagefright/omx/1.0/WOmxNode.cpp
index 91d1010..9f82283 100644
--- a/media/libstagefright/omx/1.0/WOmxNode.cpp
+++ b/media/libstagefright/omx/1.0/WOmxNode.cpp
@@ -16,9 +16,9 @@
 
 #include <algorithm>
 
-#include "WOmxNode.h"
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/stagefright/omx/1.0/WOmxNode.h>
+#include <media/stagefright/omx/1.0/WOmxBufferSource.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WOmxObserver.cpp b/media/libstagefright/omx/1.0/WOmxObserver.cpp
index 354db29..ccbe25c 100644
--- a/media/libstagefright/omx/1.0/WOmxObserver.cpp
+++ b/media/libstagefright/omx/1.0/WOmxObserver.cpp
@@ -16,14 +16,14 @@
 
 #define LOG_TAG "WOmxObserver-impl"
 
-#include <vector>
-
 #include <android-base/logging.h>
 #include <cutils/native_handle.h>
 #include <binder/Binder.h>
 
-#include "WOmxObserver.h"
-#include "Conversion.h"
+#include <media/stagefright/omx/1.0/WOmxObserver.h>
+#include <media/stagefright/omx/1.0/Conversion.h>
+
+#include <vector>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WProducerListener.cpp b/media/libstagefright/omx/1.0/WProducerListener.cpp
index be0d4d5..bdc3aa1 100644
--- a/media/libstagefright/omx/1.0/WProducerListener.cpp
+++ b/media/libstagefright/omx/1.0/WProducerListener.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "WProducerListener.h"
+#include <media/stagefright/omx/1.0/WProducerListener.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 2d921f9..bb05740 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -1,6 +1,9 @@
 cc_library_shared {
     name: "libstagefright_omx",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "FrameDropper.cpp",
@@ -25,8 +28,11 @@
         "1.0/WOmxBufferSource.cpp",
     ],
 
+    export_include_dirs: [
+        "include",
+    ],
+
     include_dirs: [
-        "frameworks/av/include", // for media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h
         "frameworks/av/include/media/",
         "frameworks/av/media/libstagefright",
         "frameworks/av/media/libstagefright/include",
@@ -35,6 +41,14 @@
         "frameworks/native/include/media/openmax",
     ],
 
+    header_libs: [
+        "media_plugin_headers",
+    ],
+
+    export_header_lib_headers: [
+        "media_plugin_headers",
+    ],
+
     shared_libs: [
         "libbase",
         "libbinder",
@@ -45,12 +59,12 @@
         "libgui",
         "libcutils",
         "libstagefright_foundation",
+        "libstagefright_xmlparser",
         "libdl",
         "libhidlbase",
         "libhidlmemory",
         "libhidltransport",
         "libnativewindow", // TODO(b/62923479): use header library
-        "libstagefright_xmlparser@1.0",
         "android.hidl.memory@1.0",
         "android.hidl.token@1.0-utils",
         "android.hardware.media@1.0",
@@ -59,7 +73,12 @@
         "android.hardware.graphics.bufferqueue@1.0",
     ],
 
-    export_shared_lib_headers: ["android.hidl.memory@1.0"],
+    export_shared_lib_headers: [
+        "android.hidl.memory@1.0",
+        "libmedia_omx",
+        "libstagefright_foundation",
+        "libstagefright_xmlparser",
+    ],
 
     cflags: [
         "-Werror",
@@ -83,12 +102,21 @@
 cc_library_static {
     name: "libstagefright_omx_utils",
     srcs: ["OMXUtils.cpp"],
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/native/include/media/hardware",
-        "frameworks/native/include/media/openmax",
+    export_include_dirs: [
+        "include",
     ],
-    shared_libs: ["libmedia"],
+    header_libs: [
+        "media_plugin_headers",
+    ],
+    export_header_lib_headers: [
+        "media_plugin_headers",
+    ],
+    shared_libs: [
+        "libmedia",
+    ],
+    export_shared_lib_headers: [
+        "libmedia",
+    ],
     sanitize: {
         misc_undefined: [
             "signed-integer-overflow",
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.cpp b/media/libstagefright/omx/BWGraphicBufferSource.cpp
index 79f6d93..94ef598 100644
--- a/media/libstagefright/omx/BWGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/BWGraphicBufferSource.cpp
@@ -17,15 +17,13 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "BWGraphicBufferSource"
 
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-
+#include <media/stagefright/omx/BWGraphicBufferSource.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
 #include <media/OMXBuffer.h>
 #include <media/IOMX.h>
 
-#include "OMXUtils.h"
-#include "BWGraphicBufferSource.h"
-
 namespace android {
 
 static const OMX_U32 kPortIndexInput = 0;
diff --git a/media/libstagefright/omx/FrameDropper.cpp b/media/libstagefright/omx/FrameDropper.cpp
index 9a4952e..0c50c58 100644
--- a/media/libstagefright/omx/FrameDropper.cpp
+++ b/media/libstagefright/omx/FrameDropper.cpp
@@ -18,8 +18,7 @@
 #define LOG_TAG "FrameDropper"
 #include <utils/Log.h>
 
-#include "FrameDropper.h"
-
+#include <media/stagefright/omx/FrameDropper.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index ef4d745..caf3ac8 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -22,7 +22,9 @@
 
 #define STRINGIFY_ENUMS // for asString in HardwareAPI.h/VideoAPI.h
 
-#include "GraphicBufferSource.h"
+#include <media/stagefright/omx/GraphicBufferSource.h>
+#include <media/stagefright/omx/FrameDropper.h>
+#include <media/stagefright/omx/OMXUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/ColorUtils.h>
@@ -31,14 +33,12 @@
 #include <media/hardware/MetadataBufferType.h>
 #include <ui/GraphicBuffer.h>
 #include <gui/BufferItem.h>
-#include <HardwareAPI.h>
-#include "omx/OMXUtils.h"
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-#include "media/OMXBuffer.h"
+#include <media/hardware/HardwareAPI.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/OMXBuffer.h>
 
 #include <inttypes.h>
-#include "FrameDropper.h"
 
 #include <functional>
 #include <memory>
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 8c1141d..93b4dbe 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -22,15 +22,12 @@
 
 #include <dlfcn.h>
 
-#include "../include/OMX.h"
-
-#include "../include/OMXNodeInstance.h"
-
+#include <media/stagefright/omx/OMX.h>
+#include <media/stagefright/omx/OMXNodeInstance.h>
+#include <media/stagefright/omx/BWGraphicBufferSource.h>
+#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include "BWGraphicBufferSource.h"
-
-#include "OMXMaster.h"
-#include "OMXUtils.h"
 
 namespace android {
 
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index ac9b0c3..fd97fdc 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -18,15 +18,13 @@
 #define LOG_TAG "OMXMaster"
 #include <utils/Log.h>
 
-#include "OMXMaster.h"
-
-#include "SoftOMXPlugin.h"
+#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/SoftOMXPlugin.h>
+#include <media/stagefright/foundation/ADebug.h>
 
 #include <dlfcn.h>
 #include <fcntl.h>
 
-#include <media/stagefright/foundation/ADebug.h>
-
 namespace android {
 
 OMXMaster::OMXMaster()
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 22d7d27..c749454 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -20,20 +20,20 @@
 
 #include <inttypes.h>
 
-#include "../include/OMXNodeInstance.h"
-#include "OMXMaster.h"
-#include "OMXUtils.h"
+#include <media/stagefright/omx/OMXNodeInstance.h>
+#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXUtils.h>
 #include <android/IOMXBufferSource.h>
 
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-#include <OMX_VideoExt.h>
-#include <OMX_AsString.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/openmax/OMX_VideoExt.h>
+#include <media/openmax/OMX_AsString.h>
 
 #include <binder/IMemory.h>
 #include <cutils/properties.h>
 #include <gui/BufferQueue.h>
-#include <HardwareAPI.h>
+#include <media/hardware/HardwareAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ColorUtils.h>
@@ -41,7 +41,7 @@
 #include <utils/misc.h>
 #include <utils/NativeHandle.h>
 #include <media/OMXBuffer.h>
-#include <media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 
 #include <hidlmemory/mapping.h>
 
@@ -246,6 +246,15 @@
     virtual ~CallbackDispatcher();
 
 private:
+    enum {
+        // This is used for frame_rendered message batching, which will eventually end up in a
+        // single AMessage in MediaCodec when it is signaled to the app. AMessage can contain
+        // up-to 64 key-value pairs, and each frame_rendered message uses 2 keys, so the max
+        // value for this would be 32. Nonetheless, limit this to 12 to which gives at least 10
+        // mseconds of batching at 120Hz.
+        kMaxQueueSize = 12,
+    };
+
     Mutex mLock;
 
     sp<OMXNodeInstance> const mOwner;
@@ -290,7 +299,7 @@
     Mutex::Autolock autoLock(mLock);
 
     mQueue.push_back(msg);
-    if (realTime) {
+    if (realTime || mQueue.size() >= kMaxQueueSize) {
         mQueueChanged.signal();
     }
 }
@@ -2168,8 +2177,8 @@
             msg.fenceFd = -1;
             msg.u.render_data.timestamp = renderData[i].nMediaTimeUs;
             msg.u.render_data.nanoTime = renderData[i].nSystemTimeNs;
-
-            instance->mDispatcher->post(msg, false /* realTime */);
+            bool realTime = msg.u.render_data.timestamp == INT64_MAX;
+            instance->mDispatcher->post(msg, realTime);
         }
         return OMX_ErrorNone;
     }
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index a66d565..5894837 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -19,13 +19,13 @@
 
 #include <string.h>
 
-#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/omx/OMXUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/hardware/HardwareAPI.h>
 #include <media/MediaDefs.h>
 #include <system/graphics-base.h>
-#include "OMXUtils.h"
 
 namespace android {
 
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index d89cb99..87c2411 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -18,8 +18,7 @@
 #define LOG_TAG "SimpleSoftOMXComponent"
 #include <utils/Log.h>
 
-#include "include/SimpleSoftOMXComponent.h"
-
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp
index df978f8..ee269e1 100644
--- a/media/libstagefright/omx/SoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftOMXComponent.cpp
@@ -18,8 +18,7 @@
 #define LOG_TAG "SoftOMXComponent"
 #include <utils/Log.h>
 
-#include "include/SoftOMXComponent.h"
-
+#include <media/stagefright/omx/SoftOMXComponent.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index fccb12b..4946ada 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -18,8 +18,8 @@
 #define LOG_TAG "SoftOMXPlugin"
 #include <utils/Log.h>
 
-#include "SoftOMXPlugin.h"
-#include "include/SoftOMXComponent.h"
+#include <media/stagefright/omx/SoftOMXPlugin.h>
+#include <media/stagefright/omx/SoftOMXComponent.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
@@ -85,7 +85,21 @@
         libName.append(kComponents[i].mLibNameSuffix);
         libName.append(".so");
 
-        void *libHandle = dlopen(libName.c_str(), RTLD_NOW);
+        // RTLD_NODELETE means we keep the shared library around forever.
+        // this eliminates thrashing during sequences like loading soundpools.
+        // It also leaves the rest of the logic around the dlopen()/dlclose()
+        // calls in this file unchanged.
+        //
+        // Implications of the change:
+        // -- the codec process (where this happens) will have a slightly larger
+        //    long-term memory footprint as it accumulates the loaded shared libraries.
+        //    This is expected to be a small amount of memory.
+        // -- plugin codecs can no longer (and never should have) depend on a
+        //    free reset of any static data as the library would have crossed
+        //    a dlclose/dlopen cycle.
+        //
+
+        void *libHandle = dlopen(libName.c_str(), RTLD_NOW|RTLD_NODELETE);
 
         if (libHandle == NULL) {
             ALOGE("unable to dlopen %s: %s", libName.c_str(), dlerror());
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 920dd18..24ed981 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -20,14 +20,14 @@
 #define LOG_TAG "SoftVideoDecoderOMXComponent"
 #include <utils/Log.h>
 
-#include "include/SoftVideoDecoderOMXComponent.h"
+#include <media/stagefright/omx/SoftVideoDecoderOMXComponent.h>
 
-#include <media/hardware/HardwareAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaDefs.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/MediaDefs.h>
 
 namespace android {
 
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 7ecfbbb..f33bdc0 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -21,25 +21,22 @@
 #include <utils/Log.h>
 #include <utils/misc.h>
 
-#include "include/SoftVideoEncoderOMXComponent.h"
-
-#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaDefs.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/MediaDefs.h>
 
 #include <ui/Fence.h>
 #include <ui/GraphicBufferMapper.h>
 #include <ui/Rect.h>
 
 #include <hardware/gralloc.h>
-
 #include <nativebase/nativebase.h>
 
-#include <OMX_IndexExt.h>
-
 namespace android {
 
 const static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = {
diff --git a/media/libstagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
similarity index 99%
rename from media/libstagefright/omx/1.0/Conversion.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index fd91574..f319bdc 100644
--- a/media/libstagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -29,12 +29,12 @@
 #include <binder/Binder.h>
 #include <binder/Status.h>
 #include <ui/FenceTime.h>
-#include <media/OMXFenceParcelable.h>
 #include <cutils/native_handle.h>
 #include <gui/IGraphicBufferProducer.h>
 
+#include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
-#include <VideoAPI.h>
+#include <media/hardware/VideoAPI.h>
 
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
diff --git a/media/libstagefright/omx/1.0/Omx.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
similarity index 95%
rename from media/libstagefright/omx/1.0/Omx.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
index 23784aa..a6a9d3e 100644
--- a/media/libstagefright/omx/1.0/Omx.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
@@ -20,10 +20,9 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
-#include "../../include/OMXNodeInstance.h"
-
+#include <media/stagefright/omx/OMXNodeInstance.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
-#include <media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h>
 
 namespace android {
 
diff --git a/media/libstagefright/omx/1.0/OmxStore.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h
similarity index 100%
rename from media/libstagefright/omx/1.0/OmxStore.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/OmxStore.h
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferProducer.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
similarity index 100%
rename from media/libstagefright/omx/1.0/WGraphicBufferProducer.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
similarity index 98%
rename from media/libstagefright/omx/1.0/WGraphicBufferSource.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
index 4549c97..b9f22ab 100644
--- a/media/libstagefright/omx/1.0/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
@@ -28,7 +28,7 @@
 
 #include <android/BnGraphicBufferSource.h>
 
-#include "../GraphicBufferSource.h"
+#include <media/stagefright/omx/GraphicBufferSource.h>
 
 namespace android {
 namespace hardware {
diff --git a/media/libstagefright/omx/1.0/WOmxBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxBufferSource.h
similarity index 100%
rename from media/libstagefright/omx/1.0/WOmxBufferSource.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxBufferSource.h
diff --git a/media/libstagefright/omx/1.0/WOmxNode.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxNode.h
similarity index 98%
rename from media/libstagefright/omx/1.0/WOmxNode.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxNode.h
index d715374..38d5885 100644
--- a/media/libstagefright/omx/1.0/WOmxNode.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxNode.h
@@ -22,7 +22,7 @@
 
 #include <utils/Errors.h>
 
-#include "../../include/OMXNodeInstance.h"
+#include <media/stagefright/omx/OMXNodeInstance.h>
 
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
diff --git a/media/libstagefright/omx/1.0/WOmxObserver.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxObserver.h
similarity index 100%
rename from media/libstagefright/omx/1.0/WOmxObserver.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WOmxObserver.h
diff --git a/media/libstagefright/omx/1.0/WProducerListener.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WProducerListener.h
similarity index 100%
rename from media/libstagefright/omx/1.0/WProducerListener.h
rename to media/libstagefright/omx/include/media/stagefright/omx/1.0/WProducerListener.h
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/BWGraphicBufferSource.h
similarity index 100%
rename from media/libstagefright/omx/BWGraphicBufferSource.h
rename to media/libstagefright/omx/include/media/stagefright/omx/BWGraphicBufferSource.h
diff --git a/media/libstagefright/omx/FrameDropper.h b/media/libstagefright/omx/include/media/stagefright/omx/FrameDropper.h
similarity index 100%
rename from media/libstagefright/omx/FrameDropper.h
rename to media/libstagefright/omx/include/media/stagefright/omx/FrameDropper.h
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/GraphicBufferSource.h
similarity index 100%
rename from media/libstagefright/omx/GraphicBufferSource.h
rename to media/libstagefright/omx/include/media/stagefright/omx/GraphicBufferSource.h
diff --git a/media/libstagefright/omx/IOmxNodeWrapper.h b/media/libstagefright/omx/include/media/stagefright/omx/IOmxNodeWrapper.h
similarity index 100%
rename from media/libstagefright/omx/IOmxNodeWrapper.h
rename to media/libstagefright/omx/include/media/stagefright/omx/IOmxNodeWrapper.h
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/omx/include/media/stagefright/omx/OMX.h
similarity index 96%
rename from media/libstagefright/include/OMX.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMX.h
index 4af3d39..594b4c0 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMX.h
@@ -20,7 +20,7 @@
 #include <media/IOMX.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
-#include <media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 #include "OmxNodeOwner.h"
 
 namespace android {
diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
similarity index 100%
rename from media/libstagefright/omx/OMXMaster.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
similarity index 100%
rename from media/libstagefright/include/OMXNodeInstance.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
diff --git a/media/libstagefright/omx/OMXUtils.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXUtils.h
similarity index 100%
rename from media/libstagefright/omx/OMXUtils.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMXUtils.h
diff --git a/media/libstagefright/include/SimpleSoftOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
similarity index 100%
rename from media/libstagefright/include/SimpleSoftOMXComponent.h
rename to media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
diff --git a/media/libstagefright/include/SoftOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h
similarity index 100%
rename from media/libstagefright/include/SoftOMXComponent.h
rename to media/libstagefright/omx/include/media/stagefright/omx/SoftOMXComponent.h
diff --git a/media/libstagefright/omx/SoftOMXPlugin.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftOMXPlugin.h
similarity index 100%
rename from media/libstagefright/omx/SoftOMXPlugin.h
rename to media/libstagefright/omx/include/media/stagefright/omx/SoftOMXPlugin.h
diff --git a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
similarity index 100%
rename from media/libstagefright/include/SoftVideoDecoderOMXComponent.h
rename to media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
diff --git a/media/libstagefright/include/SoftVideoEncoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
similarity index 100%
rename from media/libstagefright/include/SoftVideoEncoderOMXComponent.h
rename to media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
diff --git a/media/libstagefright/omx/tests/FrameDropper_test.cpp b/media/libstagefright/omx/tests/FrameDropper_test.cpp
index f966b5e..a925da6 100644
--- a/media/libstagefright/omx/tests/FrameDropper_test.cpp
+++ b/media/libstagefright/omx/tests/FrameDropper_test.cpp
@@ -20,7 +20,7 @@
 
 #include <gtest/gtest.h>
 
-#include "FrameDropper.h"
+#include <media/stagefright/omx/FrameDropper.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
diff --git a/media/vndk/xmlparser/1.0/Android.bp b/media/libstagefright/xmlparser/Android.bp
similarity index 80%
rename from media/vndk/xmlparser/1.0/Android.bp
rename to media/libstagefright/xmlparser/Android.bp
index 2f10cb1..ab893de 100644
--- a/media/vndk/xmlparser/1.0/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -1,6 +1,9 @@
 cc_library_shared {
-    name: "libstagefright_xmlparser@1.0",
+    name: "libstagefright_xmlparser",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     srcs: [
         "MediaCodecsXmlParser.cpp",
@@ -11,6 +14,10 @@
         "frameworks/av/include",
     ],
 
+    export_include_dirs: [
+        "include",
+    ],
+
     shared_libs: [
         "libexpat",
         "libutils",
diff --git a/media/vndk/xmlparser/1.0/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
similarity index 99%
rename from media/vndk/xmlparser/1.0/MediaCodecsXmlParser.cpp
rename to media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index 84e5514..4fdd107 100644
--- a/media/vndk/xmlparser/1.0/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "MediaCodecsXmlParser"
 #include <utils/Log.h>
 
-#include <media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
 
 #include <media/MediaCodecInfo.h>
 
diff --git a/include/media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
similarity index 100%
rename from include/media/vndk/xmlparser/1.0/MediaCodecsXmlParser.h
rename to media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index c50af2f..4132fed 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -719,9 +719,22 @@
 }
 
 int MtpFfsHandle::sendEvent(mtp_event me) {
+    // Mimic the behavior of f_mtp by sending the event async.
+    // Events aren't critical to the connection, so we don't need to check the return value.
+    char *temp = new char[me.length];
+    memcpy(temp, me.data, me.length);
+    me.data = temp;
+    std::thread t([this, me]() { return this->doSendEvent(me); });
+    t.detach();
+    return 0;
+}
+
+void MtpFfsHandle::doSendEvent(mtp_event me) {
     unsigned length = me.length;
-    int ret = writeHandle(mIntr, me.data, length);
-    return static_cast<unsigned>(ret) == length ? 0 : -1;
+    int ret = ::write(mIntr, me.data, length);
+    if (static_cast<unsigned>(ret) != length)
+        PLOG(ERROR) << "Mtp error sending event thread!";
+    delete[] reinterpret_cast<char*>(me.data);
 }
 
 } // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index 98669ff..b637d65 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -33,6 +33,7 @@
     bool initFunctionfs();
     void closeConfig();
     void closeEndpoints();
+    void doSendEvent(mtp_event me);
 
     bool mPtp;
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 40974f3..0d48de1 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -90,3 +90,9 @@
         },
     },
 }
+
+llndk_library {
+    name: "libmediandk",
+    symbol_file: "libmediandk.map.txt",
+    export_include_dirs: ["include"],
+}
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 5d1a20b..a450dd3 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -44,7 +44,11 @@
 const char* AImageReader::kGraphicBufferKey = "GraphicBuffer";
 
 bool
-AImageReader::isSupportedFormat(int32_t format) {
+AImageReader::isSupportedFormatAndUsage(int32_t format, uint64_t usage) {
+    // Check whether usage has either CPU_READ_OFTEN or CPU_READ set. Note that check against
+    // AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN (0x6) is sufficient as it implies
+    // AHARDWAREBUFFER_USAGE_CPU_READ (0x2).
+    bool hasCpuUsage = usage & AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
     switch (format) {
         case AIMAGE_FORMAT_RGBA_8888:
         case AIMAGE_FORMAT_RGBX_8888:
@@ -60,6 +64,9 @@
         case AIMAGE_FORMAT_DEPTH16:
         case AIMAGE_FORMAT_DEPTH_POINT_CLOUD:
             return true;
+        case AIMAGE_FORMAT_PRIVATE:
+            // For private format, cpu usage is prohibited.
+            return !hasCpuUsage;
         default:
             return false;
     }
@@ -83,6 +90,8 @@
         case AIMAGE_FORMAT_DEPTH16:
         case AIMAGE_FORMAT_DEPTH_POINT_CLOUD:
             return 1;
+        case AIMAGE_FORMAT_PRIVATE:
+            return 0;
         default:
             return -1;
     }
@@ -606,9 +615,9 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
-    if (!AImageReader::isSupportedFormat(format)) {
-        ALOGE("%s: format %d is not supported by AImageReader",
-                __FUNCTION__, format);
+    if (!AImageReader::isSupportedFormatAndUsage(format, usage)) {
+        ALOGE("%s: format %d is not supported with usage 0x%" PRIx64 " by AImageReader",
+                __FUNCTION__, format, usage);
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 989c1fd..989b937 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -49,7 +49,7 @@
 
 struct AImageReader : public RefBase {
   public:
-    static bool isSupportedFormat(int32_t format);
+    static bool isSupportedFormatAndUsage(int32_t format, uint64_t usage0);
     static int getNumPlanesForFormat(int32_t format);
 
     AImageReader(int32_t width,
diff --git a/media/ndk/include/media/NdkImage.h b/media/ndk/include/media/NdkImage.h
index d7443be..1931496 100644
--- a/media/ndk/include/media/NdkImage.h
+++ b/media/ndk/include/media/NdkImage.h
@@ -495,7 +495,13 @@
     /**
      * Android private opaque image format.
      *
-     * <p>This format is not currently supported by {@link AImageReader}.</p>
+     * <p>The choices of the actual format and pixel data layout are entirely up to the
+     * device-specific and framework internal implementations, and may vary depending on use cases
+     * even for the same device. Also note that the contents of these buffers are not directly
+     * accessible to the application.</p>
+     *
+     * <p>When an {@link AImage} of this format is obtained from an {@link AImageReader} or
+     * {@link AImage_getNumberOfPlanes()} method will return zero.</p>
      */
     AIMAGE_FORMAT_PRIVATE           = 0x22
 };
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index 59ae507..7a0c17b 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -70,7 +70,9 @@
  * @param height The default height in pixels of the Images that this reader will produce.
  * @param format The format of the Image that this reader will produce. This must be one of the
  *            AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}. Note that not all
- *            formats are supported, like {@link AIMAGE_FORMAT_PRIVATE}.
+ *            formats are supported. One example is {@link AIMAGE_FORMAT_PRIVATE}, as it is not
+ *            intended to be read by applications directly. That format is supported by
+ *            {@link AImageReader_newWithUsage} introduced in API 26.
  * @param maxImages The maximum number of images the user will want to access simultaneously. This
  *            should be as small as possible to limit memory use. Once maxImages Images are obtained
  *            by the user, one of them has to be released before a new {@link AImage} will become
@@ -307,6 +309,28 @@
  * for the consumer usage. All other parameters and the return values are identical to those passed
  * to {@line AImageReader_new}.
  *
+ * <p>If the {@code format} is {@link AIMAGE_FORMAT_PRIVATE}, the created {@link AImageReader}
+ * will produce images whose contents are not directly accessible by the application. The application can
+ * still acquire images from this {@link AImageReader} and access {@link AHardwareBuffer} via
+ * {@link AImage_getHardwareBuffer()}. The {@link AHardwareBuffer} gained this way can then
+ * be passed back to hardware (such as GPU or hardware encoder if supported) for future processing.
+ * For example, you can obtain an {@link EGLClientBuffer} from the {@link AHardwareBuffer} by using
+ * {@link eglGetNativeClientBufferANDROID} extension and pass that {@link EGLClientBuffer} to {@link
+ * eglCreateImageKHR} to create an {@link EGLImage} resource type, which may then be bound to a
+ * texture via {@link glEGLImageTargetTexture2DOES} on supported devices. This can be useful for
+ * transporting textures that may be shared cross-process.</p>
+ * <p>In general, when software access to image data is not necessary, an {@link AImageReader}
+ * created with {@link AIMAGE_FORMAT_PRIVATE} format is more efficient, compared with {@link
+ * AImageReader}s using other format such as {@link AIMAGE_FORMAT_YUV_420_888}.</p>
+ *
+ * <p>Note that not all format and usage flag combination is supported by the {@link AImageReader},
+ * especially if {@code format} is {@link AIMAGE_FORMAT_PRIVATE}, {@code usage} must not include either
+ * {@link AHARDWAREBUFFER_USAGE_READ_RARELY} or {@link AHARDWAREBUFFER_USAGE_READ_OFTEN}</p>
+ *
+ * @param width The default width in pixels of the Images that this reader will produce.
+ * @param height The default height in pixels of the Images that this reader will produce.
+ * @param format The format of the Image that this reader will produce. This must be one of the
+ *            AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}.
  * @param usage specifies how the consumer will access the AImage, using combination of the
  *            AHARDWAREBUFFER_USAGE flags described in {@link hardware_buffer.h}.
  *            Passing {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN} is equivalent to calling
@@ -331,6 +355,11 @@
  *   {@link AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
  * </tr>
  * </table>
+ * @return <ul>
+ *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
+ *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width,
+ *                 height, format, maxImages, or usage arguments is not supported.</li>
+ *         <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
  *
  * @see AImage
  * @see AImageReader_new
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 637bf9b..7e7e81e 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -27,6 +27,7 @@
 #ifndef _NDK_MEDIA_CODEC_H
 #define _NDK_MEDIA_CODEC_H
 
+#include <stdint.h>
 #include <sys/cdefs.h>
 
 #include "NdkMediaCrypto.h"
@@ -130,17 +131,45 @@
  */
 ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs);
 
-/**
- * Send the specified buffer to the codec for processing.
+/*
+ * __USE_FILE_OFFSET64 changes the type of off_t in LP32, which changes the ABI
+ * of these declarations to  not match the platform. In that case, define these
+ * APIs in terms of int32_t instead. Passing an off_t in this situation will
+ * result in silent truncation unless the user builds with -Wconversion, but the
+ * only alternative it to not expose them at all for this configuration, which
+ * makes the whole API unusable.
+ *
+ * https://github.com/android-ndk/ndk/issues/459
  */
-media_status_t AMediaCodec_queueInputBuffer(AMediaCodec*,
-        size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags);
+#if defined(__USE_FILE_OFFSET64) && !defined(__LP64__)
+#define _off_t_compat int32_t
+#else
+#define _off_t_compat off_t
+#endif  /* defined(__USE_FILE_OFFSET64) && !defined(__LP64__) */
+
+#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
+    __STDC_VERSION__ >= 201112L
+static_assert(sizeof(_off_t_compat) == sizeof(long),
+              "_off_t_compat does not match the NDK ABI. See "
+              "https://github.com/android-ndk/ndk/issues/459.");
+#endif
 
 /**
  * Send the specified buffer to the codec for processing.
  */
-media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*,
-        size_t idx, off_t offset, AMediaCodecCryptoInfo*, uint64_t time, uint32_t flags);
+media_status_t AMediaCodec_queueInputBuffer(AMediaCodec*, size_t idx,
+                                            _off_t_compat offset, size_t size,
+                                            uint64_t time, uint32_t flags);
+
+/**
+ * Send the specified buffer to the codec for processing.
+ */
+media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*, size_t idx,
+                                                  _off_t_compat offset,
+                                                  AMediaCodecCryptoInfo*,
+                                                  uint64_t time, uint32_t flags);
+
+#undef _off_t_compat
 
 /**
  * Get the index of the next available buffer of processed data.
diff --git a/media/vndk/Android.bp b/media/vndk/Android.bp
deleted file mode 100644
index e93fd16..0000000
--- a/media/vndk/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-subdirs = [
-    "xmlparser/1.0",
-]
-
diff --git a/radio/Android.bp b/radio/Android.bp
deleted file mode 100644
index 8e614f2..0000000
--- a/radio/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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_shared {
-    name: "libradio",
-
-    srcs: [
-        "Radio.cpp",
-        "IRadio.cpp",
-        "IRadioClient.cpp",
-        "IRadioService.cpp",
-    ],
-
-    shared_libs: [
-        "libcutils",
-        "libutils",
-        "liblog",
-        "libbinder",
-        "libradio_metadata",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-}
diff --git a/radio/IRadio.cpp b/radio/IRadio.cpp
deleted file mode 100644
index 72f3b68..0000000
--- a/radio/IRadio.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-**
-** Copyright 2015, 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 "IRadio"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <binder/IMemory.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-#include <system/RadioMetadataWrapper.h>
-
-namespace android {
-
-enum {
-    DETACH = IBinder::FIRST_CALL_TRANSACTION,
-    SET_CONFIGURATION,
-    GET_CONFIGURATION,
-    SET_MUTE,
-    GET_MUTE,
-    SCAN,
-    STEP,
-    TUNE,
-    CANCEL,
-    GET_PROGRAM_INFORMATION,
-    HAS_CONTROL
-};
-
-class BpRadio: public BpInterface<IRadio>
-{
-public:
-    explicit BpRadio(const sp<IBinder>& impl)
-        : BpInterface<IRadio>(impl)
-    {
-    }
-
-    void detach()
-    {
-        ALOGV("detach");
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        remote()->transact(DETACH, data, &reply);
-    }
-
-    virtual status_t setConfiguration(const struct radio_band_config *config)
-    {
-        Parcel data, reply;
-        if (config == NULL) {
-            return BAD_VALUE;
-        }
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        data.write(config, sizeof(struct radio_band_config));
-        status_t status = remote()->transact(SET_CONFIGURATION, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t getConfiguration(struct radio_band_config *config)
-    {
-        Parcel data, reply;
-        if (config == NULL) {
-            return BAD_VALUE;
-        }
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_CONFIGURATION, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-            if (status == NO_ERROR) {
-                reply.read(config, sizeof(struct radio_band_config));
-            }
-        }
-        return status;
-    }
-
-    virtual status_t setMute(bool mute)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        data.writeInt32(mute ? 1 : 0);
-        status_t status = remote()->transact(SET_MUTE, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t getMute(bool *mute)
-    {
-        Parcel data, reply;
-        if (mute == NULL) {
-            return BAD_VALUE;
-        }
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MUTE, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-            if (status == NO_ERROR) {
-                int32_t muteread = reply.readInt32();
-                *mute = muteread != 0;
-            }
-        }
-        return status;
-    }
-
-    virtual status_t scan(radio_direction_t direction, bool skipSubChannel)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        data.writeInt32(direction);
-        data.writeInt32(skipSubChannel ? 1 : 0);
-        status_t status = remote()->transact(SCAN, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t step(radio_direction_t direction, bool skipSubChannel)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        data.writeInt32(direction);
-        data.writeInt32(skipSubChannel ? 1 : 0);
-        status_t status = remote()->transact(STEP, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t tune(uint32_t channel, uint32_t subChannel)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        data.writeUint32(channel);
-        data.writeUint32(subChannel);
-        status_t status = remote()->transact(TUNE, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t cancel()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        status_t status = remote()->transact(CANCEL, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t getProgramInformation(struct radio_program_info *info)
-    {
-        Parcel data, reply;
-        if (info == nullptr || info->metadata == nullptr) {
-            return BAD_VALUE;
-        }
-        radio_metadata_t *metadata = info->metadata;
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_PROGRAM_INFORMATION, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-            if (status == NO_ERROR) {
-                reply.read(info, sizeof(struct radio_program_info));
-                // restore local metadata pointer
-                info->metadata = metadata;
-
-                uint32_t metadataSize = reply.readUint32();
-                if (metadataSize != 0) {
-                    radio_metadata_t *newMetadata = (radio_metadata_t *)malloc(metadataSize);
-                    if (newMetadata == NULL) {
-                        return NO_MEMORY;
-                    }
-                    reply.read(newMetadata, metadataSize);
-                    status = radio_metadata_add_metadata(&info->metadata, newMetadata);
-                    free(newMetadata);
-                }
-            }
-        }
-        return status;
-    }
-
-    virtual status_t hasControl(bool *hasControl)
-    {
-        Parcel data, reply;
-        if (hasControl == NULL) {
-            return BAD_VALUE;
-        }
-        data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
-        status_t status = remote()->transact(HAS_CONTROL, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-            if (status == NO_ERROR) {
-                *hasControl = reply.readInt32() != 0;
-            }
-        }
-        return status;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Radio, "android.hardware.IRadio");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadio::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case DETACH: {
-            ALOGV("DETACH");
-            CHECK_INTERFACE(IRadio, data, reply);
-            detach();
-            return NO_ERROR;
-        } break;
-        case SET_CONFIGURATION: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            struct radio_band_config config;
-            data.read(&config, sizeof(struct radio_band_config));
-            status_t status = setConfiguration(&config);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case GET_CONFIGURATION: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            struct radio_band_config config;
-            status_t status = getConfiguration(&config);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&config, sizeof(struct radio_band_config));
-            }
-            return NO_ERROR;
-        }
-        case SET_MUTE: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            bool mute = data.readInt32() != 0;
-            status_t status = setMute(mute);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case GET_MUTE: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            bool mute;
-            status_t status = getMute(&mute);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeInt32(mute ? 1 : 0);
-            }
-            return NO_ERROR;
-        }
-        case SCAN: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            radio_direction_t direction = (radio_direction_t)data.readInt32();
-            bool skipSubChannel = data.readInt32() == 1;
-            status_t status = scan(direction, skipSubChannel);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case STEP: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            radio_direction_t direction = (radio_direction_t)data.readInt32();
-            bool skipSubChannel = data.readInt32() == 1;
-            status_t status = step(direction, skipSubChannel);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case TUNE: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            uint32_t channel = data.readUint32();
-            uint32_t subChannel = data.readUint32();
-            status_t status = tune(channel, subChannel);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case CANCEL: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            status_t status = cancel();
-            reply->writeInt32(status);
-            return NO_ERROR;
-        }
-        case GET_PROGRAM_INFORMATION: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            struct radio_program_info info;
-            RadioMetadataWrapper metadataWrapper(&info.metadata);
-
-            status_t status = getProgramInformation(&info);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&info, sizeof(struct radio_program_info));
-                if (radio_metadata_get_count(info.metadata) > 0) {
-                    size_t size = radio_metadata_get_size(info.metadata);
-                    reply->writeUint32((uint32_t)size);
-                    reply->write(info.metadata, size);
-                } else {
-                    reply->writeUint32(0);
-                }
-            }
-            return NO_ERROR;
-        }
-        case HAS_CONTROL: {
-            CHECK_INTERFACE(IRadio, data, reply);
-            bool control;
-            status_t status = hasControl(&control);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeInt32(control ? 1 : 0);
-            }
-            return NO_ERROR;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/IRadioClient.cpp b/radio/IRadioClient.cpp
deleted file mode 100644
index ca21949..0000000
--- a/radio/IRadioClient.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-**
-** Copyright 2015, 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 <stdint.h>
-#include <sys/types.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <radio/IRadioClient.h>
-
-namespace android {
-
-enum {
-    ON_EVENT = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-class BpRadioClient: public BpInterface<IRadioClient>
-{
-
-public:
-    explicit BpRadioClient(const sp<IBinder>& impl)
-        : BpInterface<IRadioClient>(impl)
-    {
-    }
-
-    virtual void onEvent(const sp<IMemory>& eventMemory)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadioClient::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(eventMemory));
-        remote()->transact(ON_EVENT,
-                           data,
-                           &reply);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(RadioClient,
-                         "android.hardware.IRadioClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadioClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case ON_EVENT: {
-            CHECK_INTERFACE(IRadioClient, data, reply);
-            sp<IMemory> eventMemory = interface_cast<IMemory>(
-                data.readStrongBinder());
-            onEvent(eventMemory);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }   return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/IRadioService.cpp b/radio/IRadioService.cpp
deleted file mode 100644
index 72e3a61..0000000
--- a/radio/IRadioService.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-**
-** Copyright 2015, 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 "BpRadioService"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <radio/IRadioService.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioClient.h>
-
-namespace android {
-
-enum {
-    LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
-    ATTACH,
-};
-
-#define MAX_ITEMS_PER_LIST 1024
-
-class BpRadioService: public BpInterface<IRadioService>
-{
-public:
-    explicit BpRadioService(const sp<IBinder>& impl)
-        : BpInterface<IRadioService>(impl)
-    {
-    }
-
-    virtual status_t listModules(struct radio_properties *properties,
-                                 uint32_t *numModules)
-    {
-        if (numModules == NULL || (*numModules != 0 && properties == NULL)) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadioService::getInterfaceDescriptor());
-        uint32_t numModulesReq = (properties == NULL) ? 0 : *numModules;
-        data.writeInt32(numModulesReq);
-        status_t status = remote()->transact(LIST_MODULES, data, &reply);
-        if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
-            *numModules = (uint32_t)reply.readInt32();
-        }
-        ALOGV("listModules() status %d got *numModules %d", status, *numModules);
-        if (status == NO_ERROR) {
-            if (numModulesReq > *numModules) {
-                numModulesReq = *numModules;
-            }
-            if (numModulesReq > 0) {
-                reply.read(properties, numModulesReq * sizeof(struct radio_properties));
-            }
-        }
-        return status;
-    }
-
-    virtual status_t attach(radio_handle_t handle,
-                            const sp<IRadioClient>& client,
-                            const struct radio_band_config *config,
-                            bool withAudio,
-                            sp<IRadio>& radio)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IRadioService::getInterfaceDescriptor());
-        data.writeInt32(handle);
-        data.writeStrongBinder(IInterface::asBinder(client));
-        ALOGV("attach() config %p withAudio %d region %d type %d",
-              config == NULL ? 0 : config, withAudio,
-              config == NULL ? 0 : config->region,
-              config == NULL ? 0 : config->band.type);
-        if (config == NULL) {
-            data.writeInt32(0);
-        } else {
-            data.writeInt32(1);
-            data.write(config, sizeof(struct radio_band_config));
-        }
-        data.writeInt32(withAudio ? 1 : 0);
-        status_t status = remote()->transact(ATTACH, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        status = reply.readInt32();
-        if (reply.readInt32() != 0) {
-            radio = interface_cast<IRadio>(reply.readStrongBinder());
-        }
-        return status;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(RadioService, "android.hardware.IRadioService");
-
-// ----------------------------------------------------------------------
-
-status_t BnRadioService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case LIST_MODULES: {
-            CHECK_INTERFACE(IRadioService, data, reply);
-            uint32_t numModulesReq = data.readInt32();
-            if (numModulesReq > MAX_ITEMS_PER_LIST) {
-                numModulesReq = MAX_ITEMS_PER_LIST;
-            }
-            uint32_t numModules = numModulesReq;
-            struct radio_properties *properties =
-                    (struct radio_properties *)calloc(numModulesReq,
-                                                      sizeof(struct radio_properties));
-            if (properties == NULL) {
-                reply->writeInt32(NO_MEMORY);
-                reply->writeInt32(0);
-                return NO_ERROR;
-            }
-
-            status_t status = listModules(properties, &numModules);
-            reply->writeInt32(status);
-            reply->writeInt32(numModules);
-            ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
-
-            if (status == NO_ERROR) {
-                if (numModulesReq > numModules) {
-                    numModulesReq = numModules;
-                }
-                reply->write(properties,
-                             numModulesReq * sizeof(struct radio_properties));
-            }
-            free(properties);
-            return NO_ERROR;
-        } break;
-
-        case ATTACH: {
-            CHECK_INTERFACE(IRadioService, data, reply);
-            radio_handle_t handle = data.readInt32();
-            sp<IRadioClient> client =
-                    interface_cast<IRadioClient>(data.readStrongBinder());
-            struct radio_band_config config;
-            struct radio_band_config *configPtr = NULL;
-            if (data.readInt32() != 0) {
-                data.read(&config, sizeof(struct radio_band_config));
-                configPtr = &config;
-            }
-            bool withAudio = data.readInt32() != 0;
-            ALOGV("ATTACH configPtr %p withAudio %d", configPtr, withAudio);
-            sp<IRadio> radio;
-            status_t status = attach(handle, client, configPtr, withAudio, radio);
-            reply->writeInt32(status);
-            if (radio != 0) {
-                reply->writeInt32(1);
-                reply->writeStrongBinder(IInterface::asBinder(radio));
-            } else {
-                reply->writeInt32(0);
-            }
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/radio/Radio.cpp b/radio/Radio.cpp
deleted file mode 100644
index 9ddd221..0000000
--- a/radio/Radio.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-**
-** Copyright (C) 2015, 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 "Radio"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/IMemory.h>
-
-#include <radio/Radio.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadioClient.h>
-#include <radio/RadioCallback.h>
-
-namespace android {
-
-namespace {
-    sp<IRadioService>          gRadioService;
-    const int                  kRadioServicePollDelay = 500000; // 0.5s
-    const char*                kRadioServiceName      = "media.radio";
-    Mutex                      gLock;
-
-    class DeathNotifier : public IBinder::DeathRecipient
-    {
-    public:
-        DeathNotifier() {
-        }
-
-        virtual void binderDied(const wp<IBinder>& who __unused) {
-            ALOGV("binderDied");
-            Mutex::Autolock _l(gLock);
-            gRadioService.clear();
-            ALOGW("Radio service died!");
-        }
-    };
-
-    sp<DeathNotifier>         gDeathNotifier;
-}; // namespace anonymous
-
-const sp<IRadioService> Radio::getRadioService()
-{
-    Mutex::Autolock _l(gLock);
-    if (gRadioService.get() == 0) {
-        sp<IServiceManager> sm = defaultServiceManager();
-        sp<IBinder> binder;
-        do {
-            binder = sm->getService(String16(kRadioServiceName));
-            if (binder != 0) {
-                break;
-            }
-            ALOGW("RadioService not published, waiting...");
-            usleep(kRadioServicePollDelay);
-        } while(true);
-        if (gDeathNotifier == NULL) {
-            gDeathNotifier = new DeathNotifier();
-        }
-        binder->linkToDeath(gDeathNotifier);
-        gRadioService = interface_cast<IRadioService>(binder);
-    }
-    ALOGE_IF(gRadioService == 0, "no RadioService!?");
-    return gRadioService;
-}
-
-// Static methods
-status_t Radio::listModules(struct radio_properties *properties,
-                            uint32_t *numModules)
-{
-    ALOGV("listModules()");
-    const sp<IRadioService> service = getRadioService();
-    if (service == 0) {
-        return NO_INIT;
-    }
-    return service->listModules(properties, numModules);
-}
-
-sp<Radio> Radio::attach(radio_handle_t handle,
-                        const struct radio_band_config *config,
-                        bool withAudio,
-                        const sp<RadioCallback>& callback)
-{
-    ALOGV("attach()");
-    sp<Radio> radio;
-    const sp<IRadioService> service = getRadioService();
-    if (service == 0) {
-        return radio;
-    }
-    radio = new Radio(handle, callback);
-    status_t status = service->attach(handle, radio, config, withAudio, radio->mIRadio);
-
-    if (status == NO_ERROR && radio->mIRadio != 0) {
-        IInterface::asBinder(radio->mIRadio)->linkToDeath(radio);
-    } else {
-        ALOGW("Error %d connecting to radio service", status);
-        radio.clear();
-    }
-    return radio;
-}
-
-
-
-// Radio
-Radio::Radio(radio_handle_t /*handle*/, const sp<RadioCallback>& callback)
-    : mCallback(callback)
-{
-}
-
-Radio::~Radio()
-{
-    if (mIRadio != 0) {
-        mIRadio->detach();
-    }
-}
-
-
-void Radio::detach() {
-    ALOGV("detach()");
-    Mutex::Autolock _l(mLock);
-    mCallback.clear();
-    if (mIRadio != 0) {
-        mIRadio->detach();
-        IInterface::asBinder(mIRadio)->unlinkToDeath(this);
-        mIRadio = 0;
-    }
-}
-
-status_t Radio::setConfiguration(const struct radio_band_config *config)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->setConfiguration(config);
-}
-
-status_t Radio::getConfiguration(struct radio_band_config *config)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->getConfiguration(config);
-}
-
-status_t Radio::setMute(bool mute)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->setMute(mute);
-}
-
-status_t Radio::getMute(bool *mute)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->getMute(mute);
-}
-
-status_t Radio::scan(radio_direction_t direction, bool skipSubchannel)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->scan(direction, skipSubchannel);
-}
-
-status_t Radio::step(radio_direction_t direction, bool skipSubchannel)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->step(direction, skipSubchannel);
-}
-
-status_t Radio::tune(unsigned int channel, unsigned int subChannel)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->tune(channel, subChannel);
-}
-
-status_t Radio::cancel()
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->cancel();
-}
-
-status_t Radio::getProgramInformation(struct radio_program_info *info)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->getProgramInformation(info);
-}
-
-status_t Radio::hasControl(bool *hasControl)
-{
-    Mutex::Autolock _l(mLock);
-    if (mIRadio == 0) {
-        return NO_INIT;
-    }
-    return mIRadio->hasControl(hasControl);
-}
-
-
-// BpRadioClient
-void Radio::onEvent(const sp<IMemory>& eventMemory)
-{
-    Mutex::Autolock _l(mLock);
-    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
-        return;
-    }
-
-    // The event layout in shared memory is:
-    // sizeof(struct radio_event) bytes : the event itself
-    // 4 bytes                          : metadata size or 0
-    // N bytes                          : metadata if present
-    struct radio_event *event = (struct radio_event *)eventMemory->pointer();
-    uint32_t metadataOffset = sizeof(struct radio_event) + sizeof(uint32_t);
-    uint32_t metadataSize = *(uint32_t *)((uint8_t *)event + metadataOffset - sizeof(uint32_t));
-
-    // restore local metadata pointer from offset
-    switch (event->type) {
-    case RADIO_EVENT_TUNED:
-    case RADIO_EVENT_AF_SWITCH:
-        if (metadataSize != 0) {
-            event->info.metadata =
-                    (radio_metadata_t *)((uint8_t *)event + metadataOffset);
-        } else {
-            event->info.metadata = 0;
-        }
-        break;
-    case RADIO_EVENT_METADATA:
-        if (metadataSize != 0) {
-            event->metadata =
-                    (radio_metadata_t *)((uint8_t *)event + metadataOffset);
-        } else {
-            event->metadata = 0;
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (mCallback != 0) {
-        mCallback->onEvent(event);
-    }
-}
-
-
-//IBinder::DeathRecipient
-void Radio::binderDied(const wp<IBinder>& who __unused) {
-    Mutex::Autolock _l(mLock);
-    ALOGW("Radio server binder Died ");
-    mIRadio = 0;
-    struct radio_event event;
-    memset(&event, 0, sizeof(struct radio_event));
-    event.type = RADIO_EVENT_SERVER_DIED;
-    event.status = DEAD_OBJECT;
-    if (mCallback != 0) {
-        mCallback->onEvent(&event);
-    }
-}
-
-}; // namespace android
diff --git a/services/OWNERS b/services/OWNERS
new file mode 100644
index 0000000..d500dce
--- /dev/null
+++ b/services/OWNERS
@@ -0,0 +1,4 @@
+elaurent@google.com
+etalvala@google.com
+gkasten@android.com
+hunga@google.com
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 9023b2d..63898a0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -604,7 +604,7 @@
         virtual status_t standby();
 
     private:
-        sp<MmapThread> mThread;
+        const sp<MmapThread> mThread;
     };
 
               ThreadBase *checkThread_l(audio_io_handle_t ioHandle) const;
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index c4f1af3..c10fa05 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -138,7 +138,8 @@
 
 void FastMixer::onStateChange()
 {
-    LOG_HIST_FLUSH();
+    // log that audio was turned on/off
+    LOG_AUDIO_STATE();
     const FastMixerState * const current = (const FastMixerState *) mCurrent;
     const FastMixerState * const previous = (const FastMixerState *) mPrevious;
     FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 2a27dfd..366a164 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -28,6 +28,7 @@
                             audio_channel_mask_t channelMask,
                             audio_session_t sessionId,
                             uid_t uid,
+                            pid_t pid,
                             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
     virtual             ~MmapTrack();
 
@@ -39,7 +40,7 @@
     virtual bool        isFastTrack() const { return false; }
 
      static void        appendDumpHeader(String8& result);
-            void        dump(char* buffer, size_t size);
+            void        appendDump(String8& result, bool active);
 
 private:
     friend class MmapThread;
@@ -55,5 +56,6 @@
     virtual int64_t framesReleased() const;
     virtual void onTimestamp(const ExtendedTimestamp &timestamp);
 
+    pid_t mPid;
 };  // end of Track
 
diff --git a/services/audioflinger/OWNERS b/services/audioflinger/OWNERS
new file mode 100644
index 0000000..703e4d2
--- /dev/null
+++ b/services/audioflinger/OWNERS
@@ -0,0 +1,3 @@
+hunga@google.com
+jmtrivi@google.com
+mnaganov@google.com
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d7c0728..27c6d35 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -474,6 +474,7 @@
                                              format,
                                              frameCount,
                                              NULL,
+                                             (size_t)0 /* bufferSize */,
                                              AUDIO_INPUT_FLAG_NONE);
     if (patch->mPatchRecord == 0) {
         return NO_MEMORY;
@@ -494,6 +495,7 @@
                                            format,
                                            frameCount,
                                            patch->mPatchRecord->buffer(),
+                                           patch->mPatchRecord->bufferSize(),
                                            AUDIO_OUTPUT_FLAG_NONE);
     if (patch->mPatchTrack == 0) {
         return NO_MEMORY;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 3f1a0c0..1c1a989 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -30,6 +30,7 @@
                                 audio_channel_mask_t channelMask,
                                 size_t frameCount,
                                 void *buffer,
+                                size_t bufferSize,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
                                 uid_t uid,
@@ -40,7 +41,7 @@
     virtual status_t    initCheck() const;
 
     static  void        appendDumpHeader(String8& result);
-            void        dump(char* buffer, size_t size, bool active);
+            void        appendDump(String8& result, bool active);
     virtual status_t    start(AudioSystem::sync_event_t event =
                                     AudioSystem::SYNC_EVENT_NONE,
                              audio_session_t triggerSession = AUDIO_SESSION_NONE);
@@ -240,6 +241,7 @@
                                    audio_format_t format,
                                    size_t frameCount,
                                    void *buffer,
+                                   size_t bufferSize,
                                    audio_output_flags_t flags);
     virtual             ~PatchTrack();
 
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 3f83ca8..f8da780 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -29,6 +29,7 @@
                                 audio_channel_mask_t channelMask,
                                 size_t frameCount,
                                 void *buffer,
+                                size_t bufferSize,
                                 audio_session_t sessionId,
                                 uid_t uid,
                                 audio_input_flags_t flags,
@@ -50,7 +51,7 @@
                                                 return tmp; }
 
     static  void        appendDumpHeader(String8& result);
-            void        dump(char* buffer, size_t size, bool active);
+            void        appendDump(String8& result, bool active);
 
             void        handleSyncStartEvent(const sp<SyncEvent>& event);
             void        clearSyncStartEvent();
@@ -102,6 +103,7 @@
                 audio_format_t format,
                 size_t frameCount,
                 void *buffer,
+                size_t bufferSize,
                 audio_input_flags_t flags);
     virtual             ~PatchRecord();
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 65eccb6..8c4531a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1544,6 +1544,7 @@
         ALOGW("ActiveTracks<T>::add track %p already there", track.get());
         return index;
     }
+    logTrack("add", track);
     mActiveTracksGeneration++;
     mLatestActiveTrack = track;
     ++mBatteryCounter[track->uid()].second;
@@ -1557,6 +1558,7 @@
         ALOGW("ActiveTracks<T>::remove nonexistent track %p", track.get());
         return index;
     }
+    logTrack("remove", track);
     mActiveTracksGeneration++;
     --mBatteryCounter[track->uid()].second;
     // mLatestActiveTrack is not cleared even if is the same as track.
@@ -1567,6 +1569,7 @@
 void AudioFlinger::ThreadBase::ActiveTracks<T>::clear() {
     for (const sp<T> &track : mActiveTracks) {
         BatteryNotifier::getInstance().noteStopAudio(track->uid());
+        logTrack("clear", track);
     }
     mLastActiveTracksGeneration = mActiveTracksGeneration;
     mActiveTracks.clear();
@@ -1605,6 +1608,16 @@
     }
 }
 
+template <typename T>
+void AudioFlinger::ThreadBase::ActiveTracks<T>::logTrack(
+        const char *funcName, const sp<T> &track) const {
+    if (mLocalLog != nullptr) {
+        String8 result;
+        track->appendDump(result, false /* active */);
+        mLocalLog->log("AT::%-10s(%p) %s", funcName, track.get(), result.string());
+    }
+}
+
 void AudioFlinger::ThreadBase::broadcast_l()
 {
     // Thread could be blocked waiting for async
@@ -1640,6 +1653,7 @@
         mSuspended(0), mBytesWritten(0),
         mFramesWritten(0),
         mSuspendedFrames(0),
+        mActiveTracks(&this->mLocalLog),
         // mStreamTypes[] initialized in constructor body
         mOutput(output),
         mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
@@ -1707,8 +1721,6 @@
 
 void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
     String8 result;
 
     result.appendFormat("  Stream volumes in dB: ");
@@ -1735,8 +1747,10 @@
     size_t numactive = mActiveTracks.size();
     dprintf(fd, "  %zu Tracks", numtracks);
     size_t numactiveseen = 0;
+    const char *prefix = "    ";
     if (numtracks) {
         dprintf(fd, " of which %zu are active\n", numactive);
+        result.append(prefix);
         Track::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks; ++i) {
             sp<Track> track = mTracks[i];
@@ -1745,8 +1759,8 @@
                 if (active) {
                     numactiveseen++;
                 }
-                track->dump(buffer, SIZE, active);
-                result.append(buffer);
+                result.append(prefix);
+                track->appendDump(result, active);
             }
         }
     } else {
@@ -1754,15 +1768,15 @@
     }
     if (numactiveseen != numactive) {
         // some tracks in the active list were not in the tracks list
-        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
+        result.append("  The following tracks are in the active list but"
                 " not in the track list\n");
-        result.append(buffer);
+        result.append(prefix);
         Track::appendDumpHeader(result);
         for (size_t i = 0; i < numactive; ++i) {
             sp<Track> track = mActiveTracks[i];
             if (mTracks.indexOf(track) < 0) {
-                track->dump(buffer, SIZE, true);
-                result.append(buffer);
+                result.append(prefix);
+                track->appendDump(result, true /* active */);
             }
         }
     }
@@ -2013,7 +2027,8 @@
         }
 
         track = new Track(this, client, streamType, sampleRate, format,
-                          channelMask, frameCount, NULL, sharedBuffer,
+                          channelMask, frameCount,
+                          nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
                           sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
 
         lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
@@ -2172,10 +2187,6 @@
             chain->incActiveTrackCnt();
         }
 
-        char buffer[256];
-        track->dump(buffer, arraysize(buffer), false /* active */);
-        mLocalLog.log("addTrack_l    (%p) %s", track.get(), buffer + 4); // log for analysis
-
         status = NO_ERROR;
     }
 
@@ -2202,9 +2213,9 @@
 {
     track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
 
-    char buffer[256];
-    track->dump(buffer, arraysize(buffer), false /* active */);
-    mLocalLog.log("removeTrack_l (%p) %s", track.get(), buffer + 4); // log for analysis
+    String8 result;
+    track->appendDump(result, false /* active */);
+    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
 
     mTracks.remove(track);
     deleteTrackName_l(track->name());
@@ -3404,10 +3415,6 @@
             }
             if (track->isTerminated()) {
                 removeTrack_l(track);
-            } else { // inactive but not terminated
-                char buffer[256];
-                track->dump(buffer, arraysize(buffer), false /* active */);
-                mLocalLog.log("removeTracks_l(%p) %s", track.get(), buffer + 4);
             }
         }
     }
@@ -5925,7 +5932,9 @@
 #endif
                                          ) :
     ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
-    mInput(input), mRsmpInBuffer(NULL),
+    mInput(input),
+    mActiveTracks(&this->mLocalLog),
+    mRsmpInBuffer(NULL),
     // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
     mRsmpInRear(0)
 #ifdef TEE_SINK
@@ -6696,7 +6705,8 @@
         Mutex::Autolock _l(mLock);
 
         track = new RecordTrack(this, client, sampleRate,
-                      format, channelMask, frameCount, NULL, sessionId, uid,
+                      format, channelMask, frameCount,
+                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
                       *flags, TrackBase::TYPE_DEFAULT, portId);
 
         lStatus = track->initCheck();
@@ -6888,6 +6898,10 @@
 
 void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
 {
+    String8 result;
+    track->appendDump(result, false /* active */);
+    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
+
     mTracks.remove(track);
     // need anything related to effects here?
     if (track->isFastTrack()) {
@@ -6901,6 +6915,8 @@
     dumpInternals(fd, args);
     dumpTracks(fd, args);
     dumpEffectChains(fd, args);
+    dprintf(fd, "  Local log:\n");
+    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
 }
 
 void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
@@ -6914,6 +6930,12 @@
     if (mActiveTracks.size() == 0) {
         dprintf(fd, "  No active record clients\n");
     }
+
+    if (input != nullptr) {
+        dprintf(fd, "  Hal stream dump:\n");
+        (void)input->stream->dump(fd);
+    }
+
     dprintf(fd, "  Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no");
     dprintf(fd, "  Fast track available: %s\n", mFastTrackAvail ? "yes" : "no");
 
@@ -6928,16 +6950,15 @@
 
 void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
     String8 result;
-
     size_t numtracks = mTracks.size();
     size_t numactive = mActiveTracks.size();
     size_t numactiveseen = 0;
     dprintf(fd, "  %zu Tracks", numtracks);
+    const char *prefix = "    ";
     if (numtracks) {
         dprintf(fd, " of which %zu are active\n", numactive);
+        result.append(prefix);
         RecordTrack::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<RecordTrack> track = mTracks[i];
@@ -6946,8 +6967,8 @@
                 if (active) {
                     numactiveseen++;
                 }
-                track->dump(buffer, SIZE, active);
-                result.append(buffer);
+                result.append(prefix);
+                track->appendDump(result, active);
             }
         }
     } else {
@@ -6955,15 +6976,15 @@
     }
 
     if (numactiveseen != numactive) {
-        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
+        result.append("  The following tracks are in the active list but"
                 " not in the track list\n");
-        result.append(buffer);
+        result.append(prefix);
         RecordTrack::appendDumpHeader(result);
         for (size_t i = 0; i < numactive; ++i) {
             sp<RecordTrack> track = mActiveTracks[i];
             if (mTracks.indexOf(track) < 0) {
-                track->dump(buffer, SIZE, true);
-                result.append(buffer);
+                result.append(prefix);
+                track->appendDump(result, true /* active */);
             }
         }
 
@@ -7482,34 +7503,22 @@
 AudioFlinger::MmapThreadHandle::MmapThreadHandle(const sp<MmapThread>& thread)
     : mThread(thread)
 {
+    assert(thread != 0); // thread must start non-null and stay non-null
 }
 
 AudioFlinger::MmapThreadHandle::~MmapThreadHandle()
 {
-    MmapThread *thread = mThread.get();
-    // clear our strong reference before disconnecting the thread: the last strong reference
-    // will be removed when closeInput/closeOutput is executed upon call from audio policy manager
-    // and the thread removed from mMMapThreads list causing the thread destruction.
-    mThread.clear();
-    if (thread != nullptr) {
-        thread->disconnect();
-    }
+    mThread->disconnect();
 }
 
 status_t AudioFlinger::MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames,
                                   struct audio_mmap_buffer_info *info)
 {
-    if (mThread == 0) {
-        return NO_INIT;
-    }
     return mThread->createMmapBuffer(minSizeFrames, info);
 }
 
 status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_position *position)
 {
-    if (mThread == 0) {
-        return NO_INIT;
-    }
     return mThread->getMmapPosition(position);
 }
 
@@ -7517,25 +7526,16 @@
         audio_port_handle_t *handle)
 
 {
-    if (mThread == 0) {
-        return NO_INIT;
-    }
     return mThread->start(client, handle);
 }
 
 status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle)
 {
-    if (mThread == 0) {
-        return NO_INIT;
-    }
     return mThread->stop(handle);
 }
 
 status_t AudioFlinger::MmapThreadHandle::standby()
 {
-    if (mThread == 0) {
-        return NO_INIT;
-    }
     return mThread->standby();
 }
 
@@ -7545,7 +7545,8 @@
         AudioHwDevice *hwDev, sp<StreamHalInterface> stream,
         audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady)
     : ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady),
-      mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev)
+      mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
+      mActiveTracks(&this->mLocalLog)
 {
     mStandby = true;
     readHalParameters_l();
@@ -7566,7 +7567,7 @@
     for (const sp<MmapTrack> &t : mActiveTracks) {
         stop(t->portId());
     }
-    // this will cause the destruction of this thread.
+    // This will decrement references and may cause the destruction of this thread.
     if (isOutput()) {
         AudioSystem::releaseOutput(mId, streamType(), mSessionId);
     } else {
@@ -7693,7 +7694,7 @@
     }
 
     sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, mSessionId,
-                                        client.clientUid, portId);
+                                        client.clientUid, client.clientPid, portId);
 
     mActiveTracks.add(track);
     sp<EffectChain> chain = getEffectChain_l(mSessionId);
@@ -8178,6 +8179,8 @@
     dumpInternals(fd, args);
     dumpTracks(fd, args);
     dumpEffectChains(fd, args);
+    dprintf(fd, "  Local log:\n");
+    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
 }
 
 void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args)
@@ -8194,18 +8197,17 @@
 
 void AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
     String8 result;
-
     size_t numtracks = mActiveTracks.size();
-    dprintf(fd, "  %zu Tracks", numtracks);
+    dprintf(fd, "  %zu Tracks\n", numtracks);
+    const char *prefix = "    ";
     if (numtracks) {
+        result.append(prefix);
         MmapTrack::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<MmapTrack> track = mActiveTracks[i];
-            track->dump(buffer, SIZE);
-            result.append(buffer);
+            result.append(prefix);
+            track->appendDump(result, true /* active */);
         }
     } else {
         dprintf(fd, "\n");
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 062bad6..32f2bc4 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -508,9 +508,10 @@
                 template <typename T>
                 class ActiveTracks {
                 public:
-                    ActiveTracks()
+                    explicit ActiveTracks(SimpleLog *localLog = nullptr)
                         : mActiveTracksGeneration(0)
                         , mLastActiveTracksGeneration(0)
+                        , mLocalLog(localLog)
                     { }
 
                     ~ActiveTracks() {
@@ -562,6 +563,8 @@
                     void            updatePowerState(sp<ThreadBase> thread, bool force = false);
 
                 private:
+                    void            logTrack(const char *funcName, const sp<T> &track) const;
+
                     SortedVector<uid_t> getWakeLockUids() {
                         SortedVector<uid_t> wakeLockUids;
                         for (const sp<T> &track : mActiveTracks) {
@@ -576,6 +579,7 @@
                     int                 mActiveTracksGeneration;
                     int                 mLastActiveTracksGeneration;
                     wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
+                    SimpleLog * const   mLocalLog;
                 };
 
                 SimpleLog mLocalLog;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index cb540ca..d4ce0b4 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -61,6 +61,7 @@
                                 audio_channel_mask_t channelMask,
                                 size_t frameCount,
                                 void *buffer,
+                                size_t bufferSize,
                                 audio_session_t sessionId,
                                 uid_t uid,
                                 bool isOut,
@@ -82,6 +83,7 @@
 
             sp<IMemory> getBuffers() const { return mBufferMemory; }
             void*       buffer() const { return mBuffer; }
+            size_t      bufferSize() const { return mBufferSize; }
     virtual bool        isFastTrack() const = 0;
             bool        isOutputTrack() const { return (mType == TYPE_OUTPUT); }
             bool        isPatchTrack() const { return (mType == TYPE_PATCH); }
@@ -133,6 +135,40 @@
         mTerminated = true;
     }
 
+    // Upper case characters are final states.
+    // Lower case characters are transitory.
+    const char *getTrackStateString() const {
+        if (isTerminated()) {
+            return "T ";
+        }
+        switch (mState) {
+        case IDLE:
+            return "I ";
+        case STOPPING_1: // for Fast and Offload
+            return "s1";
+        case STOPPING_2: // for Fast and Offload
+            return "s2";
+        case STOPPED:
+            return "S ";
+        case RESUMING:
+            return "r ";
+        case ACTIVE:
+            return "A ";
+        case PAUSING:
+            return "p ";
+        case PAUSED:
+            return "P ";
+        case FLUSHED:
+            return "F ";
+        case STARTING_1: // for RecordTrack
+            return "r1";
+        case STARTING_2: // for RecordTrack
+            return "r2";
+        default:
+            return "? ";
+        }
+    }
+
     bool isOut() const { return mIsOut; }
                                     // true for Track, false for RecordTrack,
                                     // this could be a track type if needed later
@@ -144,6 +180,7 @@
     sp<IMemory>         mBufferMemory;  // currently non-0 for fast RecordTrack only
     void*               mBuffer;    // start of track buffer, typically in shared memory
                                     // except for OutputTrack when it is in local memory
+    size_t              mBufferSize; // size of mBuffer in bytes
     // we don't really need a lock for these
     track_state         mState;
     const uint32_t      mSampleRate;    // initial sample rate only; for tracks which
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9763bf2..0f25153 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -50,10 +50,6 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
-// TODO move to a common header  (Also shared with AudioTrack.cpp)
-#define NANOS_PER_SECOND    1000000000
-#define TIME_TO_NANOS(time) ((uint64_t)(time).tv_sec * NANOS_PER_SECOND + (time).tv_nsec)
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -71,6 +67,7 @@
             audio_channel_mask_t channelMask,
             size_t frameCount,
             void *buffer,
+            size_t bufferSize,
             audio_session_t sessionId,
             uid_t clientUid,
             bool isOut,
@@ -81,7 +78,7 @@
         mThread(thread),
         mClient(client),
         mCblk(NULL),
-        // mBuffer
+        // mBuffer, mBufferSize
         mState(IDLE),
         mSampleRate(sampleRate),
         mFormat(format),
@@ -113,15 +110,22 @@
 
     // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
 
-    size_t bufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
+    size_t minBufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
     // check overflow when computing bufferSize due to multiplication by mFrameSize.
-    if (bufferSize < frameCount  // roundup rounds down for values above UINT_MAX / 2
+    if (minBufferSize < frameCount  // roundup rounds down for values above UINT_MAX / 2
             || mFrameSize == 0   // format needs to be correct
-            || bufferSize > SIZE_MAX / mFrameSize) {
+            || minBufferSize > SIZE_MAX / mFrameSize) {
         android_errorWriteLog(0x534e4554, "34749571");
         return;
     }
-    bufferSize *= mFrameSize;
+    minBufferSize *= mFrameSize;
+
+    if (buffer == nullptr) {
+        bufferSize = minBufferSize; // allocated here.
+    } else if (minBufferSize > bufferSize) {
+        android_errorWriteLog(0x534e4554, "38340117");
+        return;
+    }
 
     size_t size = sizeof(audio_track_cblk_t);
     if (buffer == NULL && alloc == ALLOC_CBLK) {
@@ -177,6 +181,7 @@
             // It should references the buffer via the pipe.
             // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
             mBuffer = NULL;
+            bufferSize = 0;
             break;
         case ALLOC_CBLK:
             // clear all buffers
@@ -196,7 +201,10 @@
         case ALLOC_NONE:
             mBuffer = buffer;
             break;
+        default:
+            LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
         }
+        mBufferSize = bufferSize;
 
 #ifdef TEE_SINK
         if (mTeeSinkTrackEnabled) {
@@ -368,6 +376,7 @@
             audio_channel_mask_t channelMask,
             size_t frameCount,
             void *buffer,
+            size_t bufferSize,
             const sp<IMemory>& sharedBuffer,
             audio_session_t sessionId,
             uid_t uid,
@@ -376,6 +385,7 @@
             audio_port_handle_t portId)
     :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
+                  (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
                   sessionId, uid, true /*isOut*/,
                   (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
                   type, portId),
@@ -411,21 +421,6 @@
         mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
                 mFrameSize, !isExternalTrack(), sampleRate);
     } else {
-        // Is the shared buffer of sufficient size?
-        // (frameCount * mFrameSize) is <= SIZE_MAX, checked in TrackBase.
-        if (sharedBuffer->size() < frameCount * mFrameSize) {
-            // Workaround: clear out mCblk to indicate track hasn't been properly created.
-            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
-            if (mClient == 0) {
-                free(mCblk);
-            }
-            mCblk = NULL;
-
-            mSharedBuffer.clear(); // release shared buffer early
-            android_errorWriteLog(0x534e4554, "38340117");
-            return;
-        }
-
         mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
                 mFrameSize);
     }
@@ -503,58 +498,40 @@
 
 /*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
 {
-    result.append("    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  "
-                  "L dB  R dB  VS dB    Server Main buf  Aux buf Flags UndFrmCnt  Flushed\n");
+    result.append("T Name Active Client Session S  Flags "
+                  "  Format Chn mask  SRate "
+                  "ST  L dB  R dB  VS dB "
+                  "  Server FrmCnt  FrmRdy F Underruns  Flushed "
+                  "Main Buf  Aux Buf\n");
 }
 
-void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
+void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
 {
-    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
-    if (isFastTrack()) {
-        sprintf(buffer, "    F %2d", mFastIndex);
-    } else if (mName >= AudioMixer::TRACK0) {
-        sprintf(buffer, "    %4d", mName - AudioMixer::TRACK0);
-    } else {
-        sprintf(buffer, "    none");
-    }
-    track_state state = mState;
-    char stateChar;
-    if (isTerminated()) {
-        stateChar = 'T';
-    } else {
-        switch (state) {
-        case IDLE:
-            stateChar = 'I';
-            break;
-        case STOPPING_1:
-            stateChar = 's';
-            break;
-        case STOPPING_2:
-            stateChar = '5';
-            break;
-        case STOPPED:
-            stateChar = 'S';
-            break;
-        case RESUMING:
-            stateChar = 'R';
-            break;
-        case ACTIVE:
-            stateChar = 'A';
-            break;
-        case PAUSING:
-            stateChar = 'p';
-            break;
-        case PAUSED:
-            stateChar = 'P';
-            break;
-        case FLUSHED:
-            stateChar = 'F';
-            break;
-        default:
-            stateChar = '?';
-            break;
+    char trackType;
+    switch (mType) {
+    case TYPE_DEFAULT:
+    case TYPE_OUTPUT:
+        if (mSharedBuffer.get() != nullptr) {
+            trackType = 'S'; // static
+        } else {
+            trackType = ' '; // normal
         }
+        break;
+    case TYPE_PATCH:
+        trackType = 'P';
+        break;
+    default:
+        trackType = '?';
     }
+
+    if (isFastTrack()) {
+        result.appendFormat("F%c %3d", trackType, mFastIndex);
+    } else if (mName >= AudioMixer::TRACK0) {
+        result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
+    } else {
+        result.appendFormat("%c none", trackType);
+    }
+
     char nowInUnderrun;
     switch (mObservedUnderruns.mBitFields.mMostRecent) {
     case UNDERRUN_FULL:
@@ -571,31 +548,75 @@
         break;
     }
 
-    std::pair<float /* volume */, bool /* active */> vsVolume = mVolumeHandler->getLastVolume();
-    snprintf(&buffer[8], size - 8, " %6s %6u %4u %08X %08X %7u %6zu %1c %1d %5u "
-                                   "%5.2g %5.2g %5.2g%c  "
-                                   "%08X %08zX %08zX 0x%03X %9u%c %7u\n",
+    char fillingStatus;
+    switch (mFillingUpStatus) {
+    case FS_INVALID:
+        fillingStatus = 'I';
+        break;
+    case FS_FILLING:
+        fillingStatus = 'f';
+        break;
+    case FS_FILLED:
+        fillingStatus = 'F';
+        break;
+    case FS_ACTIVE:
+        fillingStatus = 'A';
+        break;
+    default:
+        fillingStatus = '?';
+        break;
+    }
+
+    // clip framesReadySafe to max representation in dump
+    const size_t framesReadySafe =
+            std::min(mAudioTrackServerProxy->framesReadySafe(), (size_t)99999999);
+
+    // obtain volumes
+    const gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
+    const std::pair<float /* volume */, bool /* active */> vsVolume =
+            mVolumeHandler->getLastVolume();
+
+    // Our effective frame count is obtained by ServerProxy::getBufferSizeInFrames()
+    // as it may be reduced by the application.
+    const size_t bufferSizeInFrames = (size_t)mAudioTrackServerProxy->getBufferSizeInFrames();
+    // Check whether the buffer size has been modified by the app.
+    const char modifiedBufferChar = bufferSizeInFrames < mFrameCount
+            ? 'r' /* buffer reduced */: bufferSizeInFrames > mFrameCount
+                    ? 'e' /* error */ : ' ' /* identical */;
+
+    result.appendFormat("%7s %6u %7u %2s 0x%03X "
+                           "%08X %08X %6u "
+                           "%2u %5.2g %5.2g %5.2g%c "
+                           "%08X %6zu%c %6zu %c %9u%c %7u "
+                           "%08zX %08zX\n",
             active ? "yes" : "no",
             (mClient == 0) ? getpid_cached : mClient->pid(),
-            mStreamType,
+            mSessionId,
+            getTrackStateString(),
+            mCblk->mFlags,
+
             mFormat,
             mChannelMask,
-            mSessionId,
-            mFrameCount,
-            stateChar,
-            mFillingUpStatus,
             mAudioTrackServerProxy->getSampleRate(),
+
+            mStreamType,
             20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
             20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
             20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
             vsVolume.second ? 'A' : ' ',  // if any VolumeShapers active
+
             mCblk->mServer,
-            (size_t)mMainBuffer, // use %zX as %p appends 0x
-            (size_t)mAuxBuffer,  // use %zX as %p appends 0x
-            mCblk->mFlags,
+            bufferSizeInFrames,
+            modifiedBufferChar,
+            framesReadySafe,
+            fillingStatus,
             mAudioTrackServerProxy->getUnderrunFrames(),
             nowInUnderrun,
-            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000); // 7 digits
+            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000,
+
+            (size_t)mMainBuffer, // use %zX as %p appends 0x
+            (size_t)mAuxBuffer   // use %zX as %p appends 0x
+            );
 }
 
 uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
@@ -1235,7 +1256,8 @@
             uid_t uid)
     :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
               sampleRate, format, channelMask, frameCount,
-              NULL, 0, AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
+              nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
+              AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
               TYPE_OUTPUT),
     mActive(false), mSourceThread(sourceThread)
 {
@@ -1351,7 +1373,9 @@
             if (mBufferQueue.size()) {
                 mBufferQueue.removeAt(0);
                 free(pInBuffer->mBuffer);
-                delete pInBuffer;
+                if (pInBuffer != &inBuffer) {
+                    delete pInBuffer;
+                }
                 ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
                         mThread.unsafe_get(), mBufferQueue.size());
             } else {
@@ -1430,10 +1454,12 @@
                                                      audio_format_t format,
                                                      size_t frameCount,
                                                      void *buffer,
+                                                     size_t bufferSize,
                                                      audio_output_flags_t flags)
     :   Track(playbackThread, NULL, streamType,
               sampleRate, format, channelMask, frameCount,
-              buffer, 0, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+              buffer, bufferSize, nullptr /* sharedBuffer */,
+              AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
               mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
 {
     uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
@@ -1567,13 +1593,14 @@
             audio_channel_mask_t channelMask,
             size_t frameCount,
             void *buffer,
+            size_t bufferSize,
             audio_session_t sessionId,
             uid_t uid,
             audio_input_flags_t flags,
             track_type type,
             audio_port_handle_t portId)
     :   TrackBase(thread, client, sampleRate, format,
-                  channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
+                  channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
                   (type == TYPE_DEFAULT) ?
                           ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
                           ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
@@ -1701,22 +1728,28 @@
 
 /*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
 {
-    result.append("    Active Client Fmt Chn mask Session S   Server fCount SRate\n");
+    result.append("Active Client Session S  Flags   Format Chn mask  SRate   Server FrmCnt\n");
 }
 
-void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size, bool active)
+void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
 {
-    snprintf(buffer, size, "    %6s %6u %3u %08X %7u %1d %08X %6zu %5u\n",
+    result.appendFormat("%c%5s %6u %7u %2s 0x%03X "
+            "%08X %08X %6u "
+            "%08X %6zu\n",
+            isFastTrack() ? 'F' : ' ',
             active ? "yes" : "no",
             (mClient == 0) ? getpid_cached : mClient->pid(),
+            mSessionId,
+            getTrackStateString(),
+            mCblk->mFlags,
+
             mFormat,
             mChannelMask,
-            mSessionId,
-            mState,
-            mCblk->mServer,
-            mFrameCount,
-            mSampleRate);
+            mSampleRate,
 
+            mCblk->mServer,
+            mFrameCount
+            );
 }
 
 void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
@@ -1767,9 +1800,10 @@
                                                      audio_format_t format,
                                                      size_t frameCount,
                                                      void *buffer,
+                                                     size_t bufferSize,
                                                      audio_input_flags_t flags)
     :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
-                buffer, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
+                buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
                 mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
 {
     uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
@@ -1834,11 +1868,15 @@
         audio_channel_mask_t channelMask,
         audio_session_t sessionId,
         uid_t uid,
+        pid_t pid,
         audio_port_handle_t portId)
     :   TrackBase(thread, NULL, sampleRate, format,
-                  channelMask, 0, NULL, sessionId, uid, false,
+                  channelMask, (size_t)0 /* frameCount */,
+                  nullptr /* buffer */, (size_t)0 /* bufferSize */,
+                  sessionId, uid, false /* isOut */,
                   ALLOC_NONE,
-                  TYPE_DEFAULT, portId)
+                  TYPE_DEFAULT, portId),
+        mPid(pid)
 {
 }
 
@@ -1885,17 +1923,17 @@
 
 /*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
 {
-    result.append("    Client Fmt Chn mask  SRate\n");
+    result.append("Client Session   Format Chn mask  SRate\n");
 }
 
-void AudioFlinger::MmapThread::MmapTrack::dump(char* buffer, size_t size)
+void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
 {
-    snprintf(buffer, size, "            %6u %3u    %08X %5u\n",
-            mUid,
+    result.appendFormat("%6u %7u %08X %08X %6u\n",
+            mPid,
+            mSessionId,
             mFormat,
             mChannelMask,
             mSampleRate);
-
 }
 
 } // namespace android
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 2d84028..909af09 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -88,11 +88,11 @@
 
 // Write histogram timestamp entry
 #define LOG_HIST_TS() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
-                                x->logHistTS(hash(__FILE__, __LINE__)); } while(0)
+        x->logEventHistTs(NBLog::EVENT_HISTOGRAM_ENTRY_TS, hash(__FILE__, __LINE__)); } while(0)
 
-// flush all histogram
-#define LOG_HIST_FLUSH() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
-                                x->logHistFlush(hash(__FILE__, __LINE__)); } while(0)
+// Record that audio was turned on/off
+#define LOG_AUDIO_STATE() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+        x->logEventHistTs(NBLog::EVENT_AUDIO_STATE, hash(__FILE__, __LINE__)); } while(0)
 
 namespace android {
 extern "C" {
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index ad340e5..65571f9 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -24,7 +24,8 @@
     libhardware_legacy \
     libserviceutility \
     libaudiopolicymanager \
-    libmedia_helper
+    libmedia_helper \
+    libeffectsconfig
 
 LOCAL_STATIC_LIBRARIES := \
     libaudiopolicycomponents
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index c868206..7b19f58 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -349,8 +349,8 @@
 
     virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
 
-    virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
-                    audio_source_t source,
+    virtual void onRecordingConfigurationUpdate(int event,
+                    const record_client_info_t *clientInfo,
                     const struct audio_config_base *clientConfig,
                     const struct audio_config_base *deviceConfig,
                     audio_patch_handle_t patchHandle) = 0;
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
new file mode 100644
index 0000000..a8483fa
--- /dev/null
+++ b/services/audiopolicy/OWNERS
@@ -0,0 +1,3 @@
+jmtrivi@google.com
+krocard@google.com
+mnaganov@google.com
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index ca070cf..cedf22d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -22,6 +22,7 @@
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <media/AudioPolicy.h>
+#include <media/IAudioPolicyServiceClient.h>
 #include "AudioSessionInfoProvider.h"
 
 namespace android {
@@ -44,14 +45,14 @@
 
     status_t dump(int fd, int spaces, int index) const;
 
-    audio_session_t session() const { return mSession; }
-    audio_source_t inputSource()const { return mInputSource; }
+    audio_session_t session() const { return mRecordClientInfo.session; }
+    audio_source_t inputSource()const { return mRecordClientInfo.source; }
     audio_format_t format() const { return mConfig.format; }
     uint32_t sampleRate() const { return mConfig.sample_rate; }
     audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
     audio_input_flags_t flags() const { return mFlags; }
-    uid_t uid() const { return mUid; }
-    void setUid(uid_t uid) { mUid = uid; }
+    uid_t uid() const { return mRecordClientInfo.uid; }
+    void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
     bool matches(const sp<AudioSession> &other) const;
     bool isSoundTrigger() const { return mIsSoundTrigger; }
     uint32_t openCount() const { return mOpenCount; } ;
@@ -65,11 +66,9 @@
     virtual void onSessionInfoUpdate() const;
 
 private:
-    const audio_session_t mSession;
-    const audio_source_t mInputSource;
+    record_client_info_t mRecordClientInfo;
     const struct audio_config_base mConfig;
     const audio_input_flags_t mFlags;
-    uid_t mUid;
     bool  mIsSoundTrigger;
     uint32_t  mOpenCount;
     uint32_t  mActiveCount;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index bea9f4f..5b57d3d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -38,9 +38,9 @@
                            bool isSoundTrigger,
                            AudioMix* policyMix,
                            AudioPolicyClientInterface *clientInterface) :
-    mSession(session), mInputSource(inputSource),
+    mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
     mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
-    mFlags(flags), mUid(uid), mIsSoundTrigger(isSoundTrigger),
+    mFlags(flags), mIsSoundTrigger(isSoundTrigger),
     mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
     mInfoProvider(NULL)
 {
@@ -92,7 +92,7 @@
         const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
                 AUDIO_PATCH_HANDLE_NONE;
         if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-            mClientInterface->onRecordingConfigurationUpdate(event, mSession, mInputSource,
+            mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
                     &mConfig, &deviceConfig, patchHandle);
         }
     }
@@ -102,13 +102,13 @@
 
 bool AudioSession::matches(const sp<AudioSession> &other) const
 {
-    if (other->session() == mSession &&
-        other->inputSource() == mInputSource &&
+    if (other->session() == mRecordClientInfo.session &&
+        other->inputSource() == mRecordClientInfo.source &&
         other->format() == mConfig.format &&
         other->sampleRate() == mConfig.sample_rate &&
         other->channelMask() == mConfig.channel_mask &&
         other->flags() == mFlags &&
-        other->uid() == mUid) {
+        other->uid() == mRecordClientInfo.uid) {
         return true;
     }
     return false;
@@ -130,8 +130,7 @@
                 AUDIO_PATCH_HANDLE_NONE;
         if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
             mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
-                    mSession, mInputSource,
-                    &mConfig, &deviceConfig, patchHandle);
+                    &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
         }
     }
 }
@@ -144,11 +143,11 @@
 
     snprintf(buffer, SIZE, "%*sAudio session %d:\n", spaces, "", index+1);
     result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mSession);
+    snprintf(buffer, SIZE, "%*s- session: %2d\n", spaces, "", mRecordClientInfo.session);
     result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
+    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mRecordClientInfo.uid);
     result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mInputSource);
+    snprintf(buffer, SIZE, "%*s- input source: %d\n", spaces, "", mRecordClientInfo.source);
     result.append(buffer);
     snprintf(buffer, SIZE, "%*s- format: %08x\n", spaces, "", mConfig.format);
     result.append(buffer);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index dbcc070..31c9575 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -220,11 +220,11 @@
 }
 
 void AudioPolicyService::AudioPolicyClient::onRecordingConfigurationUpdate(
-        int event, audio_session_t session, audio_source_t source,
+        int event, const record_client_info_t *clientInfo,
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle)
 {
-    mAudioPolicyService->onRecordingConfigurationUpdate(event, session, source,
+    mAudioPolicyService->onRecordingConfigurationUpdate(event, clientInfo,
             clientConfig, deviceConfig, patchHandle);
 }
 
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 654465d..84b1073 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -20,8 +20,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <memory>
 #include <cutils/misc.h>
 #include <media/AudioEffect.h>
+#include <media/EffectsConfig.h>
 #include <system/audio.h>
 #include <system/audio_effects/audio_effects_conf.h>
 #include <utils/Vector.h>
@@ -39,11 +41,17 @@
 
 AudioPolicyEffects::AudioPolicyEffects()
 {
-    // load automatic audio effect modules
-    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
-        loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
-    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
-        loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+    status_t loadResult = loadAudioEffectXmlConfig();
+    if (loadResult < 0) {
+        ALOGW("Failed to load XML effect configuration, fallback to .conf");
+        // load automatic audio effect modules
+        if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+            loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+        } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+            loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+        }
+    } else if (loadResult > 0) {
+        ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
     }
 }
 
@@ -685,6 +693,28 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
+    auto result = effectsConfig::parse();
+    if (result.parsedConfig == nullptr) {
+        return -ENOENT;
+    }
+
+    auto loadProcessingChain = [](auto& processingChain, auto& streams) {
+        for (auto& stream : processingChain) {
+            auto effectDescs = std::make_unique<EffectDescVector>();
+            for (auto& effect : stream.effects) {
+                effectDescs->mEffects.add(
+                        new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
+            }
+            streams.add(stream.type, effectDescs.release());
+        }
+    };
+    loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
+    loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
+    // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
+    return result.nbSkippedElement;
+}
+
 status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
 {
     cnode *root;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 0c74d87..59d5d14 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -155,7 +155,8 @@
     audio_stream_type_t streamNameToEnum(const char *name);
 
     // Parse audio_effects.conf
-    status_t loadAudioEffectConfig(const char *path);
+    status_t loadAudioEffectConfig(const char *path); // TODO: add legacy in the name
+    status_t loadAudioEffectXmlConfig(); // TODO: remove "Xml" in the name
 
     // Load all effects descriptors in configuration file
     status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index c4f6367..b417631 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -185,21 +185,21 @@
     }
 }
 
-void AudioPolicyService::onRecordingConfigurationUpdate(int event, audio_session_t session,
-        audio_source_t source, const audio_config_base_t *clientConfig,
+void AudioPolicyService::onRecordingConfigurationUpdate(int event,
+        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
         const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
 {
-    mOutputCommandThread->recordingConfigurationUpdateCommand(event, session, source,
+    mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
             clientConfig, deviceConfig, patchHandle);
 }
 
-void AudioPolicyService::doOnRecordingConfigurationUpdate(int event, audio_session_t session,
-        audio_source_t source, const audio_config_base_t *clientConfig,
+void AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
+        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
         const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
 {
     Mutex::Autolock _l(mNotificationClientsLock);
     for (size_t i = 0; i < mNotificationClients.size(); i++) {
-        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, session, source,
+        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
                 clientConfig, deviceConfig, patchHandle);
     }
 }
@@ -267,12 +267,12 @@
 }
 
 void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
-        int event, audio_session_t session, audio_source_t source,
+        int event, const record_client_info_t *clientInfo,
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle)
 {
     if (mAudioPolicyServiceClient != 0) {
-        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, session, source,
+        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
                 clientConfig, deviceConfig, patchHandle);
     }
 }
@@ -544,8 +544,8 @@
                         break;
                     }
                     mLock.unlock();
-                    svc->doOnRecordingConfigurationUpdate(data->mEvent, data->mSession,
-                            data->mSource, &data->mClientConfig, &data->mDeviceConfig,
+                    svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
+                            &data->mClientConfig, &data->mDeviceConfig,
                             data->mPatchHandle);
                     mLock.lock();
                     } break;
@@ -810,7 +810,7 @@
 }
 
 void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
-        int event, audio_session_t session, audio_source_t source,
+        int event, const record_client_info_t *clientInfo,
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle)
 {
@@ -818,14 +818,13 @@
     command->mCommand = RECORDING_CONFIGURATION_UPDATE;
     RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
     data->mEvent = event;
-    data->mSession = session;
-    data->mSource = source;
+    data->mClientInfo = *clientInfo;
     data->mClientConfig = *clientConfig;
     data->mDeviceConfig = *deviceConfig;
     data->mPatchHandle = patchHandle;
     command->mParam = data;
-    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d",
-            event, source);
+    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
+            event, clientInfo->source, clientInfo->uid);
     sendCommand(command);
 }
 
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 35542f1..38d4b17 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -228,11 +228,11 @@
 
             void onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
             void doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
-            void onRecordingConfigurationUpdate(int event, audio_session_t session,
-                    audio_source_t source, const audio_config_base_t *clientConfig,
+            void onRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+                    const audio_config_base_t *clientConfig,
                     const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
-            void doOnRecordingConfigurationUpdate(int event, audio_session_t session,
-                    audio_source_t source, const audio_config_base_t *clientConfig,
+            void doOnRecordingConfigurationUpdate(int event, const record_client_info_t *clientInfo,
+                    const audio_config_base_t *clientConfig,
                     const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
 
 private:
@@ -306,8 +306,8 @@
                                                           int delayMs);
                     void        dynamicPolicyMixStateUpdateCommand(const String8& regId, int32_t state);
                     void        recordingConfigurationUpdateCommand(
-                                                        int event, audio_session_t session,
-                                                        audio_source_t source,
+                                                        int event,
+                                                        const record_client_info_t *clientInfo,
                                                         const audio_config_base_t *clientConfig,
                                                         const audio_config_base_t *deviceConfig,
                                                         audio_patch_handle_t patchHandle);
@@ -404,8 +404,7 @@
         class RecordingConfigurationUpdateData : public AudioCommandData {
         public:
             int mEvent;
-            audio_session_t mSession;
-            audio_source_t mSource;
+            record_client_info_t mClientInfo;
             struct audio_config_base mClientConfig;
             struct audio_config_base mDeviceConfig;
             audio_patch_handle_t mPatchHandle;
@@ -518,7 +517,7 @@
         virtual void onAudioPatchListUpdate();
         virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
         virtual void onRecordingConfigurationUpdate(int event,
-                        audio_session_t session, audio_source_t source,
+                        const record_client_info_t *clientInfo,
                         const audio_config_base_t *clientConfig,
                         const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
 
@@ -540,8 +539,7 @@
                             void      onAudioPatchListUpdate();
                             void      onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state);
                             void      onRecordingConfigurationUpdate(
-                                        int event, audio_session_t session,
-                                        audio_source_t source,
+                                        int event, const record_client_info_t *clientInfo,
                                         const audio_config_base_t *clientConfig,
                                         const audio_config_base_t *deviceConfig,
                                         audio_patch_handle_t patchHandle);
diff --git a/services/camera/OWNERS b/services/camera/OWNERS
new file mode 100644
index 0000000..18acfee
--- /dev/null
+++ b/services/camera/OWNERS
@@ -0,0 +1,6 @@
+cychen@google.com
+epeev@google.com
+etalvala@google.com
+shuzhenwang@google.com
+yinchiayeh@google.com
+zhijunhe@google.com
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 0429e7f..6fd9263 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -313,11 +313,13 @@
 
 binder::Status CameraDeviceClient::beginConfigure() {
     // TODO: Implement this.
+    ATRACE_CALL();
     ALOGV("%s: Not implemented yet.", __FUNCTION__);
     return binder::Status::ok();
 }
 
 binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
+    ATRACE_CALL();
     ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
             __FUNCTION__, mInputStream.configured ? 1 : 0,
             mStreamMap.size());
@@ -568,7 +570,7 @@
         /*out*/
         int* newStreamId) {
     int width, height, format, surfaceType;
-    int32_t consumerUsage;
+    uint64_t consumerUsage;
     android_dataspace dataSpace;
     status_t err;
     binder::Status res;
@@ -764,24 +766,23 @@
     // Query consumer usage bits to set async operation mode for
     // GLConsumer using controlledByApp parameter.
     bool useAsync = false;
-    int32_t consumerUsage;
+    uint64_t consumerUsage = 0;
     status_t err;
-    if ((err = gbp->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
-            &consumerUsage)) != OK) {
+    if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
         String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
                 mCameraIdStr.string(), strerror(-err), err);
         ALOGE("%s: %s", __FUNCTION__, msg.string());
         return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
     }
     if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
-        ALOGW("%s: Camera %s with consumer usage flag: 0x%x: Forcing asynchronous mode for stream",
+        ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for stream",
                 __FUNCTION__, mCameraIdStr.string(), consumerUsage);
         useAsync = true;
     }
 
-    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
+    uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
                               GRALLOC_USAGE_RENDERSCRIPT;
-    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
+    uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
                            GraphicBuffer::USAGE_HW_TEXTURE |
                            GraphicBuffer::USAGE_HW_COMPOSER;
     bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
@@ -874,7 +875,7 @@
         //surface class type. Use usage flag to approximate the comparison.
         if (consumerUsage != streamInfo.consumerUsage) {
             String8 msg = String8::format(
-                    "Camera %s:Surface usage flag doesn't match 0x%x vs 0x%x",
+                    "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
                     mCameraIdStr.string(), consumerUsage, streamInfo.consumerUsage);
             ALOGE("%s: %s", __FUNCTION__, msg.string());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index e8fc080..50661cb 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -213,13 +213,13 @@
         int height;
         int format;
         android_dataspace dataSpace;
-        int32_t consumerUsage;
+        uint64_t consumerUsage;
         bool finalized = false;
         OutputStreamInfo() :
                 width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
                 consumerUsage(0) {}
         OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
-                int32_t _consumerUsage) :
+                uint64_t _consumerUsage) :
                     width(_width), height(_height), format(_format),
                     dataSpace(_dataSpace), consumerUsage(_consumerUsage) {}
     };
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index d9059f3..54fcb0a 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -119,7 +119,7 @@
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            bool isShared = false, uint32_t consumerUsage = 0) = 0;
+            bool isShared = false, uint64_t consumerUsage = 0) = 0;
 
     /**
      * Create an output stream of the requested size, format, rotation and
@@ -132,7 +132,7 @@
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            bool isShared = false, uint32_t consumerUsage = 0) = 0;
+            bool isShared = false, uint64_t consumerUsage = 0) = 0;
 
     /**
      * Create an input stream of width, height, and format.
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index 469c86c..991b50f 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -29,11 +29,6 @@
 CameraHardwareInterface::~CameraHardwareInterface()
 {
     ALOGI("Destroying camera %s", mName.string());
-    if (mDevice) {
-        int rc = mDevice->common.close(&mDevice->common);
-        if (rc != OK)
-            ALOGE("Could not close camera %s: %d", mName.string(), rc);
-    }
     if (mHidlDevice != nullptr) {
         mHidlDevice->close();
         mHidlDevice.clear();
@@ -42,12 +37,6 @@
 }
 
 status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
-    if (mDevice) {
-        ALOGE("%s: camera hardware interface has been initialized to libhardware path!",
-                __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-
     ALOGI("Opening camera %s", mName.string());
 
     status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
@@ -372,7 +361,7 @@
         ALOGE("%s: preview window is null", __FUNCTION__);
         return s;
     }
-    mPreviewUsage = (int) usage;
+    mPreviewUsage = static_cast<uint64_t> (usage);
     int rc = native_window_set_usage(a, mPreviewUsage);
     if (rc == OK) {
         cleanupCirculatingBuffers();
@@ -444,23 +433,6 @@
         }
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
-    } else if (mDevice) {
-        if (mDevice->ops->set_preview_window) {
-            mPreviewWindow = buf;
-            if (buf != nullptr) {
-                if (mPreviewScalingMode != NOT_SET) {
-                    setPreviewScalingMode(mPreviewScalingMode);
-                }
-                if (mPreviewTransform != NOT_SET) {
-                    setPreviewTransform(mPreviewTransform);
-                }
-            }
-            mHalPreviewWindow.user = this;
-            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p",__FUNCTION__,
-                    &mHalPreviewWindow, mHalPreviewWindow.user);
-            return mDevice->ops->set_preview_window(mDevice,
-                    buf.get() ? &mHalPreviewWindow.nw : 0);
-        }
     }
     return INVALID_OPERATION;
 }
@@ -478,15 +450,6 @@
     mCbUser = user;
 
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
-
-    if (mDevice && mDevice->ops->set_callbacks) {
-        mDevice->ops->set_callbacks(mDevice,
-                               sNotifyCb,
-                               sDataCb,
-                               sDataCbTimestamp,
-                               sGetMemory,
-                               this);
-    }
 }
 
 void CameraHardwareInterface::enableMsgType(int32_t msgType)
@@ -494,8 +457,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         mHidlDevice->enableMsgType(msgType);
-    } else if (mDevice && mDevice->ops->enable_msg_type) {
-        mDevice->ops->enable_msg_type(mDevice, msgType);
     }
 }
 
@@ -504,8 +465,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         mHidlDevice->disableMsgType(msgType);
-    } else if (mDevice && mDevice->ops->disable_msg_type) {
-        mDevice->ops->disable_msg_type(mDevice, msgType);
     }
 }
 
@@ -514,8 +473,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return mHidlDevice->msgTypeEnabled(msgType);
-    } else if (mDevice && mDevice->ops->msg_type_enabled) {
-        return mDevice->ops->msg_type_enabled(mDevice, msgType);
     }
     return false;
 }
@@ -526,8 +483,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->startPreview());
-    } else if (mDevice && mDevice->ops->start_preview) {
-        return mDevice->ops->start_preview(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -537,8 +492,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         mHidlDevice->stopPreview();
-    } else if (mDevice && mDevice->ops->stop_preview) {
-        mDevice->ops->stop_preview(mDevice);
     }
 }
 
@@ -547,8 +500,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return mHidlDevice->previewEnabled();
-    } else if (mDevice && mDevice->ops->preview_enabled) {
-        return mDevice->ops->preview_enabled(mDevice);
     }
     return false;
 }
@@ -559,8 +510,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->storeMetaDataInBuffers(enable));
-    } else if (mDevice && mDevice->ops->store_meta_data_in_buffers) {
-        return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
     }
     return enable ? INVALID_OPERATION: OK;
 }
@@ -571,8 +520,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->startRecording());
-    } else if (mDevice && mDevice->ops->start_recording) {
-        return mDevice->ops->start_recording(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -585,8 +532,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         mHidlDevice->stopRecording();
-    } else if (mDevice && mDevice->ops->stop_recording) {
-        mDevice->ops->stop_recording(mDevice);
     }
 }
 
@@ -598,8 +543,6 @@
     ALOGV("%s(%s)", __FUNCTION__, mName.string());
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return mHidlDevice->recordingEnabled();
-    } else if (mDevice && mDevice->ops->recording_enabled) {
-        return mDevice->ops->recording_enabled(mDevice);
     }
     return false;
 }
@@ -624,9 +567,6 @@
         } else {
             mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
         }
-    } else if (mDevice && mDevice->ops->release_recording_frame) {
-        void *data = ((uint8_t *)heap->base()) + offset;
-        return mDevice->ops->release_recording_frame(mDevice, data);
     }
 }
 
@@ -653,9 +593,6 @@
                 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
                 return;
             }
-        } else {
-            ALOGE("Non HIDL mode do not support %s", __FUNCTION__);
-            return;
         }
     }
 
@@ -674,8 +611,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->autoFocus());
-    } else if (mDevice && mDevice->ops->auto_focus) {
-        return mDevice->ops->auto_focus(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -686,8 +621,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->cancelAutoFocus());
-    } else if (mDevice && mDevice->ops->cancel_auto_focus) {
-        return mDevice->ops->cancel_auto_focus(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -698,8 +631,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->takePicture());
-    } else if (mDevice && mDevice->ops->take_picture) {
-        return mDevice->ops->take_picture(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -710,8 +641,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->cancelPicture());
-    } else if (mDevice && mDevice->ops->cancel_picture) {
-        return mDevice->ops->cancel_picture(mDevice);
     }
     return INVALID_OPERATION;
 }
@@ -722,8 +651,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->setParameters(params.flatten().string()));
-    } else if (mDevice && mDevice->ops->set_parameters) {
-        return mDevice->ops->set_parameters(mDevice, params.flatten().string());
     }
     return INVALID_OPERATION;
 }
@@ -740,14 +667,6 @@
                 });
         String8 tmp(outParam.c_str());
         parms.unflatten(tmp);
-    } else if (mDevice && mDevice->ops->get_parameters) {
-        char *temp = mDevice->ops->get_parameters(mDevice);
-        String8 str_parms(temp);
-        if (mDevice->ops->put_parameters)
-            mDevice->ops->put_parameters(mDevice, temp);
-        else
-            free(temp);
-        parms.unflatten(str_parms);
     }
     return parms;
 }
@@ -758,8 +677,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         return CameraProviderManager::mapToStatusT(
                 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
-    } else if (mDevice && mDevice->ops->send_command) {
-        return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
     }
     return INVALID_OPERATION;
 }
@@ -773,8 +690,6 @@
     if (CC_LIKELY(mHidlDevice != nullptr)) {
         mHidlDevice->close();
         mHidlDevice.clear();
-    } else if (mDevice && mDevice->ops->release) {
-        mDevice->ops->release(mDevice);
     }
 }
 
@@ -790,15 +705,10 @@
         Status s = mHidlDevice->dumpState(handle);
         native_handle_delete(handle);
         return CameraProviderManager::mapToStatusT(s);
-    } else if (mDevice && mDevice->ops->dump) {
-        return mDevice->ops->dump(mDevice, fd);
     }
     return OK; // It's fine if the HAL doesn't implement dump()
 }
 
-/**
- * Methods for legacy (non-HIDL) path follows
- */
 void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
                         int32_t ext2, void *user)
 {
@@ -868,177 +778,4 @@
     mem->decStrong(mem);
 }
 
-ANativeWindow* CameraHardwareInterface::sToAnw(void *user)
-{
-    CameraHardwareInterface *object =
-            reinterpret_cast<CameraHardwareInterface *>(user);
-    return object->mPreviewWindow.get();
-}
-#define anw(n) sToAnw(((struct camera_preview_window *)(n))->user)
-#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
-    ((struct camera_preview_window *)(n))->user)
-
-int CameraHardwareInterface::sDequeueBuffer(struct preview_stream_ops* w,
-                            buffer_handle_t** buffer, int *stride)
-{
-    int rc;
-    ANativeWindow *a = anw(w);
-    ANativeWindowBuffer* anb;
-    rc = native_window_dequeue_buffer_and_wait(a, &anb);
-    if (rc == OK) {
-        *buffer = &anb->handle;
-        *stride = anb->stride;
-    }
-    return rc;
-}
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({                      \
-    const __typeof__(((type *) 0)->member) *__mptr = (ptr);     \
-    (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
-#endif
-
-int CameraHardwareInterface::sLockBuffer(struct preview_stream_ops* w,
-                  buffer_handle_t* /*buffer*/)
-{
-    ANativeWindow *a = anw(w);
-    (void)a;
-    return 0;
-}
-
-int CameraHardwareInterface::sEnqueueBuffer(struct preview_stream_ops* w,
-                  buffer_handle_t* buffer)
-{
-    ANativeWindow *a = anw(w);
-    return a->queueBuffer(a,
-              container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int CameraHardwareInterface::sCancelBuffer(struct preview_stream_ops* w,
-                  buffer_handle_t* buffer)
-{
-    ANativeWindow *a = anw(w);
-    return a->cancelBuffer(a,
-              container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int CameraHardwareInterface::sSetBufferCount(struct preview_stream_ops* w, int count)
-{
-    ANativeWindow *a = anw(w);
-
-    if (a != nullptr) {
-        // Workaround for b/27039775
-        // Previously, setting the buffer count would reset the buffer
-        // queue's flag that allows for all buffers to be dequeued on the
-        // producer side, instead of just the producer's declared max count,
-        // if no filled buffers have yet been queued by the producer.  This
-        // reset no longer happens, but some HALs depend on this behavior,
-        // so it needs to be maintained for HAL backwards compatibility.
-        // Simulate the prior behavior by disconnecting/reconnecting to the
-        // window and setting the values again.  This has the drawback of
-        // actually causing memory reallocation, which may not have happened
-        // in the past.
-        CameraHardwareInterface *hw = hwi(w);
-        native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
-        native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
-        if (hw->mPreviewScalingMode != NOT_SET) {
-            native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
-        }
-        if (hw->mPreviewTransform != NOT_SET) {
-            native_window_set_buffers_transform(a, hw->mPreviewTransform);
-        }
-        if (hw->mPreviewWidth != NOT_SET) {
-            native_window_set_buffers_dimensions(a,
-                    hw->mPreviewWidth, hw->mPreviewHeight);
-            native_window_set_buffers_format(a, hw->mPreviewFormat);
-        }
-        if (hw->mPreviewUsage != 0) {
-            native_window_set_usage(a, hw->mPreviewUsage);
-        }
-        if (hw->mPreviewSwapInterval != NOT_SET) {
-            a->setSwapInterval(a, hw->mPreviewSwapInterval);
-        }
-        if (hw->mPreviewCrop.left != NOT_SET) {
-            native_window_set_crop(a, &(hw->mPreviewCrop));
-        }
-    }
-
-    return native_window_set_buffer_count(a, count);
-}
-
-int CameraHardwareInterface::sSetBuffersGeometry(struct preview_stream_ops* w,
-                  int width, int height, int format)
-{
-    int rc;
-    ANativeWindow *a = anw(w);
-    CameraHardwareInterface *hw = hwi(w);
-    hw->mPreviewWidth = width;
-    hw->mPreviewHeight = height;
-    hw->mPreviewFormat = format;
-    rc = native_window_set_buffers_dimensions(a, width, height);
-    if (rc == OK) {
-        rc = native_window_set_buffers_format(a, format);
-    }
-    return rc;
-}
-
-int CameraHardwareInterface::sSetCrop(struct preview_stream_ops *w,
-                  int left, int top, int right, int bottom)
-{
-    ANativeWindow *a = anw(w);
-    CameraHardwareInterface *hw = hwi(w);
-    hw->mPreviewCrop.left = left;
-    hw->mPreviewCrop.top = top;
-    hw->mPreviewCrop.right = right;
-    hw->mPreviewCrop.bottom = bottom;
-    return native_window_set_crop(a, &(hw->mPreviewCrop));
-}
-
-int CameraHardwareInterface::sSetTimestamp(struct preview_stream_ops *w,
-                           int64_t timestamp) {
-    ANativeWindow *a = anw(w);
-    return native_window_set_buffers_timestamp(a, timestamp);
-}
-
-int CameraHardwareInterface::sSetUsage(struct preview_stream_ops* w, int usage)
-{
-    ANativeWindow *a = anw(w);
-    CameraHardwareInterface *hw = hwi(w);
-    hw->mPreviewUsage = usage;
-    return native_window_set_usage(a, usage);
-}
-
-int CameraHardwareInterface::sSetSwapInterval(struct preview_stream_ops *w, int interval)
-{
-    ANativeWindow *a = anw(w);
-    CameraHardwareInterface *hw = hwi(w);
-    hw->mPreviewSwapInterval = interval;
-    return a->setSwapInterval(a, interval);
-}
-
-int CameraHardwareInterface::sGetMinUndequeuedBufferCount(
-                  const struct preview_stream_ops *w,
-                  int *count)
-{
-    ANativeWindow *a = anw(w);
-    return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
-}
-
-void CameraHardwareInterface::initHalPreviewWindow()
-{
-    mHalPreviewWindow.nw.cancel_buffer = sCancelBuffer;
-    mHalPreviewWindow.nw.lock_buffer = sLockBuffer;
-    mHalPreviewWindow.nw.dequeue_buffer = sDequeueBuffer;
-    mHalPreviewWindow.nw.enqueue_buffer = sEnqueueBuffer;
-    mHalPreviewWindow.nw.set_buffer_count = sSetBufferCount;
-    mHalPreviewWindow.nw.set_buffers_geometry = sSetBuffersGeometry;
-    mHalPreviewWindow.nw.set_crop = sSetCrop;
-    mHalPreviewWindow.nw.set_timestamp = sSetTimestamp;
-    mHalPreviewWindow.nw.set_usage = sSetUsage;
-    mHalPreviewWindow.nw.set_swap_interval = sSetSwapInterval;
-
-    mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
-            sGetMinUndequeuedBufferCount;
-}
-
 }; // namespace android
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 1c38d00..6a1b4fb 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -90,7 +90,6 @@
 
 public:
     explicit CameraHardwareInterface(const char *name):
-            mDevice(nullptr),
             mHidlDevice(nullptr),
             mName(name),
             mPreviewScalingMode(NOT_SET),
@@ -299,7 +298,6 @@
     status_t dump(int fd, const Vector<String16>& /*args*/) const;
 
 private:
-    camera_device_t *mDevice;
     sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;
     String8 mName;
 
@@ -369,41 +367,6 @@
 
     static void sPutMemory(camera_memory_t *data);
 
-    static ANativeWindow *sToAnw(void *user);
-
-    static int sDequeueBuffer(struct preview_stream_ops* w,
-                                buffer_handle_t** buffer, int *stride);
-
-    static int sLockBuffer(struct preview_stream_ops* w,
-                      buffer_handle_t* /*buffer*/);
-
-    static int sEnqueueBuffer(struct preview_stream_ops* w,
-                      buffer_handle_t* buffer);
-
-    static int sCancelBuffer(struct preview_stream_ops* w,
-                      buffer_handle_t* buffer);
-
-    static int sSetBufferCount(struct preview_stream_ops* w, int count);
-
-    static int sSetBuffersGeometry(struct preview_stream_ops* w,
-                      int width, int height, int format);
-
-    static int sSetCrop(struct preview_stream_ops *w,
-                      int left, int top, int right, int bottom);
-
-    static int sSetTimestamp(struct preview_stream_ops *w,
-                               int64_t timestamp);
-
-    static int sSetUsage(struct preview_stream_ops* w, int usage);
-
-    static int sSetSwapInterval(struct preview_stream_ops *w, int interval);
-
-    static int sGetMinUndequeuedBufferCount(
-                      const struct preview_stream_ops *w,
-                      int *count);
-
-    void initHalPreviewWindow();
-
     std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
     void cleanupCirculatingBuffers();
 
@@ -459,13 +422,6 @@
 
     sp<ANativeWindow>        mPreviewWindow;
 
-    struct camera_preview_window {
-        struct preview_stream_ops nw;
-        void *user;
-    };
-
-    struct camera_preview_window mHalPreviewWindow;
-
     notify_callback               mNotifyCb;
     data_callback                 mDataCb;
     data_callback_timestamp       mDataCbTimestamp;
@@ -479,7 +435,7 @@
     int mPreviewWidth;
     int mPreviewHeight;
     int mPreviewFormat;
-    int mPreviewUsage;
+    uint64_t mPreviewUsage;
     int mPreviewSwapInterval;
     android_native_rect_t mPreviewCrop;
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 69b1d7d..02f54245 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -407,7 +407,7 @@
 }
 
 BufferUsageFlags Camera3Device::mapToConsumerUsage(
-        uint32_t usage) {
+        uint64_t usage) {
     return usage;
 }
 
@@ -460,12 +460,12 @@
     return static_cast<uint32_t>(pixelFormat);
 }
 
-uint32_t Camera3Device::mapConsumerToFrameworkUsage(
+uint64_t Camera3Device::mapConsumerToFrameworkUsage(
         BufferUsageFlags usage) {
     return usage;
 }
 
-uint32_t Camera3Device::mapProducerToFrameworkUsage(
+uint64_t Camera3Device::mapProducerToFrameworkUsage(
         BufferUsageFlags usage) {
     return usage;
 }
@@ -1208,7 +1208,7 @@
 status_t Camera3Device::createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-            int streamSetId, bool isShared, uint32_t consumerUsage) {
+            int streamSetId, bool isShared, uint64_t consumerUsage) {
     ATRACE_CALL();
 
     if (consumer == nullptr) {
@@ -1226,13 +1226,13 @@
 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
         android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-        int streamSetId, bool isShared, uint32_t consumerUsage) {
+        int streamSetId, bool isShared, uint64_t consumerUsage) {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
     Mutex::Autolock l(mLock);
     ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
-            " consumer usage 0x%x, isShared %d", mId.string(), mNextStreamId, width, height, format,
+            " consumer usage %" PRIu64 ", isShared %d", mId.string(), mNextStreamId, width, height, format,
             dataSpace, rotation, consumerUsage, isShared);
 
     status_t res;
@@ -1478,6 +1478,7 @@
 
 status_t Camera3Device::getInputBufferProducer(
         sp<IGraphicBufferProducer> *producer) {
+    ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
@@ -1691,6 +1692,7 @@
 }
 
 status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
+    ATRACE_CALL();
     status_t res;
     Mutex::Autolock l(mOutputLock);
 
@@ -1884,6 +1886,7 @@
  */
 
 void Camera3Device::notifyStatus(bool idle) {
+    ATRACE_CALL();
     {
         // Need mLock to safely update state and synchronize to current
         // state of methods in flight.
@@ -2317,6 +2320,7 @@
 }
 
 void Camera3Device::setErrorState(const char *fmt, ...) {
+    ATRACE_CALL();
     Mutex::Autolock l(mLock);
     va_list args;
     va_start(args, fmt);
@@ -2327,6 +2331,7 @@
 }
 
 void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
+    ATRACE_CALL();
     Mutex::Autolock l(mLock);
     setErrorStateLockedV(fmt, args);
 }
@@ -2411,6 +2416,7 @@
 }
 
 void Camera3Device::removeInFlightMapEntryLocked(int idx) {
+    ATRACE_CALL();
     nsecs_t duration = mInFlightMap.valueAt(idx).maxExpectedDuration;
     mInFlightMap.removeItemsAt(idx, 1);
 
@@ -2495,6 +2501,7 @@
 }
 
 void Camera3Device::flushInflightRequests() {
+    ATRACE_CALL();
     { // First return buffers cached in mInFlightMap
         Mutex::Autolock l(mInFlightLock);
         for (size_t idx = 0; idx < mInFlightMap.size(); idx++) {
@@ -2621,6 +2628,7 @@
 
 void Camera3Device::sendPartialCaptureResult(const camera_metadata_t * partialResult,
         const CaptureResultExtras &resultExtras, uint32_t frameNumber) {
+    ATRACE_CALL();
     Mutex::Autolock l(mOutputLock);
 
     CaptureResult captureResult;
@@ -2636,6 +2644,7 @@
         CameraMetadata &collectedPartialResult,
         uint32_t frameNumber,
         bool reprocess) {
+    ATRACE_CALL();
     if (pendingMetadata.isEmpty())
         return;
 
@@ -2884,7 +2893,7 @@
 
 void Camera3Device::notifyError(const camera3_error_msg_t &msg,
         sp<NotificationListener> listener) {
-
+    ATRACE_CALL();
     // Map camera HAL error codes to ICameraDeviceCallback error codes
     // Index into this with the HAL error code
     static const int32_t halErrorMap[CAMERA3_MSG_NUM_ERRORS] = {
@@ -2962,6 +2971,7 @@
 
 void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
         sp<NotificationListener> listener) {
+    ATRACE_CALL();
     ssize_t idx;
 
     // Set timestamp for the request in the in-flight tracking
@@ -3048,24 +3058,20 @@
 Camera3Device::HalInterface::HalInterface(
             sp<ICameraDeviceSession> &session,
             std::shared_ptr<RequestMetadataQueue> queue) :
-        mHal3Device(nullptr),
         mHidlSession(session),
         mRequestMetadataQueue(queue) {}
 
-Camera3Device::HalInterface::HalInterface() :
-        mHal3Device(nullptr) {}
+Camera3Device::HalInterface::HalInterface() {}
 
 Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
-        mHal3Device(other.mHal3Device),
         mHidlSession(other.mHidlSession),
         mRequestMetadataQueue(other.mRequestMetadataQueue) {}
 
 bool Camera3Device::HalInterface::valid() {
-    return (mHal3Device != nullptr) || (mHidlSession != nullptr);
+    return (mHidlSession != nullptr);
 }
 
 void Camera3Device::HalInterface::clear() {
-    mHal3Device = nullptr;
     mHidlSession.clear();
 }
 
@@ -3080,72 +3086,60 @@
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        const camera_metadata *r;
-        r = mHal3Device->ops->construct_default_request_settings(
-                mHal3Device, templateId);
-        if (r == nullptr) return BAD_VALUE;
-        *requestTemplate = clone_camera_metadata(r);
-        if (requestTemplate == nullptr) {
-            ALOGE("%s: Unable to clone camera metadata received from HAL",
-                    __FUNCTION__);
-            return INVALID_OPERATION;
-        }
-    } else {
-        common::V1_0::Status status;
-        RequestTemplate id;
-        switch (templateId) {
-            case CAMERA3_TEMPLATE_PREVIEW:
-                id = RequestTemplate::PREVIEW;
-                break;
-            case CAMERA3_TEMPLATE_STILL_CAPTURE:
-                id = RequestTemplate::STILL_CAPTURE;
-                break;
-            case CAMERA3_TEMPLATE_VIDEO_RECORD:
-                id = RequestTemplate::VIDEO_RECORD;
-                break;
-            case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
-                id = RequestTemplate::VIDEO_SNAPSHOT;
-                break;
-            case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
-                id = RequestTemplate::ZERO_SHUTTER_LAG;
-                break;
-            case CAMERA3_TEMPLATE_MANUAL:
-                id = RequestTemplate::MANUAL;
-                break;
-            default:
-                // Unknown template ID
-                return BAD_VALUE;
-        }
-        auto err = mHidlSession->constructDefaultRequestSettings(id,
-                [&status, &requestTemplate]
-                (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
-                    status = s;
-                    if (status == common::V1_0::Status::OK) {
-                        const camera_metadata *r =
-                                reinterpret_cast<const camera_metadata_t*>(request.data());
-                        size_t expectedSize = request.size();
-                        int ret = validate_camera_metadata_structure(r, &expectedSize);
-                        if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
-                            *requestTemplate = clone_camera_metadata(r);
-                            if (*requestTemplate == nullptr) {
-                                ALOGE("%s: Unable to clone camera metadata received from HAL",
-                                        __FUNCTION__);
-                                status = common::V1_0::Status::INTERNAL_ERROR;
-                            }
-                        } else {
-                            ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+    common::V1_0::Status status;
+    RequestTemplate id;
+    switch (templateId) {
+        case CAMERA3_TEMPLATE_PREVIEW:
+            id = RequestTemplate::PREVIEW;
+            break;
+        case CAMERA3_TEMPLATE_STILL_CAPTURE:
+            id = RequestTemplate::STILL_CAPTURE;
+            break;
+        case CAMERA3_TEMPLATE_VIDEO_RECORD:
+            id = RequestTemplate::VIDEO_RECORD;
+            break;
+        case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
+            id = RequestTemplate::VIDEO_SNAPSHOT;
+            break;
+        case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
+            id = RequestTemplate::ZERO_SHUTTER_LAG;
+            break;
+        case CAMERA3_TEMPLATE_MANUAL:
+            id = RequestTemplate::MANUAL;
+            break;
+        default:
+            // Unknown template ID
+            return BAD_VALUE;
+    }
+    auto err = mHidlSession->constructDefaultRequestSettings(id,
+            [&status, &requestTemplate]
+            (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
+                status = s;
+                if (status == common::V1_0::Status::OK) {
+                    const camera_metadata *r =
+                            reinterpret_cast<const camera_metadata_t*>(request.data());
+                    size_t expectedSize = request.size();
+                    int ret = validate_camera_metadata_structure(r, &expectedSize);
+                    if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
+                        *requestTemplate = clone_camera_metadata(r);
+                        if (*requestTemplate == nullptr) {
+                            ALOGE("%s: Unable to clone camera metadata received from HAL",
+                                    __FUNCTION__);
                             status = common::V1_0::Status::INTERNAL_ERROR;
                         }
+                    } else {
+                        ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+                        status = common::V1_0::Status::INTERNAL_ERROR;
                     }
-                });
-        if (!err.isOk()) {
-            ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
-            res = DEAD_OBJECT;
-        } else {
-            res = CameraProviderManager::mapToStatusT(status);
-        }
+                }
+            });
+    if (!err.isOk()) {
+        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+        res = DEAD_OBJECT;
+    } else {
+        res = CameraProviderManager::mapToStatusT(status);
     }
+
     return res;
 }
 
@@ -3154,145 +3148,144 @@
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        res = mHal3Device->ops->configure_streams(mHal3Device, config);
-    } else {
-        // Convert stream config to HIDL
-        std::set<int> activeStreams;
-        StreamConfiguration requestedConfiguration;
-        requestedConfiguration.streams.resize(config->num_streams);
-        for (size_t i = 0; i < config->num_streams; i++) {
-            Stream &dst = requestedConfiguration.streams[i];
-            camera3_stream_t *src = config->streams[i];
+    // Convert stream config to HIDL
+    std::set<int> activeStreams;
+    StreamConfiguration requestedConfiguration;
+    requestedConfiguration.streams.resize(config->num_streams);
+    for (size_t i = 0; i < config->num_streams; i++) {
+        Stream &dst = requestedConfiguration.streams[i];
+        camera3_stream_t *src = config->streams[i];
 
-            Camera3Stream* cam3stream = Camera3Stream::cast(src);
-            cam3stream->setBufferFreedListener(this);
-            int streamId = cam3stream->getId();
-            StreamType streamType;
-            switch (src->stream_type) {
-                case CAMERA3_STREAM_OUTPUT:
-                    streamType = StreamType::OUTPUT;
-                    break;
-                case CAMERA3_STREAM_INPUT:
-                    streamType = StreamType::INPUT;
-                    break;
-                default:
-                    ALOGE("%s: Stream %d: Unsupported stream type %d",
-                            __FUNCTION__, streamId, config->streams[i]->stream_type);
-                    return BAD_VALUE;
+        Camera3Stream* cam3stream = Camera3Stream::cast(src);
+        cam3stream->setBufferFreedListener(this);
+        int streamId = cam3stream->getId();
+        StreamType streamType;
+        switch (src->stream_type) {
+            case CAMERA3_STREAM_OUTPUT:
+                streamType = StreamType::OUTPUT;
+                break;
+            case CAMERA3_STREAM_INPUT:
+                streamType = StreamType::INPUT;
+                break;
+            default:
+                ALOGE("%s: Stream %d: Unsupported stream type %d",
+                        __FUNCTION__, streamId, config->streams[i]->stream_type);
+                return BAD_VALUE;
+        }
+        dst.id = streamId;
+        dst.streamType = streamType;
+        dst.width = src->width;
+        dst.height = src->height;
+        dst.format = mapToPixelFormat(src->format);
+        dst.usage = mapToConsumerUsage(cam3stream->getUsage());
+        dst.dataSpace = mapToHidlDataspace(src->data_space);
+        dst.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+
+        activeStreams.insert(streamId);
+        // Create Buffer ID map if necessary
+        if (mBufferIdMaps.count(streamId) == 0) {
+            mBufferIdMaps.emplace(streamId, BufferIdMap{});
+        }
+    }
+    // remove BufferIdMap for deleted streams
+    for(auto it = mBufferIdMaps.begin(); it != mBufferIdMaps.end();) {
+        int streamId = it->first;
+        bool active = activeStreams.count(streamId) > 0;
+        if (!active) {
+            it = mBufferIdMaps.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    res = mapToStreamConfigurationMode(
+            (camera3_stream_configuration_mode_t) config->operation_mode,
+            /*out*/ &requestedConfiguration.operationMode);
+    if (res != OK) {
+        return res;
+    }
+
+    // Invoke configureStreams
+
+    HalStreamConfiguration finalConfiguration;
+    common::V1_0::Status status;
+    auto err = mHidlSession->configureStreams(requestedConfiguration,
+            [&status, &finalConfiguration]
+            (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
+                finalConfiguration = halConfiguration;
+                status = s;
+            });
+    if (!err.isOk()) {
+        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+        return DEAD_OBJECT;
+    }
+
+    if (status != common::V1_0::Status::OK ) {
+        return CameraProviderManager::mapToStatusT(status);
+    }
+
+    // And convert output stream configuration from HIDL
+
+    for (size_t i = 0; i < config->num_streams; i++) {
+        camera3_stream_t *dst = config->streams[i];
+        int streamId = Camera3Stream::cast(dst)->getId();
+
+        // Start scan at i, with the assumption that the stream order matches
+        size_t realIdx = i;
+        bool found = false;
+        for (size_t idx = 0; idx < finalConfiguration.streams.size(); idx++) {
+            if (finalConfiguration.streams[realIdx].id == streamId) {
+                found = true;
+                break;
             }
-            dst.id = streamId;
-            dst.streamType = streamType;
-            dst.width = src->width;
-            dst.height = src->height;
-            dst.format = mapToPixelFormat(src->format);
-            dst.usage = mapToConsumerUsage(src->usage);
-            dst.dataSpace = mapToHidlDataspace(src->data_space);
-            dst.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+            realIdx = (realIdx >= finalConfiguration.streams.size()) ? 0 : realIdx + 1;
+        }
+        if (!found) {
+            ALOGE("%s: Stream %d not found in stream configuration response from HAL",
+                    __FUNCTION__, streamId);
+            return INVALID_OPERATION;
+        }
+        HalStream &src = finalConfiguration.streams[realIdx];
 
-            activeStreams.insert(streamId);
-            // Create Buffer ID map if necessary
-            if (mBufferIdMaps.count(streamId) == 0) {
-                mBufferIdMaps.emplace(streamId, BufferIdMap{});
+        int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
+        if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+            if (dst->format != overrideFormat) {
+                ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
+                        streamId, dst->format);
             }
-        }
-        // remove BufferIdMap for deleted streams
-        for(auto it = mBufferIdMaps.begin(); it != mBufferIdMaps.end();) {
-            int streamId = it->first;
-            bool active = activeStreams.count(streamId) > 0;
-            if (!active) {
-                it = mBufferIdMaps.erase(it);
-            } else {
-                ++it;
-            }
+        } else {
+            // Override allowed with IMPLEMENTATION_DEFINED
+            dst->format = overrideFormat;
         }
 
-        res = mapToStreamConfigurationMode(
-                (camera3_stream_configuration_mode_t) config->operation_mode,
-                /*out*/ &requestedConfiguration.operationMode);
-        if (res != OK) {
-            return res;
-        }
-
-        // Invoke configureStreams
-
-        HalStreamConfiguration finalConfiguration;
-        common::V1_0::Status status;
-        auto err = mHidlSession->configureStreams(requestedConfiguration,
-                [&status, &finalConfiguration]
-                (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
-                    finalConfiguration = halConfiguration;
-                    status = s;
-                });
-        if (!err.isOk()) {
-            ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
-            return DEAD_OBJECT;
-        }
-
-        if (status != common::V1_0::Status::OK ) {
-            return CameraProviderManager::mapToStatusT(status);
-        }
-
-        // And convert output stream configuration from HIDL
-
-        for (size_t i = 0; i < config->num_streams; i++) {
-            camera3_stream_t *dst = config->streams[i];
-            int streamId = Camera3Stream::cast(dst)->getId();
-
-            // Start scan at i, with the assumption that the stream order matches
-            size_t realIdx = i;
-            bool found = false;
-            for (size_t idx = 0; idx < finalConfiguration.streams.size(); idx++) {
-                if (finalConfiguration.streams[realIdx].id == streamId) {
-                    found = true;
-                    break;
-                }
-                realIdx = (realIdx >= finalConfiguration.streams.size()) ? 0 : realIdx + 1;
-            }
-            if (!found) {
-                ALOGE("%s: Stream %d not found in stream configuration response from HAL",
+        if (dst->stream_type == CAMERA3_STREAM_INPUT) {
+            if (src.producerUsage != 0) {
+                ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
                         __FUNCTION__, streamId);
                 return INVALID_OPERATION;
             }
-            HalStream &src = finalConfiguration.streams[realIdx];
-
-            int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
-            if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
-                if (dst->format != overrideFormat) {
-                    ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
-                            streamId, dst->format);
-                }
-            } else {
-                // Override allowed with IMPLEMENTATION_DEFINED
-                dst->format = overrideFormat;
+            Camera3Stream::cast(dst)->setUsage(
+                    mapConsumerToFrameworkUsage(src.consumerUsage));
+        } else {
+            // OUTPUT
+            if (src.consumerUsage != 0) {
+                ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
+                        __FUNCTION__, streamId);
+                return INVALID_OPERATION;
             }
-
-            if (dst->stream_type == CAMERA3_STREAM_INPUT) {
-                if (src.producerUsage != 0) {
-                    ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
-                            __FUNCTION__, streamId);
-                    return INVALID_OPERATION;
-                }
-                dst->usage = mapConsumerToFrameworkUsage(src.consumerUsage);
-            } else {
-                // OUTPUT
-                if (src.consumerUsage != 0) {
-                    ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
-                            __FUNCTION__, streamId);
-                    return INVALID_OPERATION;
-                }
-                dst->usage = mapProducerToFrameworkUsage(src.producerUsage);
-            }
-            dst->max_buffers = src.maxBuffers;
+            Camera3Stream::cast(dst)->setUsage(
+                    mapProducerToFrameworkUsage(src.producerUsage));
         }
+        dst->max_buffers = src.maxBuffers;
     }
+
     return res;
 }
 
 void Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
         /*out*/device::V3_2::CaptureRequest* captureRequest,
         /*out*/std::vector<native_handle_t*>* handlesCreated) {
-
+    ATRACE_CALL();
     if (captureRequest == nullptr || handlesCreated == nullptr) {
         ALOGE("%s: captureRequest (%p) and handlesCreated (%p) must not be null",
                 __FUNCTION__, captureRequest, handlesCreated);
@@ -3441,14 +3434,11 @@
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        res = mHal3Device->ops->process_capture_request(mHal3Device, request);
-    } else {
-        uint32_t numRequestProcessed = 0;
-        std::vector<camera3_capture_request_t*> requests(1);
-        requests[0] = request;
-        res = processBatchCaptureRequests(requests, &numRequestProcessed);
-    }
+    uint32_t numRequestProcessed = 0;
+    std::vector<camera3_capture_request_t*> requests(1);
+    requests[0] = request;
+    res = processBatchCaptureRequests(requests, &numRequestProcessed);
+
     return res;
 }
 
@@ -3457,31 +3447,24 @@
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        res = mHal3Device->ops->flush(mHal3Device);
+    auto err = mHidlSession->flush();
+    if (!err.isOk()) {
+        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
+        res = DEAD_OBJECT;
     } else {
-        auto err = mHidlSession->flush();
-        if (!err.isOk()) {
-            ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
-            res = DEAD_OBJECT;
-        } else {
-            res = CameraProviderManager::mapToStatusT(err);
-        }
+        res = CameraProviderManager::mapToStatusT(err);
     }
+
     return res;
 }
 
-status_t Camera3Device::HalInterface::dump(int fd) {
+status_t Camera3Device::HalInterface::dump(int /*fd*/) {
     ATRACE_NAME("CameraHal::dump");
     if (!valid()) return INVALID_OPERATION;
-    status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        mHal3Device->ops->dump(mHal3Device, fd);
-    } else {
-        // Handled by CameraProviderManager::dump
-    }
-    return res;
+    // Handled by CameraProviderManager::dump
+
+    return OK;
 }
 
 status_t Camera3Device::HalInterface::close() {
@@ -3489,15 +3472,12 @@
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
 
-    if (mHal3Device != nullptr) {
-        mHal3Device->common.close(&mHal3Device->common);
-    } else {
-        auto err = mHidlSession->close();
-        // Interface will be dead shortly anyway, so don't log errors
-        if (!err.isOk()) {
-            res = DEAD_OBJECT;
-        }
+    auto err = mHidlSession->close();
+    // Interface will be dead shortly anyway, so don't log errors
+    if (!err.isOk()) {
+        res = DEAD_OBJECT;
     }
+
     return res;
 }
 
@@ -3614,11 +3594,13 @@
 
 void Camera3Device::RequestThread::setNotificationListener(
         wp<NotificationListener> listener) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     mListener = listener;
 }
 
 void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     mReconfigured = true;
     // Prepare video stream for high speed recording.
@@ -3629,6 +3611,7 @@
         List<sp<CaptureRequest> > &requests,
         /*out*/
         int64_t *lastFrameNumber) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
             ++it) {
@@ -3651,7 +3634,7 @@
 status_t Camera3Device::RequestThread::queueTrigger(
         RequestTrigger trigger[],
         size_t count) {
-
+    ATRACE_CALL();
     Mutex::Autolock l(mTriggerMutex);
     status_t ret;
 
@@ -3708,6 +3691,7 @@
         const RequestList &requests,
         /*out*/
         int64_t *lastFrameNumber) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     if (lastFrameNumber != NULL) {
         *lastFrameNumber = mRepeatingLastFrameNumber;
@@ -3734,6 +3718,7 @@
 }
 
 status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     return clearRepeatingRequestsLocked(lastFrameNumber);
 
@@ -3750,6 +3735,7 @@
 
 status_t Camera3Device::RequestThread::clear(
         /*out*/int64_t *lastFrameNumber) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     ALOGV("RequestThread::%s:", __FUNCTION__);
 
@@ -3805,6 +3791,7 @@
 }
 
 void Camera3Device::RequestThread::setPaused(bool paused) {
+    ATRACE_CALL();
     Mutex::Autolock l(mPauseLock);
     mDoPause = paused;
     mDoPauseSignal.signal();
@@ -3812,6 +3799,7 @@
 
 status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
         int32_t requestId, nsecs_t timeout) {
+    ATRACE_CALL();
     Mutex::Autolock l(mLatestRequestMutex);
     status_t res;
     while (mLatestRequestId != requestId) {
@@ -3838,6 +3826,7 @@
 }
 
 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
+    ATRACE_CALL();
     bool surfaceAbandoned = false;
     int64_t lastFrameNumber = 0;
     sp<NotificationListener> listener;
@@ -3866,6 +3855,7 @@
 }
 
 bool Camera3Device::RequestThread::sendRequestsBatch() {
+    ATRACE_CALL();
     status_t res;
     size_t batchSize = mNextRequests.size();
     std::vector<camera3_capture_request_t*> requests(batchSize);
@@ -4261,6 +4251,7 @@
 }
 
 CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
+    ATRACE_CALL();
     Mutex::Autolock al(mLatestRequestMutex);
 
     ALOGV("RequestThread::%s", __FUNCTION__);
@@ -4270,6 +4261,7 @@
 
 bool Camera3Device::RequestThread::isStreamPending(
         sp<Camera3StreamInterface>& stream) {
+    ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
 
     for (const auto& nextRequest : mNextRequests) {
@@ -4299,6 +4291,7 @@
 }
 
 nsecs_t Camera3Device::getExpectedInFlightDuration() {
+    ATRACE_CALL();
     Mutex::Autolock al(mInFlightLock);
     return mExpectedInflightDuration > kMinInflightDuration ?
             mExpectedInflightDuration : kMinInflightDuration;
@@ -4370,6 +4363,7 @@
 }
 
 void Camera3Device::RequestThread::waitForNextRequestBatch() {
+    ATRACE_CALL();
     // Optimized a bit for the simple steady-state case (single repeating
     // request), to avoid putting that request in the queue temporarily.
     Mutex::Autolock l(mRequestLock);
@@ -4519,6 +4513,7 @@
 }
 
 bool Camera3Device::RequestThread::waitIfPaused() {
+    ATRACE_CALL();
     status_t res;
     Mutex::Autolock l(mPauseLock);
     while (mDoPause) {
@@ -4543,6 +4538,7 @@
 }
 
 void Camera3Device::RequestThread::unpauseForNewRequests() {
+    ATRACE_CALL();
     // With work to do, mark thread as unpaused.
     // If paused by request (setPaused), don't resume, to avoid
     // extra signaling/waiting overhead to waitUntilPaused
@@ -4574,7 +4570,7 @@
 
 status_t Camera3Device::RequestThread::insertTriggers(
         const sp<CaptureRequest> &request) {
-
+    ATRACE_CALL();
     Mutex::Autolock al(mTriggerMutex);
 
     sp<Camera3Device> parent = mParent.promote();
@@ -4663,6 +4659,7 @@
 
 status_t Camera3Device::RequestThread::removeTriggers(
         const sp<CaptureRequest> &request) {
+    ATRACE_CALL();
     Mutex::Autolock al(mTriggerMutex);
 
     CameraMetadata &metadata = request->mSettings;
@@ -4779,6 +4776,7 @@
 }
 
 status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
+    ATRACE_CALL();
     status_t res;
 
     Mutex::Autolock l(mLock);
@@ -4822,6 +4820,7 @@
 }
 
 status_t Camera3Device::PreparerThread::clear() {
+    ATRACE_CALL();
     Mutex::Autolock l(mLock);
 
     for (const auto& stream : mPendingStreams) {
@@ -4834,6 +4833,7 @@
 }
 
 void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
+    ATRACE_CALL();
     Mutex::Autolock l(mLock);
     mListener = listener;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d700e03..b5f19d7 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -117,12 +117,12 @@
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            bool isShared = false, uint32_t consumerUsage = 0) override;
+            bool isShared = false, uint64_t consumerUsage = 0) override;
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            bool isShared = false, uint32_t consumerUsage = 0) override;
+            bool isShared = false, uint64_t consumerUsage = 0) override;
 
     status_t createInputStream(
             uint32_t width, uint32_t height, int format,
@@ -271,7 +271,6 @@
         void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
 
       private:
-        camera3_device_t *mHal3Device;
         sp<hardware::camera::device::V3_2::ICameraDeviceSession> mHidlSession;
         std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
 
@@ -590,7 +589,7 @@
     static hardware::graphics::common::V1_0::PixelFormat mapToPixelFormat(int frameworkFormat);
     static hardware::camera::device::V3_2::DataspaceFlags mapToHidlDataspace(
             android_dataspace dataSpace);
-    static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint32_t usage);
+    static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
     static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
             camera3_stream_rotation_t rotation);
     // Returns a negative error code if the passed-in operation mode is not valid.
@@ -598,9 +597,9 @@
             /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
     static camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status);
     static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
-    static uint32_t mapConsumerToFrameworkUsage(
+    static uint64_t mapConsumerToFrameworkUsage(
             hardware::camera::device::V3_2::BufferUsageFlags usage);
-    static uint32_t mapProducerToFrameworkUsage(
+    static uint64_t mapProducerToFrameworkUsage(
             hardware::camera::device::V3_2::BufferUsageFlags usage);
 
     struct RequestTrigger {
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 9c951b7..6e2978f 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -95,7 +95,7 @@
     return OK;
 }
 
-status_t Camera3DummyStream::getEndpointUsage(uint32_t *usage) const {
+status_t Camera3DummyStream::getEndpointUsage(uint64_t *usage) const {
     *usage = DUMMY_USAGE;
     return OK;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 35a6a18..492fb49 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -94,7 +94,7 @@
     static const int DUMMY_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
     static const android_dataspace DUMMY_DATASPACE = HAL_DATASPACE_UNKNOWN;
     static const camera3_stream_rotation_t DUMMY_ROTATION = CAMERA3_STREAM_ROTATION_0;
-    static const uint32_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER;
+    static const uint64_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER;
 
     /**
      * Internal Camera3Stream interface
@@ -107,7 +107,7 @@
 
     virtual status_t configureQueueLocked();
 
-    virtual status_t getEndpointUsage(uint32_t *usage) const;
+    virtual status_t getEndpointUsage(uint64_t *usage) const;
 
 }; // class Camera3DummyStream
 
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 7ad2300..a52422d 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -69,7 +69,7 @@
     (void) args;
     String8 lines;
 
-    uint32_t consumerUsage = 0;
+    uint64_t consumerUsage = 0;
     status_t res = getEndpointUsage(&consumerUsage);
     if (res != OK) consumerUsage = 0;
 
@@ -78,8 +78,8 @@
             camera3_stream::width, camera3_stream::height,
             camera3_stream::format, camera3_stream::data_space);
     lines.appendFormat("      Max size: %zu\n", mMaxSize);
-    lines.appendFormat("      Combined usage: %d, max HAL buffers: %d\n",
-            camera3_stream::usage | consumerUsage, camera3_stream::max_buffers);
+    lines.appendFormat("      Combined usage: %" PRIu64 ", max HAL buffers: %d\n",
+            mUsage | consumerUsage, camera3_stream::max_buffers);
     lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
     lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 35dda39..2376058 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -85,7 +85,7 @@
 
     virtual size_t   getHandoutInputBufferCountLocked();
 
-    virtual status_t getEndpointUsage(uint32_t *usage) const = 0;
+    virtual status_t getEndpointUsage(uint64_t *usage) const = 0;
 
     status_t getBufferPreconditionCheckLocked() const;
     status_t returnBufferPreconditionCheckLocked() const;
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index ff2dcef..2cb1ea7 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -258,7 +258,7 @@
             camera3_stream::max_buffers : minBufs;
         // TODO: somehow set the total buffer count when producer connects?
 
-        mConsumer = new BufferItemConsumer(consumer, camera3_stream::usage,
+        mConsumer = new BufferItemConsumer(consumer, mUsage,
                                            mTotalBufferCount);
         mConsumer->setName(String8::format("Camera3-InputStream-%d", mId));
 
@@ -284,7 +284,7 @@
     return OK;
 }
 
-status_t Camera3InputStream::getEndpointUsage(uint32_t *usage) const {
+status_t Camera3InputStream::getEndpointUsage(uint64_t *usage) const {
     // Per HAL3 spec, input streams have 0 for their initial usage field.
     *usage = 0;
     return OK;
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 8f5b431..81226f8 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -76,7 +76,7 @@
 
     virtual status_t configureQueueLocked();
 
-    virtual status_t getEndpointUsage(uint32_t *usage) const;
+    virtual status_t getEndpointUsage(uint64_t *usage) const;
 
     /**
      * BufferItemConsumer::BufferFreedListener interface
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index b02cd6a..dcaefe3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -90,7 +90,7 @@
 
 Camera3OutputStream::Camera3OutputStream(int id,
         uint32_t width, uint32_t height, int format,
-        uint32_t consumerUsage, android_dataspace dataSpace,
+        uint64_t consumerUsage, android_dataspace dataSpace,
         camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) :
         Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
                             /*maxSize*/0, format, dataSpace, rotation, setId),
@@ -111,7 +111,8 @@
     // Sanity check for the consumer usage flag.
     if ((consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) == 0 &&
             (consumerUsage & GraphicBuffer::USAGE_HW_COMPOSER) == 0) {
-        ALOGE("%s: Deferred consumer usage flag is illegal (0x%x)!", __FUNCTION__, consumerUsage);
+        ALOGE("%s: Deferred consumer usage flag is illegal %" PRIu64 "!",
+              __FUNCTION__, consumerUsage);
         mState = STATE_ERROR;
     }
 
@@ -127,7 +128,7 @@
                                          int format,
                                          android_dataspace dataSpace,
                                          camera3_stream_rotation_t rotation,
-                                         uint32_t consumerUsage, nsecs_t timestampOffset,
+                                         uint64_t consumerUsage, nsecs_t timestampOffset,
                                          int setId) :
         Camera3IOStreamBase(id, type, width, height,
                             /*maxSize*/0,
@@ -365,10 +366,10 @@
 
     mConsumerName = mConsumer->getConsumerName();
 
-    res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
+    res = native_window_set_usage(mConsumer.get(), mUsage);
     if (res != OK) {
-        ALOGE("%s: Unable to configure usage %08x for stream %d",
-                __FUNCTION__, camera3_stream::usage, mId);
+        ALOGE("%s: Unable to configure usage %" PRIu64 " for stream %d",
+                __FUNCTION__, mUsage, mId);
         return res;
     }
 
@@ -461,11 +462,11 @@
      * HAL3.2 devices may not support the dynamic buffer registeration.
      */
     if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) {
-        uint32_t consumerUsage = 0;
+        uint64_t consumerUsage = 0;
         getEndpointUsage(&consumerUsage);
         StreamInfo streamInfo(
                 getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(),
-                camera3_stream::usage | consumerUsage, mTotalBufferCount,
+                mUsage | consumerUsage, mTotalBufferCount,
                 /*isConfigured*/true);
         wp<Camera3OutputStream> weakThis(this);
         res = mBufferManager->registerStream(weakThis,
@@ -628,7 +629,7 @@
     return OK;
 }
 
-status_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) const {
+status_t Camera3OutputStream::getEndpointUsage(uint64_t *usage) const {
 
     status_t res;
 
@@ -643,14 +644,12 @@
     return res;
 }
 
-status_t Camera3OutputStream::getEndpointUsageForSurface(uint32_t *usage,
+status_t Camera3OutputStream::getEndpointUsageForSurface(uint64_t *usage,
         const sp<Surface>& surface) const {
     status_t res;
-    int32_t u = 0;
+    uint64_t u = 0;
 
-    res = static_cast<ANativeWindow*>(surface.get())->query(surface.get(),
-            NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u);
-
+    res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
     // If an opaque output stream's endpoint is ImageReader, add
     // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
     // for the ZSL use case.
@@ -670,7 +669,7 @@
 }
 
 bool Camera3OutputStream::isVideoStream() const {
-    uint32_t usage = 0;
+    uint64_t usage = 0;
     status_t res = getEndpointUsage(&usage);
     if (res != OK) {
         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
@@ -813,7 +812,7 @@
 }
 
 bool Camera3OutputStream::isConsumedByHWComposer() const {
-    uint32_t usage = 0;
+    uint64_t usage = 0;
     status_t res = getEndpointUsage(&usage);
     if (res != OK) {
         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
@@ -824,7 +823,7 @@
 }
 
 bool Camera3OutputStream::isConsumedByHWTexture() const {
-    uint32_t usage = 0;
+    uint64_t usage = 0;
     status_t res = getEndpointUsage(&usage);
     if (res != OK) {
         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 97aa7d4..7023d5d 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -44,7 +44,7 @@
     uint32_t height;
     uint32_t format;
     android_dataspace dataSpace;
-    uint32_t combinedUsage;
+    uint64_t combinedUsage;
     size_t totalBufferCount;
     bool isConfigured;
     explicit StreamInfo(int id = CAMERA3_STREAM_ID_INVALID,
@@ -53,7 +53,7 @@
             uint32_t h = 0,
             uint32_t fmt = 0,
             android_dataspace ds = HAL_DATASPACE_UNKNOWN,
-            uint32_t usage = 0,
+            uint64_t usage = 0,
             size_t bufferCount = 0,
             bool configured = false) :
                 streamId(id),
@@ -101,7 +101,7 @@
      * stream set id needs to be set to support buffer sharing between multiple streams.
      */
     Camera3OutputStream(int id, uint32_t width, uint32_t height, int format,
-            uint32_t consumerUsage, android_dataspace dataSpace,
+            uint64_t consumerUsage, android_dataspace dataSpace,
             camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -176,7 +176,7 @@
     Camera3OutputStream(int id, camera3_stream_type_t type,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation,
-            uint32_t consumerUsage = 0, nsecs_t timestampOffset = 0,
+            uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
     /**
@@ -191,14 +191,14 @@
 
     virtual status_t disconnectLocked();
 
-    status_t getEndpointUsageForSurface(uint32_t *usage,
+    status_t getEndpointUsageForSurface(uint64_t *usage,
             const sp<Surface>& surface) const;
     status_t configureConsumerQueueLocked();
 
     // Consumer as the output of camera HAL
     sp<Surface> mConsumer;
 
-    uint32_t getPresetConsumerUsage() const { return mConsumerUsage; }
+    uint64_t getPresetConsumerUsage() const { return mConsumerUsage; }
 
     static const nsecs_t       kDequeueBufferTimeout   = 1000000000; // 1 sec
 
@@ -245,7 +245,7 @@
      * Consumer end point usage flag set by the constructor for the deferred
      * consumer case.
      */
-    uint32_t    mConsumerUsage;
+    uint64_t    mConsumerUsage;
 
     /**
      * Internal Camera3Stream interface
@@ -262,7 +262,7 @@
 
     virtual status_t configureQueueLocked();
 
-    virtual status_t getEndpointUsage(uint32_t *usage) const;
+    virtual status_t getEndpointUsage(uint64_t *usage) const;
 
     /**
      * Private methods
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 2ae5660..5051711 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -23,7 +23,7 @@
 Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
         const std::vector<sp<Surface>>& surfaces,
         uint32_t width, uint32_t height, int format,
-        uint32_t consumerUsage, android_dataspace dataSpace,
+        uint64_t consumerUsage, android_dataspace dataSpace,
         camera3_stream_rotation_t rotation,
         nsecs_t timestampOffset, int setId) :
         Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
@@ -41,7 +41,7 @@
 
     mStreamSplitter = new Camera3StreamSplitter();
 
-    uint32_t usage;
+    uint64_t usage;
     getEndpointUsage(&usage);
 
     res = mStreamSplitter->connect(mSurfaces, usage, camera3_stream::max_buffers, &mConsumer);
@@ -191,10 +191,10 @@
     return res;
 }
 
-status_t Camera3SharedOutputStream::getEndpointUsage(uint32_t *usage) const {
+status_t Camera3SharedOutputStream::getEndpointUsage(uint64_t *usage) const {
 
     status_t res = OK;
-    uint32_t u = 0;
+    uint64_t u = 0;
 
     if (mConsumer == nullptr) {
         // Called before shared buffer queue is constructed.
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 7be0940..22bb2fc 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -34,7 +34,7 @@
      */
     Camera3SharedOutputStream(int id, const std::vector<sp<Surface>>& surfaces,
             uint32_t width, uint32_t height, int format,
-            uint32_t consumerUsage, android_dataspace dataSpace,
+            uint64_t consumerUsage, android_dataspace dataSpace,
             camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -74,7 +74,7 @@
 
     virtual status_t disconnectLocked();
 
-    virtual status_t getEndpointUsage(uint32_t *usage) const;
+    virtual status_t getEndpointUsage(uint64_t *usage) const;
 
 }; // class Camera3SharedOutputStream
 
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 9e6ac79..25e44a5 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -56,6 +56,7 @@
     mState(STATE_CONSTRUCTED),
     mStatusId(StatusTracker::NO_STATUS_ID),
     mStreamUnpreparable(true),
+    mUsage(0),
     mOldUsage(0),
     mOldMaxBuffers(0),
     mPrepared(false),
@@ -69,7 +70,6 @@
     camera3_stream::format = format;
     camera3_stream::data_space = dataSpace;
     camera3_stream::rotation = rotation;
-    camera3_stream::usage = 0;
     camera3_stream::max_buffers = 0;
     camera3_stream::priv = NULL;
 
@@ -104,6 +104,14 @@
     return camera3_stream::data_space;
 }
 
+uint64_t Camera3Stream::getUsage() const {
+    return mUsage;
+}
+
+void Camera3Stream::setUsage(uint64_t usage) {
+    mUsage = usage;
+}
+
 camera3_stream* Camera3Stream::startConfiguration() {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
@@ -133,10 +141,10 @@
             return NULL;
     }
 
-    mOldUsage = camera3_stream::usage;
+    mOldUsage = mUsage;
     mOldMaxBuffers = camera3_stream::max_buffers;
 
-    res = getEndpointUsage(&(camera3_stream::usage));
+    res = getEndpointUsage(&mUsage);
     if (res != OK) {
         ALOGE("%s: Cannot query consumer endpoint usage!",
                 __FUNCTION__);
@@ -197,7 +205,7 @@
     // Check if the stream configuration is unchanged, and skip reallocation if
     // so. As documented in hardware/camera3.h:configure_streams().
     if (mState == STATE_IN_RECONFIG &&
-            mOldUsage == camera3_stream::usage &&
+            mOldUsage == mUsage &&
             mOldMaxBuffers == camera3_stream::max_buffers) {
         mState = STATE_CONFIGURED;
         return OK;
@@ -243,7 +251,7 @@
             return INVALID_OPERATION;
     }
 
-    camera3_stream::usage = mOldUsage;
+    mUsage = mOldUsage;
     camera3_stream::max_buffers = mOldMaxBuffers;
 
     mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 44fe6b6..9090f83 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -144,6 +144,8 @@
     uint32_t          getHeight() const;
     int               getFormat() const;
     android_dataspace getDataSpace() const;
+    uint64_t          getUsage() const;
+    void              setUsage(uint64_t usage);
 
     camera3_stream*   asHalStream() override {
         return this;
@@ -459,7 +461,7 @@
 
     // Get the usage flags for the other endpoint, or return
     // INVALID_OPERATION if they cannot be obtained.
-    virtual status_t getEndpointUsage(uint32_t *usage) const = 0;
+    virtual status_t getEndpointUsage(uint64_t *usage) const = 0;
 
     // Return whether the buffer is in the list of outstanding buffers.
     bool isOutstandingBuffer(const camera3_stream_buffer& buffer) const;
@@ -473,8 +475,10 @@
     // prepareNextBuffer called on it.
     bool mStreamUnpreparable;
 
+    uint64_t mUsage;
+
   private:
-    uint32_t mOldUsage;
+    uint64_t mOldUsage;
     uint32_t mOldMaxBuffers;
     Condition mOutputBufferReturnedSignal;
     Condition mInputBufferReturnedSignal;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 869e93a..a0a50c2 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -39,7 +39,7 @@
 namespace android {
 
 status_t Camera3StreamSplitter::connect(const std::vector<sp<Surface> >& surfaces,
-        uint32_t consumerUsage, size_t halMaxBuffers, sp<Surface>* consumer) {
+        uint64_t consumerUsage, size_t halMaxBuffers, sp<Surface>* consumer) {
     ATRACE_CALL();
     if (consumer == nullptr) {
         SP_LOGE("%s: consumer pointer is NULL", __FUNCTION__);
@@ -195,10 +195,8 @@
 
     // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
     // We need skip these cases as timeout will disable the non-blocking (async) mode.
-    int32_t usage = 0;
-    static_cast<ANativeWindow*>(outputQueue.get())->query(
-            outputQueue.get(),
-            NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage);
+    uint64_t usage = 0;
+    res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(outputQueue.get()), &usage);
     if (!(usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE))) {
         outputQueue->setDequeueTimeout(kDequeueBufferTimeout);
     }
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index cc623e0..3b8839e 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -52,7 +52,7 @@
     // Connect to the stream splitter by creating buffer queue and connecting it
     // with output surfaces.
     status_t connect(const std::vector<sp<Surface> >& surfaces,
-            uint32_t consumerUsage, size_t halMaxBuffers,
+            uint64_t consumerUsage, size_t halMaxBuffers,
             sp<Surface>* consumer);
 
     // addOutput adds an output BufferQueue to the splitter. The splitter
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index 3d54460..ee018c3 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -38,7 +38,7 @@
 namespace android {
 
 RingBufferConsumer::RingBufferConsumer(const sp<IGraphicBufferConsumer>& consumer,
-        uint32_t consumerUsage,
+        uint64_t consumerUsage,
         int bufferCount) :
     ConsumerBase(consumer),
     mBufferCount(bufferCount),
@@ -368,7 +368,7 @@
     return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
-status_t RingBufferConsumer::setConsumerUsage(uint32_t usage) {
+status_t RingBufferConsumer::setConsumerUsage(uint64_t usage) {
     Mutex::Autolock _l(mMutex);
     return mConsumer->setConsumerUsageBits(usage);
 }
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h
index 2bafe4a..b737469 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.h
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h
@@ -60,7 +60,7 @@
     // the consumer usage flags passed to the graphics allocator. The
     // bufferCount parameter specifies how many buffers can be pinned for user
     // access at the same time.
-    RingBufferConsumer(const sp<IGraphicBufferConsumer>& consumer, uint32_t consumerUsage,
+    RingBufferConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
             int bufferCount);
 
     virtual ~RingBufferConsumer();
@@ -80,7 +80,7 @@
 
     // setConsumerUsage allows the BufferQueue consumer usage to be
     // set at a later time after construction.
-    status_t setConsumerUsage(uint32_t usage);
+    status_t setConsumerUsage(uint64_t usage);
 
     // Buffer info, minus the graphics buffer/slot itself.
     struct BufferInfo {
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index 876c685..f3bb35c 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -404,6 +404,8 @@
     } else {
         dumpRecent(result, ts_since, only);
     }
+    free((void*)only);
+    only=NULL;
 
 
     if (clear) {
diff --git a/services/mediacodec/MediaCodecService.h b/services/mediacodec/MediaCodecService.h
index d64debb..0d2c9d8 100644
--- a/services/mediacodec/MediaCodecService.h
+++ b/services/mediacodec/MediaCodecService.h
@@ -19,7 +19,7 @@
 
 #include <binder/BinderService.h>
 #include <media/IMediaCodecService.h>
-#include <include/OMX.h>
+#include <media/stagefright/omx/OMX.h>
 
 namespace android {
 
diff --git a/services/mediacodec/OWNERS b/services/mediacodec/OWNERS
new file mode 100644
index 0000000..c716cce
--- /dev/null
+++ b/services/mediacodec/OWNERS
@@ -0,0 +1,2 @@
+jeffv@google.com
+marcone@google.com
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index c59944a..79d6da5 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -32,8 +32,8 @@
 #include "minijail.h"
 
 #include <hidl/HidlTransportSupport.h>
-#include <omx/1.0/Omx.h>
-#include <omx/1.0/OmxStore.h>
+#include <media/stagefright/omx/1.0/Omx.h>
+#include <media/stagefright/omx/1.0/OmxStore.h>
 
 using namespace android;
 
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 6b30db6..2daa829 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -17,7 +17,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    MediaCasService.cpp \
     MediaDrmService.cpp \
     main_mediadrmserver.cpp
 
diff --git a/services/mediadrm/FactoryLoader.h b/services/mediadrm/FactoryLoader.h
deleted file mode 100644
index d7f1118..0000000
--- a/services/mediadrm/FactoryLoader.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_LOADER_H_
-#define MEDIA_CAS_LOADER_H_
-
-#include <dirent.h>
-#include <dlfcn.h>
-#include <media/SharedLibrary.h>
-#include <utils/KeyedVector.h>
-#include <utils/Mutex.h>
-
-namespace android {
-using namespace std;
-using namespace media;
-using namespace MediaCas;
-
-template <class T>
-class FactoryLoader {
-public:
-    FactoryLoader(const char *name) :
-        mFactory(NULL), mCreateFactoryFuncName(name) {}
-
-    virtual ~FactoryLoader() { closeFactory(); }
-
-    bool findFactoryForScheme(
-            int32_t CA_system_id,
-            sp<SharedLibrary> *library = NULL,
-            T** factory = NULL);
-
-    bool enumeratePlugins(vector<ParcelableCasPluginDescriptor>* results);
-
-private:
-    typedef T*(*CreateFactoryFunc)();
-
-    Mutex mMapLock;
-    T* mFactory;
-    const char *mCreateFactoryFuncName;
-    sp<SharedLibrary> mLibrary;
-    KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap;
-    KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
-
-    bool loadFactoryForSchemeFromPath(
-            const String8 &path,
-            int32_t CA_system_id,
-            sp<SharedLibrary> *library,
-            T** factory);
-
-    bool queryPluginsFromPath(
-            const String8 &path,
-            vector<ParcelableCasPluginDescriptor>* results);
-
-    bool openFactory(const String8 &path);
-    void closeFactory();
-};
-
-template <class T>
-bool FactoryLoader<T>::findFactoryForScheme(
-        int32_t CA_system_id, sp<SharedLibrary> *library, T** factory) {
-    if (library != NULL) {
-        library->clear();
-    }
-    if (factory != NULL) {
-        *factory = NULL;
-    }
-
-    Mutex::Autolock autoLock(mMapLock);
-
-    // first check cache
-    ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id);
-    if (index >= 0) {
-        return loadFactoryForSchemeFromPath(
-                mCASystemIdToLibraryPathMap[index],
-                CA_system_id, library, factory);
-    }
-
-    // no luck, have to search
-    String8 dirPath("/system/lib/mediacas");
-    DIR* pDir = opendir(dirPath.string());
-
-    if (pDir == NULL) {
-        ALOGE("Failed to open plugin directory %s", dirPath.string());
-        return false;
-    }
-
-    struct dirent* pEntry;
-    while ((pEntry = readdir(pDir))) {
-        String8 pluginPath = dirPath + "/" + pEntry->d_name;
-        if (pluginPath.getPathExtension() == ".so") {
-            if (loadFactoryForSchemeFromPath(
-                    pluginPath, CA_system_id, library, factory)) {
-                mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath);
-                closedir(pDir);
-
-                return true;
-            }
-        }
-    }
-
-    closedir(pDir);
-
-    ALOGE("Failed to find plugin");
-    return false;
-}
-
-template <class T>
-bool FactoryLoader<T>::enumeratePlugins(
-        vector<ParcelableCasPluginDescriptor>* results) {
-    ALOGI("enumeratePlugins");
-
-    results->clear();
-
-    String8 dirPath("/system/lib/mediacas");
-    DIR* pDir = opendir(dirPath.string());
-
-    if (pDir == NULL) {
-        ALOGE("Failed to open plugin directory %s", dirPath.string());
-        return false;
-    }
-
-    Mutex::Autolock autoLock(mMapLock);
-
-    struct dirent* pEntry;
-    while ((pEntry = readdir(pDir))) {
-        String8 pluginPath = dirPath + "/" + pEntry->d_name;
-        if (pluginPath.getPathExtension() == ".so") {
-            queryPluginsFromPath(pluginPath, results);
-        }
-    }
-    return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::loadFactoryForSchemeFromPath(
-        const String8 &path, int32_t CA_system_id,
-        sp<SharedLibrary> *library, T** factory) {
-    closeFactory();
-
-    if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) {
-        closeFactory();
-        return false;
-    }
-
-    if (library != NULL) {
-        *library = mLibrary;
-    }
-    if (factory != NULL) {
-        *factory = mFactory;
-    }
-    return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::queryPluginsFromPath(
-        const String8 &path, vector<ParcelableCasPluginDescriptor>* results) {
-    closeFactory();
-
-    vector<CasPluginDescriptor> descriptors;
-    if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) {
-        closeFactory();
-        return false;
-    }
-
-    for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
-        results->push_back(ParcelableCasPluginDescriptor(
-                it->CA_system_id, it->name));
-    }
-    return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::openFactory(const String8 &path) {
-    // get strong pointer to open shared library
-    ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
-    if (index >= 0) {
-        mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
-    } else {
-        index = mLibraryPathToOpenLibraryMap.add(path, NULL);
-    }
-
-    if (!mLibrary.get()) {
-        mLibrary = new SharedLibrary(path);
-        if (!*mLibrary) {
-            return false;
-        }
-
-        mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
-    }
-
-    CreateFactoryFunc createFactory =
-        (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName);
-    if (createFactory == NULL || (mFactory = createFactory()) == NULL) {
-        return false;
-    }
-    return true;
-}
-
-template <class T>
-void FactoryLoader<T>::closeFactory() {
-    delete mFactory;
-    mFactory = NULL;
-    mLibrary.clear();
-}
-
-} // namespace android
-
-#endif // MEDIA_CAS_LOADER_H_
diff --git a/services/mediadrm/MediaCasService.cpp b/services/mediadrm/MediaCasService.cpp
deleted file mode 100644
index c111283..0000000
--- a/services/mediadrm/MediaCasService.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCasService"
-
-#include <binder/IServiceManager.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/CasImpl.h>
-#include <media/DescramblerImpl.h>
-#include <utils/Log.h>
-#include <utils/List.h>
-#include "MediaCasService.h"
-#include <android/media/ICasListener.h>
-
-namespace android {
-
-//static
-void MediaCasService::instantiate() {
-    defaultServiceManager()->addService(
-            String16("media.cas"), new MediaCasService());
-}
-
-MediaCasService::MediaCasService() :
-    mCasLoader(new FactoryLoader<CasFactory>("createCasFactory")),
-    mDescramblerLoader(new FactoryLoader<DescramblerFactory>(
-            "createDescramblerFactory")) {
-}
-
-MediaCasService::~MediaCasService() {
-    delete mCasLoader;
-    delete mDescramblerLoader;
-}
-
-Status MediaCasService::enumeratePlugins(
-        vector<ParcelableCasPluginDescriptor>* results) {
-    ALOGV("enumeratePlugins");
-
-    mCasLoader->enumeratePlugins(results);
-
-    return Status::ok();
-}
-
-Status MediaCasService::isSystemIdSupported(
-        int32_t CA_system_id, bool* result) {
-    ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
-
-    *result = mCasLoader->findFactoryForScheme(CA_system_id);
-
-    return Status::ok();
-}
-
-Status MediaCasService::createPlugin(
-        int32_t CA_system_id,
-        const sp<ICasListener> &listener,
-        sp<ICas>* result) {
-    ALOGV("createPlugin: CA_system_id=%d", CA_system_id);
-
-    result->clear();
-
-    CasFactory *factory;
-    sp<SharedLibrary> library;
-    if (mCasLoader->findFactoryForScheme(CA_system_id, &library, &factory)) {
-        CasPlugin *plugin = NULL;
-        sp<CasImpl> casImpl = new CasImpl(listener);
-        if (factory->createPlugin(CA_system_id, (uint64_t)casImpl.get(),
-                &CasImpl::OnEvent, &plugin) == OK && plugin != NULL) {
-            casImpl->init(library, plugin);
-            *result = casImpl;
-        }
-    }
-
-    return Status::ok();
-}
-
-Status MediaCasService::isDescramblerSupported(
-        int32_t CA_system_id, bool* result) {
-    ALOGV("isDescramblerSupported: CA_system_id=%d", CA_system_id);
-
-    *result = mDescramblerLoader->findFactoryForScheme(CA_system_id);
-
-    return Status::ok();
-}
-
-Status MediaCasService::createDescrambler(
-        int32_t CA_system_id, sp<IDescrambler>* result) {
-    ALOGV("createDescrambler: CA_system_id=%d", CA_system_id);
-
-    result->clear();
-
-    DescramblerFactory *factory;
-    sp<SharedLibrary> library;
-    if (mDescramblerLoader->findFactoryForScheme(
-            CA_system_id, &library, &factory)) {
-        DescramblerPlugin *plugin = NULL;
-        if (factory->createPlugin(CA_system_id, &plugin) == OK
-                && plugin != NULL) {
-            *result = new DescramblerImpl(library, plugin);
-        }
-    }
-
-    return Status::ok();
-}
-
-} // namespace android
diff --git a/services/mediadrm/MediaCasService.h b/services/mediadrm/MediaCasService.h
deleted file mode 100644
index cb828f2..0000000
--- a/services/mediadrm/MediaCasService.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MEDIA_CAS_SERVICE_H_
-#define MEDIA_CAS_SERVICE_H_
-
-#include <android/media/BnMediaCasService.h>
-
-#include "FactoryLoader.h"
-
-namespace android {
-using binder::Status;
-struct CasFactory;
-struct DescramblerFactory;
-
-class MediaCasService : public BnMediaCasService {
-public:
-    static void instantiate();
-
-    virtual Status enumeratePlugins(
-            vector<ParcelableCasPluginDescriptor>* results) override;
-
-    virtual Status isSystemIdSupported(
-            int32_t CA_system_id, bool* result) override;
-
-    virtual Status createPlugin(
-            int32_t CA_system_id,
-            const sp<ICasListener> &listener,
-            sp<ICas>* result) override;
-
-    virtual Status isDescramblerSupported(
-            int32_t CA_system_id, bool* result) override;
-
-    virtual Status createDescrambler(
-            int32_t CA_system_id, sp<IDescrambler>* result) override;
-
-private:
-    FactoryLoader<CasFactory> *mCasLoader;
-    FactoryLoader<DescramblerFactory> *mDescramblerLoader;
-
-    MediaCasService();
-    virtual ~MediaCasService();
-};
-
-} // namespace android
-
-#endif // MEDIA_CAS_SERVICE_H_
diff --git a/services/mediadrm/OWNERS b/services/mediadrm/OWNERS
new file mode 100644
index 0000000..6d3b533
--- /dev/null
+++ b/services/mediadrm/OWNERS
@@ -0,0 +1,2 @@
+jtinker@google.com
+marcone@google.com
diff --git a/services/mediadrm/main_mediadrmserver.cpp b/services/mediadrm/main_mediadrmserver.cpp
index b685ae0..b767b8c 100644
--- a/services/mediadrm/main_mediadrmserver.cpp
+++ b/services/mediadrm/main_mediadrmserver.cpp
@@ -27,7 +27,6 @@
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include "MediaDrmService.h"
-#include "MediaCasService.h"
 
 using namespace android;
 
@@ -39,7 +38,6 @@
     sp<IServiceManager> sm = defaultServiceManager();
     ALOGI("ServiceManager: %p", sm.get());
     MediaDrmService::instantiate();
-    MediaCasService::instantiate();
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
 }
diff --git a/services/mediaextractor/OWNERS b/services/mediaextractor/OWNERS
new file mode 100644
index 0000000..c716cce
--- /dev/null
+++ b/services/mediaextractor/OWNERS
@@ -0,0 +1,2 @@
+jeffv@google.com
+marcone@google.com
diff --git a/services/medialog/OWNERS b/services/medialog/OWNERS
new file mode 100644
index 0000000..fb8b8ee
--- /dev/null
+++ b/services/medialog/OWNERS
@@ -0,0 +1,3 @@
+elaurent@google.com
+gkasten@android.com
+hunga@google.com
diff --git a/services/mediaresourcemanager/OWNERS b/services/mediaresourcemanager/OWNERS
new file mode 100644
index 0000000..82abf8f
--- /dev/null
+++ b/services/mediaresourcemanager/OWNERS
@@ -0,0 +1 @@
+dwkang@google.com
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 0f863fe..81f1d1b 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -64,8 +64,9 @@
     }
 
     result << "    Registered Streams:" << "\n";
+    result << AAudioServiceStreamShared::dumpHeader() << "\n";
     for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
-        result << sharedStream->dump();
+        result << sharedStream->dump() << "\n";
     }
 
     if (isLocked) {
@@ -177,7 +178,10 @@
             configuration.getSamplesPerFrame() != mStreamInternal->getSamplesPerFrame()) {
         return false;
     }
-
     return true;
 }
 
+
+aaudio_result_t AAudioServiceEndpoint::getTimestamp(int64_t *positionFrames, int64_t *timeNanos) {
+    return mStreamInternal->getTimestamp(CLOCK_MONOTONIC, positionFrames, timeNanos);
+}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index e40a670..603d497 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -69,6 +69,8 @@
         mReferenceCount = count;
     }
 
+    aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos);
+
     bool matches(const AAudioStreamConfiguration& configuration);
 
     virtual AudioStreamInternal *getStreamInternal() = 0;
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 6a37330..6504cc1 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -62,6 +62,9 @@
 
     // result might be a frame count
     while (mCallbackEnabled.load() && getStreamInternal()->isActive() && (result >= 0)) {
+
+        int64_t mmapFramesRead = getStreamInternal()->getFramesRead();
+
         // Read audio data from stream using a blocking read.
         result = getStreamInternal()->read(mDistributionBuffer, getFramesPerBurst(), timeoutNanos);
         if (result == AAUDIO_ERROR_DISCONNECTED) {
@@ -74,18 +77,32 @@
         }
 
         // Distribute data to each active stream.
-        { // use lock guard
+        { // brackets are for lock_guard
+
             std::lock_guard <std::mutex> lock(mLockStreams);
-            for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
-                if (sharedStream->isRunning()) {
-                    FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
+            for (sp<AAudioServiceStreamShared> clientStream : mRegisteredStreams) {
+                if (clientStream->isRunning()) {
+                    FifoBuffer *fifo = clientStream->getDataFifoBuffer();
+
+                    // Determine offset between framePosition in client's stream vs the underlying
+                    // MMAP stream.
+                    int64_t clientFramesWritten = fifo->getWriteCounter();
+                    // There are two indices that refer to the same frame.
+                    int64_t positionOffset = mmapFramesRead - clientFramesWritten;
+                    clientStream->setTimestampPositionOffset(positionOffset);
+
                     if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
                         getFramesPerBurst()) {
                         underflowCount++;
                     } else {
                         fifo->write(mDistributionBuffer, getFramesPerBurst());
                     }
-                    sharedStream->markTransferTime(AudioClock::getNanoseconds());
+
+                    // This timestamp represents the completion of data being written into the
+                    // client buffer. It is sent to the client and used in the timing model
+                    // to decide when data will be available to read.
+                    Timestamp timestamp(fifo->getWriteCounter(), AudioClock::getNanoseconds());
+                    clientStream->markTransferTime(timestamp);
                 }
             }
         }
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index b83b918..8b1cc9f 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -65,7 +65,6 @@
 
 // Mix data from each application stream and write result to the shared MMAP stream.
 void *AAudioServiceEndpointPlay::callbackLoop() {
-    int32_t underflowCount = 0;
     aaudio_result_t result = AAUDIO_OK;
     int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();
 
@@ -73,17 +72,33 @@
     while (mCallbackEnabled.load() && getStreamInternal()->isActive() && (result >= 0)) {
         // Mix data from each active stream.
         mMixer.clear();
-        { // use lock guard
+        { // brackets are for lock_guard
             int index = 0;
+            int64_t mmapFramesWritten = getStreamInternal()->getFramesWritten();
+
             std::lock_guard <std::mutex> lock(mLockStreams);
-            for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
-                if (sharedStream->isRunning()) {
-                    FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
+            for (sp<AAudioServiceStreamShared> clientStream : mRegisteredStreams) {
+                if (clientStream->isRunning()) {
+                    FifoBuffer *fifo = clientStream->getDataFifoBuffer();
+                    // Determine offset between framePosition in client's stream vs the underlying
+                    // MMAP stream.
+                    int64_t clientFramesRead = fifo->getReadCounter();
+                    // These two indices refer to the same frame.
+                    int64_t positionOffset = mmapFramesWritten - clientFramesRead;
+                    clientStream->setTimestampPositionOffset(positionOffset);
+
                     float volume = 1.0; // to match legacy volume
                     bool underflowed = mMixer.mix(index, fifo, volume);
-                    underflowCount += underflowed ? 1 : 0;
-                    // TODO log underflows in each stream
-                    sharedStream->markTransferTime(AudioClock::getNanoseconds());
+
+                    // This timestamp represents the completion of data being read out of the
+                    // client buffer. It is sent to the client and used in the timing model
+                    // to decide when the client has room to write more data.
+                    Timestamp timestamp(fifo->getReadCounter(), AudioClock::getNanoseconds());
+                    clientStream->markTransferTime(timestamp);
+
+                    if (underflowed) {
+                        clientStream->incrementXRunCount();
+                    }
                 }
                 index++;
             }
@@ -102,8 +117,5 @@
         }
     }
 
-    ALOGW_IF((underflowCount > 0),
-             "AAudioServiceEndpointPlay(): callbackLoop() had %d underflows", underflowCount);
-
     return NULL; // TODO review
 }
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 5f7d179..e5f916c 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <iomanip>
+#include <iostream>
 #include <mutex>
 
 #include "binding/IAAudioService.h"
@@ -37,7 +39,8 @@
 
 AAudioServiceStreamBase::AAudioServiceStreamBase()
         : mUpMessageQueue(nullptr)
-        , mAAudioThread() {
+        , mAAudioThread()
+        , mAtomicTimestamp() {
     mMmapClient.clientUid = -1;
     mMmapClient.clientPid = -1;
     mMmapClient.packageName = String16("");
@@ -53,16 +56,22 @@
                         "service stream still open, state = %d", mState);
 }
 
+std::string AAudioServiceStreamBase::dumpHeader() {
+    return std::string("    T   Handle   UId Run State Format Burst Chan Capacity");
+}
+
 std::string AAudioServiceStreamBase::dump() const {
     std::stringstream result;
 
-    result << "      -------- handle = 0x" << std::hex << mHandle << std::dec << "\n";
-    result << "      state          = " << AAudio_convertStreamStateToText(mState) << "\n";
-    result << "      format         = " << mAudioFormat << "\n";
-    result << "      framesPerBurst = " << mFramesPerBurst << "\n";
-    result << "      channelCount   = " << mSamplesPerFrame << "\n";
-    result << "      capacityFrames = " << mCapacityInFrames << "\n";
-    result << "      owner uid      = " << mMmapClient.clientUid << "\n";
+    result << "    0x" << std::setfill('0') << std::setw(8) << std::hex << mHandle
+           << std::dec << std::setfill(' ') ;
+    result << std::setw(6) << mMmapClient.clientUid;
+    result << std::setw(4) << (isRunning() ? "yes" : " no");
+    result << std::setw(6) << mState;
+    result << std::setw(7) << mAudioFormat;
+    result << std::setw(6) << mFramesPerBurst;
+    result << std::setw(5) << mSamplesPerFrame;
+    result << std::setw(9) << mCapacityInFrames;
 
     return result.str();
 }
@@ -211,15 +220,25 @@
 
 aaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() {
     AAudioServiceMessage command;
+    // Send a timestamp for the clock model.
     aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
                                                     &command.timestamp.timestamp);
     if (result == AAUDIO_OK) {
-    //    ALOGD("sendCurrentTimestamp(): position = %lld, nanos = %lld",
-    //          (long long) command.timestamp.position,
-    //          (long long) command.timestamp.timestamp);
-        command.what = AAudioServiceMessage::code::TIMESTAMP;
+        command.what = AAudioServiceMessage::code::TIMESTAMP_SERVICE;
         result = writeUpMessageQueue(&command);
-    } else if (result == AAUDIO_ERROR_UNAVAILABLE) {
+
+        if (result == AAUDIO_OK) {
+            // Send a hardware timestamp for presentation time.
+            result = getHardwareTimestamp(&command.timestamp.position,
+                                          &command.timestamp.timestamp);
+            if (result == AAUDIO_OK) {
+                command.what = AAudioServiceMessage::code::TIMESTAMP_HARDWARE;
+                result = writeUpMessageQueue(&command);
+            }
+        }
+    }
+
+    if (result == AAUDIO_ERROR_UNAVAILABLE) {
         result = AAUDIO_OK; // just not available yet, try again later
     }
     return result;
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index cebefec..2f94614 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <mutex>
 
+#include <media/AudioClient.h>
 #include <utils/RefBase.h>
 
 #include "fifo/FifoBuffer.h"
@@ -27,7 +28,7 @@
 #include "binding/AudioEndpointParcelable.h"
 #include "binding/AAudioServiceMessage.h"
 #include "utility/AAudioUtilities.h"
-#include <media/AudioClient.h>
+#include "utility/AudioClock.h"
 
 #include "SharedRingBuffer.h"
 #include "AAudioThread.h"
@@ -53,7 +54,10 @@
         ILLEGAL_THREAD_ID = 0
     };
 
-    std::string dump() const;
+    static std::string dumpHeader();
+
+    // does not include EOL
+    virtual std::string dump() const;
 
     // -------------------------------------------------------------------
     /**
@@ -170,6 +174,8 @@
      */
     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
+    virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0;
+
     virtual aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) = 0;
 
     aaudio_stream_state_t   mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
@@ -191,6 +197,8 @@
     android::AudioClient    mMmapClient;
     audio_port_handle_t     mClientHandle = AUDIO_PORT_HANDLE_NONE;
 
+    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
+
 private:
     aaudio_handle_t         mHandle = -1;
 };
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 08dd680..68dcaff 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -38,6 +38,11 @@
 #define AAUDIO_BUFFER_CAPACITY_MIN    4 * 512
 #define AAUDIO_SAMPLE_RATE_DEFAULT    48000
 
+// This is an estimate of the time difference between the HW and the MMAP time.
+// TODO Get presentation timestamps from the HAL instead of using these estimates.
+#define OUTPUT_ESTIMATED_HARDWARE_OFFSET_NANOS  (3 * AAUDIO_NANOS_PER_MILLISECOND)
+#define INPUT_ESTIMATED_HARDWARE_OFFSET_NANOS   (-1 * AAUDIO_NANOS_PER_MILLISECOND)
+
 /**
  * Service Stream that uses an MMAP buffer.
  */
@@ -109,10 +114,14 @@
         config.channel_mask = (aaudioSamplesPerFrame == AAUDIO_UNSPECIFIED)
                             ? AUDIO_CHANNEL_OUT_STEREO
                             : audio_channel_out_mask_from_count(aaudioSamplesPerFrame);
+        mHardwareTimeOffsetNanos = OUTPUT_ESTIMATED_HARDWARE_OFFSET_NANOS; // frames at DAC later
+
     } else if (direction == AAUDIO_DIRECTION_INPUT) {
         config.channel_mask =  (aaudioSamplesPerFrame == AAUDIO_UNSPECIFIED)
                             ? AUDIO_CHANNEL_IN_STEREO
                             : audio_channel_in_mask_from_count(aaudioSamplesPerFrame);
+        mHardwareTimeOffsetNanos = INPUT_ESTIMATED_HARDWARE_OFFSET_NANOS; // frames at ADC earlier
+
     } else {
         ALOGE("openMmapStream - invalid direction = %d", direction);
         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
@@ -291,6 +300,7 @@
     return AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
 }
 
+// Get free-running DSP or DMA hardware position from the HAL.
 aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
                                                                 int64_t *timeNanos) {
     struct audio_mmap_position position;
@@ -307,12 +317,29 @@
         disconnect();
     } else {
         mFramesRead.update32(position.position_frames);
-        *positionFrames = mFramesRead.get();
-        *timeNanos = position.time_nanoseconds;
+
+        Timestamp timestamp(mFramesRead.get(), position.time_nanoseconds);
+        mAtomicTimestamp.write(timestamp);
+        *positionFrames = timestamp.getPosition();
+        *timeNanos = timestamp.getNanoseconds();
     }
     return result;
 }
 
+// Get timestamp that was written by getFreeRunningPosition()
+aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
+                                                                int64_t *timeNanos) {
+    // TODO Get presentation timestamp from the HAL
+    if (mAtomicTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicTimestamp.read();
+        *positionFrames = timestamp.getPosition();
+        *timeNanos = timestamp.getNanoseconds() + mHardwareTimeOffsetNanos;
+        return AAUDIO_OK;
+    } else {
+        return AAUDIO_ERROR_UNAVAILABLE;
+    }
+}
+
 void AAudioServiceStreamMMAP::onTearDown() {
     ALOGD("AAudioServiceStreamMMAP::onTearDown() called");
     disconnect();
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index b69dc46..e631fd3 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -102,6 +102,8 @@
     aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) override;
 
     aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override;
+    virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames,
+                                                 int64_t *timeNanos) override;
 
 private:
     // This proxy class was needed to prevent a crash in AudioFlinger
@@ -133,6 +135,8 @@
     MonotonicCounter                    mFramesWritten;
     MonotonicCounter                    mFramesRead;
     int32_t                             mPreviousFrameCounter = 0;   // from HAL
+    int64_t                             mHardwareTimeOffsetNanos = 0; // TODO get from HAL
+
 
     // Interface to the AudioFlinger MMAP support.
     android::sp<android::MmapStreamInterface> mMmapStream;
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 5654113..57990ce 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <iomanip>
+#include <iostream>
 #include <mutex>
 
 #include <aaudio/AAudio.h>
@@ -41,9 +43,33 @@
 
 AAudioServiceStreamShared::AAudioServiceStreamShared(AAudioService &audioService)
     : mAudioService(audioService)
+    , mTimestampPositionOffset(0)
+    , mXRunCount(0)
     {
 }
 
+std::string AAudioServiceStreamShared::dumpHeader() {
+    std::stringstream result;
+    result << AAudioServiceStreamBase::dumpHeader();
+    result << "    Write#     Read#   Avail   XRuns";
+    return result.str();
+}
+
+std::string AAudioServiceStreamShared::dump() const {
+    std::stringstream result;
+    result << AAudioServiceStreamBase::dump();
+
+    auto fifo = mAudioDataQueue->getFifoBuffer();
+    int32_t readCounter = fifo->getReadCounter();
+    int32_t writeCounter = fifo->getWriteCounter();
+    result << std::setw(10) << writeCounter;
+    result << std::setw(10) << readCounter;
+    result << std::setw(8) << (writeCounter - readCounter);
+    result << std::setw(8) << getXRunCount();
+
+    return result.str();
+}
+
 int32_t AAudioServiceStreamShared::calculateBufferCapacity(int32_t requestedCapacityFrames,
                                                            int32_t framesPerBurst) {
 
@@ -105,7 +131,7 @@
     aaudio_direction_t direction = request.getDirection();
 
     AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
-    mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, configurationOutput, direction);
+    mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, configurationInput, direction);
     if (mServiceEndpoint == nullptr) {
         ALOGE("AAudioServiceStreamShared::open() mServiceEndPoint = %p", mServiceEndpoint);
         return AAUDIO_ERROR_UNAVAILABLE;
@@ -196,6 +222,7 @@
     }
     AAudioServiceEndpoint *endpoint = mServiceEndpoint;
     if (endpoint == nullptr) {
+        ALOGE("AAudioServiceStreamShared::start() missing endpoint");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     // For output streams, this will add the stream to the mixer.
@@ -223,6 +250,7 @@
     }
     AAudioServiceEndpoint *endpoint = mServiceEndpoint;
     if (endpoint == nullptr) {
+        ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     endpoint->getStreamInternal()->stopClient(mClientHandle);
@@ -240,6 +268,7 @@
     }
     AAudioServiceEndpoint *endpoint = mServiceEndpoint;
     if (endpoint == nullptr) {
+        ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     endpoint->getStreamInternal()->stopClient(mClientHandle);
@@ -259,6 +288,7 @@
 aaudio_result_t AAudioServiceStreamShared::flush()  {
     AAudioServiceEndpoint *endpoint = mServiceEndpoint;
     if (endpoint == nullptr) {
+        ALOGE("AAudioServiceStreamShared::flush() missing endpoint");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     if (mState != AAUDIO_STREAM_STATE_PAUSED) {
@@ -307,15 +337,30 @@
     return AAUDIO_OK;
 }
 
-void AAudioServiceStreamShared::markTransferTime(int64_t nanoseconds) {
-    mMarkedPosition = mAudioDataQueue->getFifoBuffer()->getReadCounter();
-    mMarkedTime = nanoseconds;
+void AAudioServiceStreamShared::markTransferTime(Timestamp &timestamp) {
+    mAtomicTimestamp.write(timestamp);
 }
 
+// Get timestamp that was written by the real-time service thread, eg. mixer.
 aaudio_result_t AAudioServiceStreamShared::getFreeRunningPosition(int64_t *positionFrames,
                                                                 int64_t *timeNanos) {
-    // TODO get these two numbers as an atomic pair
-    *positionFrames = mMarkedPosition;
-    *timeNanos = mMarkedTime;
-    return AAUDIO_OK;
+    if (mAtomicTimestamp.isValid()) {
+        Timestamp timestamp = mAtomicTimestamp.read();
+        *positionFrames = timestamp.getPosition();
+        *timeNanos = timestamp.getNanoseconds();
+        return AAUDIO_OK;
+    } else {
+        return AAUDIO_ERROR_UNAVAILABLE;
+    }
+}
+
+// Get timestamp from lower level service.
+aaudio_result_t AAudioServiceStreamShared::getHardwareTimestamp(int64_t *positionFrames,
+                                                              int64_t *timeNanos) {
+
+    aaudio_result_t result = mServiceEndpoint->getTimestamp(positionFrames, timeNanos);
+    if (result == AAUDIO_OK) {
+        *positionFrames -= mTimestampPositionOffset.load(); // Offset from shared MMAP stream
+    }
+    return result;
 }
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 6b67337..36a56b8 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -46,6 +46,10 @@
     AAudioServiceStreamShared(android::AAudioService &aAudioService);
     virtual ~AAudioServiceStreamShared() = default;
 
+    static std::string dumpHeader();
+
+    std::string dump() const override;
+
     aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
                          aaudio::AAudioStreamConfiguration &configurationOutput) override;
 
@@ -85,7 +89,19 @@
     /* Keep a record of when a buffer transfer completed.
      * This allows for a more accurate timing model.
      */
-    void markTransferTime(int64_t nanoseconds);
+    void markTransferTime(Timestamp &timestamp);
+
+    void setTimestampPositionOffset(int64_t deltaFrames) {
+        mTimestampPositionOffset.store(deltaFrames);
+    }
+
+    void incrementXRunCount() {
+        mXRunCount++;
+    }
+
+    int32_t getXRunCount() const {
+        return mXRunCount.load();
+    }
 
 protected:
 
@@ -93,6 +109,9 @@
 
     aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override;
 
+    virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames,
+                                                 int64_t *timeNanos) override;
+
     /**
      * @param requestedCapacityFrames
      * @param framesPerBurst
@@ -106,8 +125,8 @@
     AAudioServiceEndpoint   *mServiceEndpoint = nullptr;
     SharedRingBuffer        *mAudioDataQueue = nullptr;
 
-    int64_t                  mMarkedPosition = 0;
-    int64_t                  mMarkedTime = 0;
+    std::atomic<int64_t>     mTimestampPositionOffset;
+    std::atomic<int32_t>     mXRunCount;
 };
 
 } /* namespace aaudio */
diff --git a/services/oboeservice/AAudioThread.cpp b/services/oboeservice/AAudioThread.cpp
index ebb50f8..c6fb57d 100644
--- a/services/oboeservice/AAudioThread.cpp
+++ b/services/oboeservice/AAudioThread.cpp
@@ -53,7 +53,7 @@
 
 aaudio_result_t AAudioThread::start(Runnable *runnable) {
     if (mHasThread) {
-        ALOGE("AAudioThread::start() - mHasThread.load() already true");
+        ALOGE("AAudioThread::start() - mHasThread already true");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     // mRunnable will be read by the new thread when it starts.
@@ -71,6 +71,7 @@
 
 aaudio_result_t AAudioThread::stop() {
     if (!mHasThread) {
+        ALOGE("AAudioThread::stop() but no thread running");
         return AAUDIO_ERROR_INVALID_STATE;
     }
     int err = pthread_join(mThread, nullptr);
diff --git a/services/oboeservice/OWNERS b/services/oboeservice/OWNERS
new file mode 100644
index 0000000..f4d51f9
--- /dev/null
+++ b/services/oboeservice/OWNERS
@@ -0,0 +1 @@
+philburk@google.com
diff --git a/services/oboeservice/SharedMemoryProxy.cpp b/services/oboeservice/SharedMemoryProxy.cpp
index fc4532c..c31557e 100644
--- a/services/oboeservice/SharedMemoryProxy.cpp
+++ b/services/oboeservice/SharedMemoryProxy.cpp
@@ -16,12 +16,11 @@
 
 #define LOG_TAG "AAudioService"
 //#define LOG_NDEBUG 0
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include <aaudio/AAudio.h>
 #include "SharedMemoryProxy.h"
 
-using namespace android;
 using namespace aaudio;
 
 SharedMemoryProxy::~SharedMemoryProxy()
diff --git a/services/radio/Android.mk b/services/radio/Android.mk
deleted file mode 100644
index 1b50dc3..0000000
--- a/services/radio/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-
-LOCAL_SRC_FILES:= \
-    RadioService.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
-    liblog \
-    libutils \
-    libbinder \
-    libcutils \
-    libaudioclient \
-    libhardware \
-    libradio \
-    libradio_metadata
-
-ifeq ($(USE_LEGACY_LOCAL_AUDIO_HAL),true)
-# libhardware configuration
-LOCAL_SRC_FILES +=               \
-    RadioHalLegacy.cpp
-else
-# Treble configuration
-
-LOCAL_SRC_FILES += \
-    HidlUtils.cpp \
-    RadioHalHidl.cpp
-
-LOCAL_SHARED_LIBRARIES += \
-    libhwbinder \
-    libhidlbase \
-    libhidltransport \
-    libbase \
-    libaudiohal \
-    android.hardware.broadcastradio@1.0
-endif
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libradioservice
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/radio/HidlUtils.cpp b/services/radio/HidlUtils.cpp
deleted file mode 100644
index 6895377..0000000
--- a/services/radio/HidlUtils.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 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 "HidlUtils"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <system/radio_metadata.h>
-
-#include "HidlUtils.h"
-
-namespace android {
-
-using android::hardware::broadcastradio::V1_0::MetadataType;
-using android::hardware::broadcastradio::V1_0::Band;
-using android::hardware::broadcastradio::V1_0::Deemphasis;
-using android::hardware::broadcastradio::V1_0::Rds;
-
-//static
-int HidlUtils::convertHalResult(Result result)
-{
-    switch (result) {
-        case Result::OK:
-            return 0;
-        case Result::INVALID_ARGUMENTS:
-            return -EINVAL;
-        case Result::INVALID_STATE:
-            return -ENOSYS;
-        case Result::TIMEOUT:
-            return -ETIMEDOUT;
-        case Result::NOT_INITIALIZED:
-        default:
-            return -ENODEV;
-    }
-}
-
-
-//static
-void HidlUtils::convertBandConfigToHal(BandConfig *halConfig,
-                                       const radio_hal_band_config_t *config)
-{
-    halConfig->type = static_cast<Band>(config->type);
-    halConfig->antennaConnected = config->antenna_connected;
-    halConfig->lowerLimit = config->lower_limit;
-    halConfig->upperLimit = config->upper_limit;
-    halConfig->spacings.setToExternal(const_cast<unsigned int *>(&config->spacings[0]),
-                                       config->num_spacings * sizeof(uint32_t));
-    // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
-    halConfig->spacings.resize(config->num_spacings);
-
-    if (halConfig->type == Band::FM) {
-        halConfig->ext.fm.deemphasis = static_cast<Deemphasis>(config->fm.deemphasis);
-        halConfig->ext.fm.stereo = config->fm.stereo;
-        halConfig->ext.fm.rds = static_cast<Rds>(config->fm.rds);
-        halConfig->ext.fm.ta = config->fm.ta;
-        halConfig->ext.fm.af = config->fm.af;
-        halConfig->ext.fm.ea = config->fm.ea;
-    } else {
-        halConfig->ext.am.stereo = config->am.stereo;
-    }
-}
-
-//static
-void HidlUtils::convertPropertiesFromHal(radio_hal_properties_t *properties,
-                                         const Properties *halProperties)
-{
-    properties->class_id = static_cast<radio_class_t>(halProperties->classId);
-    strlcpy(properties->implementor, halProperties->implementor.c_str(), RADIO_STRING_LEN_MAX);
-    strlcpy(properties->product, halProperties->product.c_str(), RADIO_STRING_LEN_MAX);
-    strlcpy(properties->version, halProperties->version.c_str(), RADIO_STRING_LEN_MAX);
-    strlcpy(properties->serial, halProperties->serial.c_str(), RADIO_STRING_LEN_MAX);
-    properties->num_tuners = halProperties->numTuners;
-    properties->num_audio_sources = halProperties->numAudioSources;
-    properties->supports_capture = halProperties->supportsCapture;
-    properties->num_bands = halProperties->bands.size();
-
-    for (size_t i = 0; i < halProperties->bands.size(); i++) {
-        convertBandConfigFromHal(&properties->bands[i], &halProperties->bands[i]);
-    }
-}
-
-//static
-void HidlUtils::convertBandConfigFromHal(radio_hal_band_config_t *config,
-                                         const BandConfig *halConfig)
-{
-    config->type = static_cast<radio_band_t>(halConfig->type);
-    config->antenna_connected = halConfig->antennaConnected;
-    config->lower_limit = halConfig->lowerLimit;
-    config->upper_limit = halConfig->upperLimit;
-    config->num_spacings = halConfig->spacings.size();
-    if (config->num_spacings > RADIO_NUM_SPACINGS_MAX) {
-        config->num_spacings = RADIO_NUM_SPACINGS_MAX;
-    }
-    memcpy(config->spacings, halConfig->spacings.data(),
-           sizeof(uint32_t) * config->num_spacings);
-
-    if (halConfig->type == Band::FM) {
-        config->fm.deemphasis = static_cast<radio_deemphasis_t>(halConfig->ext.fm.deemphasis);
-        config->fm.stereo = halConfig->ext.fm.stereo;
-        config->fm.rds = static_cast<radio_rds_t>(halConfig->ext.fm.rds);
-        config->fm.ta = halConfig->ext.fm.ta;
-        config->fm.af = halConfig->ext.fm.af;
-        config->fm.ea = halConfig->ext.fm.ea;
-    } else {
-        config->am.stereo = halConfig->ext.am.stereo;
-    }
-}
-
-
-//static
-void HidlUtils::convertProgramInfoFromHal(radio_program_info_t *info,
-                                          const ProgramInfo *halInfo)
-{
-    info->channel = halInfo->channel;
-    info->sub_channel = halInfo->subChannel;
-    info->tuned = halInfo->tuned;
-    info->stereo = halInfo->stereo;
-    info->digital = halInfo->digital;
-    info->signal_strength = halInfo->signalStrength;
-    convertMetaDataFromHal(&info->metadata, halInfo->metadata,
-                           halInfo->channel, halInfo->subChannel);
-}
-
-// TODO(twasilczyk): drop unnecessary channel info
-//static
-void HidlUtils::convertMetaDataFromHal(radio_metadata_t **metadata,
-                                       const hidl_vec<MetaData>& halMetadata,
-                                       uint32_t channel __unused,
-                                       uint32_t subChannel __unused)
-{
-
-    if (metadata == nullptr || *metadata == nullptr) {
-        ALOGE("destination metadata buffer is a nullptr");
-        return;
-    }
-    for (size_t i = 0; i < halMetadata.size(); i++) {
-        radio_metadata_key_t key = static_cast<radio_metadata_key_t>(halMetadata[i].key);
-        radio_metadata_type_t type = static_cast<radio_metadata_key_t>(halMetadata[i].type);
-        radio_metadata_clock_t clock;
-
-        switch (type) {
-        case RADIO_METADATA_TYPE_INT:
-            radio_metadata_add_int(metadata, key, halMetadata[i].intValue);
-            break;
-        case RADIO_METADATA_TYPE_TEXT:
-            radio_metadata_add_text(metadata, key, halMetadata[i].stringValue.c_str());
-            break;
-        case RADIO_METADATA_TYPE_RAW:
-            radio_metadata_add_raw(metadata, key,
-                                   halMetadata[i].rawValue.data(),
-                                   halMetadata[i].rawValue.size());
-            break;
-        case RADIO_METADATA_TYPE_CLOCK:
-            clock.utc_seconds_since_epoch =
-                    halMetadata[i].clockValue.utcSecondsSinceEpoch;
-            clock.timezone_offset_in_minutes =
-                    halMetadata[i].clockValue.timezoneOffsetInMinutes;
-            radio_metadata_add_clock(metadata, key, &clock);
-            break;
-        default:
-            ALOGW("%s invalid metadata type %u",__FUNCTION__, halMetadata[i].type);
-            break;
-        }
-    }
-}
-
-}  // namespace android
diff --git a/services/radio/HidlUtils.h b/services/radio/HidlUtils.h
deleted file mode 100644
index c771060..0000000
--- a/services/radio/HidlUtils.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
-#define ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
-
-#include <android/hardware/broadcastradio/1.0/types.h>
-#include <hardware/radio.h>
-
-namespace android {
-
-using android::hardware::hidl_vec;
-using android::hardware::broadcastradio::V1_0::Result;
-using android::hardware::broadcastradio::V1_0::Properties;
-using android::hardware::broadcastradio::V1_0::BandConfig;
-using android::hardware::broadcastradio::V1_0::ProgramInfo;
-using android::hardware::broadcastradio::V1_0::MetaData;
-
-class HidlUtils {
-public:
-    static int convertHalResult(Result result);
-    static void convertBandConfigFromHal(radio_hal_band_config_t *config,
-                                         const BandConfig *halConfig);
-    static void convertPropertiesFromHal(radio_hal_properties_t *properties,
-                                         const Properties *halProperties);
-    static void convertBandConfigToHal(BandConfig *halConfig,
-                                       const radio_hal_band_config_t *config);
-    static void convertProgramInfoFromHal(radio_program_info_t *info,
-                                          const ProgramInfo *halInfo);
-    static void convertMetaDataFromHal(radio_metadata_t **metadata,
-                                       const hidl_vec<MetaData>& halMetadata,
-                                       uint32_t channel,
-                                       uint32_t subChannel);
-};
-
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_RADIO_HAL_HIDL_UTILS_H
diff --git a/services/radio/RadioHalHidl.cpp b/services/radio/RadioHalHidl.cpp
deleted file mode 100644
index f637275..0000000
--- a/services/radio/RadioHalHidl.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2016 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 "RadioHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <media/audiohal/hidl/HalDeathHandler.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <system/RadioMetadataWrapper.h>
-#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
-
-#include "RadioHalHidl.h"
-#include "HidlUtils.h"
-
-namespace android {
-
-using android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
-using android::hardware::broadcastradio::V1_0::Class;
-using android::hardware::broadcastradio::V1_0::Direction;
-using android::hardware::broadcastradio::V1_0::Properties;
-
-
-/* static */
-sp<RadioInterface> RadioInterface::connectModule(radio_class_t classId)
-{
-    return new RadioHalHidl(classId);
-}
-
-int RadioHalHidl::getProperties(radio_hal_properties_t *properties)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    sp<IBroadcastRadio> module = getService();
-    if (module == 0) {
-        return -ENODEV;
-    }
-    Properties halProperties;
-    Result halResult = Result::NOT_INITIALIZED;
-    Return<void> hidlReturn =
-            module->getProperties([&](Result result, const Properties& properties) {
-                    halResult = result;
-                    if (result == Result::OK) {
-                        halProperties = properties;
-                    }
-                });
-
-    if (halResult == Result::OK) {
-        HidlUtils::convertPropertiesFromHal(properties, &halProperties);
-    }
-    return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::openTuner(const radio_hal_band_config_t *config,
-                            bool audio,
-                            sp<TunerCallbackInterface> callback,
-                            sp<TunerInterface>& tuner)
-{
-    sp<IBroadcastRadio> module = getService();
-    if (module == 0) {
-        return -ENODEV;
-    }
-    sp<Tuner> tunerImpl = new Tuner(callback, this);
-
-    BandConfig halConfig;
-    Result halResult = Result::NOT_INITIALIZED;
-    sp<ITuner> halTuner;
-
-    HidlUtils::convertBandConfigToHal(&halConfig, config);
-    Return<void> hidlReturn =
-            module->openTuner(halConfig, audio, tunerImpl,
-                              [&](Result result, const sp<ITuner>& tuner) {
-                    halResult = result;
-                    if (result == Result::OK) {
-                        halTuner = tuner;
-                    }
-                });
-
-    if (halResult == Result::OK) {
-        tunerImpl->setHalTuner(halTuner);
-        tuner = tunerImpl;
-    }
-
-    return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::closeTuner(sp<TunerInterface>& tuner)
-{
-    sp<Tuner> tunerImpl = static_cast<Tuner *>(tuner.get());
-    sp<ITuner> clearTuner;
-    tunerImpl->setHalTuner(clearTuner);
-    return 0;
-}
-
-RadioHalHidl::RadioHalHidl(radio_class_t classId)
-    : mClassId(classId)
-{
-}
-
-RadioHalHidl::~RadioHalHidl()
-{
-}
-
-sp<IBroadcastRadio> RadioHalHidl::getService()
-{
-    if (mHalModule == 0) {
-        sp<IBroadcastRadioFactory> factory = IBroadcastRadioFactory::getService();
-        if (factory != 0) {
-            factory->connectModule(static_cast<Class>(mClassId),
-                               [&](Result retval, const ::android::sp<IBroadcastRadio>& result) {
-                if (retval == Result::OK) {
-                    mHalModule = result;
-                }
-            });
-        }
-    }
-    ALOGV("%s OUT module %p", __FUNCTION__, mHalModule.get());
-    return mHalModule;
-}
-
-void RadioHalHidl::clearService()
-{
-    ALOGV("%s IN module %p", __FUNCTION__, mHalModule.get());
-    mHalModule.clear();
-}
-
-
-int RadioHalHidl::Tuner::setConfiguration(const radio_hal_band_config_t *config)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    BandConfig halConfig;
-    HidlUtils::convertBandConfigToHal(&halConfig, config);
-
-    Return<Result> hidlResult = mHalTuner->setConfiguration(halConfig);
-    return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::getConfiguration(radio_hal_band_config_t *config)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    BandConfig halConfig;
-    Result halResult;
-    Return<void> hidlReturn =
-            mHalTuner->getConfiguration([&](Result result, const BandConfig& config) {
-                    halResult = result;
-                    if (result == Result::OK) {
-                        halConfig = config;
-                    }
-                });
-    if (hidlReturn.isOk() && halResult == Result::OK) {
-        HidlUtils::convertBandConfigFromHal(config, &halConfig);
-    }
-    return HidlUtils::convertHalResult(halResult);
-}
-
-int RadioHalHidl::Tuner::scan(radio_direction_t direction, bool skip_sub_channel)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    Return<Result> hidlResult =
-            mHalTuner->scan(static_cast<Direction>(direction), skip_sub_channel);
-    return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::step(radio_direction_t direction, bool skip_sub_channel)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    Return<Result> hidlResult =
-            mHalTuner->step(static_cast<Direction>(direction), skip_sub_channel);
-    return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::tune(unsigned int channel, unsigned int sub_channel)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    Return<Result> hidlResult =
-            mHalTuner->tune(channel, sub_channel);
-    return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::cancel()
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    Return<Result> hidlResult = mHalTuner->cancel();
-    return HidlUtils::convertHalResult(hidlResult);
-}
-
-int RadioHalHidl::Tuner::getProgramInformation(radio_program_info_t *info)
-{
-    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
-    if (mHalTuner == 0) {
-        return -ENODEV;
-    }
-    if (info == nullptr || info->metadata == nullptr) {
-        return BAD_VALUE;
-    }
-    ProgramInfo halInfo;
-    Result halResult;
-    Return<void> hidlReturn = mHalTuner->getProgramInformation(
-        [&](Result result, const ProgramInfo& info) {
-            halResult = result;
-            if (result == Result::OK) {
-                halInfo = info;
-            }
-        });
-    if (hidlReturn.isOk() && halResult == Result::OK) {
-        HidlUtils::convertProgramInfoFromHal(info, &halInfo);
-    }
-    return HidlUtils::convertHalResult(halResult);
-}
-
-Return<void> RadioHalHidl::Tuner::hardwareFailure()
-{
-    ALOGV("%s IN", __FUNCTION__);
-    handleHwFailure();
-    return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::configChange(Result result, const BandConfig& config)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event;
-    memset(&event, 0, sizeof(radio_hal_event_t));
-    event.type = RADIO_EVENT_CONFIG;
-    event.status = HidlUtils::convertHalResult(result);
-    HidlUtils::convertBandConfigFromHal(&event.config, &config);
-    onCallback(&event);
-    return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::tuneComplete(Result result, const ProgramInfo& info)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event = {};
-    RadioMetadataWrapper metadataWrapper(&event.info.metadata);
-
-    event.type = RADIO_EVENT_TUNED;
-    event.status = HidlUtils::convertHalResult(result);
-    HidlUtils::convertProgramInfoFromHal(&event.info, &info);
-    onCallback(&event);
-    return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::afSwitch(const ProgramInfo& info)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event = {};
-    RadioMetadataWrapper metadataWrapper(&event.info.metadata);
-
-    event.type = RADIO_EVENT_AF_SWITCH;
-    HidlUtils::convertProgramInfoFromHal(&event.info, &info);
-    onCallback(&event);
-    return Return<void>();
-}
-
-Return<void> RadioHalHidl::Tuner::antennaStateChange(bool connected)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event;
-    memset(&event, 0, sizeof(radio_hal_event_t));
-    event.type = RADIO_EVENT_ANTENNA;
-    event.on = connected;
-    onCallback(&event);
-    return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::trafficAnnouncement(bool active)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event;
-    memset(&event, 0, sizeof(radio_hal_event_t));
-    event.type = RADIO_EVENT_TA;
-    event.on = active;
-    onCallback(&event);
-    return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::emergencyAnnouncement(bool active)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event;
-    memset(&event, 0, sizeof(radio_hal_event_t));
-    event.type = RADIO_EVENT_EA;
-    event.on = active;
-    onCallback(&event);
-    return Return<void>();
-}
-Return<void> RadioHalHidl::Tuner::newMetadata(uint32_t channel, uint32_t subChannel,
-                                          const ::android::hardware::hidl_vec<MetaData>& metadata)
-{
-    ALOGV("%s IN", __FUNCTION__);
-    radio_hal_event_t event = {};
-    RadioMetadataWrapper metadataWrapper(&event.metadata);
-
-    event.type = RADIO_EVENT_METADATA;
-    HidlUtils::convertMetaDataFromHal(&event.metadata, metadata, channel, subChannel);
-    onCallback(&event);
-    return Return<void>();
-}
-
-
-RadioHalHidl::Tuner::Tuner(sp<TunerCallbackInterface> callback, sp<RadioHalHidl> module)
-    : TunerInterface(), mHalTuner(NULL), mCallback(callback), mParentModule(module)
-{
-    // Make sure the handler we are passing in only deals with const members,
-    // as it can be called on an arbitrary thread.
-    const auto& self = this;
-    HalDeathHandler::getInstance()->registerAtExitHandler(
-            this, [&self]() { self->sendHwFailureEvent(); });
-}
-
-
-RadioHalHidl::Tuner::~Tuner()
-{
-    HalDeathHandler::getInstance()->unregisterAtExitHandler(this);
-}
-
-void RadioHalHidl::Tuner::setHalTuner(sp<ITuner>& halTuner) {
-    if (mHalTuner != 0) {
-        mHalTuner->unlinkToDeath(HalDeathHandler::getInstance());
-    }
-    mHalTuner = halTuner;
-    if (mHalTuner != 0) {
-        mHalTuner->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
-    }
-}
-
-void RadioHalHidl::Tuner::handleHwFailure()
-{
-    ALOGV("%s IN", __FUNCTION__);
-    sp<RadioHalHidl> parentModule = mParentModule.promote();
-    if (parentModule != 0) {
-        parentModule->clearService();
-    }
-    sendHwFailureEvent();
-    mHalTuner.clear();
-}
-
-void RadioHalHidl::Tuner::sendHwFailureEvent() const
-{
-    radio_hal_event_t event;
-    memset(&event, 0, sizeof(radio_hal_event_t));
-    event.type = RADIO_EVENT_HW_FAILURE;
-    onCallback(&event);
-}
-
-void RadioHalHidl::Tuner::onCallback(radio_hal_event_t *halEvent) const
-{
-    if (mCallback != 0) {
-        mCallback->onEvent(halEvent);
-    }
-}
-
-} // namespace android
diff --git a/services/radio/RadioHalHidl.h b/services/radio/RadioHalHidl.h
deleted file mode 100644
index f98420d..0000000
--- a/services/radio/RadioHalHidl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_HAL_HIDL_H
-#define ANDROID_HARDWARE_RADIO_HAL_HIDL_H
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-#include <android/hardware/broadcastradio/1.0/types.h>
-#include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
-#include <android/hardware/broadcastradio/1.0/ITuner.h>
-#include <android/hardware/broadcastradio/1.0/ITunerCallback.h>
-
-namespace android {
-
-using android::hardware::Return;
-using android::hardware::broadcastradio::V1_0::Result;
-using android::hardware::broadcastradio::V1_0::IBroadcastRadio;
-using android::hardware::broadcastradio::V1_0::ITuner;
-using android::hardware::broadcastradio::V1_0::ITunerCallback;
-
-using android::hardware::broadcastradio::V1_0::BandConfig;
-using android::hardware::broadcastradio::V1_0::ProgramInfo;
-using android::hardware::broadcastradio::V1_0::MetaData;
-
-class RadioHalHidl : public RadioInterface
-{
-public:
-                    RadioHalHidl(radio_class_t classId);
-
-                    // RadioInterface
-        virtual int getProperties(radio_hal_properties_t *properties);
-        virtual int openTuner(const radio_hal_band_config_t *config,
-                              bool audio,
-                              sp<TunerCallbackInterface> callback,
-                              sp<TunerInterface>& tuner);
-        virtual int closeTuner(sp<TunerInterface>& tuner);
-
-        class Tuner  : public TunerInterface, public virtual ITunerCallback
-        {
-        public:
-                        Tuner(sp<TunerCallbackInterface> callback, sp<RadioHalHidl> module);
-
-                        // TunerInterface
-            virtual int setConfiguration(const radio_hal_band_config_t *config);
-            virtual int getConfiguration(radio_hal_band_config_t *config);
-            virtual int scan(radio_direction_t direction, bool skip_sub_channel);
-            virtual int step(radio_direction_t direction, bool skip_sub_channel);
-            virtual int tune(unsigned int channel, unsigned int sub_channel);
-            virtual int cancel();
-            virtual int getProgramInformation(radio_program_info_t *info);
-
-                        // ITunerCallback
-            virtual Return<void> hardwareFailure();
-            virtual Return<void> configChange(Result result, const BandConfig& config);
-            virtual Return<void> tuneComplete(Result result, const ProgramInfo& info);
-            virtual Return<void> afSwitch(const ProgramInfo& info);
-            virtual Return<void> antennaStateChange(bool connected);
-            virtual Return<void> trafficAnnouncement(bool active);
-            virtual Return<void> emergencyAnnouncement(bool active);
-            virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
-                                         const ::android::hardware::hidl_vec<MetaData>& metadata);
-
-            void setHalTuner(sp<ITuner>& halTuner);
-            sp<ITuner> getHalTuner() { return mHalTuner; }
-
-        private:
-            virtual          ~Tuner();
-
-                    void     onCallback(radio_hal_event_t *halEvent) const;
-                    void     handleHwFailure();
-                    void     sendHwFailureEvent() const;
-
-            sp<ITuner> mHalTuner;
-            const sp<TunerCallbackInterface> mCallback;
-            wp<RadioHalHidl> mParentModule;
-        };
-
-        sp<IBroadcastRadio> getService();
-        void clearService();
-
-private:
-        virtual         ~RadioHalHidl();
-
-                radio_class_t mClassId;
-                sp<IBroadcastRadio> mHalModule;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_HAL_HIDL_H
diff --git a/services/radio/RadioHalLegacy.cpp b/services/radio/RadioHalLegacy.cpp
deleted file mode 100644
index d50ccd4..0000000
--- a/services/radio/RadioHalLegacy.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2016 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 "RadioHalLegacy"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include "RadioHalLegacy.h"
-
-namespace android {
-
-const char *RadioHalLegacy::sClassModuleNames[] = {
-    RADIO_HARDWARE_MODULE_ID_FM, /* corresponds to RADIO_CLASS_AM_FM */
-    RADIO_HARDWARE_MODULE_ID_SAT,  /* corresponds to RADIO_CLASS_SAT */
-    RADIO_HARDWARE_MODULE_ID_DT,   /* corresponds to RADIO_CLASS_DT */
-};
-
-/* static */
-sp<RadioInterface> RadioInterface::connectModule(radio_class_t classId)
-{
-    return new RadioHalLegacy(classId);
-}
-
-RadioHalLegacy::RadioHalLegacy(radio_class_t classId)
-    : RadioInterface(), mClassId(classId), mHwDevice(NULL)
-{
-}
-
-void RadioHalLegacy::onFirstRef()
-{
-    const hw_module_t *mod;
-    int rc;
-    ALOGI("%s mClassId %d", __FUNCTION__, mClassId);
-
-    mHwDevice = NULL;
-
-    if ((mClassId < 0) ||
-            (mClassId >= NELEM(sClassModuleNames))) {
-        ALOGE("invalid class ID %d", mClassId);
-        return;
-    }
-
-    ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s",
-          __FUNCTION__, RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId]);
-
-    rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId], &mod);
-    if (rc != 0) {
-        ALOGE("couldn't load radio module %s.%s (%s)",
-              RADIO_HARDWARE_MODULE_ID, sClassModuleNames[mClassId], strerror(-rc));
-        return;
-    }
-    rc = radio_hw_device_open(mod, &mHwDevice);
-    if (rc != 0) {
-        ALOGE("couldn't open radio hw device in %s.%s (%s)",
-              RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc));
-        mHwDevice = NULL;
-        return;
-    }
-    if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) {
-        ALOGE("wrong radio hw device version %04x", mHwDevice->common.version);
-        radio_hw_device_close(mHwDevice);
-        mHwDevice = NULL;
-    }
-}
-
-RadioHalLegacy::~RadioHalLegacy()
-{
-    if (mHwDevice != NULL) {
-        radio_hw_device_close(mHwDevice);
-    }
-}
-
-int RadioHalLegacy::getProperties(radio_hal_properties_t *properties)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-
-    int rc = mHwDevice->get_properties(mHwDevice, properties);
-    if (rc != 0) {
-        ALOGE("could not read implementation properties");
-    }
-
-    return rc;
-}
-
-int RadioHalLegacy::openTuner(const radio_hal_band_config_t *config,
-                bool audio,
-                sp<TunerCallbackInterface> callback,
-                sp<TunerInterface>& tuner)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    sp<Tuner> tunerImpl = new Tuner(callback);
-
-    const struct radio_tuner *halTuner;
-    int rc = mHwDevice->open_tuner(mHwDevice, config, audio,
-                                   RadioHalLegacy::Tuner::callback, tunerImpl.get(),
-                                   &halTuner);
-    if (rc == 0) {
-        tunerImpl->setHalTuner(halTuner);
-        tuner = tunerImpl;
-    }
-    return rc;
-}
-
-int RadioHalLegacy::closeTuner(sp<TunerInterface>& tuner)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    if (tuner == 0) {
-        return -EINVAL;
-    }
-    sp<Tuner> tunerImpl = (Tuner *)tuner.get();
-    return mHwDevice->close_tuner(mHwDevice, tunerImpl->getHalTuner());
-}
-
-int RadioHalLegacy::Tuner::setConfiguration(const radio_hal_band_config_t *config)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->set_configuration(mHalTuner, config);
-}
-
-int RadioHalLegacy::Tuner::getConfiguration(radio_hal_band_config_t *config)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->get_configuration(mHalTuner, config);
-}
-
-int RadioHalLegacy::Tuner::scan(radio_direction_t direction, bool skip_sub_channel)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->scan(mHalTuner, direction, skip_sub_channel);
-}
-
-int RadioHalLegacy::Tuner::step(radio_direction_t direction, bool skip_sub_channel)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->step(mHalTuner, direction, skip_sub_channel);
-}
-
-int RadioHalLegacy::Tuner::tune(unsigned int channel, unsigned int sub_channel)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->tune(mHalTuner, channel, sub_channel);
-}
-
-int RadioHalLegacy::Tuner::cancel()
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->cancel(mHalTuner);
-}
-
-int RadioHalLegacy::Tuner::getProgramInformation(radio_program_info_t *info)
-{
-    if (mHalTuner == NULL) {
-        return -ENODEV;
-    }
-    return mHalTuner->get_program_information(mHalTuner, info);
-}
-
-void RadioHalLegacy::Tuner::onCallback(radio_hal_event_t *halEvent)
-{
-    if (mCallback != 0) {
-        mCallback->onEvent(halEvent);
-    }
-}
-
-//static
-void RadioHalLegacy::Tuner::callback(radio_hal_event_t *halEvent, void *cookie)
-{
-    wp<RadioHalLegacy::Tuner> weak = wp<RadioHalLegacy::Tuner>((RadioHalLegacy::Tuner *)cookie);
-    sp<RadioHalLegacy::Tuner> tuner = weak.promote();
-    if (tuner != 0) {
-        tuner->onCallback(halEvent);
-    }
-}
-
-RadioHalLegacy::Tuner::Tuner(sp<TunerCallbackInterface> callback)
-    : TunerInterface(), mHalTuner(NULL), mCallback(callback)
-{
-}
-
-
-RadioHalLegacy::Tuner::~Tuner()
-{
-}
-
-
-} // namespace android
diff --git a/services/radio/RadioHalLegacy.h b/services/radio/RadioHalLegacy.h
deleted file mode 100644
index 7d4831b..0000000
--- a/services/radio/RadioHalLegacy.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
-#define ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
-
-#include <utils/RefBase.h>
-#include <hardware/radio.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class RadioHalLegacy : public RadioInterface
-{
-public:
-        RadioHalLegacy(radio_class_t classId);
-
-        // RadioInterface
-        virtual int getProperties(radio_hal_properties_t *properties);
-        virtual int openTuner(const radio_hal_band_config_t *config,
-                        bool audio,
-                        sp<TunerCallbackInterface> callback,
-                        sp<TunerInterface>& tuner);
-        virtual int closeTuner(sp<TunerInterface>& tuner);
-
-        // RefBase
-        virtual void onFirstRef();
-
-        class Tuner  : public TunerInterface
-        {
-        public:
-                        Tuner(sp<TunerCallbackInterface> callback);
-
-            virtual int setConfiguration(const radio_hal_band_config_t *config);
-            virtual int getConfiguration(radio_hal_band_config_t *config);
-            virtual int scan(radio_direction_t direction, bool skip_sub_channel);
-            virtual int step(radio_direction_t direction, bool skip_sub_channel);
-            virtual int tune(unsigned int channel, unsigned int sub_channel);
-            virtual int cancel();
-            virtual int getProgramInformation(radio_program_info_t *info);
-
-            static void callback(radio_hal_event_t *halEvent, void *cookie);
-                   void onCallback(radio_hal_event_t *halEvent);
-
-            void setHalTuner(const struct radio_tuner *halTuner) { mHalTuner = halTuner; }
-            const struct radio_tuner *getHalTuner() { return mHalTuner; }
-
-        private:
-            virtual      ~Tuner();
-
-            const struct radio_tuner    *mHalTuner;
-            sp<TunerCallbackInterface>  mCallback;
-        };
-
-protected:
-        virtual     ~RadioHalLegacy();
-
-private:
-        static const char * sClassModuleNames[];
-
-        radio_class_t mClassId;
-        struct radio_hw_device  *mHwDevice;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_HAL_LEGACY_H
diff --git a/services/radio/RadioInterface.h b/services/radio/RadioInterface.h
deleted file mode 100644
index fcfb4d5..0000000
--- a/services/radio/RadioInterface.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_INTERFACE_H
-#define ANDROID_HARDWARE_RADIO_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class RadioInterface : public virtual RefBase
-{
-public:
-        /* get a sound trigger HAL instance */
-        static sp<RadioInterface> connectModule(radio_class_t classId);
-
-        /*
-         * Retrieve implementation properties.
-         *
-         * arguments:
-         * - properties: where to return the module properties
-         *
-         * returns:
-         *  0 if no error
-         *  -EINVAL if invalid arguments are passed
-         */
-        virtual int getProperties(radio_hal_properties_t *properties) = 0;
-
-        /*
-         * Open a tuner interface for the requested configuration.
-         * If no other tuner is opened, this will activate the radio module.
-         *
-         * arguments:
-         * - config: the band configuration to apply
-         * - audio: this tuner will be used for live radio listening and should be connected to
-         * the radio audio source.
-         * - callback: the event callback
-         * - cookie: the cookie to pass when calling the callback
-         * - tuner: where to return the tuner interface
-         *
-         * returns:
-         *  0 if HW was powered up and configuration could be applied
-         *  -EINVAL if configuration requested is invalid
-         *  -ENOSYS if called out of sequence
-         *
-         * Callback function with event RADIO_EVENT_CONFIG MUST be called once the
-         * configuration is applied or a failure occurs or after a time out.
-         */
-        virtual int openTuner(const radio_hal_band_config_t *config,
-                        bool audio,
-                        sp<TunerCallbackInterface> callback,
-                        sp<TunerInterface>& tuner) = 0;
-
-        /*
-         * Close a tuner interface.
-         * If the last tuner is closed, the radio module is deactivated.
-         *
-         * arguments:
-         * - tuner: the tuner interface to close
-         *
-         * returns:
-         *  0 if powered down successfully.
-         *  -EINVAL if an invalid argument is passed
-         *  -ENOSYS if called out of sequence
-         */
-        virtual int closeTuner(sp<TunerInterface>& tuner) = 0;
-
-protected:
-        RadioInterface() {}
-        virtual     ~RadioInterface() {}
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_INTERFACE_H
diff --git a/services/radio/RadioRegions.h b/services/radio/RadioRegions.h
deleted file mode 100644
index d40ee83..0000000
--- a/services/radio/RadioRegions.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_REGIONS_H
-#define ANDROID_HARDWARE_RADIO_REGIONS_H
-
-namespace android {
-
-#define RADIO_BAND_LOWER_FM_ITU1    87500
-#define RADIO_BAND_UPPER_FM_ITU1    108000
-#define RADIO_BAND_SPACING_FM_ITU1  100
-
-#define RADIO_BAND_LOWER_FM_ITU2    87900
-#define RADIO_BAND_UPPER_FM_ITU2    107900
-#define RADIO_BAND_SPACING_FM_ITU2  200
-
-#define RADIO_BAND_LOWER_FM_JAPAN    76000
-#define RADIO_BAND_UPPER_FM_JAPAN    90000
-#define RADIO_BAND_SPACING_FM_JAPAN  100
-
-#define RADIO_BAND_LOWER_FM_OIRT    65800
-#define RADIO_BAND_UPPER_FM_OIRT    74000
-#define RADIO_BAND_SPACING_FM_OIRT  10
-
-#define RADIO_BAND_LOWER_LW         153
-#define RADIO_BAND_UPPER_LW         279
-#define RADIO_BAND_SPACING_LW       9
-
-#define RADIO_BAND_LOWER_MW_IUT1    531
-#define RADIO_BAND_UPPER_MW_ITU1    1611
-#define RADIO_BAND_SPACING_MW_ITU1  9
-
-#define RADIO_BAND_LOWER_MW_IUT2    540
-#define RADIO_BAND_UPPER_MW_ITU2    1610
-#define RADIO_BAND_SPACING_MW_ITU2  10
-
-#define RADIO_BAND_LOWER_SW         2300
-#define RADIO_BAND_UPPER_SW         26100
-#define RADIO_BAND_SPACING_SW       5
-
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#endif
-
-const radio_band_config_t sKnownRegionConfigs[] = {
-    {   // FM ITU 1
-        RADIO_REGION_ITU_1,
-        {
-        RADIO_BAND_FM,
-            false,
-            RADIO_BAND_LOWER_FM_ITU1,
-            RADIO_BAND_UPPER_FM_ITU1,
-            1,
-            {RADIO_BAND_SPACING_FM_ITU1},
-            {
-                {
-                RADIO_DEEMPHASIS_50,
-                true,
-                RADIO_RDS_WORLD,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // FM Americas
-        RADIO_REGION_ITU_2,
-        {
-        RADIO_BAND_FM,
-            false,
-            RADIO_BAND_LOWER_FM_ITU2,
-            RADIO_BAND_UPPER_FM_ITU2,
-            1,
-            {RADIO_BAND_SPACING_FM_ITU2},
-            {
-                {
-                RADIO_DEEMPHASIS_75,
-                true,
-                RADIO_RDS_US,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // FM Japan
-        RADIO_REGION_JAPAN,
-        {
-        RADIO_BAND_FM,
-            false,
-            RADIO_BAND_LOWER_FM_JAPAN,
-            RADIO_BAND_UPPER_FM_JAPAN,
-            1,
-            {RADIO_BAND_SPACING_FM_JAPAN},
-            {
-                {
-                RADIO_DEEMPHASIS_50,
-                true,
-                RADIO_RDS_WORLD,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // FM Korea
-        RADIO_REGION_KOREA,
-        {
-        RADIO_BAND_FM,
-            false,
-            RADIO_BAND_LOWER_FM_ITU1,
-            RADIO_BAND_UPPER_FM_ITU1,
-            1,
-            {RADIO_BAND_SPACING_FM_ITU1},
-            {
-                {
-                RADIO_DEEMPHASIS_75,
-                true,
-                RADIO_RDS_WORLD,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // FM OIRT
-        RADIO_REGION_OIRT,
-        {
-        RADIO_BAND_FM,
-            false,
-            RADIO_BAND_LOWER_FM_OIRT,
-            RADIO_BAND_UPPER_FM_OIRT,
-            1,
-            {RADIO_BAND_SPACING_FM_OIRT},
-            {
-                {
-                RADIO_DEEMPHASIS_50,
-                true,
-                RADIO_RDS_WORLD,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // FM US HD radio
-        RADIO_REGION_ITU_2,
-        {
-            RADIO_BAND_FM_HD,
-            false,
-            RADIO_BAND_LOWER_FM_ITU2,
-            RADIO_BAND_UPPER_FM_ITU2,
-            1,
-            {RADIO_BAND_SPACING_FM_ITU2},
-            {
-                {
-                RADIO_DEEMPHASIS_75,
-                true,
-                RADIO_RDS_US,
-                true,
-                true,
-                true,
-                }
-            }
-        }
-    },
-    {   // AM LW
-        RADIO_REGION_ITU_1,
-        {
-            RADIO_BAND_AM,
-            false,
-            RADIO_BAND_LOWER_LW,
-            RADIO_BAND_UPPER_LW,
-            1,
-            {RADIO_BAND_SPACING_LW},
-            {
-            }
-        }
-    },
-    {   // AM SW
-        RADIO_REGION_ITU_1,
-        {
-            RADIO_BAND_AM,
-            false,
-            RADIO_BAND_LOWER_SW,
-            RADIO_BAND_UPPER_SW,
-            1,
-            {RADIO_BAND_SPACING_SW},
-            {
-            }
-        }
-    },
-    {   // AM MW ITU1
-        RADIO_REGION_ITU_1,
-        {
-            RADIO_BAND_AM,
-            false,
-            RADIO_BAND_LOWER_MW_IUT1,
-            RADIO_BAND_UPPER_MW_ITU1,
-            1,
-            {RADIO_BAND_SPACING_MW_ITU1},
-            {
-            }
-        }
-    },
-    {   // AM MW ITU2
-        RADIO_REGION_ITU_2,
-        {
-            RADIO_BAND_AM,
-            false,
-            RADIO_BAND_LOWER_MW_IUT2,
-            RADIO_BAND_UPPER_MW_ITU2,
-            1,
-            {RADIO_BAND_SPACING_MW_ITU2},
-            {
-            }
-        }
-    }
-};
-
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_REGIONS_H
diff --git a/services/radio/RadioService.cpp b/services/radio/RadioService.cpp
deleted file mode 100644
index beb7c09..0000000
--- a/services/radio/RadioService.cpp
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright (C) 2015 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 "RadioService"
-//#define LOG_NDEBUG 0
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <pthread.h>
-
-#include <system/audio.h>
-#include <system/audio_policy.h>
-#include <system/radio.h>
-#include <system/radio_metadata.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <hardware/hardware.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IServiceManager.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <binder/PermissionCache.h>
-#include <hardware/radio.h>
-#include <media/AudioSystem.h>
-#include "RadioService.h"
-#include "RadioRegions.h"
-
-namespace android {
-
-static const char kRadioTunerAudioDeviceName[] = "Radio tuner source";
-
-static const String16 RADIO_PERMISSION("android.permission.ACCESS_FM_RADIO");
-
-RadioService::RadioService()
-    : BnRadioService(), mNextUniqueId(1)
-{
-    ALOGI("%s", __FUNCTION__);
-}
-
-void RadioService::onFirstRef()
-{
-    ALOGI("%s", __FUNCTION__);
-
-    sp<RadioInterface> dev = RadioInterface::connectModule(RADIO_CLASS_AM_FM);
-
-    if (dev == 0) {
-        return;
-    }
-    struct radio_hal_properties halProperties;
-    int rc = dev->getProperties(&halProperties);
-    if (rc != 0) {
-        ALOGE("could not read implementation properties");
-        return;
-    }
-
-    radio_properties_t properties;
-    properties.handle =
-            (radio_handle_t)android_atomic_inc(&mNextUniqueId);
-    convertProperties(&properties, &halProperties);
-
-    ALOGI("loaded default module %s, ver %s, handle %d", properties.product,
-        properties.version, properties.handle);
-
-    sp<Module> module = new Module(dev, properties);
-    mModules.add(properties.handle, module);
-}
-
-RadioService::~RadioService()
-{
-}
-
-status_t RadioService::listModules(struct radio_properties *properties,
-                             uint32_t *numModules)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    ALOGV("listModules");
-
-    AutoMutex lock(mServiceLock);
-    if (numModules == NULL || (*numModules != 0 && properties == NULL)) {
-        return BAD_VALUE;
-    }
-    uint32_t maxModules = *numModules;
-    *numModules = mModules.size();
-    for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
-        properties[i] = mModules.valueAt(i)->properties();
-    }
-    return NO_ERROR;
-}
-
-status_t RadioService::attach(radio_handle_t handle,
-                        const sp<IRadioClient>& client,
-                        const struct radio_band_config *config,
-                        bool withAudio,
-                        sp<IRadio>& radio)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    ALOGV("%s %d config %p withAudio %d", __FUNCTION__, handle, config, withAudio);
-
-    AutoMutex lock(mServiceLock);
-    radio.clear();
-    if (client == 0) {
-        return BAD_VALUE;
-    }
-    ssize_t index = mModules.indexOfKey(handle);
-    if (index < 0) {
-        return BAD_VALUE;
-    }
-    sp<Module> module = mModules.valueAt(index);
-
-    if (config == NULL) {
-        config = module->getDefaultConfig();
-        if (config == NULL) {
-            return INVALID_OPERATION;
-        }
-    }
-    ALOGV("%s region %d type %d", __FUNCTION__, config->region, config->band.type);
-
-    radio = module->addClient(client, config, withAudio);
-
-    if (radio == 0) {
-        return NO_INIT;
-    }
-    return NO_ERROR;
-}
-
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 60000;
-
-static bool tryLock(Mutex& mutex)
-{
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleep);
-    }
-    return locked;
-}
-
-status_t RadioService::dump(int fd, const Vector<String16>& args __unused) {
-    String8 result;
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        result.appendFormat("Permission Denial: can't dump RadioService");
-        write(fd, result.string(), result.size());
-    } else {
-        bool locked = tryLock(mServiceLock);
-        // failed to lock - RadioService is probably deadlocked
-        if (!locked) {
-            result.append("RadioService may be deadlocked\n");
-            write(fd, result.string(), result.size());
-        }
-
-        if (locked) mServiceLock.unlock();
-    }
-    return NO_ERROR;
-}
-
-status_t RadioService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
-    return BnRadioService::onTransact(code, data, reply, flags);
-}
-
-
-/* static */
-void RadioService::convertProperties(radio_properties_t *properties,
-                                     const radio_hal_properties_t *halProperties)
-{
-    memset(properties, 0, sizeof(struct radio_properties));
-    properties->class_id = halProperties->class_id;
-    strlcpy(properties->implementor, halProperties->implementor,
-            RADIO_STRING_LEN_MAX);
-    strlcpy(properties->product, halProperties->product,
-            RADIO_STRING_LEN_MAX);
-    strlcpy(properties->version, halProperties->version,
-            RADIO_STRING_LEN_MAX);
-    strlcpy(properties->serial, halProperties->serial,
-            RADIO_STRING_LEN_MAX);
-    properties->num_tuners = halProperties->num_tuners;
-    properties->num_audio_sources = halProperties->num_audio_sources;
-    properties->supports_capture = halProperties->supports_capture;
-
-    for (size_t i = 0; i < ARRAY_SIZE(sKnownRegionConfigs); i++) {
-        const radio_hal_band_config_t *band = &sKnownRegionConfigs[i].band;
-        size_t j;
-        for (j = 0; j < halProperties->num_bands; j++) {
-            const radio_hal_band_config_t *halBand = &halProperties->bands[j];
-            size_t k;
-            if (band->type != halBand->type) continue;
-            if (band->lower_limit < halBand->lower_limit) continue;
-            if (band->upper_limit > halBand->upper_limit) continue;
-            for (k = 0; k < halBand->num_spacings; k++) {
-                if (band->spacings[0] == halBand->spacings[k]) break;
-            }
-            if (k == halBand->num_spacings) continue;
-            if (band->type == RADIO_BAND_AM) break;
-            if ((band->fm.deemphasis & halBand->fm.deemphasis) == 0) continue;
-            if (halBand->fm.rds == 0) break;
-            if ((band->fm.rds & halBand->fm.rds) != 0) break;
-        }
-        if (j == halProperties->num_bands) continue;
-
-        ALOGI("convertProperties() Adding band type %d region %d",
-              sKnownRegionConfigs[i].band.type , sKnownRegionConfigs[i].region);
-
-        memcpy(&properties->bands[properties->num_bands++],
-               &sKnownRegionConfigs[i],
-               sizeof(radio_band_config_t));
-    }
-}
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::CallbackThread"
-
-RadioService::CallbackThread::CallbackThread(const wp<ModuleClient>& moduleClient)
-    : mModuleClient(moduleClient), mMemoryDealer(new MemoryDealer(1024 * 1024, "RadioService"))
-{
-}
-
-RadioService::CallbackThread::~CallbackThread()
-{
-    mEventQueue.clear();
-}
-
-void RadioService::CallbackThread::onFirstRef()
-{
-    run("RadioService cbk", ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-bool RadioService::CallbackThread::threadLoop()
-{
-    while (!exitPending()) {
-        sp<IMemory> eventMemory;
-        sp<ModuleClient> moduleClient;
-        {
-            Mutex::Autolock _l(mCallbackLock);
-            while (mEventQueue.isEmpty() && !exitPending()) {
-                ALOGV("CallbackThread::threadLoop() sleep");
-                mCallbackCond.wait(mCallbackLock);
-                ALOGV("CallbackThread::threadLoop() wake up");
-            }
-            if (exitPending()) {
-                break;
-            }
-            eventMemory = mEventQueue[0];
-            mEventQueue.removeAt(0);
-            moduleClient = mModuleClient.promote();
-        }
-        if (moduleClient != 0) {
-            moduleClient->onCallbackEvent(eventMemory);
-            eventMemory.clear();
-        }
-    }
-    return false;
-}
-
-void RadioService::CallbackThread::exit()
-{
-    Mutex::Autolock _l(mCallbackLock);
-    requestExit();
-    mCallbackCond.broadcast();
-}
-
-sp<IMemory> RadioService::CallbackThread::prepareEvent(radio_hal_event_t *halEvent)
-{
-    sp<IMemory> eventMemory;
-
-    // The event layout in shared memory is:
-    // sizeof(struct radio_event) bytes : the event itself
-    // 4 bytes                          : metadata size or 0
-    // N bytes                          : metadata if present
-    uint32_t metadataOffset = sizeof(struct radio_event) + sizeof(uint32_t);
-    uint32_t metadataSize = 0;
-
-    switch (halEvent->type) {
-    case RADIO_EVENT_TUNED:
-    case RADIO_EVENT_AF_SWITCH:
-        if (radio_metadata_check(halEvent->info.metadata) == 0) {
-            metadataSize = (uint32_t)radio_metadata_get_size(halEvent->info.metadata);
-        }
-        break;
-    case RADIO_EVENT_METADATA:
-        if (radio_metadata_check(halEvent->metadata) != 0) {
-            return eventMemory;
-        }
-        metadataSize = (uint32_t)radio_metadata_get_size(halEvent->metadata);
-        break;
-    default:
-        break;
-    }
-
-    eventMemory = mMemoryDealer->allocate(metadataOffset + metadataSize);
-    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
-        eventMemory.clear();
-        return eventMemory;
-    }
-
-    struct radio_event *event = (struct radio_event *)eventMemory->pointer();
-
-    *(uint32_t *)((uint8_t *)event + metadataOffset - sizeof(uint32_t)) = metadataSize;
-
-    event->type = halEvent->type;
-    event->status = halEvent->status;
-
-    switch (event->type) {
-    case RADIO_EVENT_CONFIG:
-        event->config.band = halEvent->config;
-        break;
-    case RADIO_EVENT_TUNED:
-    case RADIO_EVENT_AF_SWITCH:
-        event->info = halEvent->info;
-        if (metadataSize != 0) {
-            memcpy((uint8_t *)event + metadataOffset, halEvent->info.metadata, metadataSize);
-        }
-        break;
-    case RADIO_EVENT_TA:
-    case RADIO_EVENT_EA:
-    case RADIO_EVENT_ANTENNA:
-    case RADIO_EVENT_CONTROL:
-        event->on = halEvent->on;
-        break;
-    case RADIO_EVENT_METADATA:
-        if (metadataSize != 0) {
-            memcpy((uint8_t *)event + metadataOffset, halEvent->metadata, metadataSize);
-        }
-        break;
-    case RADIO_EVENT_HW_FAILURE:
-    default:
-        break;
-    }
-
-    return eventMemory;
-}
-
-void RadioService::CallbackThread::sendEvent(radio_hal_event_t *event)
- {
-     sp<IMemory> eventMemory = prepareEvent(event);
-     if (eventMemory == 0) {
-         return;
-     }
-
-     AutoMutex lock(mCallbackLock);
-     mEventQueue.add(eventMemory);
-     mCallbackCond.signal();
-     ALOGV("%s DONE", __FUNCTION__);
-}
-
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::Module"
-
-RadioService::Module::Module(sp<RadioInterface> hwDevice, radio_properties properties)
- : mHwDevice(hwDevice), mProperties(properties), mMute(true)
-{
-}
-
-RadioService::Module::~Module() {
-    mHwDevice.clear();
-    mModuleClients.clear();
-}
-
-status_t RadioService::Module::dump(int fd __unused, const Vector<String16>& args __unused) {
-    String8 result;
-    return NO_ERROR;
-}
-
-sp<RadioService::ModuleClient> RadioService::Module::addClient(const sp<IRadioClient>& client,
-                                    const struct radio_band_config *config,
-                                    bool audio)
-{
-    ALOGV("addClient() %p config %p product %s", this, config, mProperties.product);
-
-    AutoMutex lock(mLock);
-    sp<ModuleClient> moduleClient;
-    int ret;
-
-    if (mHwDevice == 0) {
-        return moduleClient;
-    }
-
-    for (size_t i = 0; i < mModuleClients.size(); i++) {
-        if (mModuleClients[i]->client() == client) {
-            // client already connected: reject
-            return moduleClient;
-        }
-    }
-    moduleClient = new ModuleClient(this, client, config, audio);
-
-    struct radio_hal_band_config halConfig;
-    halConfig = config->band;
-
-    // Tuner preemption logic:
-    // There is a limited amount of tuners and a limited amount of radio audio sources per module.
-    // The minimum is one tuner and one audio source.
-    // The numbers of tuners and sources are indicated in the module properties.
-    // NOTE: current framework implementation only supports one radio audio source.
-    // It is possible to open more than one tuner at a time but only one tuner can be connected
-    // to the radio audio source (AUDIO_DEVICE_IN_FM_TUNER).
-    // The base rule is that a newly connected tuner always wins, i.e. always gets a tuner
-    // and can use the audio source if requested.
-    // If another client is preempted, it is notified by a callback with RADIO_EVENT_CONTROL
-    // indicating loss of control.
-    // - If the newly connected client requests the audio source (audio == true):
-    //    - if an audio source is available
-    //          no problem
-    //    - if not:
-    //          the oldest client in the list using audio is preempted.
-    // - If the newly connected client does not request the audio source (audio == false):
-    //    - if a tuner is available
-    //          no problem
-    //    - if not:
-    //          The oldest client not using audio is preempted first and if none is found the
-    //          the oldest client using audio is preempted.
-    // Each time a tuner using the audio source is opened or closed, the audio policy manager is
-    // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER.
-
-    sp<ModuleClient> oldestTuner;
-    sp<ModuleClient> oldestAudio;
-    size_t allocatedTuners = 0;
-    size_t allocatedAudio = 0;
-    for (size_t i = 0; i < mModuleClients.size(); i++) {
-        if (mModuleClients[i]->getTuner() != NULL) {
-            if (mModuleClients[i]->audio()) {
-                if (oldestAudio == 0) {
-                    oldestAudio = mModuleClients[i];
-                }
-                allocatedAudio++;
-            } else {
-                if (oldestTuner == 0) {
-                    oldestTuner = mModuleClients[i];
-                }
-                allocatedTuners++;
-            }
-        }
-    }
-
-    sp<TunerInterface> halTuner;
-    sp<ModuleClient> preemtedClient;
-    if (audio) {
-        if (allocatedAudio >= mProperties.num_audio_sources) {
-            ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch");
-            preemtedClient = oldestAudio;
-        }
-    } else {
-        if (allocatedAudio + allocatedTuners >= mProperties.num_tuners) {
-            if (allocatedTuners != 0) {
-                ALOG_ASSERT(oldestTuner != 0, "addClient() allocatedTuners/oldestTuner mismatch");
-                preemtedClient = oldestTuner;
-            } else {
-                ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch");
-                preemtedClient = oldestAudio;
-            }
-        }
-    }
-    if (preemtedClient != 0) {
-        halTuner = preemtedClient->getTuner();
-        sp<TunerInterface> clear;
-        preemtedClient->setTuner(clear);
-        mHwDevice->closeTuner(halTuner);
-        if (preemtedClient->audio()) {
-            notifyDeviceConnection(false, "");
-        }
-    }
-
-    ret = mHwDevice->openTuner(&halConfig, audio,
-                               moduleClient,
-                               halTuner);
-    if (ret == 0) {
-        ALOGV("addClient() setTuner %p", halTuner.get());
-        moduleClient->setTuner(halTuner);
-        mModuleClients.add(moduleClient);
-        if (audio) {
-            notifyDeviceConnection(true, "");
-        }
-        ALOGV("addClient() DONE moduleClient %p", moduleClient.get());
-    } else {
-        ALOGW("%s open_tuner failed with error %d", __FUNCTION__, ret);
-        moduleClient.clear();
-    }
-
-    return moduleClient;
-}
-
-void RadioService::Module::removeClient(const sp<ModuleClient>& moduleClient) {
-    ALOGV("removeClient()");
-    AutoMutex lock(mLock);
-    int ret;
-    ssize_t index = -1;
-
-    for (size_t i = 0; i < mModuleClients.size(); i++) {
-        if (mModuleClients[i] == moduleClient) {
-            index = i;
-            break;
-        }
-    }
-    if (index == -1) {
-        return;
-    }
-
-    mModuleClients.removeAt(index);
-    sp<TunerInterface> halTuner = moduleClient->getTuner();
-    if (halTuner == NULL) {
-        return;
-    }
-
-    if (mHwDevice != 0) {
-        mHwDevice->closeTuner(halTuner);
-    }
-
-    if (moduleClient->audio()) {
-        notifyDeviceConnection(false, "");
-    }
-
-    mMute = true;
-
-    if (mModuleClients.isEmpty()) {
-        return;
-    }
-
-    if (mHwDevice == 0) {
-        return;
-    }
-
-    // Tuner reallocation logic:
-    // When a client is removed and was controlling a tuner, this tuner will be allocated to a
-    // previously preempted client. This client will be notified by a callback with
-    // RADIO_EVENT_CONTROL indicating gain of control.
-    // - If a preempted client is waiting for an audio source and one becomes available:
-    //    Allocate the tuner to the most recently added client waiting for an audio source
-    // - If not:
-    //    Allocate the tuner to the most recently added client.
-    // Each time a tuner using the audio source is opened or closed, the audio policy manager is
-    // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER.
-
-    sp<ModuleClient> youngestClient;
-    sp<ModuleClient> youngestClientAudio;
-    size_t allocatedTuners = 0;
-    size_t allocatedAudio = 0;
-    for (ssize_t i = mModuleClients.size() - 1; i >= 0; i--) {
-        if (mModuleClients[i]->getTuner() == NULL) {
-            if (mModuleClients[i]->audio()) {
-                if (youngestClientAudio == 0) {
-                    youngestClientAudio = mModuleClients[i];
-                }
-            } else {
-                if (youngestClient == 0) {
-                    youngestClient = mModuleClients[i];
-                }
-            }
-        } else {
-            if (mModuleClients[i]->audio()) {
-                allocatedAudio++;
-            } else {
-                allocatedTuners++;
-            }
-        }
-    }
-
-    ALOG_ASSERT(allocatedTuners + allocatedAudio < mProperties.num_tuners,
-                "removeClient() removed client but no tuner available");
-
-    ALOG_ASSERT(!moduleClient->audio() || allocatedAudio < mProperties.num_audio_sources,
-                "removeClient() removed audio client but no tuner with audio available");
-
-    if (allocatedAudio < mProperties.num_audio_sources && youngestClientAudio != 0) {
-        youngestClient = youngestClientAudio;
-    }
-
-    ALOG_ASSERT(youngestClient != 0, "removeClient() removed client no candidate found for tuner");
-
-    struct radio_hal_band_config halConfig = youngestClient->halConfig();
-    ret = mHwDevice->openTuner(&halConfig, youngestClient->audio(),
-                                moduleClient,
-                                halTuner);
-
-    if (ret == 0) {
-        youngestClient->setTuner(halTuner);
-        if (youngestClient->audio()) {
-            notifyDeviceConnection(true, "");
-        }
-    }
-}
-
-status_t RadioService::Module::setMute(bool mute)
-{
-    Mutex::Autolock _l(mLock);
-    if (mute != mMute) {
-        mMute = mute;
-        //TODO notifify audio policy manager of media activity on radio audio device
-    }
-    return NO_ERROR;
-}
-
-status_t RadioService::Module::getMute(bool *mute)
-{
-    Mutex::Autolock _l(mLock);
-    *mute = mMute;
-    return NO_ERROR;
-}
-
-
-const struct radio_band_config *RadioService::Module::getDefaultConfig() const
-{
-    if (mProperties.num_bands == 0) {
-        return NULL;
-    }
-    return &mProperties.bands[0];
-}
-
-void RadioService::Module::notifyDeviceConnection(bool connected,
-                                                  const char *address) {
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_FM_TUNER,
-                                          connected ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE :
-                                                  AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          address, kRadioTunerAudioDeviceName);
-    IPCThreadState::self()->restoreCallingIdentity(token);
-}
-
-#undef LOG_TAG
-#define LOG_TAG "RadioService::ModuleClient"
-
-RadioService::ModuleClient::ModuleClient(const sp<Module>& module,
-                                         const sp<IRadioClient>& client,
-                                         const struct radio_band_config *config,
-                                         bool audio)
- : mModule(module), mClient(client), mConfig(*config), mAudio(audio), mTuner(0)
-{
-}
-
-void RadioService::ModuleClient::onFirstRef()
-{
-    mCallbackThread = new CallbackThread(this);
-    IInterface::asBinder(mClient)->linkToDeath(this);
-}
-
-RadioService::ModuleClient::~ModuleClient() {
-    if (mClient != 0) {
-        IInterface::asBinder(mClient)->unlinkToDeath(this);
-        mClient.clear();
-    }
-    if (mCallbackThread != 0) {
-        mCallbackThread->exit();
-    }
-}
-
-void RadioService::ModuleClient::onEvent(radio_hal_event_t *halEvent)
-{
-    mCallbackThread->sendEvent(halEvent);
-}
-
-status_t RadioService::ModuleClient::dump(int fd __unused,
-                                             const Vector<String16>& args __unused) {
-    String8 result;
-    return NO_ERROR;
-}
-
-void RadioService::ModuleClient::detach() {
-    ALOGV("%s", __FUNCTION__);
-    sp<ModuleClient> strongMe = this;
-    {
-        AutoMutex lock(mLock);
-        if (mClient != 0) {
-            IInterface::asBinder(mClient)->unlinkToDeath(this);
-            mClient.clear();
-        }
-    }
-    sp<Module> module = mModule.promote();
-    if (module == 0) {
-        return;
-    }
-    module->removeClient(this);
-}
-
-radio_hal_band_config_t RadioService::ModuleClient::halConfig() const
-{
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    return mConfig.band;
-}
-
-sp<TunerInterface>& RadioService::ModuleClient::getTuner()
-{
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    return mTuner;
-}
-
-void RadioService::ModuleClient::setTuner(sp<TunerInterface>& tuner)
-{
-    ALOGV("%s %p", __FUNCTION__, this);
-
-    AutoMutex lock(mLock);
-    mTuner = tuner;
-    ALOGV("%s locked", __FUNCTION__);
-
-    radio_hal_event_t event;
-    event.type = RADIO_EVENT_CONTROL;
-    event.status = 0;
-    event.on = mTuner != 0;
-    mCallbackThread->sendEvent(&event);
-    ALOGV("%s DONE", __FUNCTION__);
-
-}
-
-status_t RadioService::ModuleClient::setConfiguration(const struct radio_band_config *config)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    status_t status = NO_ERROR;
-    ALOGV("%s locked", __FUNCTION__);
-
-    if (mTuner != 0) {
-        struct radio_hal_band_config halConfig;
-        halConfig = config->band;
-        status = (status_t)mTuner->setConfiguration(&halConfig);
-        if (status == NO_ERROR) {
-            mConfig = *config;
-        }
-    } else {
-        mConfig = *config;
-        status = INVALID_OPERATION;
-    }
-
-    return status;
-}
-
-status_t RadioService::ModuleClient::getConfiguration(struct radio_band_config *config)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    status_t status = NO_ERROR;
-    ALOGV("%s locked", __FUNCTION__);
-
-    if (mTuner != 0) {
-        struct radio_hal_band_config halConfig;
-        status = (status_t)mTuner->getConfiguration(&halConfig);
-        if (status == NO_ERROR) {
-            mConfig.band = halConfig;
-        }
-    }
-    *config = mConfig;
-
-    return status;
-}
-
-status_t RadioService::ModuleClient::setMute(bool mute)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    sp<Module> module;
-    {
-        Mutex::Autolock _l(mLock);
-        ALOGV("%s locked", __FUNCTION__);
-        if (mTuner == 0 || !mAudio) {
-            return INVALID_OPERATION;
-        }
-        module = mModule.promote();
-        if (module == 0) {
-            return NO_INIT;
-        }
-    }
-    module->setMute(mute);
-    return NO_ERROR;
-}
-
-status_t RadioService::ModuleClient::getMute(bool *mute)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    sp<Module> module;
-    {
-        Mutex::Autolock _l(mLock);
-        ALOGV("%s locked", __FUNCTION__);
-        module = mModule.promote();
-        if (module == 0) {
-            return NO_INIT;
-        }
-    }
-    return module->getMute(mute);
-}
-
-status_t RadioService::ModuleClient::scan(radio_direction_t direction, bool skipSubChannel)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    status_t status;
-    if (mTuner != 0) {
-        status = (status_t)mTuner->scan(direction, skipSubChannel);
-    } else {
-        status = INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t RadioService::ModuleClient::step(radio_direction_t direction, bool skipSubChannel)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    status_t status;
-    if (mTuner != 0) {
-        status = (status_t)mTuner->step(direction, skipSubChannel);
-    } else {
-        status = INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t RadioService::ModuleClient::tune(uint32_t channel, uint32_t subChannel)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    status_t status;
-    if (mTuner != 0) {
-        status = (status_t)mTuner->tune(channel, subChannel);
-    } else {
-        status = INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t RadioService::ModuleClient::cancel()
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    status_t status;
-    if (mTuner != 0) {
-        status = (status_t)mTuner->cancel();
-    } else {
-        status = INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t RadioService::ModuleClient::getProgramInformation(struct radio_program_info *info)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    AutoMutex lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    status_t status;
-    if (mTuner != NULL) {
-        status = (status_t)mTuner->getProgramInformation(info);
-    } else {
-        status = INVALID_OPERATION;
-    }
-
-    return status;
-}
-
-status_t RadioService::ModuleClient::hasControl(bool *hasControl)
-{
-    if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
-        return PERMISSION_DENIED;
-    }
-    Mutex::Autolock lock(mLock);
-    ALOGV("%s locked", __FUNCTION__);
-    *hasControl = mTuner != 0;
-    return NO_ERROR;
-}
-
-void RadioService::ModuleClient::onCallbackEvent(const sp<IMemory>& eventMemory)
-{
-    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
-        return;
-    }
-
-    sp<IRadioClient> client;
-    {
-        AutoMutex lock(mLock);
-        ALOGV("%s locked", __FUNCTION__);
-        radio_event_t *event = (radio_event_t *)eventMemory->pointer();
-        switch (event->type) {
-        case RADIO_EVENT_CONFIG:
-            mConfig.band = event->config.band;
-            event->config.region = mConfig.region;
-            break;
-        default:
-            break;
-        }
-
-        client = mClient;
-    }
-    if (client != 0) {
-        client->onEvent(eventMemory);
-    }
-}
-
-
-void RadioService::ModuleClient::binderDied(
-    const wp<IBinder> &who __unused) {
-    ALOGW("client binder died for client %p", this);
-    detach();
-}
-
-}; // namespace android
diff --git a/services/radio/RadioService.h b/services/radio/RadioService.h
deleted file mode 100644
index 444eb7a..0000000
--- a/services/radio/RadioService.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_RADIO_SERVICE_H
-#define ANDROID_HARDWARE_RADIO_SERVICE_H
-
-#include <utils/Vector.h>
-//#include <binder/AppOpsManager.h>
-#include <binder/MemoryDealer.h>
-#include <binder/BinderService.h>
-#include <binder/IAppOpsCallback.h>
-#include <radio/IRadioService.h>
-#include <radio/IRadio.h>
-#include <radio/IRadioClient.h>
-#include <system/radio.h>
-#include <hardware/radio.h>
-#include "RadioInterface.h"
-#include "TunerInterface.h"
-#include "TunerCallbackInterface.h"
-
-namespace android {
-
-class MemoryHeapBase;
-
-class RadioService :
-    public BinderService<RadioService>,
-    public BnRadioService
-{
-    friend class BinderService<RadioService>;
-
-public:
-    class ModuleClient;
-    class Module;
-
-    static char const* getServiceName() { return "media.radio"; }
-
-                        RadioService();
-    virtual             ~RadioService();
-
-    // IRadioService
-    virtual status_t listModules(struct radio_properties *properties,
-                                 uint32_t *numModules);
-
-    virtual status_t attach(radio_handle_t handle,
-                            const sp<IRadioClient>& client,
-                            const struct radio_band_config *config,
-                            bool withAudio,
-                            sp<IRadio>& radio);
-
-    virtual status_t    onTransact(uint32_t code, const Parcel& data,
-                                   Parcel* reply, uint32_t flags);
-
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-
-
-    class Module : public virtual RefBase {
-    public:
-
-       Module(sp<RadioInterface> hwDevice,
-              struct radio_properties properties);
-
-       virtual ~Module();
-
-               sp<ModuleClient> addClient(const sp<IRadioClient>& client,
-                                  const struct radio_band_config *config,
-                                  bool audio);
-
-               void removeClient(const sp<ModuleClient>& moduleClient);
-
-               status_t setMute(bool mute);
-
-               status_t getMute(bool *mute);
-
-       virtual status_t dump(int fd, const Vector<String16>& args);
-
-       sp<RadioInterface> hwDevice() const { return mHwDevice; }
-       const struct radio_properties properties() const { return mProperties; }
-       const struct radio_band_config *getDefaultConfig() const ;
-
-    private:
-
-       void notifyDeviceConnection(bool connected, const char *address);
-
-        Mutex                         mLock;          // protects  mModuleClients
-        sp<RadioInterface>            mHwDevice;      // HAL hardware device
-        const struct radio_properties mProperties;    // cached hardware module properties
-        Vector< sp<ModuleClient> >    mModuleClients; // list of attached clients
-        bool                          mMute;          // radio audio source state
-                                                      // when unmuted, audio is routed to the
-                                                      // output device selected for media use case.
-    }; // class Module
-
-    class CallbackThread : public Thread {
-    public:
-
-        explicit CallbackThread(const wp<ModuleClient>& moduleClient);
-
-        virtual ~CallbackThread();
-
-
-        // Thread virtuals
-        virtual bool threadLoop();
-
-        // RefBase
-        virtual void onFirstRef();
-
-                void exit();
-
-                void sendEvent(radio_hal_event_t *halEvent);
-                sp<IMemory> prepareEvent(radio_hal_event_t *halEvent);
-
-    private:
-        wp<ModuleClient>      mModuleClient;    // client module the thread belongs to
-        Condition             mCallbackCond;    // condition signaled when a new event is posted
-        Mutex                 mCallbackLock;    // protects mEventQueue
-        Vector< sp<IMemory> > mEventQueue;      // pending callback events
-        sp<MemoryDealer>      mMemoryDealer;    // shared memory for callback event
-    }; // class CallbackThread
-
-    class ModuleClient : public BnRadio,
-                   public IBinder::DeathRecipient,
-                   public TunerCallbackInterface {
-    public:
-
-       ModuleClient(const sp<Module>& module,
-              const sp<IRadioClient>& client,
-              const struct radio_band_config *config,
-              bool audio);
-
-       virtual ~ModuleClient();
-
-       // IRadio
-       virtual void detach();
-
-       virtual status_t setConfiguration(const struct radio_band_config *config);
-
-       virtual status_t getConfiguration(struct radio_band_config *config);
-
-       virtual status_t setMute(bool mute);
-
-       virtual status_t getMute(bool *mute);
-
-       virtual status_t scan(radio_direction_t direction, bool skipSubChannel);
-
-       virtual status_t step(radio_direction_t direction, bool skipSubChannel);
-
-       virtual status_t tune(unsigned int channel, unsigned int subChannel);
-
-       virtual status_t cancel();
-
-       virtual status_t getProgramInformation(struct radio_program_info *info);
-
-       virtual status_t hasControl(bool *hasControl);
-
-       virtual status_t dump(int fd, const Vector<String16>& args);
-
-               sp<IRadioClient> client() const { return mClient; }
-               wp<Module> module() const { return mModule; }
-               radio_hal_band_config_t halConfig() const;
-               sp<CallbackThread> callbackThread() const { return mCallbackThread; }
-               void setTuner(sp<TunerInterface>& tuner);
-               sp<TunerInterface>& getTuner();
-               bool audio() const { return mAudio; }
-
-               void onCallbackEvent(const sp<IMemory>& event);
-
-       virtual void onFirstRef();
-
-
-       // IBinder::DeathRecipient implementation
-       virtual void        binderDied(const wp<IBinder> &who);
-
-       // TunerCallbackInterface
-       virtual void onEvent(radio_hal_event_t *event);
-
-    private:
-
-        mutable Mutex               mLock;           // protects mClient, mConfig and mTuner
-        wp<Module>                  mModule;         // The module this client is attached to
-        sp<IRadioClient>            mClient;         // event callback binder interface
-        radio_band_config_t         mConfig;         // current band configuration
-        sp<CallbackThread>          mCallbackThread; // event callback thread
-        const bool                  mAudio;
-        sp<TunerInterface>          mTuner;        // HAL tuner interface. NULL indicates that
-                                                    // this client does not have control on any
-                                                    // tuner
-    }; // class ModuleClient
-
-
-    static void callback(radio_hal_event_t *halEvent, void *cookie);
-
-private:
-
-    virtual void onFirstRef();
-
-    static void convertProperties(radio_properties_t *properties,
-                                  const radio_hal_properties_t *halProperties);
-    Mutex               mServiceLock;   // protects mModules
-    volatile int32_t    mNextUniqueId;  // for module ID allocation
-    DefaultKeyedVector< radio_handle_t, sp<Module> > mModules;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_RADIO_SERVICE_H
diff --git a/services/radio/TunerCallbackInterface.h b/services/radio/TunerCallbackInterface.h
deleted file mode 100644
index 4973cce..0000000
--- a/services/radio/TunerCallbackInterface.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
-#define ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class TunerCallbackInterface : public virtual RefBase
-{
-public:
-    virtual void onEvent(radio_hal_event_t *event) = 0;
-
-protected:
-                 TunerCallbackInterface() {}
-    virtual      ~TunerCallbackInterface() {}
-
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_TUNER_CALLBACK_INTERFACE_H
diff --git a/services/radio/TunerInterface.h b/services/radio/TunerInterface.h
deleted file mode 100644
index 4e657d3..0000000
--- a/services/radio/TunerInterface.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_TUNER_INTERFACE_H
-#define ANDROID_HARDWARE_TUNER_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/radio.h>
-
-namespace android {
-
-class TunerInterface : public virtual RefBase
-{
-public:
-        /*
-         * Apply current radio band configuration (band, range, channel spacing ...).
-         *
-         * arguments:
-         * - config: the band configuration to apply
-         *
-         * returns:
-         *  0 if configuration could be applied
-         *  -EINVAL if configuration requested is invalid
-         *
-         * Automatically cancels pending scan, step or tune.
-         *
-         * Callback function with event RADIO_EVENT_CONFIG MUST be called once the
-         * configuration is applied or a failure occurs or after a time out.
-         */
-    virtual int setConfiguration(const radio_hal_band_config_t *config) = 0;
-
-        /*
-         * Retrieve current radio band configuration.
-         *
-         * arguments:
-         * - config: where to return the band configuration
-         *
-         * returns:
-         *  0 if valid configuration is returned
-         *  -EINVAL if invalid arguments are passed
-         */
-    virtual int getConfiguration(radio_hal_band_config_t *config) = 0;
-
-        /*
-         * Start scanning up to next valid station.
-         * Must be called when a valid configuration has been applied.
-         *
-         * arguments:
-         * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN
-         * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels
-         *  (e.g SPS for HD radio).
-         *
-         * returns:
-         *  0 if scan successfully started
-         *  -ENOSYS if called out of sequence
-         *  -ENODEV if another error occurs
-         *
-         * Automatically cancels pending scan, step or tune.
-         *
-         *  Callback function with event RADIO_EVENT_TUNED MUST be called once
-         *  locked on a station or after a time out or full frequency scan if
-         *  no station found. The event status should indicate if a valid station
-         *  is tuned or not.
-         */
-    virtual int scan(radio_direction_t direction, bool skip_sub_channel) = 0;
-
-        /*
-         * Move one channel spacing up or down.
-         * Must be called when a valid configuration has been applied.
-         *
-         * arguments:
-         * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN
-         * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels
-         *  (e.g SPS for HD radio).
-         *
-         * returns:
-         *  0 if step successfully started
-         *  -ENOSYS if called out of sequence
-         *  -ENODEV if another error occurs
-         *
-         * Automatically cancels pending scan, step or tune.
-         *
-         * Callback function with event RADIO_EVENT_TUNED MUST be called once
-         * step completed or after a time out. The event status should indicate
-         * if a valid station is tuned or not.
-         */
-    virtual int step(radio_direction_t direction, bool skip_sub_channel) = 0;
-
-        /*
-         * Tune to specified frequency.
-         * Must be called when a valid configuration has been applied.
-         *
-         * arguments:
-         * - channel: channel to tune to. A frequency in kHz for AM/FM/HD Radio bands.
-         * - sub_channel: valid for HD radio or digital radios only: (e.g SPS number for HD radio).
-         *
-         * returns:
-         *  0 if tune successfully started
-         *  -ENOSYS if called out of sequence
-         *  -EINVAL if invalid arguments are passed
-         *  -ENODEV if another error occurs
-         *
-         * Automatically cancels pending scan, step or tune.
-         *
-         * Callback function with event RADIO_EVENT_TUNED MUST be called once
-         * tuned or after a time out. The event status should indicate
-         * if a valid station is tuned or not.
-         */
-    virtual int tune(unsigned int channel, unsigned int sub_channel) = 0;
-
-        /*
-         * Cancel a scan, step or tune operation.
-         * Must be called while a scan, step or tune operation is pending
-         * (callback not yet sent).
-         *
-         * returns:
-         *  0 if successful
-         *  -ENOSYS if called out of sequence
-         *  -ENODEV if another error occurs
-         *
-         * The callback is not sent.
-         */
-    virtual int cancel() = 0;
-
-        /*
-         * Retrieve current station information.
-         *
-         * arguments:
-         * - info: where to return the program info.
-         * If info->metadata is NULL. no meta data should be returned.
-         * If meta data must be returned, they should be added to or cloned to
-         * info->metadata, not passed from a newly created meta data buffer.
-         *
-         * returns:
-         *  0 if tuned and information available
-         *  -EINVAL if invalid arguments are passed
-         *  -ENODEV if another error occurs
-         */
-    virtual int getProgramInformation(radio_program_info_t *info) = 0;
-
-protected:
-                TunerInterface() {}
-    virtual     ~TunerInterface() {}
-
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_TUNER_INTERFACE_H
diff --git a/services/soundtrigger/OWNERS b/services/soundtrigger/OWNERS
new file mode 100644
index 0000000..e83f6b9
--- /dev/null
+++ b/services/soundtrigger/OWNERS
@@ -0,0 +1,2 @@
+elaurent@google.com
+thorntonc@google.com
diff --git a/soundtrigger/OWNERS b/soundtrigger/OWNERS
new file mode 100644
index 0000000..e83f6b9
--- /dev/null
+++ b/soundtrigger/OWNERS
@@ -0,0 +1,2 @@
+elaurent@google.com
+thorntonc@google.com
diff --git a/tools/OWNERS b/tools/OWNERS
new file mode 100644
index 0000000..6dcb035
--- /dev/null
+++ b/tools/OWNERS
@@ -0,0 +1 @@
+gkasten@android.com