Merge "hdr10+: parameter passing for OMX"
diff --git a/apex/Android.bp b/apex/Android.bp
index 449d29c..05cc2c5 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -24,6 +24,8 @@
         "libmkvextractor",
         "libmp3extractor",
         "libmp4extractor",
+        "libmpeg2extractor",
+        "liboggextractor",
         "libwavextractor",
     ],
     key: "com.android.media.key",
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 94f9e02..41d1833 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -73,7 +73,6 @@
         // Suppress unused parameter and no error options. These cause problems
         // with the when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ],
 }
 
@@ -106,7 +105,6 @@
         // Suppress unused parameter and no error options. These cause problems
         // when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ],
 }
 
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index dcd59b7..9e0115e 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -34,7 +34,6 @@
         // Suppress unused parameter and no error options. These cause problems
         // when using the map type in a proto definition.
         "-Wno-unused-parameter",
-        "-Wno-error",
     ]
 }
 
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index 292ec93..705aa81 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -183,32 +183,32 @@
         mBuffer = buf;
     }
 
-    ~MediaBufferHelperV3() {}
+    virtual ~MediaBufferHelperV3() {}
 
-    void release() {
+    virtual void release() {
         mBuffer->release(mBuffer->handle);
     }
 
-    void* data() {
+    virtual void* data() {
         return mBuffer->data(mBuffer->handle);
     }
 
-    size_t size() {
+    virtual size_t size() {
         return mBuffer->size(mBuffer->handle);
     }
 
-    size_t range_offset() {
+    virtual size_t range_offset() {
         return mBuffer->range_offset(mBuffer->handle);
     }
 
-    size_t range_length() {
+    virtual size_t range_length() {
         return mBuffer->range_length(mBuffer->handle);
     }
 
-    void set_range(size_t offset, size_t length) {
+    virtual void set_range(size_t offset, size_t length) {
         mBuffer->set_range(mBuffer->handle, offset, length);
     }
-    AMediaFormat *meta_data() {
+    virtual AMediaFormat *meta_data() {
         return mBuffer->meta_data(mBuffer->handle);
     }
 };
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
index 2c734ac..5260909 100644
--- a/media/bufferpool/2.0/AccessorImpl.cpp
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
@@ -253,9 +253,21 @@
 }
 
 void Accessor::Impl::handleInvalidateAck() {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    mBufferPool.mInvalidation.onHandleAck();
+    std::map<ConnectionId, const sp<IObserver>> observers;
+    uint32_t invalidationId;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        mBufferPool.processStatusMessages();
+        mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+    }
+    // Do not hold lock for send invalidations
+    for (auto it = observers.begin(); it != observers.end(); ++it) {
+        const sp<IObserver> observer = it->second;
+        if (observer) {
+            Return<void> transResult = observer->onMessage(it->first, invalidationId);
+            (void) transResult;
+        }
+    }
 }
 
 bool Accessor::Impl::isValid() {
@@ -365,19 +377,21 @@
     sInvalidator->addAccessor(mId, impl);
 }
 
-void Accessor::Impl::BufferPool::Invalidation::onHandleAck() {
+void Accessor::Impl::BufferPool::Invalidation::onHandleAck(
+        std::map<ConnectionId, const sp<IObserver>> *observers,
+        uint32_t *invalidationId) {
     if (mInvalidationId != 0) {
+        *invalidationId = mInvalidationId;
         std::set<int> deads;
         for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
             if (it->second != mInvalidationId) {
                 const sp<IObserver> observer = mObservers[it->first];
                 if (observer) {
-                    ALOGV("connection %lld call observer (%u: %u)",
+                    observers->emplace(it->first, observer);
+                    ALOGV("connection %lld will call observer (%u: %u)",
                           (long long)it->first, it->second, mInvalidationId);
-                    Return<void> transResult = observer->onMessage(it->first, mInvalidationId);
-                    (void) transResult;
-                    // N.B: ignore possibility of onMessage oneway call being
-                    // lost.
+                    // N.B: onMessage will be called later. ignore possibility of
+                    // onMessage# oneway call being lost.
                     it->second = mInvalidationId;
                 } else {
                     ALOGV("bufferpool2 observer died %lld", (long long)it->first);
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
index b3faa96..eea72b9 100644
--- a/media/bufferpool/2.0/AccessorImpl.h
+++ b/media/bufferpool/2.0/AccessorImpl.h
@@ -158,7 +158,9 @@
                     BufferInvalidationChannel &channel,
                     const std::shared_ptr<Accessor::Impl> &impl);
 
-            void onHandleAck();
+            void onHandleAck(
+                    std::map<ConnectionId, const sp<IObserver>> *observers,
+                    uint32_t *invalidationId);
         } mInvalidation;
         /// Buffer pool statistics which tracks allocation and transfer statistics.
         struct Stats {
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index ee5cf27..cf06623 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -768,7 +768,11 @@
     s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
 
     s_profile_params_ip.e_profile = mIntf->getProfile_l();
-    s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode;
+    if (s_profile_params_ip.e_profile == IV_PROFILE_BASE) {
+        s_profile_params_ip.u4_entropy_coding_mode = 0;
+    } else {
+        s_profile_params_ip.u4_entropy_coding_mode = 1;
+    }
     s_profile_params_ip.u4_timestamp_high = -1;
     s_profile_params_ip.u4_timestamp_low = -1;
 
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index 280ae36..48825e4 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -405,10 +405,7 @@
     int numFrames = 0;
     int ret = vorbis_dsp_synthesis(mState, &pack, 1);
     if (0 != ret) {
-        ALOGE("vorbis_dsp_synthesis returned %d", ret);
-        mSignalledError = true;
-        work->result = C2_CORRUPTED;
-        return;
+        ALOGD("vorbis_dsp_synthesis returned %d; ignored", ret);
     } else {
         numFrames = vorbis_dsp_pcmout(
                 mState,  reinterpret_cast<int16_t *> (wView.data()),
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 8ecbf5d..9ba2362 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -188,6 +188,24 @@
                 .withConstValue(defaultColorInfo)
                 .build());
 
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
         // TODO: support more formats?
         addParameter(
                 DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
@@ -228,6 +246,22 @@
         return C2R::Ok();
     }
 
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+            me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+            me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+            me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+            me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
 
     static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
                                   const C2P<C2StreamPictureSizeInfo::output> &size) {
@@ -236,6 +270,9 @@
         (void)me;  // TODO: validate
         return C2R::Ok();
     }
+    std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
+        return mDefaultColorAspects;
+    }
 
     static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) {
         (void)mayBlock;
@@ -256,6 +293,7 @@
     std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
     std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
     std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
 #ifdef VP9
 #if 0
     std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
@@ -524,32 +562,129 @@
 static void copyOutputBufferToYV12Frame(uint8_t *dst,
         const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
         size_t srcYStride, size_t srcUStride, size_t srcVStride,
-        uint32_t width, uint32_t height, int32_t bpp) {
-    size_t dstYStride = align(width, 16) * bpp ;
+        uint32_t width, uint32_t height) {
+    size_t dstYStride = align(width, 16);
     size_t dstUVStride = align(dstYStride / 2, 16);
     uint8_t *dstStart = dst;
 
     for (size_t i = 0; i < height; ++i) {
-         memcpy(dst, srcY, width * bpp);
+         memcpy(dst, srcY, width);
          srcY += srcYStride;
          dst += dstYStride;
     }
 
     dst = dstStart + dstYStride * height;
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcV, width / 2 * bpp);
+         memcpy(dst, srcV, width / 2);
          srcV += srcVStride;
          dst += dstUVStride;
     }
 
     dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
     for (size_t i = 0; i < height / 2; ++i) {
-         memcpy(dst, srcU, width / 2 * bpp);
+         memcpy(dst, srcU, width / 2);
          srcU += srcUStride;
          dst += dstUVStride;
     }
 }
 
+static void convertYUV420Planar16ToY410(uint32_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    // Converting two lines at a time, slightly faster
+    for (size_t y = 0; y < height; y += 2) {
+        uint32_t *dstTop = (uint32_t *) dst;
+        uint32_t *dstBot = (uint32_t *) (dst + dstStride);
+        uint16_t *ySrcTop = (uint16_t*) srcY;
+        uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride);
+        uint16_t *uSrc = (uint16_t*) srcU;
+        uint16_t *vSrc = (uint16_t*) srcV;
+
+        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
+        size_t x = 0;
+        for (; x < width - 3; x += 4) {
+
+            u01 = *((uint32_t*)uSrc); uSrc += 2;
+            v01 = *((uint32_t*)vSrc); vSrc += 2;
+
+            y01 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y23 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y45 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+            y67 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);
+
+            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
+            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;
+
+            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
+            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
+        }
+
+        // There should be at most 2 more pixels to process. Note that we don't
+        // need to consider odd case as the buffer is always aligned to even.
+        if (x < width) {
+            u01 = *uSrc;
+            v01 = *vSrc;
+            y01 = *((uint32_t*)ySrcTop);
+            y45 = *((uint32_t*)ySrcBot);
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = ((y01 >> 16) << 10) | uv0;
+            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = ((y45 >> 16) << 10) | uv0;
+        }
+
+        srcY += srcYStride * 2;
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dst += dstStride * 2;
+    }
+
+    return;
+}
+
+static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    uint8_t *dstY = (uint8_t *)dst;
+    size_t dstYSize = dstStride * height;
+    size_t dstUVStride = align(dstStride / 2, 16);
+    size_t dstUVSize = dstUVStride * height / 2;
+    uint8_t *dstV = dstY + dstYSize;
+    uint8_t *dstU = dstV + dstUVSize;
+
+    for (size_t y = 0; y < height; ++y) {
+        for (size_t x = 0; x < width; ++x) {
+            dstY[x] = (uint8_t)(srcY[x] >> 2);
+        }
+
+        srcY += srcYStride;
+        dstY += dstStride;
+    }
+
+    for (size_t y = 0; y < (height + 1) / 2; ++y) {
+        for (size_t x = 0; x < (width + 1) / 2; ++x) {
+            dstU[x] = (uint8_t)(srcU[x] >> 2);
+            dstV[x] = (uint8_t)(srcV[x] >> 2);
+        }
+
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dstU += dstUVStride;
+        dstV += dstUVStride;
+    }
+    return;
+}
 bool C2SoftVpxDec::outputBuffer(
         const std::shared_ptr<C2BlockPool> &pool,
         const std::unique_ptr<C2Work> &work)
@@ -581,15 +716,21 @@
 
     }
     CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
-    int32_t bpp = 1;
-    if (img->fmt == VPX_IMG_FMT_I42016) {
-        bpp = 2;
-    }
 
     std::shared_ptr<C2GraphicBlock> block;
     uint32_t format = HAL_PIXEL_FORMAT_YV12;
+    if (img->fmt == VPX_IMG_FMT_I42016) {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l();
+
+        if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+            defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+            defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+            format = HAL_PIXEL_FORMAT_RGBA_1010102;
+        }
+    }
     C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16) * bpp, mHeight, format, usage, &block);
+    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &block);
     if (err != C2_OK) {
         ALOGE("fetchGraphicBlock for Output failed with status %d", err);
         work->result = err;
@@ -610,12 +751,30 @@
     size_t srcYStride = img->stride[VPX_PLANE_Y];
     size_t srcUStride = img->stride[VPX_PLANE_U];
     size_t srcVStride = img->stride[VPX_PLANE_V];
-    const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
-    const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
-    const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
-    copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV,
-                                srcYStride, srcUStride, srcVStride, mWidth, mHeight, bpp);
 
+    if (img->fmt == VPX_IMG_FMT_I42016) {
+        const uint16_t *srcY = (const uint16_t *)img->planes[VPX_PLANE_Y];
+        const uint16_t *srcU = (const uint16_t *)img->planes[VPX_PLANE_U];
+        const uint16_t *srcV = (const uint16_t *)img->planes[VPX_PLANE_V];
+
+        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    align(mWidth, 16),
+                                    mWidth, mHeight);
+        } else {
+            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    align(mWidth, 16),
+                                    mWidth, mHeight);
+        }
+    } else {
+        const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
+        const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
+        const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
+        copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV,
+                                srcYStride, srcUStride, srcVStride, mWidth, mHeight);
+    }
     finishWork(*(int64_t *)img->user_priv, work, std::move(block));
     return true;
 }
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index 22e8d84..4878974 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -366,16 +366,165 @@
                 generation, igbp_id, igbp_slot);
     }
 
-    // UGLY HACK: assume YCbCr 4:2:0 8-bit format (and lockable via lockYCbCr) if we don't
-    // recognize the format
-    PixelFormat format = mInfo.mapperInfo.format;
-    if (format != PixelFormat::RGBA_8888 && format != PixelFormat::RGBX_8888) {
-        format = PixelFormat::YCBCR_420_888;
-    }
+    switch (mInfo.mapperInfo.format) {
+        case PixelFormat::RGBA_1010102: {
+            // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
+            // Surface. In all other cases it is RGBA. We don't know which case it is here, so
+            // default to YUV for now.
+            void *pointer = nullptr;
+            mMapper->lock(
+                    const_cast<native_handle_t *>(mBuffer),
+                    grallocUsage,
+                    { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
+                    // TODO: fence
+                    hidl_handle(),
+                    [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+                        err = maperr2error(maperr);
+                        if (err == C2_OK) {
+                            pointer = mapPointer;
+                        }
+                    });
+            if (err != C2_OK) {
+                ALOGD("lock failed: %d", err);
+                return err;
+            }
+            // treat as 32-bit values
+            addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
+            layout->type = C2PlanarLayout::TYPE_YUVA;
+            layout->numPlanes = 4;
+            layout->rootPlanes = 1;
+            layout->planes[C2PlanarLayout::PLANE_Y] = {
+                C2PlaneInfo::CHANNEL_Y,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                10,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_U] = {
+                C2PlaneInfo::CHANNEL_CB,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_V] = {
+                C2PlaneInfo::CHANNEL_CR,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                10,                             // bitDepth
+                20,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_A] = {
+                C2PlaneInfo::CHANNEL_A,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                32,                             // allocatedDepth
+                2,                              // bitDepth
+                30,                             // rightShift
+                C2PlaneInfo::LITTLE_END,        // endianness
+                C2PlanarLayout::PLANE_Y,        // rootIx
+                0,                              // offset
+            };
+            break;
+        }
 
-    switch (format) {
+        case PixelFormat::RGBA_8888:
+            // TODO: alpha channel
+            // fall-through
+        case PixelFormat::RGBX_8888: {
+            void *pointer = nullptr;
+            mMapper->lock(
+                    const_cast<native_handle_t *>(mBuffer),
+                    grallocUsage,
+                    { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
+                    // TODO: fence
+                    hidl_handle(),
+                    [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+                        err = maperr2error(maperr);
+                        if (err == C2_OK) {
+                            pointer = mapPointer;
+                        }
+                    });
+            if (err != C2_OK) {
+                ALOGD("lock failed: %d", err);
+                return err;
+            }
+            addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
+            addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
+            addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
+            layout->type = C2PlanarLayout::TYPE_RGB;
+            layout->numPlanes = 3;
+            layout->rootPlanes = 1;
+            layout->planes[C2PlanarLayout::PLANE_R] = {
+                C2PlaneInfo::CHANNEL_R,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                0,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_G] = {
+                C2PlaneInfo::CHANNEL_G,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                1,                              // offset
+            };
+            layout->planes[C2PlanarLayout::PLANE_B] = {
+                C2PlaneInfo::CHANNEL_B,         // channel
+                4,                              // colInc
+                4 * (int32_t)mInfo.stride,      // rowInc
+                1,                              // mColSampling
+                1,                              // mRowSampling
+                8,                              // allocatedDepth
+                8,                              // bitDepth
+                0,                              // rightShift
+                C2PlaneInfo::NATIVE,            // endianness
+                C2PlanarLayout::PLANE_R,        // rootIx
+                2,                              // offset
+            };
+            break;
+        }
+
         case PixelFormat::YCBCR_420_888:
-        case PixelFormat::YV12: {
+            // fall-through
+        case PixelFormat::YV12:
+            // fall-through
+        default: {
             YCbCrLayout ycbcrLayout;
             mMapper->lockYCbCr(
                     const_cast<native_handle_t *>(mBuffer), grallocUsage,
@@ -450,79 +599,6 @@
             }
             break;
         }
-
-        case PixelFormat::RGBA_8888:
-            // TODO: alpha channel
-            // fall-through
-        case PixelFormat::RGBX_8888: {
-            void *pointer = nullptr;
-            mMapper->lock(
-                    const_cast<native_handle_t *>(mBuffer),
-                    grallocUsage,
-                    { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
-                    // TODO: fence
-                    hidl_handle(),
-                    [&err, &pointer](const auto &maperr, const auto &mapPointer) {
-                        err = maperr2error(maperr);
-                        if (err == C2_OK) {
-                            pointer = mapPointer;
-                        }
-                    });
-            if (err != C2_OK) {
-                ALOGD("lock failed: %d", err);
-                return err;
-            }
-            addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
-            addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
-            addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
-            layout->type = C2PlanarLayout::TYPE_RGB;
-            layout->numPlanes = 3;
-            layout->rootPlanes = 1;
-            layout->planes[C2PlanarLayout::PLANE_R] = {
-                C2PlaneInfo::CHANNEL_R,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                0,                              // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_G] = {
-                C2PlaneInfo::CHANNEL_G,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                1,                              // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_B] = {
-                C2PlaneInfo::CHANNEL_B,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                2,                              // offset
-            };
-            break;
-        }
-        default: {
-            ALOGD("unsupported pixel format: %d", mInfo.mapperInfo.format);
-            return C2_OMITTED;
-        }
     }
     mLocked = true;
 
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index c4b539d..390ba43 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1553,9 +1553,40 @@
                 return ERROR_IO;
             }
 
-            String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
-            AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+            // Prior to API 29, the metadata track was not compliant with ISO/IEC
+            // 14496-12-2015. This led to some ISO-compliant parsers failing to read the
+            // metatrack. As of API 29 and onwards, a change was made to metadata track to
+            // make it compliant with the standard. The workaround is to write the
+            // null-terminated mime_format string twice. This allows compliant parsers to
+            // read the missing reserved, data_reference_index, and content_encoding fields
+            // from the first mime_type string. The actual mime_format field would then be
+            // read correctly from the second string. The non-compliant Android frameworks
+            // from API 28 and earlier would still be able to read the mime_format correctly
+            // as it would only read the first null-terminated mime_format string. To enable
+            // reading metadata tracks generated from both the non-compliant and compliant
+            // formats, a check needs to be done to see which format is used.
+            int null_pos = 0;
+            const unsigned char *str = buffer.get();
+            while (null_pos < chunk_data_size) {
+              if (*(str + null_pos) == '\0') {
+                break;
+              }
+              ++null_pos;
+            }
 
+            if (null_pos == chunk_data_size - 1) {
+              // This is not a standard ompliant metadata track.
+              String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
+              AMediaFormat_setString(mLastTrack->meta,
+                  AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+            } else {
+              // This is a standard compliant metadata track.
+              String8 contentEncoding((const char *)(buffer.get() + 8));
+              String8 mimeFormat((const char *)(buffer.get() + 8 + contentEncoding.size() + 1),
+                  chunk_data_size - 8 - contentEncoding.size() - 1);
+              AMediaFormat_setString(mLastTrack->meta,
+                  AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+            }
             break;
         }
 
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 38c86eb..b816093 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -15,14 +15,11 @@
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
         "android.hidl.token@1.0-utils",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhidlallocatorutils",
+        "android.hidl.allocator@1.0",
+        "libhidlmemory",
         "libhidlbase",
         "liblog",
-        "libmediaextractor",
-        "libstagefright_foundation",
+        "libmediandk",
     ],
 
     header_libs: [
@@ -30,8 +27,13 @@
     ],
 
     static_libs: [
+        "libcrypto",
+        "libstagefright_foundation",
         "libstagefright_mpeg2support",
+        "libmediaextractor",
         "libutils",
+        "libstagefright",
+        "libstagefright_esds",
     ],
 
     name: "libmpeg2extractor",
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 366aa59..c10a797 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -31,27 +31,27 @@
 __attribute__ ((visibility ("default")))
 ExtractorDef GETEXTRACTORDEF() {
     return {
-        EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION_CURRENT + 1,
         UUID("3d1dcfeb-e40a-436d-a574-c2438a555e5f"),
         1,
         "MPEG2-PS/TS Extractor",
         {
-            [](
+            .v3 = [](
                     CDataSource *source,
                     float *confidence,
                     void **,
-                    FreeMetaFunc *) -> CreatorFunc {
+                    FreeMetaFunc *) -> CreatorFuncV3 {
                 DataSourceHelper helper(source);
                 if (SniffMPEG2TS(&helper, confidence)) {
                     return [](
                             CDataSource *source,
-                            void *) -> CMediaExtractor* {
-                        return wrap(new MPEG2TSExtractor(new DataSourceHelper(source)));};
+                            void *) -> CMediaExtractorV3* {
+                        return wrapV3(new MPEG2TSExtractor(new DataSourceHelper(source)));};
                 } else if (SniffMPEG2PS(&helper, confidence)) {
                             return [](
                                     CDataSource *source,
-                                    void *) -> CMediaExtractor* {
-                                return wrap(new MPEG2PSExtractor(new DataSourceHelper(source)));};
+                                    void *) -> CMediaExtractorV3* {
+                                return wrapV3(new MPEG2PSExtractor(new DataSourceHelper(source)));};
                 }
                 return NULL;
             }
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index fc13d2c..b60fc4e 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -33,22 +33,23 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
 #include <utils/String8.h>
 
 #include <inttypes.h>
 
 namespace android {
 
-struct MPEG2PSExtractor::Track : public MediaTrackHelper, public RefBase {
+struct MPEG2PSExtractor::Track : public MediaTrackHelperV3 {
     Track(MPEG2PSExtractor *extractor,
           unsigned stream_id, unsigned stream_type);
 
-    virtual status_t start();
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options);
+    virtual media_status_t read(
+            MediaBufferHelperV3 **buffer, const ReadOptions *options);
 
 protected:
     virtual ~Track();
@@ -71,22 +72,22 @@
     DISALLOW_EVIL_CONSTRUCTORS(Track);
 };
 
-struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelper {
-    WrappedTrack(MPEG2PSExtractor *extractor, const sp<Track> &track);
+struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelperV3 {
+    WrappedTrack(MPEG2PSExtractor *extractor, Track *track);
 
-    virtual status_t start();
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options);
+    virtual media_status_t read(
+            MediaBufferHelperV3 **buffer, const ReadOptions *options);
 
 protected:
     virtual ~WrappedTrack();
 
 private:
     MPEG2PSExtractor *mExtractor;
-    sp<MPEG2PSExtractor::Track> mTrack;
+    MPEG2PSExtractor::Track *mTrack;
 
     DISALLOW_EVIL_CONSTRUCTORS(WrappedTrack);
 };
@@ -107,13 +108,14 @@
     }
 
     // Remove all tracks that were unable to determine their format.
-    MetaDataBase meta;
+    AMediaFormat *meta = AMediaFormat_new();
     for (size_t i = mTracks.size(); i > 0;) {
         i--;
-        if (mTracks.valueAt(i)->getFormat(meta) != OK) {
+        if (mTracks.valueAt(i)->getFormat(meta) != AMEDIA_OK) {
             mTracks.removeItemsAt(i);
         }
     }
+    AMediaFormat_delete(meta);
 
     mScanning = false;
 }
@@ -126,7 +128,7 @@
     return mTracks.size();
 }
 
-MediaTrackHelper *MPEG2PSExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MPEG2PSExtractor::getTrack(size_t index) {
     if (index >= mTracks.size()) {
         return NULL;
     }
@@ -134,20 +136,20 @@
     return new WrappedTrack(this, mTracks.valueAt(index));
 }
 
-status_t MPEG2PSExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MPEG2PSExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (index >= mTracks.size()) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     return mTracks.valueAt(index)->getFormat(meta);
 }
 
-status_t MPEG2PSExtractor::getMetaData(MetaDataBase &meta) {
-    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
+media_status_t MPEG2PSExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
 
-    return OK;
+    return AMEDIA_OK;
 }
 
 uint32_t MPEG2PSExtractor::flags() const {
@@ -635,42 +637,55 @@
     mQueue = NULL;
 }
 
-status_t MPEG2PSExtractor::Track::start() {
+media_status_t MPEG2PSExtractor::Track::start() {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    return mSource->start(NULL); // AnotherPacketSource::start doesn't use its argument
+    // initialize with one small buffer, but allow growth
+    mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+    if (mSource->start(NULL) == OK) { // AnotherPacketSource::start doesn't use its argument
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2PSExtractor::Track::stop() {
+media_status_t MPEG2PSExtractor::Track::stop() {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
-    return mSource->stop();
+    if (mSource->stop() == OK) {
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2PSExtractor::Track::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg);
+
+media_status_t MPEG2PSExtractor::Track::getFormat(AMediaFormat *meta) {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     sp<MetaData> sourceMeta = mSource->getFormat();
-    meta = *sourceMeta;
-    return OK;
+    sp<AMessage> msg;
+    convertMetaDataToMessage(sourceMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2PSExtractor::Track::read(
-        MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::Track::read(
+        MediaBufferHelperV3 **buffer, const ReadOptions *options) {
     if (mSource == NULL) {
-        return NO_INIT;
+        return AMEDIA_ERROR_UNKNOWN;
     }
 
     status_t finalResult;
     while (!mSource->hasBufferAvailable(&finalResult)) {
         if (finalResult != OK) {
-            return ERROR_END_OF_STREAM;
+            return AMEDIA_ERROR_END_OF_STREAM;
         }
 
         status_t err = mExtractor->feedMore();
@@ -680,7 +695,46 @@
         }
     }
 
-    return mSource->read(buffer, (MediaSource::ReadOptions*)options);
+    MediaBufferBase *mbuf;
+    mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    size_t length = mbuf->range_length();
+    MediaBufferHelperV3 *outbuf;
+    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    memcpy(outbuf->data(), mbuf->data(), length);
+    outbuf->set_range(0, length);
+    *buffer = outbuf;
+    MetaDataBase &inMeta = mbuf->meta_data();
+    AMediaFormat *outMeta = outbuf->meta_data();
+    int64_t val64;
+    if (inMeta.findInt64(kKeyTime, &val64)) {
+        AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+    }
+    int32_t val32;
+    if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+    }
+    if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+    }
+    uint32_t bufType;
+    const void *bufData;
+    size_t bufSize;
+    if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+    }
+    return AMEDIA_OK;
 }
 
 status_t MPEG2PSExtractor::Track::appendPESData(
@@ -726,7 +780,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG2PSExtractor::WrappedTrack::WrappedTrack(
-        MPEG2PSExtractor *extractor, const sp<Track> &track)
+        MPEG2PSExtractor *extractor, Track *track)
     : mExtractor(extractor),
       mTrack(track) {
 }
@@ -734,20 +788,20 @@
 MPEG2PSExtractor::WrappedTrack::~WrappedTrack() {
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::start() {
+media_status_t MPEG2PSExtractor::WrappedTrack::start() {
     return mTrack->start();
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::stop() {
+media_status_t MPEG2PSExtractor::WrappedTrack::stop() {
     return mTrack->stop();
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::getFormat(MetaDataBase &meta) {
+media_status_t MPEG2PSExtractor::WrappedTrack::getFormat(AMediaFormat *meta) {
     return mTrack->getFormat(meta);
 }
 
-status_t MPEG2PSExtractor::WrappedTrack::read(
-        MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::WrappedTrack::read(
+        MediaBufferHelperV3 **buffer, const ReadOptions *options) {
     return mTrack->read(buffer, options);
 }
 
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h
index c4082ef..d251688 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.h
@@ -32,14 +32,14 @@
 struct Track;
 class String8;
 
-struct MPEG2PSExtractor : public MediaExtractorPluginHelper {
+struct MPEG2PSExtractor : public MediaExtractorPluginHelperV3 {
     explicit MPEG2PSExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrackHelper *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelperV3 *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
 
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG2PSExtractor"; }
@@ -57,7 +57,7 @@
     off64_t mOffset;
     status_t mFinalResult;
     sp<ABuffer> mBuffer;
-    KeyedVector<unsigned, sp<Track> > mTracks;
+    KeyedVector<unsigned, Track* > mTracks;
     bool mScanning;
 
     bool mProgramStreamMapValid;
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index 605b13a..fc066ee 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -34,6 +34,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
 #include <utils/String8.h>
 
 #include "mpeg2ts/AnotherPacketSource.h"
@@ -50,19 +51,19 @@
 static const int kMaxDurationReadSize = 250000LL;
 static const int kMaxDurationRetry = 6;
 
-struct MPEG2TSSource : public MediaTrackHelper {
+struct MPEG2TSSource : public MediaTrackHelperV3 {
     MPEG2TSSource(
             MPEG2TSExtractor *extractor,
             const sp<AnotherPacketSource> &impl,
             bool doesSeek);
     virtual ~MPEG2TSSource();
 
-    virtual status_t start();
-    virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &);
+    virtual media_status_t start();
+    virtual media_status_t stop();
+    virtual media_status_t getFormat(AMediaFormat *);
 
-    virtual status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+    virtual media_status_t read(
+            MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
 
 private:
     MPEG2TSExtractor *mExtractor;
@@ -87,22 +88,84 @@
 MPEG2TSSource::~MPEG2TSSource() {
 }
 
-status_t MPEG2TSSource::start() {
-    return mImpl->start(NULL); // AnotherPacketSource::start() doesn't use its argument
+media_status_t MPEG2TSSource::start() {
+    // initialize with one small buffer, but allow growth
+    mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+    if (!mImpl->start(NULL)) { // AnotherPacketSource::start() doesn't use its argument
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2TSSource::stop() {
-    return mImpl->stop();
+media_status_t MPEG2TSSource::stop() {
+    if (!mImpl->stop()) {
+        return AMEDIA_OK;
+    }
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
-status_t MPEG2TSSource::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg) {
+    size_t numEntries = msg->countEntries();
+    for (size_t i = 0; i < numEntries; i++) {
+        AMessage::Type type;
+        const char *name = msg->getEntryNameAt(i, &type);
+        AMessage::ItemData id = msg->getEntryAt(i);
+
+        switch (type) {
+            case AMessage::kTypeInt32:
+                int32_t val32;
+                if (id.find(&val32)) {
+                    AMediaFormat_setInt32(format, name, val32);
+                }
+                break;
+            case AMessage::kTypeInt64:
+                int64_t val64;
+                if (id.find(&val64)) {
+                    AMediaFormat_setInt64(format, name, val64);
+                }
+                break;
+            case AMessage::kTypeFloat:
+                float valfloat;
+                if (id.find(&valfloat)) {
+                    AMediaFormat_setFloat(format, name, valfloat);
+                }
+                break;
+            case AMessage::kTypeDouble:
+                double valdouble;
+                if (id.find(&valdouble)) {
+                    AMediaFormat_setDouble(format, name, valdouble);
+                }
+                break;
+            case AMessage::kTypeString:
+                if (AString s; id.find(&s)) {
+                    AMediaFormat_setString(format, name, s.c_str());
+                }
+                break;
+            case AMessage::kTypeBuffer:
+            {
+                sp<ABuffer> buffer;
+                if (id.find(&buffer)) {
+                    AMediaFormat_setBuffer(format, name, buffer->data(), buffer->size());
+                }
+                break;
+            }
+            default:
+                ALOGW("ignoring unsupported type %d '%s'", type, name);
+        }
+    }
+}
+
+media_status_t MPEG2TSSource::getFormat(AMediaFormat *meta) {
     sp<MetaData> implMeta = mImpl->getFormat();
-    meta = *implMeta;
-    return OK;
+    sp<AMessage> msg;
+    convertMetaDataToMessage(implMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2TSSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+media_status_t MPEG2TSSource::read(
+        MediaBufferHelperV3 **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
@@ -110,16 +173,59 @@
     if (mDoesSeek && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
         // seek is needed
         status_t err = mExtractor->seek(seekTimeUs, (ReadOptions::SeekMode)seekMode);
-        if (err != OK) {
-            return err;
+        if (err == ERROR_END_OF_STREAM) {
+            return AMEDIA_ERROR_END_OF_STREAM;
+        } else if (err != OK) {
+            return AMEDIA_ERROR_UNKNOWN;
         }
     }
 
     if (mExtractor->feedUntilBufferAvailable(mImpl) != OK) {
-        return ERROR_END_OF_STREAM;
+        return AMEDIA_ERROR_END_OF_STREAM;
     }
 
-    return mImpl->read(out, (MediaSource::ReadOptions*) options);
+    MediaBufferBase *mbuf;
+    mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    size_t length = mbuf->range_length();
+    MediaBufferHelperV3 *outbuf;
+    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    memcpy(outbuf->data(), mbuf->data(), length);
+    outbuf->set_range(0, length);
+    *out = outbuf;
+    MetaDataBase &inMeta = mbuf->meta_data();
+    AMediaFormat *outMeta = outbuf->meta_data();
+    AMediaFormat_clear(outMeta);
+    int64_t val64;
+    if (inMeta.findInt64(kKeyTime, &val64)) {
+        AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+    }
+    int32_t val32;
+    if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+    }
+    if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+        AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+    }
+    uint32_t bufType;
+    const void *bufData;
+    size_t bufSize;
+    if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+    }
+    if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+        AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+    }
+
+    return AMEDIA_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -140,7 +246,7 @@
     return mSourceImpls.size();
 }
 
-MediaTrackHelper *MPEG2TSExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MPEG2TSExtractor::getTrack(size_t index) {
     if (index >= mSourceImpls.size()) {
         return NULL;
     }
@@ -151,22 +257,23 @@
             (mSeekSyncPoints == &mSyncPoints.editItemAt(index)));
 }
 
-status_t MPEG2TSExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+media_status_t MPEG2TSExtractor::getTrackMetaData(
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     sp<MetaData> implMeta = index < mSourceImpls.size()
         ? mSourceImpls.editItemAt(index)->getFormat() : NULL;
     if (implMeta == NULL) {
-        return UNKNOWN_ERROR;
+        return AMEDIA_ERROR_UNKNOWN;
     }
-    meta = *implMeta;
-    return OK;
+    sp<AMessage> msg = new AMessage;
+    convertMetaDataToMessage(implMeta, &msg);
+    copyAMessageToAMediaFormat(meta, msg);
+    return AMEDIA_OK;
 }
 
-status_t MPEG2TSExtractor::getMetaData(MetaDataBase &meta) {
-    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
-
-    return OK;
+media_status_t MPEG2TSExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+    return AMEDIA_OK;
 }
 
 //static
@@ -177,7 +284,7 @@
                     || !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
 }
 
-status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
+media_status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
     HalToken halToken;
     halToken.setToExternal((uint8_t*)casToken, size);
     sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
@@ -187,8 +294,9 @@
     if (err == OK) {
         ALOGI("All tracks now have descramblers");
         init();
+        return AMEDIA_OK;
     }
-    return err;
+    return AMEDIA_ERROR_UNKNOWN;
 }
 
 void MPEG2TSExtractor::addSource(const sp<AnotherPacketSource> &impl) {
@@ -494,7 +602,7 @@
 }
 
 status_t MPEG2TSExtractor::seek(int64_t seekTimeUs,
-        const MediaTrackHelper::ReadOptions::SeekMode &seekMode) {
+        const MediaTrackHelperV3::ReadOptions::SeekMode &seekMode) {
     if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) {
         ALOGW("No sync point to seek to.");
         // ... and therefore we have nothing useful to do here.
@@ -515,18 +623,18 @@
     }
 
     switch (seekMode) {
-        case MediaTrackHelper::ReadOptions::SEEK_NEXT_SYNC:
+        case MediaTrackHelperV3::ReadOptions::SEEK_NEXT_SYNC:
             if (index == mSeekSyncPoints->size()) {
                 ALOGW("Next sync not found; starting from the latest sync.");
                 --index;
             }
             break;
-        case MediaTrackHelper::ReadOptions::SEEK_CLOSEST_SYNC:
-        case MediaTrackHelper::ReadOptions::SEEK_CLOSEST:
+        case MediaTrackHelperV3::ReadOptions::SEEK_CLOSEST_SYNC:
+        case MediaTrackHelperV3::ReadOptions::SEEK_CLOSEST:
             ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC",
                     seekMode);
             FALLTHROUGH_INTENDED;
-        case MediaTrackHelper::ReadOptions::SEEK_PREVIOUS_SYNC:
+        case MediaTrackHelperV3::ReadOptions::SEEK_PREVIOUS_SYNC:
             if (index == 0) {
                 ALOGW("Previous sync not found; starting from the earliest "
                         "sync.");
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index 4013442..aed17bb 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -38,16 +38,16 @@
 struct MPEG2TSSource;
 class String8;
 
-struct MPEG2TSExtractor : public MediaExtractorPluginHelper {
+struct MPEG2TSExtractor : public MediaExtractorPluginHelperV3 {
     explicit MPEG2TSExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrackHelper *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelperV3 *getTrack(size_t index);
+    virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual media_status_t getMetaData(AMediaFormat *meta);
 
-    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
+    virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
 
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG2TSExtractor"; }
@@ -90,7 +90,7 @@
     // the data has syntax error during parsing, etc.
     status_t feedMore(bool isInit = false);
     status_t seek(int64_t seekTimeUs,
-            const MediaTrackHelper::ReadOptions::SeekMode& seekMode);
+            const MediaTrackHelperV3::ReadOptions::SeekMode& seekMode);
     status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
     status_t seekBeyond(int64_t seekTimeUs);
 
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index b28877d..604ec59 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -13,7 +13,6 @@
 
     shared_libs: [
         "liblog",
-        "libmediaextractor",
         "libmediandk",
     ],
 
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index cc2c792..29fe2b1 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -28,11 +28,8 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaBufferBase.h>
-#include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaDataBase.h>
 #include <media/stagefright/MetaDataUtils.h>
 #include <system/audio.h>
 #include <utils/String8.h>
@@ -48,7 +45,7 @@
 
 namespace android {
 
-struct OggSource : public MediaTrackHelperV2 {
+struct OggSource : public MediaTrackHelperV3 {
     explicit OggSource(OggExtractor *extractor);
 
     virtual media_status_t getFormat(AMediaFormat *);
@@ -57,7 +54,7 @@
     virtual media_status_t stop();
 
     virtual media_status_t read(
-            MediaBufferBase **buffer, const ReadOptions *options = NULL);
+            MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
 
 protected:
     virtual ~OggSource();
@@ -85,7 +82,7 @@
 
     status_t seekToTime(int64_t timeUs);
     status_t seekToOffset(off64_t offset);
-    virtual media_status_t readNextPacket(MediaBufferBase **buffer) = 0;
+    virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) = 0;
 
     status_t init();
 
@@ -93,6 +90,9 @@
         return AMediaFormat_copy(meta, mFileMeta);
     }
 
+    void setBufferGroup(MediaBufferGroupHelperV3 *group) {
+        mBufferGroup = group;
+    }
 protected:
     struct Page {
         uint64_t mGranulePosition;
@@ -110,6 +110,7 @@
         int64_t mTimeUs;
     };
 
+    MediaBufferGroupHelperV3 *mBufferGroup;
     DataSourceHelper *mSource;
     off64_t mOffset;
     Page mCurrentPage;
@@ -148,7 +149,7 @@
     // 1 - bitstream identification header
     // 3 - comment header
     // 5 - codec setup header (Vorbis only)
-    virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type) = 0;
+    virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) = 0;
 
     // Read the next ogg packet from the underlying data source; optionally
     // calculate the timestamp for the output packet whilst pretending
@@ -156,9 +157,9 @@
     //
     // *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated;
     // clients are responsible for releasing the original buffer.
-    media_status_t _readNextPacket(MediaBufferBase **buffer, bool calcVorbisTimestamp);
+    media_status_t _readNextPacket(MediaBufferHelperV3 **buffer, bool calcVorbisTimestamp);
 
-    int32_t getPacketBlockSize(MediaBufferBase *buffer);
+    int32_t getPacketBlockSize(MediaBufferHelperV3 *buffer);
 
     void parseFileMetaData();
 
@@ -182,7 +183,7 @@
 
     virtual uint64_t approxBitrate() const;
 
-    virtual media_status_t readNextPacket(MediaBufferBase **buffer) {
+    virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) {
         return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true);
     }
 
@@ -194,7 +195,7 @@
         return granulePos * 1000000ll / mVi.rate;
     }
 
-    virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+    virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type);
 };
 
 struct MyOpusExtractor : public MyOggExtractor {
@@ -212,16 +213,16 @@
         return 0;
     }
 
-    virtual media_status_t readNextPacket(MediaBufferBase **buffer);
+    virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer);
 
 protected:
     virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const;
-    virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+    virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type);
 
 private:
-    media_status_t verifyOpusHeader(MediaBufferBase *buffer);
-    media_status_t verifyOpusComments(MediaBufferBase *buffer);
-    uint32_t getNumSamplesInPacket(MediaBufferBase *buffer) const;
+    media_status_t verifyOpusHeader(MediaBufferHelperV3 *buffer);
+    media_status_t verifyOpusComments(MediaBufferHelperV3 *buffer);
+    uint32_t getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const;
 
     uint8_t mChannelCount;
     uint16_t mCodecDelay;
@@ -249,7 +250,9 @@
     if (mStarted) {
         return AMEDIA_ERROR_INVALID_OPERATION;
     }
-
+    // initialize buffer group with a single small buffer, but a generous upper limit
+    mBufferGroup->init(1 /* number of buffers */, 128 /* size */, 64 /* max number of buffers */);
+    mExtractor->mImpl->setBufferGroup(mBufferGroup);
     mStarted = true;
 
     return AMEDIA_OK;
@@ -262,7 +265,7 @@
 }
 
 media_status_t OggSource::read(
-        MediaBufferBase **out, const ReadOptions *options) {
+        MediaBufferHelperV3 **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
@@ -274,26 +277,27 @@
         }
     }
 
-    MediaBufferBase *packet;
+    MediaBufferHelperV3 *packet;
     media_status_t err = mExtractor->mImpl->readNextPacket(&packet);
 
     if (err != AMEDIA_OK) {
         return err;
     }
 
+    AMediaFormat *meta = packet->meta_data();
 #if 0
     int64_t timeUs;
-    if (packet->meta_data().findInt64(kKeyTime, &timeUs)) {
+    if (AMediaFormat_findInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs)) {
         ALOGI("found time = %lld us", timeUs);
     } else {
         ALOGI("NO time");
     }
 #endif
 
-    packet->meta_data().setInt32(kKeyIsSyncFrame, 1);
+    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     *out = packet;
-
+    ALOGV("returning buffer %p", packet);
     return AMEDIA_OK;
 }
 
@@ -304,7 +308,8 @@
         const char *mimeType,
         size_t numHeaders,
         int64_t seekPreRollUs)
-    : mSource(source),
+    : mBufferGroup(NULL),
+      mSource(source),
       mOffset(0),
       mCurGranulePosition(0),
       mPrevGranulePosition(0),
@@ -573,13 +578,13 @@
     return sizeof(header) + page->mNumSegments + totalSize;
 }
 
-media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) {
+media_status_t MyOpusExtractor::readNextPacket(MediaBufferHelperV3 **out) {
     if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) {
         // The first sample might not start at time 0; find out where by subtracting
         // the number of samples on the first page from the granule position
         // (position of last complete sample) of the first page. This happens
         // the first time before we attempt to read a packet from the first page.
-        MediaBufferBase *mBuf;
+        MediaBufferHelperV3 *mBuf;
         uint32_t numSamples = 0;
         uint64_t curGranulePosition = 0;
         while (true) {
@@ -617,24 +622,25 @@
     int32_t currentPageSamples;
     // Calculate timestamps by accumulating durations starting from the first sample of a page;
     // We assume that we only seek to page boundaries.
-    if ((*out)->meta_data().findInt32(kKeyValidSamples, &currentPageSamples)) {
+    AMediaFormat *meta = (*out)->meta_data();
+    if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, &currentPageSamples)) {
         // first packet in page
         if (mOffset == mFirstDataOffset) {
             currentPageSamples -= mStartGranulePosition;
-            (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples);
+            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, currentPageSamples);
         }
         mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples;
     }
 
     int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition);
-    (*out)->meta_data().setInt64(kKeyTime, timeUs);
+    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
 
     uint32_t frames = getNumSamplesInPacket(*out);
     mCurGranulePosition += frames;
     return AMEDIA_OK;
 }
 
-uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const {
+uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const {
     if (buffer == NULL || buffer->range_length() < 1) {
         return 0;
     }
@@ -680,10 +686,66 @@
     return numSamples;
 }
 
-media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisTimestamp) {
+/*
+ * basic mediabuffer implementation used during initial parsing of the
+ * header packets, which happens before we have a buffer group
+ */
+class StandAloneMediaBuffer : public MediaBufferHelperV3 {
+private:
+    void *mData;
+    size_t mSize;
+    size_t mOffset;
+    size_t mLength;
+    AMediaFormat *mFormat;
+public:
+    StandAloneMediaBuffer(size_t size) : MediaBufferHelperV3(NULL) {
+        mSize = size;
+        mData = malloc(mSize);
+        mOffset = 0;
+        mLength = mSize;
+        mFormat = AMediaFormat_new();
+        ALOGV("created standalone media buffer %p of size %zu", this, mSize);
+    }
+
+    ~StandAloneMediaBuffer() override {
+        free(mData);
+        AMediaFormat_delete(mFormat);
+        ALOGV("deleted standalone media buffer %p of size %zu", this, mSize);
+    }
+
+    void release() override {
+        delete this;
+    }
+
+    void* data() override {
+        return mData;
+    }
+
+    size_t size() override {
+        return mSize;
+    }
+
+    size_t range_offset() override {
+        return mOffset;
+    }
+
+    size_t range_length() override {
+        return mLength;
+    }
+
+    void set_range(size_t offset, size_t length) override {
+        mOffset = offset;
+        mLength = length;
+    }
+    AMediaFormat *meta_data() override {
+        return mFormat;
+    }
+};
+
+media_status_t MyOggExtractor::_readNextPacket(MediaBufferHelperV3 **out, bool calcVorbisTimestamp) {
     *out = NULL;
 
-    MediaBufferBase *buffer = NULL;
+    MediaBufferHelperV3 *buffer = NULL;
     int64_t timeUs = -1;
 
     for (;;) {
@@ -719,7 +781,13 @@
                 ALOGE("b/36592202");
                 return AMEDIA_ERROR_MALFORMED;
             }
-            MediaBufferBase *tmp = MediaBufferBase::Create(fullSize);
+            MediaBufferHelperV3 *tmp;
+            if (mBufferGroup) {
+                mBufferGroup->acquire_buffer(&tmp, false, fullSize);
+                ALOGV("acquired buffer %p from group", tmp);
+            } else {
+                tmp = new StandAloneMediaBuffer(fullSize);
+            }
             if (tmp == NULL) {
                 if (buffer != NULL) {
                     buffer->release();
@@ -727,6 +795,7 @@
                 ALOGE("b/36592202");
                 return AMEDIA_ERROR_MALFORMED;
             }
+            AMediaFormat_clear(tmp->meta_data());
             if (buffer != NULL) {
                 memcpy(tmp->data(), buffer->data(), buffer->range_length());
                 tmp->set_range(0, buffer->range_length());
@@ -756,8 +825,9 @@
                 // We've just read the entire packet.
 
                 if (mFirstPacketInPage) {
-                    buffer->meta_data().setInt32(
-                            kKeyValidSamples, mCurrentPageSamples);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt32(
+                            meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
                     mFirstPacketInPage = false;
                 }
 
@@ -778,7 +848,8 @@
                         mCurrentPage.mPrevPacketPos += actualBlockSize / 2;
                         mCurrentPage.mPrevPacketSize = curBlockSize;
                     }
-                    buffer->meta_data().setInt64(kKeyTime, timeUs);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
                 }
                 *out = buffer;
 
@@ -824,11 +895,13 @@
                 // is already complete.
 
                 if (timeUs >= 0) {
-                    buffer->meta_data().setInt64(kKeyTime, timeUs);
+                    AMediaFormat *meta = buffer->meta_data();
+                    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
                 }
 
-                buffer->meta_data().setInt32(
-                        kKeyValidSamples, mCurrentPageSamples);
+                AMediaFormat *meta = buffer->meta_data();
+                AMediaFormat_setInt32(
+                        meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
                 mFirstPacketInPage = false;
 
                 *out = buffer;
@@ -843,7 +916,7 @@
     AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
 
     media_status_t err;
-    MediaBufferBase *packet;
+    MediaBufferHelperV3 *packet;
     for (size_t i = 0; i < mNumHeaders; ++i) {
         // ignore timestamp for configuration packets
         if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
@@ -920,7 +993,7 @@
     }
 }
 
-int32_t MyOggExtractor::getPacketBlockSize(MediaBufferBase *buffer) {
+int32_t MyOggExtractor::getPacketBlockSize(MediaBufferHelperV3 *buffer) {
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
 
@@ -960,7 +1033,7 @@
     return pcmSamplePosition * 1000000ll / kOpusSampleRate;
 }
 
-media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t type) {
+media_status_t MyOpusExtractor::verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) {
     switch (type) {
         // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean
         // header and comments such that we can share code with MyVorbisExtractor.
@@ -973,7 +1046,7 @@
     }
 }
 
-media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferHelperV3 *buffer) {
     const size_t kOpusHeaderSize = 19;
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
@@ -1001,7 +1074,7 @@
     return AMEDIA_OK;
 }
 
-media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferHelperV3 *buffer) {
     // add artificial framing bit so we can reuse _vorbis_unpack_comment
     int32_t commentSize = buffer->range_length() + 1;
     auto tmp = heapbuffer<uint8_t>(commentSize);
@@ -1094,7 +1167,7 @@
 }
 
 media_status_t MyVorbisExtractor::verifyHeader(
-        MediaBufferBase *buffer, uint8_t type) {
+        MediaBufferHelperV3 *buffer, uint8_t type) {
     const uint8_t *data =
         (const uint8_t *)buffer->data() + buffer->range_offset();
 
@@ -1262,7 +1335,7 @@
     return mInitCheck != OK ? 0 : 1;
 }
 
-MediaTrackHelperV2 *OggExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *OggExtractor::getTrack(size_t index) {
     if (index >= 1) {
         return NULL;
     }
@@ -1284,13 +1357,13 @@
     return mImpl->getFileMetaData(meta);
 }
 
-static CMediaExtractorV2* CreateExtractor(
+static CMediaExtractorV3* CreateExtractor(
         CDataSource *source,
         void *) {
-    return wrapV2(new OggExtractor(new DataSourceHelper(source)));
+    return wrapV3(new OggExtractor(new DataSourceHelper(source)));
 }
 
-static CreatorFuncV2 Sniff(
+static CreatorFuncV3 Sniff(
         CDataSource *source,
         float *confidence,
         void **,
@@ -1311,11 +1384,11 @@
 __attribute__ ((visibility ("default")))
 ExtractorDef GETEXTRACTORDEF() {
     return {
-        EXTRACTORDEF_VERSION_CURRENT,
+        EXTRACTORDEF_VERSION_CURRENT + 1,
         UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
         1, // version
         "Ogg Extractor",
-        { .v2 = Sniff }
+        { .v3 = Sniff }
     };
 }
 
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index cd674f3..97506ad 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -31,11 +31,11 @@
 struct MyOggExtractor;
 struct OggSource;
 
-struct OggExtractor : public MediaExtractorPluginHelperV2 {
+struct OggExtractor : public MediaExtractorPluginHelperV3 {
     explicit OggExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrackHelperV2 *getTrack(size_t index);
+    virtual MediaTrackHelperV3 *getTrack(size_t index);
     virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
     virtual media_status_t getMetaData(AMediaFormat *meta);
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 4a0e6da..58ef7b1 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -258,7 +258,7 @@
         callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
+            ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
             break;
         }
     }
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 2ae37a5..9af47b2 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -293,7 +293,7 @@
                 break;
             }
         } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+            ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
             break;
         }
     }
diff --git a/media/libaaudio/tests/test_return_stop.cpp b/media/libaaudio/tests/test_return_stop.cpp
index f34c3c8..9a9e00c 100644
--- a/media/libaaudio/tests/test_return_stop.cpp
+++ b/media/libaaudio/tests/test_return_stop.cpp
@@ -228,8 +228,6 @@
         result = AAudioStream_requestStart(engine.stream);
         printf("AAudioStream_requestStart() returned %d >>>>>>>>>>>>>>>>>>>>>>\n", result);
         if (result != AAUDIO_OK) {
-            printf("ERROR - AAudioStream_requestStart returned %s",
-                   AAudio_convertResultToText(result));
             errorCount++;
             break;
         }
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 1f6dd60..b444d2d 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -952,7 +952,8 @@
     if (rate == mSampleRate) {
         return NO_ERROR;
     }
-    if (isOffloadedOrDirect_l() || (mFlags & AUDIO_OUTPUT_FLAG_FAST)) {
+    if (isOffloadedOrDirect_l() || (mFlags & AUDIO_OUTPUT_FLAG_FAST)
+            || (mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL)) {
         return INVALID_OPERATION;
     }
     if (mOutput == AUDIO_IO_HANDLE_NONE) {
diff --git a/media/libaudiohal/HalDeathHandlerHidl.cpp b/media/libaudiohal/HalDeathHandlerHidl.cpp
index 1e3ab58..6e33523 100644
--- a/media/libaudiohal/HalDeathHandlerHidl.cpp
+++ b/media/libaudiohal/HalDeathHandlerHidl.cpp
@@ -54,7 +54,7 @@
         handler.second();
     }
     ALOGE("HAL server crashed, audio server is restarting");
-    exit(1);
+    _exit(1);  // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool.
 }
 
 } // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 9747859..9f8a520 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -22,19 +22,12 @@
 
 #include "ConversionHelperHidl.h"
 
-using ::android::hardware::audio::CPP_VERSION::Result;
-
-#if MAJOR_VERSION >= 4
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneChannelMapping;
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneDirectionality;
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneLocation;
-using ::android::hardware::audio::CPP_VERSION::DeviceAddress;
-using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
-#endif
-
 namespace android {
 namespace CPP_VERSION {
 
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
 // static
 status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) {
     AudioParameter halKeys(keys);
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index fe92d43..b764ccb 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -17,6 +17,8 @@
 #define LOG_TAG "BufferProvider"
 //#define LOG_NDEBUG 0
 
+#include <algorithm>
+
 #include <audio_utils/primitives.h>
 #include <audio_utils/format.h>
 #include <audio_utils/channels.h>
@@ -36,13 +38,6 @@
 namespace android {
 
 // ----------------------------------------------------------------------------
-
-template <typename T>
-static inline T min(const T& a, const T& b)
-{
-    return a < b ? a : b;
-}
-
 CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
         size_t outputFrameSize, size_t bufferFrameCount) :
         mInputFrameSize(inputFrameSize),
@@ -100,8 +95,8 @@
         mConsumed = 0;
     }
     ALOG_ASSERT(mConsumed < mBuffer.frameCount);
-    size_t count = min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
-    count = min(count, pBuffer->frameCount);
+    size_t count = std::min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
+    count = std::min(count, pBuffer->frameCount);
     pBuffer->raw = mLocalBufferData;
     pBuffer->frameCount = count;
     copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
@@ -491,7 +486,7 @@
         }
 
         // time-stretch the data
-        dstAvailable = min(mLocalBufferFrameCount - mRemaining, outputDesired);
+        dstAvailable = std::min(mLocalBufferFrameCount - mRemaining, outputDesired);
         size_t srcAvailable = mBuffer.frameCount;
         processFrames((uint8_t*)mLocalBufferData + mRemaining * mFrameSize, &dstAvailable,
                 mBuffer.raw, &srcAvailable);
@@ -589,7 +584,7 @@
                   } else {
                       // cyclically repeat the source.
                       for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
-                          size_t remaining = min(*srcFrames, *dstFrames - count);
+                          size_t remaining = std::min(*srcFrames, *dstFrames - count);
                           memcpy((uint8_t*)dstBuffer + mFrameSize * count,
                                   srcBuffer, mFrameSize * remaining);
                       }
@@ -657,9 +652,9 @@
         audio_format_t format, size_t inChannelCount, size_t outChannelCount,
         audio_format_t contractedFormat, size_t contractedFrameCount, void* contractedBuffer) :
         CopyBufferProvider(
-                audio_bytes_per_frame(inChannelCount, format),
-                audio_bytes_per_frame(outChannelCount, format),
-                0 /*bufferFrameCount*/),
+                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
+                audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
+                contractedFrameCount),
         mFormat(format),
         mInChannelCount(inChannelCount),
         mOutChannelCount(outChannelCount),
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index a1fa79a..cc066b0 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -199,8 +199,10 @@
 #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
+#define LVDBE_CAP_FS_88200               512
+#define LVDBE_CAP_FS_96000               1024
+#define LVDBE_CAP_FS_176400              2048
+#define LVDBE_CAP_FS_192000              4096
 #endif
 
 typedef enum
@@ -215,8 +217,10 @@
     LVDBE_FS_44100 = 7,
     LVDBE_FS_48000 = 8,
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-    LVDBE_FS_96000 = 9,
-    LVDBE_FS_192000 = 10,
+    LVDBE_FS_88200 = 9,
+    LVDBE_FS_96000 = 10,
+    LVDBE_FS_176400 = 11,
+    LVDBE_FS_192000 = 12,
 #endif
     LVDBE_FS_MAX   = LVM_MAXINT_32
 } LVDBE_Fs_en;
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
index 4ecaf14..8f058e8 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
@@ -580,12 +580,24 @@
 #define HPF_Fs48000_Fc55_B2                       0.989882f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc55_A0                       0.985818f
+#define HPF_Fs88200_Fc55_A1                       (-1.971636f)
+#define HPF_Fs88200_Fc55_A2                       0.985818f
+#define HPF_Fs88200_Fc55_B1                       (-1.994466f)
+#define HPF_Fs88200_Fc55_B2                       0.994481f
+
 #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_Fs176400_Fc55_A0                      0.987183f
+#define HPF_Fs176400_Fc55_A1                      (-1.974366f)
+#define HPF_Fs176400_Fc55_A2                      0.987183f
+#define HPF_Fs176400_Fc55_B1                      (-1.997233f)
+#define HPF_Fs176400_Fc55_B2                      0.997237f
+
 #define HPF_Fs192000_Fc55_A0                      0.987294f
 #define HPF_Fs192000_Fc55_A1                      (-1.974588f)
 #define HPF_Fs192000_Fc55_A2                      0.987294f
@@ -642,12 +654,24 @@
 #define HPF_Fs48000_Fc66_B2                       0.987871f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc66_A0                       0.985273f
+#define HPF_Fs88200_Fc66_A1                       (-1.970546f)
+#define HPF_Fs88200_Fc66_A2                       0.985273f
+#define HPF_Fs88200_Fc66_B1                       (-1.993359f)
+#define HPF_Fs88200_Fc66_B2                       0.993381f
+
 #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_Fs176400_Fc66_A0                      0.986910f
+#define HPF_Fs176400_Fc66_A1                      (-1.973820f)
+#define HPF_Fs176400_Fc66_A2                      0.986910f
+#define HPF_Fs176400_Fc66_B1                      (-1.996679f)
+#define HPF_Fs176400_Fc66_B2                      0.996685f
+
 #define HPF_Fs192000_Fc66_A0                      0.987043f
 #define HPF_Fs192000_Fc66_A1                      (-1.974086f)
 #define HPF_Fs192000_Fc66_A2                      0.987043f
@@ -703,12 +727,24 @@
 #define HPF_Fs48000_Fc78_B2                       0.985681f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc78_A0                       0.984678f
+#define HPF_Fs88200_Fc78_A1                       (-1.969356f)
+#define HPF_Fs88200_Fc78_A2                       0.984678f
+#define HPF_Fs88200_Fc78_B1                       (-1.992151f)
+#define HPF_Fs88200_Fc78_B2                       0.992182f
+
 #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_Fs176400_Fc78_A0                      0.986612f
+#define HPF_Fs176400_Fc78_A1                      (-1.973224f)
+#define HPF_Fs176400_Fc78_A2                      0.986612f
+#define HPF_Fs176400_Fc78_B1                      (-1.996076f)
+#define HPF_Fs176400_Fc78_B2                      0.996083f
+
 #define HPF_Fs192000_Fc78_A0                      0.986769f
 #define HPF_Fs192000_Fc78_A1                      (-1.973539f)
 #define HPF_Fs192000_Fc78_A2                      0.986769f
@@ -764,12 +800,24 @@
 #define HPF_Fs48000_Fc90_B2                      0.983497f
 
 #ifdef HIGHER_FS
+#define HPF_Fs88200_Fc90_A0                       0.984084f
+#define HPF_Fs88200_Fc90_A1                       (-1.968168f)
+#define HPF_Fs88200_Fc90_A2                       0.984084f
+#define HPF_Fs88200_Fc90_B1                       (-1.990944f)
+#define HPF_Fs88200_Fc90_B2                       0.990985f
+
 #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_Fs176400_Fc90_A0                      0.986314f
+#define HPF_Fs176400_Fc90_A1                      (-1.972629f)
+#define HPF_Fs176400_Fc90_A2                      0.986314f
+#define HPF_Fs176400_Fc90_B1                      (-1.995472f)
+#define HPF_Fs176400_Fc90_B2                      0.995482f
+
 #define HPF_Fs192000_Fc90_A0                      0.986496f
 #define HPF_Fs192000_Fc90_A1                      (-1.972992f)
 #define HPF_Fs192000_Fc90_A2                      0.986496f
@@ -831,12 +879,24 @@
 #define BPF_Fs48000_Fc55_B2                      0.996875f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc55_A0                      0.000831f
+#define BPF_Fs88200_Fc55_A1                      0.000000f
+#define BPF_Fs88200_Fc55_A2                      (-0.000831f)
+#define BPF_Fs88200_Fc55_B1                      (-1.998321f)
+#define BPF_Fs88200_Fc55_B2                      0.998338f
+
 #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_Fs176400_Fc55_A0                     0.000416f
+#define BPF_Fs176400_Fc55_A1                     0.000000f
+#define BPF_Fs176400_Fc55_A2                     (-0.000416f)
+#define BPF_Fs176400_Fc55_B1                     (-1.999164f)
+#define BPF_Fs176400_Fc55_B2                     0.999169f
+
 #define BPF_Fs192000_Fc55_A0                     0.000381f
 #define BPF_Fs192000_Fc55_A1                     0.000000f
 #define BPF_Fs192000_Fc55_A2                     (-0.000381f)
@@ -892,12 +952,24 @@
 #define BPF_Fs48000_Fc66_B2                     0.995690f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc66_A0                     0.001146f
+#define BPF_Fs88200_Fc66_A1                     0.000000f
+#define BPF_Fs88200_Fc66_A2                     (-0.001146f)
+#define BPF_Fs88200_Fc66_B1                     (-1.997684f)
+#define BPF_Fs88200_Fc66_B2                     0.997708f
+
 #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_Fs176400_Fc66_A0                    0.000573f
+#define BPF_Fs176400_Fc66_A1                    0.000000f
+#define BPF_Fs176400_Fc66_A2                    (-0.000573f)
+#define BPF_Fs176400_Fc66_B1                    (-1.998847f)
+#define BPF_Fs176400_Fc66_B2                    0.998853f
+
 #define BPF_Fs192000_Fc66_A0                    0.000528f
 #define BPF_Fs192000_Fc66_A1                    0.000000f
 #define BPF_Fs192000_Fc66_A2                   (-0.000528f)
@@ -953,12 +1025,24 @@
 #define BPF_Fs48000_Fc78_B2                     0.993639f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc78_A0                    0.001693f
+#define BPF_Fs88200_Fc78_A1                    0.000000f
+#define BPF_Fs88200_Fc78_A2                    (-0.001693f)
+#define BPF_Fs88200_Fc78_B1                    (-1.996582f)
+#define BPF_Fs88200_Fc78_B2                    0.996615f
+
 #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_Fs176400_Fc78_A0                    0.000847f
+#define BPF_Fs176400_Fc78_A1                    0.000000f
+#define BPF_Fs176400_Fc78_A2                    (-0.000847f)
+#define BPF_Fs176400_Fc78_B1                    (-1.998298f)
+#define BPF_Fs176400_Fc78_B2                    0.998306f
+
 #define BPF_Fs192000_Fc78_A0                    0.000778f
 #define BPF_Fs192000_Fc78_A1                    0.000000f
 #define BPF_Fs192000_Fc78_A2                   (-0.000778f)
@@ -1014,12 +1098,24 @@
 #define BPF_Fs48000_Fc90_B2                      0.992177f
 
 #ifdef HIGHER_FS
+#define BPF_Fs88200_Fc90_A0                      0.002083f
+#define BPF_Fs88200_Fc90_A1                      0.000000f
+#define BPF_Fs88200_Fc90_A2                      (-0.002083f)
+#define BPF_Fs88200_Fc90_B1                      (-1.995791f)
+#define BPF_Fs88200_Fc90_B2                      0.995835f
+
 #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_Fs176400_Fc90_A0                     0.001042f
+#define BPF_Fs176400_Fc90_A1                     0.000000f
+#define BPF_Fs176400_Fc90_A2                     (-0.001042f)
+#define BPF_Fs176400_Fc90_B1                     (-1.997904f)
+#define BPF_Fs176400_Fc90_B2                     0.997915f
+
 #define BPF_Fs192000_Fc90_A0                     0.000958f
 #define BPF_Fs192000_Fc90_A1                     0.000000f
 #define BPF_Fs192000_Fc90_A2                    (-0.000958f)
@@ -1045,7 +1141,9 @@
 #define AGC_ATTACK_Fs48000                            0.971628f
 
 #ifdef HIGHER_FS
+#define AGC_ATTACK_Fs88200                             0.984458f
 #define AGC_ATTACK_Fs96000                             0.985712f
+#define AGC_ATTACK_Fs176400                            0.992199f
 #define AGC_ATTACK_Fs192000                            0.992830f
 #endif
 
@@ -1062,7 +1160,9 @@
 #define AGC_DECAY_Fs48000                             0.000007f
 
 #ifdef HIGHER_FS
+#define AGC_DECAY_Fs88200                            0.0000038f
 #define AGC_DECAY_FS96000                            0.0000035f
+#define AGC_DECAY_Fs176400                          0.00000188f
 #define AGC_DECAY_FS192000                          0.00000175f
 #endif
 
@@ -1125,7 +1225,9 @@
 #define VOL_TC_Fs44100                                  0.004525f
 #define VOL_TC_Fs48000                                  0.004158f
 #ifdef HIGHER_FS
+#define VOL_TC_Fs88200                                  0.002263f
 #define VOL_TC_Fs96000                                  0.002079f
+#define VOL_TC_Fs176400                                 0.001131f
 #define VOL_TC_Fs192000                                 0.001039f
 #endif
 #define MIX_TC_Fs8000                                   29365         /* Floating point value 0.896151 */
@@ -1138,9 +1240,13 @@
 #define MIX_TC_Fs44100                                  32097         /* Floating point value 0.979515 */
 #define MIX_TC_Fs48000                                  32150         /* Floating point value 0.981150 */
 #ifdef HIGHER_FS
+/* Floating point value 0.989704 */
+#define MIX_TC_Fs88200                                  32430
 #define MIX_TC_Fs96000                                  32456         /* Floating point value 0.990530 */
+/* Floating point value 0.994838 */
+#define MIX_TC_Fs176400                                 32598
 #define MIX_TC_Fs192000                                 32611         /* Floating point value 0.992524 */
 #endif
 
 #endif /*BUILD_FLOAT*/
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
index c4a9b14..a2ce404 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -88,11 +88,21 @@
      -HPF_Fs48000_Fc55_B2,
      -HPF_Fs48000_Fc55_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc55_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc55_A1,
+     HPF_Fs88200_Fc55_A0,
+     -HPF_Fs88200_Fc55_B2,
+     -HPF_Fs88200_Fc55_B1},
     {HPF_Fs96000_Fc55_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc55_A1,
      HPF_Fs96000_Fc55_A0,
      -HPF_Fs96000_Fc55_B2,
      -HPF_Fs96000_Fc55_B1},
+    {HPF_Fs176400_Fc55_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc55_A1,
+     HPF_Fs176400_Fc55_A0,
+     -HPF_Fs176400_Fc55_B2,
+     -HPF_Fs176400_Fc55_B1},
     {HPF_Fs192000_Fc55_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc55_A1,
      HPF_Fs192000_Fc55_A0,
@@ -147,11 +157,21 @@
      -HPF_Fs48000_Fc66_B2,
      -HPF_Fs48000_Fc66_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc66_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc66_A1,
+     HPF_Fs88200_Fc66_A0,
+     -HPF_Fs88200_Fc66_B2,
+     -HPF_Fs88200_Fc66_B1},
     {HPF_Fs96000_Fc66_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc66_A1,
      HPF_Fs96000_Fc66_A0,
      -HPF_Fs96000_Fc66_B2,
      -HPF_Fs96000_Fc66_B1},
+    {HPF_Fs176400_Fc66_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc66_A1,
+     HPF_Fs176400_Fc66_A0,
+     -HPF_Fs176400_Fc66_B2,
+     -HPF_Fs176400_Fc66_B1},
     {HPF_Fs192000_Fc66_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc66_A1,
      HPF_Fs192000_Fc66_A0,
@@ -207,11 +227,21 @@
      -HPF_Fs48000_Fc78_B2,
      -HPF_Fs48000_Fc78_B1},
 #ifdef HIGHER_FS
+    {HPF_Fs88200_Fc78_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc78_A1,
+     HPF_Fs88200_Fc78_A0,
+     -HPF_Fs88200_Fc78_B2,
+     -HPF_Fs88200_Fc78_B1},
     {HPF_Fs96000_Fc78_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc78_A1,
      HPF_Fs96000_Fc78_A0,
      -HPF_Fs96000_Fc78_B2,
      -HPF_Fs96000_Fc78_B1},
+    {HPF_Fs176400_Fc78_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc78_A1,
+     HPF_Fs176400_Fc78_A0,
+     -HPF_Fs176400_Fc78_B2,
+     -HPF_Fs176400_Fc78_B1},
     {HPF_Fs192000_Fc78_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc78_A1,
      HPF_Fs192000_Fc78_A0,
@@ -269,11 +299,21 @@
 
 #ifdef HIGHER_FS
     ,
+    {HPF_Fs88200_Fc90_A2,                /* 88kS/s coefficients */
+     HPF_Fs88200_Fc90_A1,
+     HPF_Fs88200_Fc90_A0,
+     -HPF_Fs88200_Fc90_B2,
+     -HPF_Fs88200_Fc90_B1},
     {HPF_Fs96000_Fc90_A2,                /* 96kS/s coefficients */
      HPF_Fs96000_Fc90_A1,
      HPF_Fs96000_Fc90_A0,
      -HPF_Fs96000_Fc90_B2,
      -HPF_Fs96000_Fc90_B1},
+    {HPF_Fs176400_Fc90_A2,                /* 176kS/s coefficients */
+     HPF_Fs176400_Fc90_A1,
+     HPF_Fs176400_Fc90_A0,
+     -HPF_Fs176400_Fc90_B2,
+     -HPF_Fs176400_Fc90_B1},
     {HPF_Fs192000_Fc90_A2,                /* 192kS/s coefficients */
      HPF_Fs192000_Fc90_A1,
      HPF_Fs192000_Fc90_A0,
@@ -320,9 +360,15 @@
      -BPF_Fs48000_Fc55_B2,
      -BPF_Fs48000_Fc55_B1},
 #ifdef HIGHER_FS
+     {BPF_Fs88200_Fc55_A0,                /* 88kS/s coefficients */
+      -BPF_Fs88200_Fc55_B2,
+      -BPF_Fs88200_Fc55_B1},
      {BPF_Fs96000_Fc55_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc55_B2,
      -BPF_Fs96000_Fc55_B1},
+     {BPF_Fs176400_Fc55_A0,                /* 176kS/s coefficients */
+      -BPF_Fs176400_Fc55_B2,
+      -BPF_Fs176400_Fc55_B1},
      {BPF_Fs192000_Fc55_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc55_B2,
      -BPF_Fs192000_Fc55_B1},
@@ -357,9 +403,15 @@
      -BPF_Fs48000_Fc66_B2,
      -BPF_Fs48000_Fc66_B1},
 #ifdef HIGHER_FS
+    {BPF_Fs88200_Fc66_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc66_B2,
+     -BPF_Fs88200_Fc66_B1},
     {BPF_Fs96000_Fc66_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc66_B2,
      -BPF_Fs96000_Fc66_B1},
+    {BPF_Fs176400_Fc66_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc66_B2,
+     -BPF_Fs176400_Fc66_B1},
     {BPF_Fs192000_Fc66_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc66_B2,
      -BPF_Fs192000_Fc66_B1},
@@ -394,9 +446,15 @@
      -BPF_Fs48000_Fc78_B2,
      -BPF_Fs48000_Fc78_B1},
 #ifdef HIGHER_FS
+    {BPF_Fs88200_Fc66_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc66_B2,
+     -BPF_Fs88200_Fc66_B1},
     {BPF_Fs96000_Fc78_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc78_B2,
      -BPF_Fs96000_Fc78_B1},
+    {BPF_Fs176400_Fc66_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc66_B2,
+     -BPF_Fs176400_Fc66_B1},
     {BPF_Fs192000_Fc78_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc78_B2,
      -BPF_Fs192000_Fc78_B1},
@@ -432,9 +490,15 @@
      -BPF_Fs48000_Fc90_B1}
 #ifdef HIGHER_FS
     ,
+    {BPF_Fs88200_Fc90_A0,                /* 88kS/s coefficients */
+     -BPF_Fs88200_Fc90_B2,
+     -BPF_Fs88200_Fc90_B1},
     {BPF_Fs96000_Fc90_A0,                /* 96kS/s coefficients */
      -BPF_Fs96000_Fc90_B2,
      -BPF_Fs96000_Fc90_B1},
+    {BPF_Fs176400_Fc90_A0,                /* 176kS/s coefficients */
+     -BPF_Fs176400_Fc90_B2,
+     -BPF_Fs176400_Fc90_B1},
     {BPF_Fs192000_Fc90_A0,                /* 192kS/s coefficients */
      -BPF_Fs192000_Fc90_B2,
      -BPF_Fs192000_Fc90_B1}
@@ -466,7 +530,9 @@
     AGC_ATTACK_Fs44100,
     AGC_ATTACK_Fs48000
 #ifdef HIGHER_FS
+    ,AGC_ATTACK_Fs88200
     ,AGC_ATTACK_Fs96000
+    ,AGC_ATTACK_Fs176400
     ,AGC_ATTACK_Fs192000
 #endif
 
@@ -488,7 +554,9 @@
     AGC_DECAY_Fs44100,
     AGC_DECAY_Fs48000
 #ifdef HIGHER_FS
+    ,AGC_DECAY_Fs88200
     ,AGC_DECAY_FS96000
+    ,AGC_DECAY_Fs176400
     ,AGC_DECAY_FS192000
 #endif
 
@@ -583,7 +651,9 @@
     VOL_TC_Fs44100,
     VOL_TC_Fs48000
 #ifdef HIGHER_FS
+    ,VOL_TC_Fs88200
     ,VOL_TC_Fs96000
+    ,VOL_TC_Fs176400
     ,VOL_TC_Fs192000
 #endif
 };
@@ -602,7 +672,9 @@
     MIX_TC_Fs44100,
     MIX_TC_Fs48000
 #ifdef HIGHER_FS
+    ,MIX_TC_Fs88200
     ,MIX_TC_Fs96000
+    ,MIX_TC_Fs176400
     ,MIX_TC_Fs192000
 #endif
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
index 8c04847..bab4049 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
@@ -487,6 +487,97 @@
 #define HPF_Fs48000_Gain15_B2                         0.000000
 
 #ifdef HIGHER_FS
+/* Coefficients for sample rate 88200 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs88200_Gain1_A0                          1.094374f
+#define HPF_Fs88200_Gain1_A1                          (-0.641256f)
+#define HPF_Fs88200_Gain1_A2                          0.000000f
+#define HPF_Fs88200_Gain1_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain1_B2                          0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs88200_Gain2_A0                          1.200264f
+#define HPF_Fs88200_Gain2_A1                          (-0.747146f)
+#define HPF_Fs88200_Gain2_A2                          0.000000f
+#define HPF_Fs88200_Gain2_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain2_B2                          0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs88200_Gain3_A0                          1.319074f
+#define HPF_Fs88200_Gain3_A1                          (-0.865956f)
+#define HPF_Fs88200_Gain3_A2                          0.000000f
+#define HPF_Fs88200_Gain3_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain3_B2                          0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs88200_Gain4_A0                          1.452380f
+#define HPF_Fs88200_Gain4_A1                          (-0.999263f)
+#define HPF_Fs88200_Gain4_A2                          0.000000f
+#define HPF_Fs88200_Gain4_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain4_B2                          0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs88200_Gain5_A0                          1.601953f
+#define HPF_Fs88200_Gain5_A1                          (-1.148836f)
+#define HPF_Fs88200_Gain5_A2                          0.000000f
+#define HPF_Fs88200_Gain5_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain5_B2                          0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs88200_Gain6_A0                          1.769777f
+#define HPF_Fs88200_Gain6_A1                          (-1.316659f)
+#define HPF_Fs88200_Gain6_A2                          0.000000f
+#define HPF_Fs88200_Gain6_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain6_B2                          0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs88200_Gain7_A0                          1.958078f
+#define HPF_Fs88200_Gain7_A1                          (-1.504960f)
+#define HPF_Fs88200_Gain7_A2                          0.000000f
+#define HPF_Fs88200_Gain7_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain7_B2                          0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs88200_Gain8_A0                          2.169355f
+#define HPF_Fs88200_Gain8_A1                          (-1.716238f)
+#define HPF_Fs88200_Gain8_A2                          0.000000f
+#define HPF_Fs88200_Gain8_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain8_B2                          0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs88200_Gain9_A0                          2.406412f
+#define HPF_Fs88200_Gain9_A1                          (-1.953295f)
+#define HPF_Fs88200_Gain9_A2                          0.000000f
+#define HPF_Fs88200_Gain9_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain9_B2                          0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs88200_Gain10_A0                          2.672395f
+#define HPF_Fs88200_Gain10_A1                          (-2.219277f)
+#define HPF_Fs88200_Gain10_A2                          0.000000f
+#define HPF_Fs88200_Gain10_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain10_B2                          0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs88200_Gain11_A0                          2.970832f
+#define HPF_Fs88200_Gain11_A1                          (-2.517714f)
+#define HPF_Fs88200_Gain11_A2                          0.000000f
+#define HPF_Fs88200_Gain11_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain11_B2                          0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs88200_Gain12_A0                          3.305684f
+#define HPF_Fs88200_Gain12_A1                          (-2.852566f)
+#define HPF_Fs88200_Gain12_A2                          0.000000f
+#define HPF_Fs88200_Gain12_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain12_B2                          0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs88200_Gain13_A0                          3.681394f
+#define HPF_Fs88200_Gain13_A1                          (-3.228276f)
+#define HPF_Fs88200_Gain13_A2                          0.000000f
+#define HPF_Fs88200_Gain13_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain13_B2                          0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs88200_Gain14_A0                          4.102947f
+#define HPF_Fs88200_Gain14_A1                          (-3.649830f)
+#define HPF_Fs88200_Gain14_A2                          0.000000f
+#define HPF_Fs88200_Gain14_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain14_B2                          0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs88200_Gain15_A0                          4.575938f
+#define HPF_Fs88200_Gain15_A1                          (-4.122820f)
+#define HPF_Fs88200_Gain15_A2                          0.000000f
+#define HPF_Fs88200_Gain15_B1                          (-0.546882f)
+#define HPF_Fs88200_Gain15_B2                          0.000000f
 
 /* Coefficients for sample rate 96000Hz */
                                                                  /* Gain =  1.000000 dB */
@@ -580,6 +671,98 @@
 #define HPF_Fs96000_Gain15_B1                         (-0.577350)
 #define HPF_Fs96000_Gain15_B2                         0.000000
 
+/* Coefficients for sample rate 176400 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs176400_Gain1_A0                          1.106711f
+#define HPF_Fs176400_Gain1_A1                          (-0.855807f)
+#define HPF_Fs176400_Gain1_A2                          0.000000f
+#define HPF_Fs176400_Gain1_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain1_B2                          0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs176400_Gain2_A0                          1.226443f
+#define HPF_Fs176400_Gain2_A1                          (-0.975539f)
+#define HPF_Fs176400_Gain2_A2                          0.000000f
+#define HPF_Fs176400_Gain2_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain2_B2                          0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs176400_Gain3_A0                          1.360784f
+#define HPF_Fs176400_Gain3_A1                          (-1.109880f)
+#define HPF_Fs176400_Gain3_A2                          0.000000f
+#define HPF_Fs176400_Gain3_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain3_B2                          0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs176400_Gain4_A0                          1.511517f
+#define HPF_Fs176400_Gain4_A1                          (-1.260613f)
+#define HPF_Fs176400_Gain4_A2                          0.000000f
+#define HPF_Fs176400_Gain4_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain4_B2                          0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs176400_Gain5_A0                          1.680643f
+#define HPF_Fs176400_Gain5_A1                          (-1.429739f)
+#define HPF_Fs176400_Gain5_A2                          0.000000f
+#define HPF_Fs176400_Gain5_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain5_B2                          0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs176400_Gain6_A0                          1.870405f
+#define HPF_Fs176400_Gain6_A1                          (-1.619501f)
+#define HPF_Fs176400_Gain6_A2                          0.000000f
+#define HPF_Fs176400_Gain6_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain6_B2                          0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs176400_Gain7_A0                          2.083321f
+#define HPF_Fs176400_Gain7_A1                          (-1.832417f)
+#define HPF_Fs176400_Gain7_A2                          0.000000f
+#define HPF_Fs176400_Gain7_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain7_B2                          0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs176400_Gain8_A0                          2.322217f
+#define HPF_Fs176400_Gain8_A1                          (-2.071313f)
+#define HPF_Fs176400_Gain8_A2                          0.000000f
+#define HPF_Fs176400_Gain8_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain8_B2                          0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs176400_Gain9_A0                          2.590263f
+#define HPF_Fs176400_Gain9_A1                          (-2.339359f)
+#define HPF_Fs176400_Gain9_A2                          0.000000f
+#define HPF_Fs176400_Gain9_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain9_B2                          0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs176400_Gain10_A0                          2.891016f
+#define HPF_Fs176400_Gain10_A1                          (-2.640112f)
+#define HPF_Fs176400_Gain10_A2                          0.000000f
+#define HPF_Fs176400_Gain10_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain10_B2                          0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs176400_Gain11_A0                          3.228465f
+#define HPF_Fs176400_Gain11_A1                          (-2.977561f)
+#define HPF_Fs176400_Gain11_A2                          0.000000f
+#define HPF_Fs176400_Gain11_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain11_B2                          0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs176400_Gain12_A0                          3.607090f
+#define HPF_Fs176400_Gain12_A1                          (-3.356186f)
+#define HPF_Fs176400_Gain12_A2                          0.000000f
+#define HPF_Fs176400_Gain12_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain12_B2                          0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs176400_Gain13_A0                          4.031914f
+#define HPF_Fs176400_Gain13_A1                          (-3.781010f)
+#define HPF_Fs176400_Gain13_A2                          0.000000f
+#define HPF_Fs176400_Gain13_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain13_B2                          0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs176400_Gain14_A0                          4.508575f
+#define HPF_Fs176400_Gain14_A1                          (-4.257671f)
+#define HPF_Fs176400_Gain14_A2                          0.000000f
+#define HPF_Fs176400_Gain14_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain14_B2                          0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs176400_Gain15_A0                          5.043397f
+#define HPF_Fs176400_Gain15_A1                          (-4.792493f)
+#define HPF_Fs176400_Gain15_A2                          0.000000f
+#define HPF_Fs176400_Gain15_B1                          (-0.749096f)
+#define HPF_Fs176400_Gain15_B2                          0.000000f
+
 /* Coefficients for sample rate 192000Hz */
                                                                   /* Gain =  1.000000 dB */
 #define HPF_Fs192000_Gain1_A0                          1.107823
@@ -1216,4 +1399,4 @@
 
 
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index 7b85f23..62b4c73 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -71,7 +71,8 @@
     ((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))      ||
+     (pParams->SampleRate != LVM_FS_88200) && (pParams->SampleRate != LVM_FS_96000) &&
+     (pParams->SampleRate != LVM_FS_176400) && (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)       &&
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
index ade329b..0669a81 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -233,7 +233,13 @@
          * 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;
+        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+                                           LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+                                           LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+                                           LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+                                           LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+                                           LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+                                           LVDBE_CAP_FS_192000;
 #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
@@ -270,7 +276,13 @@
          * 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;
+        EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+                                         LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+                                         LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+                                         LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+                                         LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+                                         LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+                                         LVEQNB_CAP_FS_192000;
 #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
@@ -747,7 +759,13 @@
          * 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;
+        DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+                                           LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+                                           LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+                                           LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+                                           LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+                                           LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+                                           LVDBE_CAP_FS_192000;
 #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
@@ -805,7 +823,13 @@
          * 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;
+        EQNB_Capabilities.SampleRate      = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+                                            LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+                                            LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+                                            LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+                                            LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+                                            LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+                                            LVEQNB_CAP_FS_192000;
 #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
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
index 199ddde..a5356d2 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -269,6 +269,53 @@
                      -HPF_Fs48000_Gain15_B1}
 #ifdef HIGHER_FS
                     ,
+                    /* 88kHz Sampling rate */
+                    {HPF_Fs88200_Gain1_A1,             /* Gain Setting  1 */
+                    HPF_Fs88200_Gain1_A0,
+                    -HPF_Fs88200_Gain1_B1},
+                    {HPF_Fs88200_Gain2_A1,             /* Gain Setting  2 */
+                    HPF_Fs88200_Gain2_A0,
+                    -HPF_Fs88200_Gain2_B1},
+                    {HPF_Fs88200_Gain3_A1,             /* Gain Setting  3 */
+                    HPF_Fs88200_Gain3_A0,
+                    -HPF_Fs88200_Gain3_B1},
+                    {HPF_Fs88200_Gain4_A1,             /* Gain Setting  4 */
+                    HPF_Fs88200_Gain4_A0,
+                    -HPF_Fs88200_Gain4_B1},
+                    {HPF_Fs88200_Gain5_A1,             /* Gain Setting  5 */
+                    HPF_Fs88200_Gain5_A0,
+                    -HPF_Fs88200_Gain5_B1},
+                    {HPF_Fs88200_Gain6_A1,             /* Gain Setting  6 */
+                    HPF_Fs88200_Gain6_A0,
+                    -HPF_Fs88200_Gain6_B1},
+                    {HPF_Fs88200_Gain7_A1,             /* Gain Setting  7 */
+                    HPF_Fs88200_Gain7_A0,
+                    -HPF_Fs88200_Gain7_B1},
+                    {HPF_Fs88200_Gain8_A1,             /* Gain Setting  8 */
+                    HPF_Fs88200_Gain8_A0,
+                    -HPF_Fs88200_Gain8_B1},
+                    {HPF_Fs88200_Gain9_A1,             /* Gain Setting  9 */
+                    HPF_Fs88200_Gain9_A0,
+                    -HPF_Fs88200_Gain9_B1},
+                    {HPF_Fs88200_Gain10_A1,             /* Gain Setting  10 */
+                    HPF_Fs88200_Gain10_A0,
+                    -HPF_Fs88200_Gain10_B1},
+                    {HPF_Fs88200_Gain11_A1,             /* Gain Setting  11 */
+                    HPF_Fs88200_Gain11_A0,
+                    -HPF_Fs88200_Gain11_B1},
+                    {HPF_Fs88200_Gain12_A1,             /* Gain Setting  12 */
+                    HPF_Fs88200_Gain12_A0,
+                    -HPF_Fs88200_Gain12_B1},
+                    {HPF_Fs88200_Gain13_A1,             /* Gain Setting  13 */
+                    HPF_Fs88200_Gain13_A0,
+                    -HPF_Fs88200_Gain13_B1},
+                    {HPF_Fs88200_Gain14_A1,             /* Gain Setting  14 */
+                    HPF_Fs88200_Gain14_A0,
+                    -HPF_Fs88200_Gain14_B1},
+                    {HPF_Fs88200_Gain15_A1,             /* Gain Setting  15 */
+                    HPF_Fs88200_Gain15_A0,
+                    -HPF_Fs88200_Gain15_B1},
+
                     /* 96kHz sampling rate */
                     {HPF_Fs96000_Gain1_A1,             /* Gain setting 1 */
                     HPF_Fs96000_Gain1_A0,
@@ -316,6 +363,53 @@
                     HPF_Fs96000_Gain15_A0,
                     -HPF_Fs96000_Gain15_B1},
 
+                    /* 176kHz Sampling rate */
+                    {HPF_Fs176400_Gain1_A1,             /* Gain Setting  1 */
+                    HPF_Fs176400_Gain1_A0,
+                    -HPF_Fs176400_Gain1_B1},
+                    {HPF_Fs176400_Gain2_A1,             /* Gain Setting  2 */
+                    HPF_Fs176400_Gain2_A0,
+                    -HPF_Fs176400_Gain2_B1},
+                    {HPF_Fs176400_Gain3_A1,             /* Gain Setting  3 */
+                    HPF_Fs176400_Gain3_A0,
+                    -HPF_Fs176400_Gain3_B1},
+                    {HPF_Fs176400_Gain4_A1,             /* Gain Setting  4 */
+                    HPF_Fs176400_Gain4_A0,
+                    -HPF_Fs176400_Gain4_B1},
+                    {HPF_Fs176400_Gain5_A1,             /* Gain Setting  5 */
+                    HPF_Fs176400_Gain5_A0,
+                    -HPF_Fs176400_Gain5_B1},
+                    {HPF_Fs176400_Gain6_A1,             /* Gain Setting  6 */
+                    HPF_Fs176400_Gain6_A0,
+                    -HPF_Fs176400_Gain6_B1},
+                    {HPF_Fs176400_Gain7_A1,             /* Gain Setting  7 */
+                    HPF_Fs176400_Gain7_A0,
+                    -HPF_Fs176400_Gain7_B1},
+                    {HPF_Fs176400_Gain8_A1,             /* Gain Setting  8 */
+                    HPF_Fs176400_Gain8_A0,
+                    -HPF_Fs176400_Gain8_B1},
+                    {HPF_Fs176400_Gain9_A1,             /* Gain Setting  9 */
+                    HPF_Fs176400_Gain9_A0,
+                    -HPF_Fs176400_Gain9_B1},
+                    {HPF_Fs176400_Gain10_A1,             /* Gain Setting  10 */
+                    HPF_Fs176400_Gain10_A0,
+                    -HPF_Fs176400_Gain10_B1},
+                    {HPF_Fs176400_Gain11_A1,             /* Gain Setting  11 */
+                    HPF_Fs176400_Gain11_A0,
+                    -HPF_Fs176400_Gain11_B1},
+                    {HPF_Fs176400_Gain12_A1,             /* Gain Setting  12 */
+                    HPF_Fs176400_Gain12_A0,
+                    -HPF_Fs176400_Gain12_B1},
+                    {HPF_Fs176400_Gain13_A1,             /* Gain Setting  13 */
+                    HPF_Fs176400_Gain13_A0,
+                    -HPF_Fs176400_Gain13_B1},
+                    {HPF_Fs176400_Gain14_A1,             /* Gain Setting  14 */
+                    HPF_Fs176400_Gain14_A0,
+                    -HPF_Fs176400_Gain14_B1},
+                    {HPF_Fs176400_Gain15_A1,             /* Gain Setting  15 */
+                    HPF_Fs176400_Gain15_A0,
+                    -HPF_Fs176400_Gain15_B1},
+
                     /* 192kHz sampling rate */
                     {HPF_Fs192000_Gain1_A1,             /* Gain setting 1 */
                     HPF_Fs192000_Gain1_A0,
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 303b62d..59586e0 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -169,8 +169,10 @@
     LVM_FS_44100 = 7,
     LVM_FS_48000 = 8,
 #ifdef HIGHER_FS
-    LVM_FS_96000 = 9,
-    LVM_FS_192000 = 10,
+    LVM_FS_88200 = 9,
+    LVM_FS_96000 = 10,
+    LVM_FS_176400 = 11,
+    LVM_FS_192000 = 12,
 #endif
     LVM_FS_INVALID = LVM_MAXENUM-1,
     LVM_FS_DUMMY = LVM_MAXENUM
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index e7fdbf6..385dbcf 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -201,8 +201,10 @@
 #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
+#define LVEQNB_CAP_FS_88200                512
+#define LVEQNB_CAP_FS_96000                1024
+#define LVEQNB_CAP_FS_176400               2048
+#define LVEQNB_CAP_FS_192000               4096
 #endif
 
 typedef enum
@@ -217,8 +219,10 @@
     LVEQNB_FS_44100 = 7,
     LVEQNB_FS_48000 = 8,
 #ifdef HIGHER_FS
-    LVEQNB_FS_96000 = 9,
-    LVEQNB_FS_192000 = 10,
+    LVEQNB_FS_88200 = 9,
+    LVEQNB_FS_96000 = 10,
+    LVEQNB_FS_176400 = 11,
+    LVEQNB_FS_192000 = 12,
 #endif
     LVEQNB_FS_MAX   = LVM_MAXINT_32
 } LVEQNB_Fs_en;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
index 42ea46f..755141e 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
@@ -109,7 +109,9 @@
 #define LVEQNB_2PiOn_48000                               0.000131f
 
 #ifdef HIGHER_FS
+#define LVEQNB_2PiOn_88200                               0.000071f
 #define LVEQNB_2PiOn_96000                               0.000065f
+#define LVEQNB_2PiOn_176400                              0.000036f
 #define LVEQNB_2PiOn_192000                              0.000033f
 #endif
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
index 563181c..453c42d 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -46,7 +46,9 @@
                                               32000,
                                               44100,
                                               48000,
+                                              88200,
                                               96000,
+                                              176400,
                                               192000
 };
 #else
@@ -82,7 +84,9 @@
                                                LVEQNB_2PiOn_44100,
                                                LVEQNB_2PiOn_48000
 #ifdef HIGHER_FS
+                                              ,LVEQNB_2PiOn_88200
                                               ,LVEQNB_2PiOn_96000
+                                              ,LVEQNB_2PiOn_176400
                                               ,LVEQNB_2PiOn_192000
 #endif
                                                };
@@ -249,30 +253,4 @@
                                           16586,                       /* a2 */
                                           -44};                        /* a3 */
 
-/************************************************************************************/
-/*                                                                                  */
-/*  Bypass mixer time constants (100ms)                                             */
-/*                                                                                  */
-/************************************************************************************/
 
-#define LVEQNB_MIX_TC_Fs8000    32580         /* Floating point value 0.994262695 */
-#define LVEQNB_MIX_TC_Fs11025   32632         /* Floating point value 0.995849609 */
-#define LVEQNB_MIX_TC_Fs12000   32643         /* Floating point value 0.996185303 */
-#define LVEQNB_MIX_TC_Fs16000   32674         /* Floating point value 0.997131348 */
-#define LVEQNB_MIX_TC_Fs22050   32700         /* Floating point value 0.997924805 */
-#define LVEQNB_MIX_TC_Fs24000   32705         /* Floating point value 0.998077393 */
-#define LVEQNB_MIX_TC_Fs32000   32721         /* Floating point value 0.998565674 */
-#define LVEQNB_MIX_TC_Fs44100   32734         /* Floating point value 0.998962402 */
-#define LVEQNB_MIX_TC_Fs48000   32737         /* Floating point value 0.999053955 */
-
-
-const LVM_INT16 LVEQNB_MixerTCTable[] = {
-    LVEQNB_MIX_TC_Fs8000,
-    LVEQNB_MIX_TC_Fs11025,
-    LVEQNB_MIX_TC_Fs12000,
-    LVEQNB_MIX_TC_Fs16000,
-    LVEQNB_MIX_TC_Fs22050,
-    LVEQNB_MIX_TC_Fs24000,
-    LVEQNB_MIX_TC_Fs32000,
-    LVEQNB_MIX_TC_Fs44100,
-    LVEQNB_MIX_TC_Fs48000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index ff7475e..c915ac0 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -123,7 +123,7 @@
 #ifndef HIGHER_FS
 #define LVREV_NUM_FS                        9           /* Number of supported sample rates */
 #else
-#define LVREV_NUM_FS                       11           /* Number of supported sample rates */
+#define LVREV_NUM_FS                       13           /* Number of supported sample rates */
 #endif
 
 #define LVREV_MAXBLKSIZE_LIMIT             64           /* Maximum block size low limit */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
index 8c7807f..dfed28e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -68,7 +68,8 @@
         (pNewParams->SampleRate != LVM_FS_44100) &&
         (pNewParams->SampleRate != LVM_FS_48000)
 #ifdef HIGHER_FS
-        && (pNewParams->SampleRate != LVM_FS_96000) && (pNewParams->SampleRate != LVM_FS_192000)
+        && (pNewParams->SampleRate != LVM_FS_88200) && (pNewParams->SampleRate != LVM_FS_96000)
+        && (pNewParams->SampleRate != LVM_FS_176400) && (pNewParams->SampleRate != LVM_FS_192000)
 #endif
         )
 #ifdef SUPPORT_MC
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
index b3edc60..1058740 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -52,7 +52,9 @@
     32000,
     44100,
     48000,
+    88200,
     96000,
+    176400,
     192000
 };
 #endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index a750bb0..ee07e2e 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -46,7 +46,7 @@
 #ifndef HIGHER_FS
 #define LVPSA_NR_SUPPORTED_RATE          9      /* From 8000Hz to 48000Hz*/
 #else
-#define LVPSA_NR_SUPPORTED_RATE          11      /* From 8000Hz to 192000Hz*/
+#define LVPSA_NR_SUPPORTED_RATE          13      /* From 8000Hz to 192000Hz*/
 #endif
 #define LVPSA_NR_SUPPORTED_SPEED         3      /* LOW, MEDIUM, HIGH                                                */
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
index 1287503..f8af496 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -54,7 +54,9 @@
                                                 32000,
                                                 44100,
                                                 48000,
+                                                88200,
                                                 96000,
+                                               176400,
                                                192000};                  /* 192kS/s */
 #endif
 
@@ -78,7 +80,9 @@
                                                     48696,
                                                     44739
 #ifdef HIGHER_FS
+                                                    ,24348
                                                     ,22369
+                                                    ,12174
                                                     ,11185                  /* 192kS/s */
 #endif
                                                };
@@ -105,7 +109,9 @@
                                                         882,
                                                         960
 #ifdef HIGHER_FS
+                                                        ,1764
                                                         ,1920
+                                                        ,3528
                                                         ,3840                  /* 192kS/s */
 #endif
                                                     };
@@ -128,7 +134,9 @@
                                                         30,                   /* 44100 S/s  */
                                                         32                    /* 48000 S/s  */
 #ifdef HIGHER_FS
+                                                       ,60                   /* 88200 S/s  */
                                                        ,64                   /* 96000 S/s  */
+                                                       ,120                  /* 176400 S/s  */
                                                        ,128                  /*192000 S/s  */
 #endif
                                                   };
@@ -153,7 +161,9 @@
                                                  4781,
                                                  4392
 #ifdef HIGHER_FS
+                                                ,2390
                                                 ,2196
+                                                ,1195
                                                 ,1098    /* 192kS/s */
 #endif
                                              };
@@ -169,7 +179,9 @@
                                                       0.1459089f,
                                                       0.1340372f
 #ifdef HIGHER_FS
+                                                     ,0.0729476f
                                                      ,0.0670186f
+                                                     ,0.0364738f
                                                      ,0.0335093f    /* 192kS/s */
 #endif
                                                    };
@@ -352,7 +364,9 @@
                                           /* 48kS/s */
                                          {-0.9932638457976282f,0.0066249934025109f},
 #ifdef HIGHER_FS
+                                         {-0.9931269618682563f,0.0067592649720609f},
                                          {-0.9932638457976282f,0.0066249934025109f},
+                                         {-0.9931269618682563f,0.0067592649720609f},
                                          {-0.9932638457976282f,0.0066249934025109f},
 #endif
                                          /* 8kS/s  */    /* LVPSA_SPEED_MEDIUM      */
@@ -368,7 +382,9 @@
                                           /* 48kS/s */
                                          {-0.9540119562298059f,0.0445343819446862f},
 #ifdef HIGHER_FS
+                                         {-0.9531011912040412f,0.0453995238058269f},
                                          {-0.9540119562298059f,0.0445343819446862f},
+                                         {-0.9531011912040412f,0.0453995238058269f},
                                          {-0.9540119562298059f,0.0445343819446862f},
 #endif
                                           /* 8kS/s  */   /* LVPSA_SPEED_HIGH      */
@@ -383,7 +399,9 @@
                                            /* 48kS/s */
                                          {-0.7274807319045067f,0.2356666540727019f}
 #ifdef HIGHER_FS
+                                        ,{-0.7229706319049001f,0.2388987224549055f}
                                         ,{-0.7274807319045067f,0.2356666540727019f}
+                                        ,{-0.7229706319049001f,0.2388987224549055f}
                                         ,{-0.7274807319045067f,0.2356666540727019f}
 #endif
                                         };
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 0c2fe53..e45d81f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
@@ -152,6 +152,24 @@
 #define CS_SIDE_48000_SCALE                          14
 
 #ifdef HIGHER_FS
+/* Coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_88200_A0                     0.233846f
+#define CS_MIDDLE_88200_A1                     (-0.232657f)
+#define CS_MIDDLE_88200_A2                     0.000000f
+#define CS_MIDDLE_88200_B1                     (-0.992747f)
+#define CS_MIDDLE_88200_B2                     0.000000f
+#define CS_MIDDLE_88200_SCALE                  15
+#define CS_SIDE_88200_A0                       0.231541f
+#define CS_SIDE_88200_A1                       (-0.289586f)
+#define CS_SIDE_88200_A2                       0.058045f
+#define CS_SIDE_88200_B1                       (-1.765300f)
+#define CS_SIDE_88200_B2                       0.769816f
+#define CS_SIDE_88200_SCALE                    14
+
 /* 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
@@ -160,13 +178,33 @@
 #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
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_96000_A0                     0.224326f
+#define CS_SIDE_96000_A1                     (-0.294937f)
+#define CS_SIDE_96000_A2                     0.070611f
+#define CS_SIDE_96000_B1                     (-1.792166f)
+#define CS_SIDE_96000_B2                     0.795830f
+#define CS_SIDE_96000_SCALE                  14
+
+/* Stereo Enhancer coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_176400_A0                     0.233973f
+#define CS_MIDDLE_176400_A1                     (-0.233378f)
+#define CS_MIDDLE_176400_A2                     0.000000f
+#define CS_MIDDLE_176400_B1                     (-0.996367f)
+#define CS_MIDDLE_176400_B2                     0.000000f
+#define CS_MIDDLE_176400_SCALE                  15
+#define CS_SIDE_176400_A0                       0.199836f
+#define CS_SIDE_176400_A1                       (-0.307544f)
+#define CS_SIDE_176400_A2                       0.107708f
+#define CS_SIDE_176400_B1                       (-1.876572f)
+#define CS_SIDE_176400_B2                       0.877771f
+#define CS_SIDE_176400_SCALE                    14
 
 /* Stereo Enhancer coefficients for 192000Hz sample rate, scaled with  0.1689*/
 #define CS_MIDDLE_192000_A0                     0.241219
@@ -175,13 +213,15 @@
 #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
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_192000_A0                    0.196039f
+#define CS_SIDE_192000_A1                    (-0.311027f)
+#define CS_SIDE_192000_A2                    0.114988f
+#define CS_SIDE_192000_B1                    (-1.891380f)
+#define CS_SIDE_192000_B2                    0.8923460f
+#define CS_SIDE_192000_SCALE                 14
 #endif
 
 /************************************************************************************/
@@ -199,7 +239,13 @@
 #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 */
+// TODO: this should linearly scale by frequency but is limited to 512 frames until
+// we ensure enough buffer size has been allocated.
 #define LVCS_STEREODELAY_CS_48KHZ                   512         /* Sample rate 48kS/s */
+#define LVCS_STEREODELAY_CS_88KHZ                   512         /* Sample rate 88.2kS/s */
+#define LVCS_STEREODELAY_CS_96KHZ                   512         /* Sample rate 96kS/s */
+#define LVCS_STEREODELAY_CS_176KHZ                  512         /* Sample rate 176.4kS/s */
+#define LVCS_STEREODELAY_CS_192KHZ                  512         /* Sample rate 196kS/s */
 
 /* Reverb coefficients for 8000 Hz sample rate, scaled with 1.038030 */
 #define CS_REVERB_8000_A0                          0.667271
@@ -275,6 +321,14 @@
 #define CS_REVERB_48000_SCALE                        14
 
 #ifdef HIGHER_FS
+/* Reverb coefficients for 88200Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_88200_A0                       0.171901f
+#define CS_REVERB_88200_A1                       0.000000f
+#define CS_REVERB_88200_A2                      (-0.171901f)
+#define CS_REVERB_88200_B1                      (-1.553948f)
+#define CS_REVERB_88200_B2                      (0.570248f)
+#define CS_REVERB_88200_SCALE                      14
 /* 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
@@ -284,6 +338,14 @@
 #define CS_REVERB_96000_B2                       0.599377
 #define CS_REVERB_96000_SCALE                        14
 
+/* Reverb coefficients for 176400Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_176400_A0                       0.094763f
+#define CS_REVERB_176400_A1                       0.000000f
+#define CS_REVERB_176400_A2                      (-0.094763f)
+#define CS_REVERB_176400_B1                      (-1.758593f)
+#define CS_REVERB_176400_B2                      (0.763091f)
+#define CS_REVERB_176400_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
@@ -446,6 +508,24 @@
 
 
 #ifdef HIGHER_FS
+/* Equaliser coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_88200_A0                   1.771899f
+#define CS_EQUALISER_88200_A1                   (-2.930762f)
+#define CS_EQUALISER_88200_A2                   1.172175f
+#define CS_EQUALISER_88200_B1                   (-1.438349f)
+#define CS_EQUALISER_88200_B2                   0.442520f
+#define CS_EQUALISER_88200_SCALE                13
+#define CSEX_EQUALISER_88200_A0                 2.675241f
+#define CSEX_EQUALISER_88200_A1                 (-4.466154f)
+#define CSEX_EQUALISER_88200_A2                 1.810305f
+#define CSEX_EQUALISER_88200_B1                 (-0.925350f)
+#define CSEX_EQUALISER_88200_B2                 (-0.066616f)
+#define CSEX_EQUALISER_88200_SCALE              13
+
 #define CS_EQUALISER_96000_A0                    1.784497
 #define CS_EQUALISER_96000_A1                   (-3.001435)
 #define CS_EQUALISER_96000_A2                    1.228422
@@ -458,6 +538,23 @@
 #define CSEX_EQUALISER_96000_B1                 (-0.971718)
 #define CSEX_EQUALISER_96000_B2                 (-0.021216)
 #define CSEX_EQUALISER_96000_SCALE                   13
+/* Equaliser coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_176400_A0                  1.883440f
+#define CS_EQUALISER_176400_A1                  (-3.414272f)
+#define CS_EQUALISER_176400_A2                  1.534702f
+#define CS_EQUALISER_176400_B1                  (-1.674614f)
+#define CS_EQUALISER_176400_B2                  0.675827f
+#define CS_EQUALISER_176400_SCALE               13
+#define CSEX_EQUALISER_176400_A0                3.355068f
+#define CSEX_EQUALISER_176400_A1                (-6.112578f)
+#define CSEX_EQUALISER_176400_A2                2.764135f
+#define CSEX_EQUALISER_176400_B1                (-1.268533f)
+#define CSEX_EQUALISER_176400_B2                0.271277f
+#define CSEX_EQUALISER_176400_SCALE             13
 
 #define CS_EQUALISER_192000_A0                    1.889582
 #define CS_EQUALISER_192000_A1                   (-3.456140)
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
index 0765764..a1fb48f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -74,10 +74,18 @@
      (LVM_UINT16 )CS_MIDDLE_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CS_MIDDLE_88200_A0,        /* 88kS/s coefficients */
+     CS_MIDDLE_88200_A1,
+     CS_MIDDLE_88200_B1,
+     (LVM_UINT16)CS_MIDDLE_88200_SCALE},
     {CS_MIDDLE_96000_A0,        /* 96kS/s coefficients */
      CS_MIDDLE_96000_A1,
      CS_MIDDLE_96000_B1,
      (LVM_UINT16 )CS_MIDDLE_96000_SCALE},
+    {CS_MIDDLE_176400_A0,        /* 176kS/s coefficients */
+     CS_MIDDLE_176400_A1,
+     CS_MIDDLE_176400_B1,
+     (LVM_UINT16)CS_MIDDLE_176400_SCALE},
     {CS_MIDDLE_192000_A0,        /* 192kS/s coefficients */
      CS_MIDDLE_192000_A1,
      CS_MIDDLE_192000_B1,
@@ -144,12 +152,24 @@
      (LVM_UINT16 )CS_SIDE_48000_SCALE}
 #ifdef HIGHER_FS
      ,
+    {CS_SIDE_88200_A0,          /* 88kS/s coefficients */
+     CS_SIDE_88200_A1,
+     CS_SIDE_88200_A2,
+     CS_SIDE_88200_B1,
+     CS_SIDE_88200_B2,
+     (LVM_UINT16)CS_SIDE_88200_SCALE},
      {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_176400_A0,          /*176kS/s coefficients */
+     CS_SIDE_176400_A1,
+     CS_SIDE_176400_A2,
+     CS_SIDE_176400_B1,
+     CS_SIDE_176400_B2,
+     (LVM_UINT16)CS_SIDE_176400_SCALE},
      {CS_SIDE_192000_A0,          /* 192kS/s coefficients */
      CS_SIDE_192000_A1,
      CS_SIDE_192000_A2,
@@ -223,12 +243,24 @@
      CS_EQUALISER_48000_B2,
      (LVM_UINT16 )CS_EQUALISER_48000_SCALE},
 #ifdef HIGHER_FS
+    {CS_EQUALISER_88200_A0,     /* 88kS/s coeffieients */
+     CS_EQUALISER_88200_A1,
+     CS_EQUALISER_88200_A2,
+     CS_EQUALISER_88200_B1,
+     CS_EQUALISER_88200_B2,
+     (LVM_UINT16)CS_EQUALISER_88200_SCALE},
     {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_176400_A0,     /* 176kS/s coefficients */
+     CS_EQUALISER_176400_A1,
+     CS_EQUALISER_176400_A2,
+     CS_EQUALISER_176400_B1,
+     CS_EQUALISER_176400_B2,
+     (LVM_UINT16)CS_EQUALISER_176400_SCALE},
     {CS_EQUALISER_192000_A0,     /* 192kS/s coefficients */
      CS_EQUALISER_192000_A1,
      CS_EQUALISER_192000_A2,
@@ -294,12 +326,24 @@
      (LVM_UINT16 )CSEX_EQUALISER_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CSEX_EQUALISER_88200_A0,   /* 88kS/s coefficients */
+     CSEX_EQUALISER_88200_A1,
+     CSEX_EQUALISER_88200_A2,
+     CSEX_EQUALISER_88200_B1,
+     CSEX_EQUALISER_88200_B2,
+     (LVM_UINT16)CSEX_EQUALISER_88200_SCALE},
     {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_176400_A0,   /* 176kS/s coefficients */
+     CSEX_EQUALISER_176400_A1,
+     CSEX_EQUALISER_176400_A2,
+     CSEX_EQUALISER_176400_B1,
+     CSEX_EQUALISER_176400_B2,
+     (LVM_UINT16)CSEX_EQUALISER_176400_SCALE},
      {CSEX_EQUALISER_192000_A0,   /* 192kS/s coefficients */
      CSEX_EQUALISER_192000_A1,
      CSEX_EQUALISER_192000_A2,
@@ -326,7 +370,12 @@
     LVCS_STEREODELAY_CS_24KHZ,
     LVCS_STEREODELAY_CS_32KHZ,
     LVCS_STEREODELAY_CS_44KHZ,
-    LVCS_STEREODELAY_CS_48KHZ};
+    LVCS_STEREODELAY_CS_48KHZ,
+    LVCS_STEREODELAY_CS_88KHZ,
+    LVCS_STEREODELAY_CS_96KHZ,
+    LVCS_STEREODELAY_CS_176KHZ,
+    LVCS_STEREODELAY_CS_192KHZ,
+};
 
 /************************************************************************************/
 /*                                                                                  */
@@ -392,12 +441,24 @@
      (LVM_UINT16 )CS_REVERB_48000_SCALE}
 #ifdef HIGHER_FS
     ,
+    {CS_REVERB_88200_A0,            /* 88kS/s coefficients */
+     CS_REVERB_88200_A1,
+     CS_REVERB_88200_A2,
+     CS_REVERB_88200_B1,
+     CS_REVERB_88200_B2,
+     (LVM_UINT16)CS_REVERB_88200_SCALE},
     {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_176400_A0,            /* 176kS/s coefficients */
+     CS_REVERB_176400_A1,
+     CS_REVERB_176400_A2,
+     CS_REVERB_176400_B1,
+     CS_REVERB_176400_B2,
+     (LVM_UINT16)CS_REVERB_176400_SCALE},
      {CS_REVERB_192000_A0,            /* 192kS/s coefficients */
      CS_REVERB_192000_A1,
      CS_REVERB_192000_A2,
@@ -509,12 +570,14 @@
 #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_Fs88200     32751       /* Floating point value 0.999481066 */
 #define LVCS_VOL_TC_Fs96000     32751       /* Floating point value 0.999511703 */   /* Todo @ need to re check this value*/
+#define LVCS_VOL_TC_Fs176400    32759       /* Floating point value 0.999740499 */
 #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,
+const LVM_INT16 LVCS_VolumeTCTable[13] = {LVCS_VOL_TC_Fs8000,
                                           LVCS_VOL_TC_Fs11025,
                                           LVCS_VOL_TC_Fs12000,
                                           LVCS_VOL_TC_Fs16000,
@@ -523,7 +586,9 @@
                                           LVCS_VOL_TC_Fs32000,
                                           LVCS_VOL_TC_Fs44100,
                                           LVCS_VOL_TC_Fs48000,
+                                          LVCS_VOL_TC_Fs88200,
                                           LVCS_VOL_TC_Fs96000,
+                                          LVCS_VOL_TC_Fs176400,
                                           LVCS_VOL_TC_Fs192000
 };
 #else
@@ -545,7 +610,7 @@
 /*                                                                                  */
 /************************************************************************************/
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-const LVM_INT32   LVCS_SampleRateTable[11] = {8000,
+const LVM_INT32   LVCS_SampleRateTable[13] = {8000,
                                               11025,
                                               12000,
                                               16000,
@@ -554,7 +619,9 @@
                                               32000,
                                               44100,
                                               48000,
+                                              88200,
                                               96000,
+                                              176400,
                                               192000
 };
 #else
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index 01c5955..99551cc 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -447,19 +447,69 @@
                lvmConfigParams_t    *plvmConfigParams,
                LVM_ControlParams_t  *params) {
   LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
-  LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
-  int eqPresetLevel = plvmConfigParams->eqPresetLevel;
-  int nrChannels = plvmConfigParams->nrChannels;
-  params->NrChannels = nrChannels;
 
   /* Set the initial process parameters */
   /* General parameters */
   params->OperatingMode = LVM_MODE_ON;
-  params->SampleRate = LVM_FS_44100;
-  params->SourceFormat = LVM_STEREO;
   params->SpeakerType = LVM_HEADPHONES;
 
-  pContext->pBundledContext->SampleRate = LVM_FS_44100;
+  const int nrChannels = plvmConfigParams->nrChannels;
+  params->NrChannels = nrChannels;
+  if (nrChannels == 1) {
+    params->SourceFormat = LVM_MONO;
+  } else if (nrChannels == 2) {
+    params->SourceFormat = LVM_STEREO;
+  } else if (nrChannels > 2 && nrChannels <= 8) { // FCC_2 FCC_8
+    params->SourceFormat = LVM_MULTICHANNEL;
+  } else {
+      return -EINVAL;
+  }
+
+  LVM_Fs_en sampleRate;
+  switch (plvmConfigParams->samplingFreq) {
+    case 8000:
+      sampleRate = LVM_FS_8000;
+      break;
+    case 11025:
+      sampleRate = LVM_FS_11025;
+      break;
+    case 12000:
+      sampleRate = LVM_FS_12000;
+      break;
+    case 16000:
+      sampleRate = LVM_FS_16000;
+      break;
+    case 22050:
+      sampleRate = LVM_FS_22050;
+      break;
+    case 24000:
+      sampleRate = LVM_FS_24000;
+      break;
+    case 32000:
+      sampleRate = LVM_FS_32000;
+      break;
+    case 44100:
+      sampleRate = LVM_FS_44100;
+      break;
+    case 48000:
+      sampleRate = LVM_FS_48000;
+      break;
+    case 88200:
+      sampleRate = LVM_FS_88200;
+      break;
+    case 96000:
+      sampleRate = LVM_FS_96000;
+      break;
+    case 176400:
+      sampleRate = LVM_FS_176400;
+      break;
+    case 192000:
+      sampleRate = LVM_FS_192000;
+      break;
+    default:
+      return -EINVAL;
+  }
+  params->SampleRate = sampleRate;
 
   /* Concert Sound parameters */
   params->VirtualizerOperatingMode = plvmConfigParams->csEnable;
@@ -468,14 +518,17 @@
   params->CS_EffectLevel = LVM_CS_EFFECT_NONE;
 
   /* N-Band Equaliser parameters */
-  params->EQNB_OperatingMode = plvmConfigParams->eqEnable;
-  params->pEQNB_BandDefinition = &BandDefs[0];
+  const int eqPresetLevel = plvmConfigParams->eqPresetLevel;
+  LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
   for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
     BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
     BandDefs[i].QFactor = EQNB_5BandPresetsQFactors[i];
     BandDefs[i].Gain =
         EQNB_5BandSoftPresets[(FIVEBAND_NUMBANDS * eqPresetLevel) + i];
   }
+  params->EQNB_OperatingMode = plvmConfigParams->eqEnable;
+ // Caution: raw pointer to stack data, stored in instance by LVM_SetControlParameters.
+  params->pEQNB_BandDefinition = &BandDefs[0];
 
   /* Volume Control parameters */
   params->VC_EffectLevel = 0;
@@ -490,16 +543,6 @@
   /* Bass Enhancement parameters */
   params->BE_OperatingMode = plvmConfigParams->bassEnable;
 
-  if (nrChannels == 1) {
-    params->SourceFormat = LVM_MONO;
-  }
-  if (nrChannels == 2) {
-    params->SourceFormat = LVM_STEREO;
-  }
-  if ((nrChannels > 2) && (nrChannels <= 8)) {
-    params->SourceFormat = LVM_MULTICHANNEL;
-  }
-
   /* Activate the initial settings */
   LvmStatus =
       LVM_SetControlParameters(pContext->pBundledContext->hInstance, params);
@@ -613,7 +656,9 @@
           samplingFreq != 12000 && samplingFreq != 16000 &&
           samplingFreq != 22050 && samplingFreq != 24000 &&
           samplingFreq != 32000 && samplingFreq != 44100 &&
-          samplingFreq != 48000 && samplingFreq != 96000) {
+          samplingFreq != 48000 && samplingFreq != 88200 &&
+          samplingFreq != 96000 && samplingFreq != 176400 &&
+          samplingFreq != 192000) {
         ALOGE("\nError: Unsupported Sampling Frequency : %d\n", samplingFreq);
         return -1;
       }
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 09e9964..b5860de 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -1275,10 +1275,18 @@
         pContext->pBundledContext->SamplesPerSecond = 48000 * NrChannels;
         break;
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 88200:
+        SampleRate = LVM_FS_88200;
+        pContext->pBundledContext->SamplesPerSecond = 88200 * NrChannels;
+        break;
     case 96000:
         SampleRate = LVM_FS_96000;
         pContext->pBundledContext->SamplesPerSecond = 96000 * NrChannels;
         break;
+    case 176400:
+        SampleRate = LVM_FS_176400;
+        pContext->pBundledContext->SamplesPerSecond = 176400 * NrChannels;
+        break;
     case 192000:
         SampleRate = LVM_FS_192000;
         pContext->pBundledContext->SamplesPerSecond = 192000 * NrChannels;
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index d558169..602f607 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -675,9 +675,15 @@
         SampleRate = LVM_FS_48000;
         break;
 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+    case 88200:
+        SampleRate = LVM_FS_88200;
+        break;
     case 96000:
         SampleRate = LVM_FS_96000;
         break;
+    case 176400:
+        SampleRate = LVM_FS_176400;
+        break;
     case 192000:
         SampleRate = LVM_FS_192000;
         break;
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index fb861d7..b5a7172 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -285,6 +285,7 @@
 
 template <>
 const StreamTypeConverter::Table StreamTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DEFAULT),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING),
@@ -361,6 +362,22 @@
     TERMINATOR
 };
 
+template <>
+const AudioFlagConverter::Table AudioFlagConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NONE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_AUDIBILITY_ENFORCED),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SECURE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SCO),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BEACON),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_AV_SYNC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_HOTWORD),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_MUTE),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_LOW_LATENCY),
+    MAKE_STRING_FROM_ENUM(AUDIO_FLAG_DEEP_BUFFER),
+    TERMINATOR
+};
+
 template class TypeConverter<OutputDeviceTraits>;
 template class TypeConverter<InputDeviceTraits>;
 template class TypeConverter<OutputFlagTraits>;
@@ -374,6 +391,7 @@
 template class TypeConverter<AudioModeTraits>;
 template class TypeConverter<UsageTraits>;
 template class TypeConverter<SourceTraits>;
+template class TypeConverter<AudioFlagTraits>;
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device) {
     return InputDeviceConverter::fromString(literalDevice, device) ||
diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
index 86f0d4c..418e09c 100644
--- a/media/libmedia/include/media/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <string.h>
 
+#include <vector>
 #include <system/audio.h>
 #include <utils/Log.h>
 #include <utils/Vector.h>
@@ -30,77 +31,55 @@
 
 namespace android {
 
-struct SampleRateTraits
-{
-    typedef uint32_t Type;
-    typedef SortedVector<Type> Collection;
-};
-struct DeviceTraits
-{
-    typedef audio_devices_t Type;
-    typedef Vector<Type> Collection;
-};
-struct OutputDeviceTraits : public DeviceTraits {};
-struct InputDeviceTraits : public DeviceTraits {};
-struct OutputFlagTraits
-{
-    typedef audio_output_flags_t Type;
-    typedef Vector<Type> Collection;
-};
-struct InputFlagTraits
-{
-    typedef audio_input_flags_t Type;
-    typedef Vector<Type> Collection;
-};
-struct FormatTraits
-{
-    typedef audio_format_t Type;
-    typedef Vector<Type> Collection;
-};
-struct ChannelTraits
-{
-    typedef audio_channel_mask_t Type;
-    typedef SortedVector<Type> Collection;
-};
-struct OutputChannelTraits : public ChannelTraits {};
-struct InputChannelTraits : public ChannelTraits {};
-struct ChannelIndexTraits : public ChannelTraits {};
-struct GainModeTraits
-{
-    typedef audio_gain_mode_t Type;
-    typedef Vector<Type> Collection;
-};
-struct StreamTraits
-{
-    typedef audio_stream_type_t Type;
-    typedef Vector<Type> Collection;
-};
-struct AudioModeTraits
-{
-    typedef audio_mode_t Type;
-    typedef Vector<Type> Collection;
-};
-struct AudioContentTraits
-{
-    typedef audio_content_type_t Type;
-    typedef Vector<Type> Collection;
-};
-struct UsageTraits
-{
-    typedef audio_usage_t Type;
-    typedef Vector<Type> Collection;
-};
-struct SourceTraits
-{
-    typedef audio_source_t Type;
-    typedef Vector<Type> Collection;
-};
 template <typename T>
 struct DefaultTraits
 {
     typedef T Type;
-    typedef Vector<Type> Collection;
+    typedef std::vector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.push_back(value);
+    }
 };
+template <typename T>
+struct VectorTraits
+{
+    typedef T Type;
+    typedef Vector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.add(value);
+    }
+};
+template <typename T>
+struct SortedVectorTraits
+{
+    typedef T Type;
+    typedef SortedVector<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.add(value);
+    }
+};
+
+using SampleRateTraits = SortedVectorTraits<uint32_t>;
+using DeviceTraits = DefaultTraits<audio_devices_t>;
+struct OutputDeviceTraits : public DeviceTraits {};
+struct InputDeviceTraits : public DeviceTraits {};
+using ChannelTraits = SortedVectorTraits<audio_channel_mask_t>;
+struct OutputChannelTraits : public ChannelTraits {};
+struct InputChannelTraits : public ChannelTraits {};
+struct ChannelIndexTraits : public ChannelTraits {};
+using InputFlagTraits = DefaultTraits<audio_input_flags_t>;
+using OutputFlagTraits = DefaultTraits<audio_output_flags_t>;
+using FormatTraits = VectorTraits<audio_format_t>;
+using GainModeTraits = DefaultTraits<audio_gain_mode_t>;
+using StreamTraits = DefaultTraits<audio_stream_type_t>;
+using AudioModeTraits = DefaultTraits<audio_mode_t>;
+using AudioContentTraits = DefaultTraits<audio_content_type_t>;
+using UsageTraits = DefaultTraits<audio_usage_t>;
+using SourceTraits = DefaultTraits<audio_source_t>;
+struct AudioFlagTraits : public DefaultTraits<audio_flags_mask_t> {};
 
 template <class Traits>
 static void collectionFromString(const std::string &str, typename Traits::Collection &collection,
@@ -110,7 +89,7 @@
     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
         typename Traits::Type value;
         if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) {
-            collection.add(value);
+            Traits::add(collection, value);
         }
     }
     free(literal);
@@ -181,7 +160,7 @@
     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
         typename Traits::Type value;
         if (fromString(cstr, value)) {
-            collection.add(value);
+            Traits::add(collection, value);
         }
     }
     free(literal);
@@ -234,6 +213,7 @@
 typedef TypeConverter<AudioContentTraits> AudioContentTypeConverter;
 typedef TypeConverter<UsageTraits> UsageTypeConverter;
 typedef TypeConverter<SourceTraits> SourceTypeConverter;
+typedef TypeConverter<AudioFlagTraits> AudioFlagConverter;
 
 template<> const OutputDeviceConverter::Table OutputDeviceConverter::mTable[];
 template<> const InputDeviceConverter::Table InputDeviceConverter::mTable[];
@@ -249,6 +229,7 @@
 template<> const AudioContentTypeConverter::Table AudioContentTypeConverter::mTable[];
 template<> const UsageTypeConverter::Table UsageTypeConverter::mTable[];
 template<> const SourceTypeConverter::Table SourceTypeConverter::mTable[];
+template<> const AudioFlagConverter::Table AudioFlagConverter::mTable[];
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device);
 
@@ -274,6 +255,69 @@
 OutputChannelTraits::Collection outputChannelMasksFromString(
         const std::string &outChannels, const char *del = AudioParameter::valueListSeparator);
 
+static inline std::string toString(audio_usage_t usage)
+{
+    std::string usageLiteral;
+    if (!android::UsageTypeConverter::toString(usage, usageLiteral)) {
+        ALOGV("failed to convert usage: %d", usage);
+        return "AUDIO_USAGE_UNKNOWN";
+    }
+    return usageLiteral;
+}
+
+static inline std::string toString(audio_content_type_t content)
+{
+    std::string contentLiteral;
+    if (!android::AudioContentTypeConverter::toString(content, contentLiteral)) {
+        ALOGV("failed to convert content type: %d", content);
+        return "AUDIO_CONTENT_TYPE_UNKNOWN";
+    }
+    return contentLiteral;
+}
+
+static inline std::string toString(audio_stream_type_t stream)
+{
+    std::string streamLiteral;
+    if (!android::StreamTypeConverter::toString(stream, streamLiteral)) {
+        ALOGV("failed to convert stream: %d", stream);
+        return "AUDIO_STREAM_DEFAULT";
+    }
+    return streamLiteral;
+}
+
+static inline std::string toString(audio_source_t source)
+{
+    std::string sourceLiteral;
+    if (!android::SourceTypeConverter::toString(source, sourceLiteral)) {
+        ALOGV("failed to convert source: %d", source);
+        return "AUDIO_SOURCE_DEFAULT";
+    }
+    return sourceLiteral;
+}
+
+static inline std::string toString(const audio_attributes_t &attributes)
+{
+    std::ostringstream result;
+    result << "{ Content type: " << toString(attributes.content_type)
+           << " Usage: " << toString(attributes.usage)
+           << " Source: " << toString(attributes.source)
+           << " Flags: " << attributes.flags
+           << " Tags: " << attributes.tags
+           << " }";
+
+    return result.str();
+}
+
+static inline std::string toString(audio_mode_t mode)
+{
+    std::string modeLiteral;
+    if (!android::AudioModeConverter::toString(mode, modeLiteral)) {
+        ALOGV("failed to convert mode: %d", mode);
+        return "AUDIO_MODE_INVALID";
+    }
+    return modeLiteral;
+}
+
 }; // namespace android
 
 #endif  /*ANDROID_TYPE_CONVERTER_H_*/
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
index 6f2b35f..1aa1e13 100644
--- a/media/libmediaextractor/Android.bp
+++ b/media/libmediaextractor/Android.bp
@@ -14,6 +14,15 @@
         "-Wall",
     ],
 
+    static: {
+        cflags: [
+            "-Wno-multichar",
+            "-Werror",
+            "-Wall",
+            "-DNO_IMEMORY",
+        ],
+    },
+
     shared_libs: [
         "libbinder",
         "libstagefright_foundation",
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp
index 26d0bd4..bab3a03 100644
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ b/media/libmediaextractor/MediaBuffer.cpp
@@ -51,9 +51,12 @@
       mRangeLength(size),
       mOwnsData(true),
       mMetaData(new MetaDataBase) {
+#ifndef NO_IMEMORY
     if (size < kSharedMemThreshold
             || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
+#endif
         mData = malloc(size);
+#ifndef NO_IMEMORY
     } else {
         ALOGV("creating memoryDealer");
         sp<MemoryDealer> memoryDealer =
@@ -71,6 +74,7 @@
             ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
         }
     }
+#endif
 }
 
 MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libmediaextractor/MediaBufferGroup.cpp
index 4e6beca..e88ed5a 100644
--- a/media/libmediaextractor/MediaBufferGroup.cpp
+++ b/media/libmediaextractor/MediaBufferGroup.cpp
@@ -62,6 +62,7 @@
         mInternal->mGrowthLimit = buffers;
     }
 
+#ifndef NO_IMEMORY
     if (buffer_size >= kSharedMemoryThreshold) {
         ALOGD("creating MemoryDealer");
         // Using a single MemoryDealer is efficient for a group of shared memory objects.
@@ -84,6 +85,9 @@
         }
         return;
     }
+#else
+    (void)kSharedMemoryThreshold;
+#endif
 
     // Non-shared memory allocation.
     for (size_t i = 0; i < buffers; ++i) {
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
index 5b362a4..ace63ae 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
@@ -46,12 +46,13 @@
     explicit MediaBuffer(size_t size);
 
     explicit MediaBuffer(const sp<ABuffer> &buffer);
-
+#ifndef NO_IMEMORY
     MediaBuffer(const sp<IMemory> &mem) :
         MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
         // delegate and override mMemory
         mMemory = mem;
     }
+#endif
 
     // If MediaBufferGroup is set, decrement the local reference count;
     // if the local reference count drops to 0, return the buffer to the
@@ -92,17 +93,26 @@
     }
 
     virtual int remoteRefcount() const {
+#ifndef NO_IMEMORY
         if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
         int32_t remoteRefcount =
                 reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
         // Sanity check so that remoteRefCount() is non-negative.
         return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
+#else
+        return 0;
+#endif
     }
 
     // returns old value
     int addRemoteRefcount(int32_t value) {
+#ifndef NO_IMEMORY
         if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
         return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
+#else
+        (void) value;
+        return 0;
+#endif
     }
 
     bool isDeadObject() const {
@@ -110,8 +120,13 @@
     }
 
     static bool isDeadObject(const sp<IMemory> &memory) {
+#ifndef NO_IMEMORY
         if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
         return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
+#else
+        (void) memory;
+        return false;
+#endif
     }
 
     // Sticky on enabling of shared memory MediaBuffers. By default we don't use
@@ -204,7 +219,11 @@
     };
 
     inline SharedControl *getSharedControl() const {
+#ifndef NO_IMEMORY
          return reinterpret_cast<SharedControl *>(mMemory->pointer());
+#else
+         return nullptr;
+#endif
      }
 };
 
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index c7cd7d2..a945ffd 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -86,7 +86,7 @@
                     MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
             status_t        notifyAt(int64_t mediaTimeUs);
             status_t        getCurrentPosition(int64_t *msec);
-            status_t        getDuration(int64_t *msec);
+            status_t        getDuration(int64_t srcId, int64_t *msec);
             status_t        reset();
             status_t        setAudioStreamType(audio_stream_type_t type);
             status_t        getAudioStreamType(audio_stream_type_t *type);
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 2ae5a8c..f432059 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -718,8 +718,15 @@
     return ret;
 }
 
-status_t MediaPlayer2::getDuration(int64_t *msec) {
+status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
     Mutex::Autolock _l(mLock);
+    // TODO: cache duration for currentSrcId and nextSrcId, and return correct
+    // value for nextSrcId.
+    if (srcId != mSrcId) {
+        *msec = -1;
+        return OK;
+    }
+
     ALOGV("getDuration_l");
     bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
             MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index 81ffbc7..080d923 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -791,9 +791,13 @@
             sp<AReplyToken> replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
+            int64_t srcId;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
             PlayerMessage* reply;
             CHECK(msg->findPointer("reply", (void**)&reply));
 
+            // TODO: use correct source info based on srcId.
             size_t inbandTracks = 0;
             if (mCurrentSourceInfo.mSource != NULL) {
                 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
@@ -824,10 +828,14 @@
 
         case kWhatGetSelectedTrack:
         {
+            int64_t srcId;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
             int32_t type32;
             CHECK(msg->findInt32("type", (int32_t*)&type32));
             media_track_type type = (media_track_type)type32;
 
+            // TODO: use correct source info based on srcId.
             size_t inbandTracks = 0;
             status_t err = INVALID_OPERATION;
             ssize_t selectedTrack = -1;
@@ -863,15 +871,18 @@
             sp<AReplyToken> replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
+            int64_t srcId;
             size_t trackIndex;
             int32_t select;
             int64_t timeUs;
+            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK(msg->findInt32("select", &select));
             CHECK(msg->findInt64("timeUs", &timeUs));
 
             status_t err = INVALID_OPERATION;
 
+            // TODO: use correct source info based on srcId.
             size_t inbandTracks = 0;
             if (mCurrentSourceInfo.mSource != NULL) {
                 inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
@@ -2324,8 +2335,9 @@
     return OK;
 }
 
-status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
+status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
     sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
+    msg->setInt64("srcId", srcId);
     msg->setPointer("reply", reply);
 
     sp<AMessage> response;
@@ -2333,9 +2345,10 @@
     return err;
 }
 
-status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
+status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
     sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
     msg->setPointer("reply", reply);
+    msg->setInt64("srcId", srcId);
     msg->setInt32("type", type);
 
     sp<AMessage> response;
@@ -2346,8 +2359,9 @@
     return err;
 }
 
-status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
+status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
     sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
+    msg->setInt64("srcId", srcId);
     msg->setSize("trackIndex", trackIndex);
     msg->setInt32("select", select);
     msg->setInt64("timeUs", timeUs);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index e9b5f11..fdc128f 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -82,9 +82,9 @@
     void rewind();
 
     status_t setVideoScalingMode(int32_t mode);
-    status_t getTrackInfo(PlayerMessage* reply) const;
-    status_t getSelectedTrack(int32_t type, PlayerMessage* reply) const;
-    status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
+    status_t getTrackInfo(int64_t srcId, PlayerMessage* reply) const;
+    status_t getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const;
+    status_t selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs);
     status_t getCurrentPosition(int64_t *mediaUs);
     void getStats(Vector<sp<AMessage> > *mTrackStats);
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index 56d708a..2dab2dd 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -603,28 +603,33 @@
 
         case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
         {
-            return mPlayer->getTrackInfo(response);
+            int64_t srcId = (it++)->int64_value();
+            return mPlayer->getTrackInfo(srcId, response);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
         {
+            int64_t srcId = (it++)->int64_value();
             int trackIndex = (it++)->int32_value();
             int64_t msec = 0;
             // getCurrentPosition should always return OK
             getCurrentPosition(&msec);
-            return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000LL);
+            return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
         {
+            int64_t srcId = (it++)->int64_value();
             int trackIndex = (it++)->int32_value();
-            return mPlayer->selectTrack(trackIndex, false /* select */, 0xdeadbeef /* not used */);
+            return mPlayer->selectTrack(
+                    srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
         }
 
         case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
         {
+            int64_t srcId = (it++)->int64_value();
             int32_t type = (it++)->int32_value();
-            return mPlayer->getSelectedTrack(type, response);
+            return mPlayer->getSelectedTrack(srcId, type, response);
         }
 
         default:
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 9aea88a..dec5d3b 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -77,7 +77,7 @@
     },
 }
 
-cc_library_shared {
+cc_library {
     name: "libstagefright",
 
     srcs: [
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6ff3d78..a48466a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -3674,6 +3674,29 @@
         TRESPASS();
     }
     mOwner->beginBox(fourcc);    // TextMetaDataSampleEntry
+
+    //  HACK to make the metadata track compliant with the ISO standard.
+    //
+    //  Metadata track is added from API 26 and the original implementation does not
+    //  fully followed the TextMetaDataSampleEntry specified in ISO/IEC 14496-12-2015
+    //  in that only the mime_format is written out. content_encoding and
+    //  data_reference_index have not been written out. This leads to the failure
+    //  when some MP4 parser tries to parse the metadata track according to the
+    //  standard. The hack here will make the metadata track compliant with the
+    //  standard while still maintaining backwards compatibility. This would enable
+    //  Android versions before API 29 to be able to read out the standard compliant
+    //  Metadata track generated with Android API 29 and upward. The trick is based
+    //  on the fact that the Metadata track must start with prefix “application/” and
+    //  those missing fields are not used in Android's Metadata track. By writting
+    //  out the mime_format twice, the first mime_format will be used to fill out the
+    //  missing reserved, data_reference_index and content encoding fields. On the
+    //  parser side, the extracter before API 29  will read out the first mime_format
+    //  correctly and drop the second mime_format. The extractor from API 29 will
+    //  check if the reserved, data_reference_index and content encoding are filled
+    //  with “application” to detect if this is a standard compliant metadata track
+    //  and read out the data accordingly.
+    mOwner->writeCString(mime);
+
     mOwner->writeCString(mime);  // metadata mime_format
     mOwner->endBox(); // mett
 }
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index 5f2e601..1e49f6a 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -245,6 +245,9 @@
         if (format->mFormat->findInt32("crypto-skip-byte-block", &val32)) {
             meta.setInt32(kKeySkipByteBlock, val32);
         }
+        if (format->mFormat->findInt32("valid-samples", &val32)) {
+            meta.setInt32(kKeyValidSamples, val32);
+        }
         sp<ABuffer> valbuf;
         if (format->mFormat->findBuffer("crypto-plain-sizes", &valbuf)) {
             meta.setData(kKeyPlainSizes,
@@ -262,6 +265,10 @@
             meta.setData(kKeyCryptoIV,
                     MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
         }
+        if (format->mFormat->findBuffer("sei", &valbuf)) {
+            meta.setData(kKeySEI,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
     } else {
         *buffer = nullptr;
     }
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 3af4944..163cd05 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -614,13 +614,14 @@
         { "crypto-default-iv-size", kKeyCryptoDefaultIVSize },
         { "crypto-encrypted-byte-block", kKeyEncryptedByteBlock },
         { "crypto-skip-byte-block", kKeySkipByteBlock },
+        { "frame-count", kKeyFrameCount },
         { "max-bitrate", kKeyMaxBitRate },
         { "pcm-big-endian", kKeyPcmBigEndian },
         { "temporal-layer-count", kKeyTemporalLayerCount },
         { "temporal-layer-id", kKeyTemporalLayerId },
         { "thumbnail-width", kKeyThumbnailWidth },
         { "thumbnail-height", kKeyThumbnailHeight },
-        { "frame-count", kKeyFrameCount },
+        { "valid-samples", kKeyValidSamples },
     }
 };
 
@@ -634,6 +635,7 @@
         { "crypto-encrypted-sizes", kKeyEncryptedSizes },
         { "crypto-plain-sizes", kKeyPlainSizes },
         { "icc-profile", kKeyIccProfile },
+        { "sei", kKeySEI },
         { "text-format-data", kKeyTextFormatData },
     }
 };
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index 78d410a..c4a072b 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -29,7 +29,6 @@
 
     shared_libs: [
         "liblog",
-        "libbinder",
         "libcrypto",
         "libcutils",
         "libmedia",
@@ -38,10 +37,11 @@
         "libstagefright",
         "libstagefright_foundation",
         "libutils",
-        "libhidlallocatorutils",
         "libhidlbase",
+        "libhidlmemory",
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
+        "android.hidl.allocator@1.0",
     ],
 
     header_libs: [
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 590131e..e9baa1a 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,10 +23,10 @@
 #include "ESQueue.h"
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <binder/IMemory.h>
-#include <binder/MemoryDealer.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 #include <cutils/native_handle.h>
-#include <hidlmemory/FrameworkUtils.h>
+#include <hidlmemory/mapping.h>
 #include <media/cas/DescramblerAPI.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -46,12 +46,13 @@
 #include <inttypes.h>
 
 namespace android {
-using hardware::fromHeap;
 using hardware::hidl_string;
 using hardware::hidl_vec;
-using hardware::HidlMemory;
+using hardware::hidl_memory;
 using namespace hardware::cas::V1_0;
 using namespace hardware::cas::native::V1_0;
+typedef hidl::allocator::V1_0::IAllocator TAllocator;
+typedef hidl::memory::V1_0::IMemory TMemory;
 
 // I want the expression "y" evaluated even if verbose logging is off.
 #define MY_LOGV(x, y) \
@@ -208,9 +209,8 @@
     bool mScrambled;
     bool mSampleEncrypted;
     sp<AMessage> mSampleAesKeyItem;
-    sp<IMemory> mMem;
-    sp<MemoryDealer> mDealer;
-    sp<HidlMemory> mHidlMemory;
+    sp<TMemory> mHidlMemory;
+    sp<TAllocator> mHidlAllocator;
     hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
     sp<ABuffer> mDescrambledBuffer;
     List<SubSampleInfo> mSubSamples;
@@ -975,16 +975,43 @@
             mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
 
     sp<ABuffer> newBuffer, newScrambledBuffer;
-    sp<IMemory> newMem;
-    sp<MemoryDealer> newDealer;
+    sp<TMemory> newMem;
     if (mScrambled) {
-        size_t alignment = MemoryDealer::getAllocationAlignment();
-        neededSize = (neededSize + (alignment - 1)) & ~(alignment - 1);
-        // Align to multiples of 64K.
-        neededSize = (neededSize + 65535) & ~65535;
-        newDealer = new MemoryDealer(neededSize, "ATSParser");
-        newMem = newDealer->allocate(neededSize);
-        newScrambledBuffer = new ABuffer(newMem->pointer(), newMem->size());
+        if (mHidlAllocator == nullptr) {
+            mHidlAllocator = TAllocator::getService("ashmem");
+            if (mHidlAllocator == nullptr) {
+                ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
+                return false;
+            }
+        }
+
+        hidl_memory hidlMemToken;
+        bool success;
+        auto transStatus = mHidlAllocator->allocate(
+                neededSize,
+                [&success, &hidlMemToken](
+                        bool s,
+                        hidl_memory const& m) {
+                    success = s;
+                    hidlMemToken = m;
+                });
+
+        if (!transStatus.isOk()) {
+            ALOGE("[stream %d] hidl allocator failed at the transport: %s",
+                    mElementaryPID, transStatus.description().c_str());
+            return false;
+        }
+        if (!success) {
+            ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
+            return false;
+        }
+        newMem = mapMemory(hidlMemToken);
+        if (newMem == nullptr || newMem->getPointer() == nullptr) {
+            ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
+            return false;
+        }
+
+        newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
 
         if (mDescrambledBuffer != NULL) {
             memcpy(newScrambledBuffer->data(),
@@ -993,24 +1020,15 @@
         } else {
             newScrambledBuffer->setRange(0, 0);
         }
-        mMem = newMem;
-        mDealer = newDealer;
+        mHidlMemory = newMem;
         mDescrambledBuffer = newScrambledBuffer;
 
-        ssize_t offset;
-        size_t size;
-        sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
-        if (heap == NULL) {
-            return false;
-        }
+        mDescramblerSrcBuffer.heapBase = hidlMemToken;
+        mDescramblerSrcBuffer.offset = 0ULL;
+        mDescramblerSrcBuffer.size =  (uint64_t)neededSize;
 
-        mHidlMemory = fromHeap(heap);
-        mDescramblerSrcBuffer.heapBase = *mHidlMemory;
-        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);
+        ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
+                mElementaryPID, neededSize);
     } else {
         // Align to multiples of 64K.
         neededSize = (neededSize + 65535) & ~65535;
@@ -1498,7 +1516,7 @@
         return UNKNOWN_ERROR;
     }
 
-    if (mDescrambledBuffer == NULL || mMem == NULL) {
+    if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
         ALOGE("received scrambled packets without shared memory!");
 
         return UNKNOWN_ERROR;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index e516cf1..a507b91 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -30,9 +30,10 @@
     shared_libs: [
         "libcrypto",
         "libmedia",
-        "libhidlallocatorutils",
+        "libhidlmemory",
         "android.hardware.cas.native@1.0",
         "android.hidl.memory@1.0",
+        "android.hidl.allocator@1.0",
     ],
 
     header_libs: [
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 8f3a9f3..92d3aef 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -377,6 +377,7 @@
 EXPORT const char* AMEDIAFORMAT_KEY_TITLE = "title";
 EXPORT const char* AMEDIAFORMAT_KEY_TRACK_ID = "track-id";
 EXPORT const char* AMEDIAFORMAT_KEY_TRACK_INDEX = "track-index";
+EXPORT const char* AMEDIAFORMAT_KEY_VALID_SAMPLES = "valid-samples";
 EXPORT const char* AMEDIAFORMAT_KEY_WIDTH = "width";
 EXPORT const char* AMEDIAFORMAT_KEY_YEAR = "year";
 
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 6e7e0f9..2551228 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -226,6 +226,7 @@
 extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_TIME __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_TITLE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_VALID_SAMPLES __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_YEAR __INTRODUCED_IN(29);
 
 #endif /* __ANDROID_API__ >= 29 */
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index d24cc9b..c50084e 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -140,6 +140,7 @@
     AMEDIAFORMAT_KEY_TIME_US; # var introduced=28
     AMEDIAFORMAT_KEY_TRACK_INDEX; # var introduced=28
     AMEDIAFORMAT_KEY_TRACK_ID; # var introduced=28
+    AMEDIAFORMAT_KEY_VALID_SAMPLES; # var introduced=29
     AMEDIAFORMAT_KEY_WIDTH; # var introduced=21
     AMEDIAFORMAT_KEY_YEAR; # var introduced=29
     AMediaCodecActionCode_isRecoverable; # introduced=28
diff --git a/packages/MediaComponents/apex/Android.bp b/packages/MediaComponents/apex/Android.bp
index e797e14..d89eb77 100644
--- a/packages/MediaComponents/apex/Android.bp
+++ b/packages/MediaComponents/apex/Android.bp
@@ -9,6 +9,8 @@
         // "Refusing to generate code with unstructured parcelables."
         "java/android/media/MediaDescription.aidl",
         "java/android/media/MediaMetadata.aidl",
+        // TODO(insun): check why MediaParceledListSlice.aidl should be added here
+        "java/android/media/MediaParceledListSlice.aidl",
         "java/android/media/Rating.aidl",
         "java/android/media/browse/MediaBrowser.aidl",
         "java/android/media/session/MediaSession.aidl",
diff --git a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java b/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
index 33e6916..adfd20b 100644
--- a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
+++ b/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
@@ -422,9 +422,7 @@
     }
 
     private MediaMetadata(Parcel in) {
-        //TODO(b/119789387): Resolve hidden API usage: Bundle#setDefusable
-        //mBundle = Bundle.setDefusable(in.readBundle(), true);
-        mBundle = new Bundle();  //TODO:remove this.
+        mBundle = in.readBundle();
     }
 
     /**
diff --git a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl
new file mode 100644
index 0000000..228ea9c
--- /dev/null
+++ b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl
@@ -0,0 +1,19 @@
+/* Copyright (C) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/** @hide */
+parcelable MediaParceledListSlice;
\ No newline at end of file
diff --git a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java
new file mode 100644
index 0000000..ec3fdb7
--- /dev/null
+++ b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.UnsupportedAppUsage;
+import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Transfer a large list of objects across an IPC. Splits into multiple transactions if needed.
+ * Note: Only use classes declared final in order to avoid subclasses overriding reading/writing
+ * parcel logic.
+ *
+ * TODO: Add test for sending large data
+ * @hide
+ */
+public class MediaParceledListSlice<T extends Parcelable> implements Parcelable {
+    private static final String TAG = "MediaParceledListSlice";
+    private static final boolean DEBUG = false;
+
+    private static final int MAX_IPC_SIZE = 64 * 1024; // IBinder.MAX_IPC_SIZE
+
+    final List<T> mList;
+
+    public MediaParceledListSlice(List<T> list) {
+        if (list == null) {
+            throw new IllegalArgumentException("list shouldn't be null");
+        }
+        mList = list;
+    }
+
+    MediaParceledListSlice(Parcel p) {
+        final int itemCount = p.readInt();
+        mList = new ArrayList<>(itemCount);
+        if (DEBUG) {
+            Log.d(TAG, "Retrieving " + itemCount + " items");
+        }
+        if (itemCount <= 0) {
+            return;
+        }
+
+        int i = 0;
+        while (i < itemCount) {
+            if (p.readInt() == 0) {
+                break;
+            }
+
+            final T parcelable = p.readParcelable(null);
+            mList.add(parcelable);
+
+            if (DEBUG) {
+                Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size() - 1));
+            }
+            i++;
+        }
+        if (i >= itemCount) {
+            return;
+        }
+        final IBinder retriever = p.readStrongBinder();
+        while (i < itemCount) {
+            if (DEBUG) {
+                Log.d(TAG, "Reading more @" + i + " of " + itemCount + ": retriever=" + retriever);
+            }
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInt(i);
+            try {
+                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + itemCount, e);
+                return;
+            }
+            while (i < itemCount && reply.readInt() != 0) {
+                final T parcelable = reply.readParcelable(null);
+                mList.add(parcelable);
+
+                if (DEBUG) {
+                    Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size() - 1));
+                }
+                i++;
+            }
+            reply.recycle();
+            data.recycle();
+        }
+    }
+
+    public List<T> getList() {
+        return mList;
+    }
+
+    /**
+     * Write this to another Parcel. Note that this discards the internal Parcel
+     * and should not be used anymore. This is so we can pass this to a Binder
+     * where we won't have a chance to call recycle on this.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        final int itemCount = mList.size();
+        dest.writeInt(itemCount);
+        if (DEBUG) {
+            Log.d(TAG, "Writing " + itemCount + " items");
+        }
+        if (itemCount > 0) {
+            int i = 0;
+            while (i < itemCount && dest.dataSize() < MAX_IPC_SIZE) {
+                dest.writeInt(1);
+
+                final T parcelable = mList.get(i);
+                dest.writeParcelable(parcelable, flags);
+
+                if (DEBUG) {
+                    Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
+                }
+                i++;
+            }
+            if (i < itemCount) {
+                dest.writeInt(0);
+                Binder retriever = new Binder() {
+                    @Override
+                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                            throws RemoteException {
+                        if (code != FIRST_CALL_TRANSACTION) {
+                            return super.onTransact(code, data, reply, flags);
+                        }
+                        int i = data.readInt();
+                        if (DEBUG) {
+                            Log.d(TAG, "Writing more @" + i + " of " + itemCount);
+                        }
+                        while (i < itemCount && reply.dataSize() < MAX_IPC_SIZE) {
+                            reply.writeInt(1);
+
+                            final T parcelable = mList.get(i);
+                            reply.writeParcelable(parcelable, flags);
+
+                            if (DEBUG) {
+                                Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
+                            }
+                            i++;
+                        }
+                        if (i < itemCount) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Breaking @" + i + " of " + itemCount);
+                            }
+                            reply.writeInt(0);
+                        }
+                        return true;
+                    }
+                };
+                if (DEBUG) {
+                    Log.d(TAG, "Breaking @" + i + " of " + itemCount + ": retriever=" + retriever);
+                }
+                dest.writeStrongBinder(retriever);
+            }
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        int contents = 0;
+        final List<T> list = getList();
+        for (int i = 0; i < list.size(); i++) {
+            contents |= list.get(i).describeContents();
+        }
+        return contents;
+    }
+
+    public static final Parcelable.Creator<MediaParceledListSlice> CREATOR =
+            new Parcelable.Creator<MediaParceledListSlice>() {
+        @Override
+        public MediaParceledListSlice createFromParcel(Parcel in) {
+            return new MediaParceledListSlice(in);
+        }
+
+        @Override
+        public MediaParceledListSlice[] newArray(int size) {
+            return new MediaParceledListSlice[size];
+        }
+    };
+}
diff --git a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java b/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java
index 4e091ad..b1b14c6 100644
--- a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java
+++ b/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java
@@ -23,8 +23,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-//import android.content.pm.ParceledListSlice;
 import android.media.MediaDescription;
+import android.media.MediaParceledListSlice;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.os.Binder;
@@ -652,10 +652,8 @@
         });
     }
 
-    //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-    /*
     private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
-            final String parentId, final ParceledListSlice list, final Bundle options) {
+            final String parentId, final MediaParceledListSlice list, final Bundle options) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -699,7 +697,6 @@
             }
         });
     }
-    */
 
     /**
      * Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
@@ -1109,22 +1106,19 @@
             }
         }
 
-        //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-        /*
         @Override
-        public void onLoadChildren(String parentId, ParceledListSlice list) {
+        public void onLoadChildren(String parentId, MediaParceledListSlice list) {
             onLoadChildrenWithOptions(parentId, list, null);
         }
 
         @Override
-        public void onLoadChildrenWithOptions(String parentId, ParceledListSlice list,
+        public void onLoadChildrenWithOptions(String parentId, MediaParceledListSlice list,
                 final Bundle options) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
                 mediaBrowser.onLoadChildren(this, parentId, list, options);
             }
         }
-        */
     }
 
     private static class Subscription {
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl b/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
index cbd93cb..14b1c64 100644
--- a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
+++ b/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
@@ -16,9 +16,9 @@
 package android.media.session;
 
 import android.app.PendingIntent;
-import android.content.pm.ParceledListSlice;
 //import android.media.AudioAttributes;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.session.ISessionController;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
@@ -39,10 +39,9 @@
     void destroy();
 
     // These commands are for the TransportPerformer
-    void setMetadata(in MediaMetadata metadata);
+    void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription);
     void setPlaybackState(in PlaybackState state);
-    //TODO(b/119750807): Resolve hidden API usage ParceledListSlice.
-    //void setQueue(in ParceledListSlice queue);
+    void setQueue(in MediaParceledListSlice queue);
     void setQueueTitle(CharSequence title);
     void setExtras(in Bundle extras);
     void setRatingType(int type);
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl
index 031a388..74897f7 100644
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl
+++ b/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl
@@ -17,8 +17,8 @@
 
 import android.app.PendingIntent;
 import android.content.Intent;
-//import android.content.pm.ParceledListSlice;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.session.ISessionControllerCallback;
 import android.media.session.MediaSession;
@@ -81,8 +81,7 @@
             String action, in Bundle args);
     MediaMetadata getMetadata();
     PlaybackState getPlaybackState();
-    //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-    //ParceledListSlice getQueue();
+    MediaParceledListSlice getQueue();
     CharSequence getQueueTitle();
     Bundle getExtras();
     int getRatingType();
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl
index 173504b..f5cc4f6 100644
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl
+++ b/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl
@@ -15,8 +15,8 @@
 
 package android.media.session;
 
-//import android.content.pm.ParceledListSlice;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.session.ParcelableVolumeInfo;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
@@ -32,8 +32,7 @@
     // These callbacks are for the TransportController
     void onPlaybackStateChanged(in PlaybackState state);
     void onMetadataChanged(in MediaMetadata metadata);
-    //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-    //void onQueueChanged(in ParceledListSlice queue);
+    void onQueueChanged(in MediaParceledListSlice queue);
     void onQueueTitleChanged(CharSequence title);
     void onExtrasChanged(in Bundle extras);
     void onVolumeInfoChanged(in ParcelableVolumeInfo info);
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
index 60f74ab..8c3a013 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
@@ -21,10 +21,10 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.PendingIntent;
 import android.content.Context;
-//import android.content.pm.ParceledListSlice;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.net.Uri;
@@ -243,17 +243,14 @@
      * @return The current play queue or null.
      */
     public @Nullable List<MediaSession.QueueItem> getQueue() {
-        //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-        /*
         try {
-            ParceledListSlice queue = mSessionBinder.getQueue();
+            MediaParceledListSlice queue = mSessionBinder.getQueue();
             if (queue != null) {
                 return queue.getList();
             }
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getQueue.", e);
         }
-        */
         return null;
     }
 
@@ -1102,10 +1099,8 @@
             }
         }
 
-        //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-        /*
         @Override
-        public void onQueueChanged(ParceledListSlice parceledQueue) {
+        public void onQueueChanged(MediaParceledListSlice parceledQueue) {
             List<MediaSession.QueueItem> queue = parceledQueue == null ? null : parceledQueue
                     .getList();
             MediaController controller = mController.get();
@@ -1113,7 +1108,6 @@
                 controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
             }
         }
-        */
 
         @Override
         public void onQueueTitleChanged(CharSequence title) {
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
index 1ae1d2c..943843d 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
@@ -24,12 +24,13 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-//import android.content.pm.ParceledListSlice;
 import android.media.AudioAttributes;
 import android.media.MediaDescription;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -40,7 +41,6 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
-import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
 import android.util.Log;
@@ -439,11 +439,21 @@
      * @see android.media.MediaMetadata.Builder#putBitmap
      */
     public void setMetadata(@Nullable MediaMetadata metadata) {
+        long duration = -1;
+        int fields = 0;
+        MediaDescription description = null;
         if (metadata != null) {
             metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
+            if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+                duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+            }
+            fields = metadata.size();
+            description = metadata.getDescription();
         }
+        String metadataDescription = "size=" + fields + ", description=" + description;
+
         try {
-            mBinder.setMetadata(metadata);
+            mBinder.setMetadata(metadata, duration, metadataDescription);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Dead object in setPlaybackState.", e);
         }
@@ -461,14 +471,11 @@
      * @param queue A list of items in the play queue.
      */
     public void setQueue(@Nullable List<QueueItem> queue) {
-        //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-        /*
         try {
-            mBinder.setQueue(queue == null ? null : new ParceledListSlice<QueueItem>(queue));
+            mBinder.setQueue(queue == null ? null : new MediaParceledListSlice<QueueItem>(queue));
         } catch (RemoteException e) {
             Log.wtf("Dead object in setQueue.", e);
         }
-        */
     }
 
     /**
diff --git a/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index bcc2826..8dc480d 100644
--- a/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -2,8 +2,8 @@
 
 package android.service.media;
 
-//import android.content.pm.ParceledListSlice;
 import android.graphics.Bitmap;
+import android.media.MediaParceledListSlice;
 import android.media.session.MediaSession;
 import android.os.Bundle;
 
@@ -22,7 +22,7 @@
      */
     void onConnect(String root, in MediaSession.Token session, in Bundle extras);
     void onConnectFailed();
-    //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-    //void onLoadChildren(String mediaId, in ParceledListSlice list);
-    //void onLoadChildrenWithOptions(String mediaId, in ParceledListSlice list, in Bundle options);
+    void onLoadChildren(String mediaId, in MediaParceledListSlice list);
+    void onLoadChildrenWithOptions(String mediaId, in MediaParceledListSlice list,
+            in Bundle options);
 }
diff --git a/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java b/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java
index fa7696e..a66ec35 100644
--- a/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java
+++ b/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java
@@ -25,7 +25,7 @@
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-//import android.content.pm.ParceledListSlice;
+import android.media.MediaParceledListSlice;
 import android.media.browse.MediaBrowser;
 import android.media.browse.MediaBrowserUtils;
 import android.media.session.MediaSession;
@@ -687,10 +687,8 @@
                 List<MediaBrowser.MediaItem> filteredList =
                         (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
                         ? applyOptions(list, options) : list;
-                //TODO:(b/119750807) Resolve hidden API usage ParceledListSlice.
-                /*
-                final ParceledListSlice<MediaBrowser.MediaItem> pls =
-                        filteredList == null ? null : new ParceledListSlice<>(filteredList);
+                final MediaParceledListSlice<MediaBrowser.MediaItem> pls =
+                        filteredList == null ? null : new MediaParceledListSlice<>(filteredList);
                 try {
                     connection.callbacks.onLoadChildrenWithOptions(parentId, pls, options);
                 } catch (RemoteException ex) {
@@ -698,7 +696,6 @@
                     Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
                             + " package=" + connection.pkg);
                 }
-                */
             }
         };
 
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 02ab8ad..bfa1b5e 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -25,7 +25,11 @@
     libmedia_helper \
     libmediametrics \
     libmediautils \
-    libeffectsconfig
+    libeffectsconfig \
+    libsensorprivacy
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+    libsensorprivacy
 
 LOCAL_STATIC_LIBRARIES := \
     libaudiopolicycomponents
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index ebb9352..bb9cad8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -116,6 +116,7 @@
     audio_module_handle_t getModuleHandle() const;
     uint32_t getModuleVersionMajor() const;
     const char *getModuleName() const;
+    sp<HwModule> getModule() const { return mModule; }
 
     bool useInputChannelMask() const
     {
@@ -137,12 +138,12 @@
     void log(const char* indent) const;
 
     AudioGainCollection mGains; // gain controllers
-    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
 
 private:
     void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
     void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
 
+    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
     String8  mName;
     audio_port_type_t mType;
     audio_port_role_t mRole;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index 330f1d4..0357ff4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -46,6 +46,19 @@
 
     audio_route_type_t getType() const { return mType; }
 
+    /**
+     * @brief supportsPatch checks if an audio patch is supported by a Route declared in
+     * the audio_policy_configuration.xml file.
+     * If the patch is supported natively by an AudioHAL (which supports of course Routing API 3.0),
+     * audiopolicy will not request AudioFlinger to use a software bridge to realize a patch
+     * between 2 ports.
+     * @param srcPort (aka the source) to be considered
+     * @param dstPort (aka the sink) to be considered
+     * @return true if the audio route supports the connection between the sink and the source,
+     * false otherwise
+     */
+    bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
     void dump(String8 *dst, int spaces) const;
 
 private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 6f99bf3..d02123c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -39,6 +39,8 @@
     virtual const String8 getTagName() const { return mTagName; }
 
     audio_devices_t type() const { return mDeviceType; }
+    String8 address() const { return mAddress; }
+    void setAddress(const String8 &address) { mAddress = address; }
 
     const FormatVector& encodedFormats() const { return mEncodedFormats; }
 
@@ -57,39 +59,113 @@
     audio_port_handle_t getId() const;
     void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
     void log() const;
-
-    String8 mAddress;
+    std::string toString() const;
 
 private:
+    String8 mAddress{""};
     String8 mTagName; // Unique human readable identifier for a device port found in conf file.
     audio_devices_t     mDeviceType;
     FormatVector        mEncodedFormats;
-    audio_port_handle_t mId;
-
-friend class DeviceVector;
+    audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
 };
 
 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
 {
 public:
     DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
+    explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
+    {
+        add(item);
+    }
 
     ssize_t add(const sp<DeviceDescriptor>& item);
     void add(const DeviceVector &devices);
     ssize_t remove(const sp<DeviceDescriptor>& item);
+    void remove(const DeviceVector &devices);
     ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
 
     audio_devices_t types() const { return mDeviceTypes; }
 
     // If 'address' is empty, a device with a non-empty address may be returned
     // if there is no device with the specified 'type' and empty address.
-    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address) const;
+    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address = {}) const;
     DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
+
+    /**
+     * @brief getDeviceFromId
+     * @param id of the DeviceDescriptor to seach (aka Port handle).
+     * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
+     * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
+     */
     sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
     sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
     DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
     audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
 
+    bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
+
+    /**
+     * @brief containsAtLeastOne
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains at list one of the devices from the given vector.
+     */
+    bool containsAtLeastOne(const DeviceVector &devices) const;
+
+    /**
+     * @brief containsAllDevices
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains all the devices from the given vector
+     */
+    bool containsAllDevices(const DeviceVector &devices) const;
+
+    /**
+     * @brief filter the devices supported by this collection against another collection
+     * @param devices to filter against
+     * @return
+     */
+    DeviceVector filter(const DeviceVector &devices) const;
+
+    /**
+     * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
+     * of the destination vector, only of the source, it provides a safe implementation
+     * @param devices source device vector to merge with
+     * @return size of the merged vector.
+     */
+    ssize_t merge(const DeviceVector &devices)
+    {
+        if (isEmpty()) {
+            add(devices);
+            return size();
+        }
+        return SortedVector::merge(devices);
+    }
+
+    /**
+     * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
+     * DeviceDescriptor with same type and address) and the vector has same size.
+     * @param right DeviceVector to compare to.
+     * @return true if right contains the same device and has the same size.
+     */
+    bool operator==(const DeviceVector &right) const
+    {
+        if (size() != right.size()) {
+            return false;
+        }
+        for (const auto &device : *this) {
+            if (right.indexOf(device) < 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const DeviceVector &right) const
+    {
+        return !operator==(right);
+    }
+
+    std::string toString() const;
+
     void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
 
 private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 6560431..2b57fa9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -81,6 +81,17 @@
         return mPorts.findByTagName(tagName);
     }
 
+    /**
+     * @brief supportsPatch checks if an audio patch between 2 ports beloging to this HwModule
+     * is supported by a HwModule. The ports and the route shall be declared in the
+     * audio_policy_configuration.xml file.
+     * @param srcPort (aka the source) to be considered
+     * @param dstPort (aka the sink) to be considered
+     * @return true if the HwModule supports the connection between the sink and the source,
+     * false otherwise
+     */
+    bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
     // TODO remove from here (split serialization)
     void dump(String8 *dst) const;
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 8ff8238..ca6ca56 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -88,7 +88,7 @@
 
     bool supportDeviceAddress(const String8 &address) const
     {
-        return mSupportedDevices[0]->mAddress == address;
+        return mSupportedDevices[0]->address() == address;
     }
 
     // chose first device present in mSupportedDevices also part of deviceType
diff --git a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
index 63c19d1..6b0476c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
+++ b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
@@ -23,26 +23,10 @@
 
 namespace android {
 
-struct DeviceCategoryTraits
-{
-    typedef device_category Type;
-    typedef Vector<Type> Collection;
-};
-struct MixTypeTraits
-{
-    typedef int32_t Type;
-    typedef Vector<Type> Collection;
-};
-struct RouteFlagTraits
-{
-    typedef uint32_t Type;
-    typedef Vector<Type> Collection;
-};
-struct RuleTraits
-{
-    typedef uint32_t Type;
-    typedef Vector<Type> Collection;
-};
+struct RuleTraits : public DefaultTraits<uint32_t> {};
+using DeviceCategoryTraits = DefaultTraits<device_category>;
+struct MixTypeTraits : public DefaultTraits<int32_t> {};
+struct RouteFlagTraits : public DefaultTraits<uint32_t> {};
 
 typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter;
 typedef TypeConverter<MixTypeTraits> MixTypeConverter;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 4ce6b08..97504ab 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -698,8 +698,8 @@
     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
 
     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
-        && (primaryOutput->mProfile->mModule != NULL)) {
-        sp<HwModule> primaryHwModule = primaryOutput->mProfile->mModule;
+        && (primaryOutput->mProfile->getModule() != NULL)) {
+        sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
         Vector <sp<IOProfile>> primaryHwModuleOutputProfiles =
                                    primaryHwModule->getOutputProfiles();
         for (size_t i = 0; i < primaryHwModuleOutputProfiles.size(); i++) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index c1fe5b0..79f0919 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -37,4 +37,19 @@
     dst->append("\n");
 }
 
+bool AudioRoute::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const
+{
+    if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
+        return false;
+    }
+    ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().string());
+    for (const auto &sourcePort : mSources) {
+        if (sourcePort == srcPort) {
+            ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().string());
+            return true;
+        }
+    }
+    return false;
+}
+
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 9e5f944..04cbcd1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -35,7 +35,7 @@
     AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
                                              AUDIO_PORT_ROLE_SOURCE),
-    mAddress(""), mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats), mId(0)
+    mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
 {
     if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
         mAddress = String8("0");
@@ -132,6 +132,13 @@
     return ret;
 }
 
+void DeviceVector::remove(const DeviceVector &devices)
+{
+    for (const auto& device : devices) {
+        remove(device);
+    }
+}
+
 DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
 {
     DeviceVector devices;
@@ -159,9 +166,9 @@
     sp<DeviceDescriptor> device;
     for (size_t i = 0; i < size(); i++) {
         if (itemAt(i)->type() == type) {
-            if (address == "" || itemAt(i)->mAddress == address) {
+            if (address == "" || itemAt(i)->address() == address) {
                 device = itemAt(i);
-                if (itemAt(i)->mAddress == address) {
+                if (itemAt(i)->address() == address) {
                     break;
                 }
             }
@@ -174,9 +181,11 @@
 
 sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
 {
-    for (const auto& device : *this) {
-        if (device->getId() == id) {
-            return device;
+    if (id != AUDIO_PORT_HANDLE_NONE) {
+        for (const auto& device : *this) {
+            if (device->getId() == id) {
+                return device;
+            }
         }
     }
     return nullptr;
@@ -188,8 +197,8 @@
     bool isOutput = audio_is_output_devices(type);
     type &= ~AUDIO_DEVICE_BIT_IN;
     for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
-        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
-        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
+        bool curIsOutput = audio_is_output_devices(itemAt(i)->type());
+        audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN;
         if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
             devices.add(itemAt(i));
             type &= ~curType;
@@ -251,8 +260,7 @@
     // without the test?
     // This has been demonstrated to NOT be true (at start up)
     // ALOG_ASSERT(mModule != NULL);
-    dstConfig->ext.device.hw_module =
-            mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
+    dstConfig->ext.device.hw_module = getModuleHandle();
     (void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
 }
 
@@ -263,7 +271,7 @@
     port->id = mId;
     toAudioPortConfig(&port->active_config);
     port->ext.device.type = mDeviceType;
-    port->ext.device.hw_module = mModule->getHandle();
+    port->ext.device.hw_module = getModuleHandle();
     (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
 }
 
@@ -294,6 +302,49 @@
     AudioPort::dump(dst, spaces, verbose);
 }
 
+std::string DeviceDescriptor::toString() const
+{
+    std::stringstream sstream;
+    sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
+    return sstream.str();
+}
+
+std::string DeviceVector::toString() const
+{
+    if (isEmpty()) {
+        return {"AUDIO_DEVICE_NONE"};
+    }
+    std::string result = {"{"};
+    for (const auto &device : *this) {
+        if (device != *begin()) {
+           result += ";";
+        }
+        result += device->toString();
+    }
+    return result + "}";
+}
+
+DeviceVector DeviceVector::filter(const DeviceVector &devices) const
+{
+    DeviceVector filteredDevices;
+    for (const auto &device : *this) {
+        if (devices.contains(device)) {
+            filteredDevices.add(device);
+        }
+    }
+    return filteredDevices;
+}
+
+bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
+{
+    return !filter(devices).isEmpty();
+}
+
+bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
+{
+    return filter(devices).size() == devices.size();
+}
+
 void DeviceDescriptor::log() const
 {
     std::string device;
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 92bc595..80af88d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -51,7 +51,7 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
-    devDesc->mAddress = address;
+    devDesc->setAddress(address);
     profile->addSupportedDevice(devDesc);
 
     return addOutputProfile(profile);
@@ -113,7 +113,7 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
-    devDesc->mAddress = address;
+    devDesc->setAddress(address);
     profile->addSupportedDevice(devDesc);
 
     ALOGV("addInputProfile() name %s rate %d mask 0x%08x",
@@ -218,6 +218,15 @@
     mHandle = handle;
 }
 
+bool HwModule::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const {
+    for (const auto &route : mRoutes) {
+        if (route->supportsPatch(srcPort, dstPort)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 void HwModule::dump(String8 *dst) const
 {
     dst->appendFormat("  - name: %s\n", getName());
@@ -287,7 +296,7 @@
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
     devDesc->setName(String8(device_name));
-    devDesc->mAddress = address;
+    devDesc->setAddress(address);
     return devDesc;
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 179a678..1154654 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -516,7 +516,7 @@
     std::string address = getXmlAttribute(cur, Attributes::address);
     if (!address.empty()) {
         ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
-        deviceDesc->mAddress = String8(address.c_str());
+        deviceDesc->setAddress(String8(address.c_str()));
     }
 
     AudioProfileTraits::Collection profiles;
@@ -535,7 +535,7 @@
         return Status::fromStatusT(status);
     }
     ALOGV("%s: adding device tag %s type %08x address %s", __func__,
-          deviceDesc->getName().string(), type, deviceDesc->mAddress.string());
+          deviceDesc->getName().string(), type, deviceDesc->address().string());
     return deviceDesc;
 }
 
@@ -742,7 +742,7 @@
             }
             ALOGV("%s: %s=%s",
                     __func__, tag, reinterpret_cast<const char*>(pointDefinition.get()));
-            Vector<int32_t> point;
+            std::vector<int32_t> point;
             collectionFromString<DefaultTraits<int32_t>>(
                     reinterpret_cast<const char*>(pointDefinition.get()), point, ",");
             if (point.size() != 2) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 02f6f5a..64a2b8a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -149,13 +149,13 @@
 
             // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the outputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state, devDesc->address());
 
-            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
+            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->address()) != NO_ERROR) {
                 mAvailableOutputDevices.remove(devDesc);
 
                 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->mAddress);
+                                               devDesc->address());
                 return INVALID_OPERATION;
             }
             // Propagate device availability to Engine
@@ -178,12 +178,12 @@
             ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
 
             // Send Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state, devDesc->address());
 
             // remove device from available output devices
             mAvailableOutputDevices.remove(devDesc);
 
-            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
+            checkOutputsForDevice(devDesc, state, outputs, devDesc->address());
 
             // Propagate device availability to Engine
             mEngine->setDeviceConnectionState(devDesc, state);
@@ -265,11 +265,11 @@
 
             // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the inputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state, devDesc->address());
 
-            if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
+            if (checkInputsForDevice(devDesc, state, inputs, devDesc->address()) != NO_ERROR) {
                 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->mAddress);
+                                               devDesc->address());
                 return INVALID_OPERATION;
             }
 
@@ -294,9 +294,9 @@
             ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
 
             // Set Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+            broadcastDeviceConnectionState(device, state, devDesc->address());
 
-            checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
+            checkInputsForDevice(devDesc, state, inputs, devDesc->address());
             mAvailableInputDevices.remove(devDesc);
 
             // Propagate device availability to Engine
@@ -910,8 +910,7 @@
     }
 
     outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
-    *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
-            : AUDIO_PORT_HANDLE_NONE;
+    *selectedDeviceId = getFirstDeviceId(outputDevices);
 
     ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
 
@@ -1053,8 +1052,7 @@
                 new SwAudioOutputDescriptor(profile, mpClientInterface);
 
         DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
-        String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
-                : String8("");
+        String8 address = getFirstDeviceAddress(outputDevices);
 
         // MSD patch may be using the only output stream that can service this request. Release
         // MSD patch to prioritize this request over any active output on MSD.
@@ -1755,10 +1753,7 @@
     }
 
     // Explicit routing?
-    sp<DeviceDescriptor> deviceDesc;
-    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
-        deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
-    }
+    sp<DeviceDescriptor> deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
 
     // special case for mmap capture: if an input IO handle is specified, we reuse this input if
     // possible
@@ -1864,8 +1859,7 @@
 exit:
 
     inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(device);
-    *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
-                                                : AUDIO_PORT_HANDLE_NONE;
+    *selectedDeviceId = getFirstDeviceId(inputDevices);
 
     isSoundTrigger = inputSource == AUDIO_SOURCE_HOTWORD &&
         mSoundTriggerSessions.indexOfKey(session) > 0;
@@ -1996,7 +1990,7 @@
     if (address == "") {
         DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(device);
         // the inputs vector must be of size >= 1, but we don't want to crash here
-        address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
+        address = getFirstDeviceAddress(inputDevices);
     }
 
     status_t status = inputDesc->open(&lConfig, device, address,
@@ -2963,7 +2957,7 @@
             }
 
             if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
-                                                           devDesc->mAddress,
+                                                           devDesc->address(),
                                                            patch->sources[0].sample_rate,
                                                            NULL,  // updatedSamplingRate
                                                            patch->sources[0].format,
@@ -3020,7 +3014,7 @@
             }
 
             if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
-                                                          devDesc->mAddress,
+                                                          devDesc->address(),
                                                           patch->sinks[0].sample_rate,
                                                           NULL, /*updatedSampleRate*/
                                                           patch->sinks[0].format,
@@ -3083,8 +3077,10 @@
                 // create a software bridge in PatchPanel if:
                 // - source and sink devices are on different HW modules OR
                 // - audio HAL version is < 3.0
+                // - audio HAL version is >= 3.0 but no route has been declared between devices
                 if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
-                        (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
+                        (srcDeviceDesc->getModuleVersionMajor() < 3) ||
+                        !srcDeviceDesc->getModule()->supportsPatch(srcDeviceDesc, sinkDeviceDesc)) {
                     // support only one sink device for now to simplify output selection logic
                     if (patch->num_sinks > 1) {
                         return INVALID_OPERATION;
@@ -3428,14 +3424,14 @@
 
     audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
 
-    if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
-            sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
-            srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
+    if (srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) &&
+            srcDeviceDesc->getModuleVersionMajor() >= 3 &&
+            sinkDeviceDesc->getModule()->supportsPatch(srcDeviceDesc, sinkDeviceDesc) &&
             srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
-        ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
+        ALOGV("%s Device to Device route supported by >=3.0 HAL", __FUNCTION__);
         // TODO: may explicitly specify whether we should use HW or SW patch
-        // create patch between src device and output device
-        // create Hwoutput and add to mHwOutputs
+        //   create patch between src device and output device
+        //   create Hwoutput and add to mHwOutputs
     } else {
         audio_attributes_t resultAttr;
         audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
@@ -3664,7 +3660,7 @@
             AUDIO_DEVICE_OUT_HDMI);
     for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
         // Simulate reconnection to update enabled surround sound formats.
-        String8 address = hdmiOutputDevices[i]->mAddress;
+        String8 address = hdmiOutputDevices[i]->address();
         String8 name = hdmiOutputDevices[i]->getName();
         status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
                                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@@ -3684,7 +3680,7 @@
                 AUDIO_DEVICE_IN_HDMI);
     for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
         // Simulate reconnection to update enabled surround sound formats.
-        String8 address = hdmiInputDevices[i]->mAddress;
+        String8 address = hdmiInputDevices[i]->address();
         String8 name = hdmiInputDevices[i]->getName();
         status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
                                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@@ -3942,8 +3938,7 @@
             const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
             const DeviceVector &devicesForType = supportedDevices.getDevicesFromTypeMask(
                     profileType);
-            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
-                    : String8("");
+            String8 address = getFirstDeviceAddress(devicesForType);
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
             status_t status = outputDesc->open(nullptr, profileType, address,
                                            AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
@@ -3997,8 +3992,7 @@
 
             DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(profileType);
             //   the inputs vector must be of size >= 1, but we don't want to crash here
-            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
-                    : String8("");
+            String8 address = getFirstDeviceAddress(inputDevices);
             ALOGV("  for input device 0x%x using address %s", profileType, address.string());
             ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
 
@@ -4060,11 +4054,11 @@
     }
     // If microphones address is empty, set it according to device type
     for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
-        if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
+        if (mAvailableInputDevices[i]->address().isEmpty()) {
             if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->address() = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
             } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
-                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->address() = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
             }
         }
     }
@@ -5233,8 +5227,9 @@
         if (!deviceList.isEmpty()) {
             PatchBuilder patchBuilder;
             patchBuilder.addSource(outputDesc);
-            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
-                patchBuilder.addSink(deviceList.itemAt(i));
+            ALOG_ASSERT(deviceList.size() <= AUDIO_PATCH_PORTS_MAX, "Too many sink ports");
+            for (const auto &device : deviceList) {
+                patchBuilder.addSink(device);
             }
             installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
         }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index aa7ffc8..86993d4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -519,6 +519,19 @@
             return mAvailableInputDevices.getDeviceTypesFromHwModule(
                     mPrimaryOutput->getModuleHandle());
         }
+        /**
+         * @brief getFirstDeviceId of the Device Vector
+         * @return if the collection is not empty, it returns the first device Id,
+         *         otherwise AUDIO_PORT_HANDLE_NONE
+         */
+        audio_port_handle_t getFirstDeviceId(const DeviceVector &devices) const
+        {
+            return (devices.size() > 0) ? devices.itemAt(0)->getId() : AUDIO_PORT_HANDLE_NONE;
+        }
+        String8 getFirstDeviceAddress(const DeviceVector &devices) const
+        {
+            return (devices.size() > 0) ? devices.itemAt(0)->address() : String8("");
+        }
 
         uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
         sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index ee5d6ff..f233971 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -38,6 +38,7 @@
 #include <media/AudioEffect.h>
 #include <media/AudioParameter.h>
 #include <mediautils/ServiceUtilities.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
 
 #include <system/audio.h>
 #include <system/audio_policy.h>
@@ -84,6 +85,9 @@
 
     mUidPolicy = new UidPolicy(this);
     mUidPolicy->registerSelf();
+
+    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+    mSensorPrivacyPolicy->registerSelf();
 }
 
 AudioPolicyService::~AudioPolicyService()
@@ -99,6 +103,9 @@
 
     mUidPolicy->unregisterSelf();
     mUidPolicy.clear();
+
+    mSensorPrivacyPolicy->unregisterSelf();
+    mSensorPrivacyPolicy.clear();
 }
 
 // A notification client is always registered by AudioSystem when the client process
@@ -375,6 +382,12 @@
     bool isAssistantOnTop = false;
     bool isSensitiveActive = false;
 
+    // if Sensor Privacy is enabled then all recordings should be silenced.
+    if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+        silenceAllRecordings_l();
+        return;
+    }
+
     for (size_t i =0; i < mAudioRecordClients.size(); i++) {
         sp<AudioRecordClient> current = mAudioRecordClients[i];
         if (!current->active) continue;
@@ -445,6 +458,13 @@
     }
 }
 
+void AudioPolicyService::silenceAllRecordings_l() {
+    for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
+        sp<AudioRecordClient> current = mAudioRecordClients[i];
+        setAppState_l(current->uid, APP_STATE_IDLE);
+    }
+}
+
 /* static */
 app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
     switch (amState) {
@@ -858,6 +878,31 @@
     return it != mA11yUids.end();
 }
 
+// -----------  AudioPolicyService::SensorPrivacyService implementation ----------
+void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
+    SensorPrivacyManager spm;
+    mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+    spm.addSensorPrivacyListener(this);
+}
+
+void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
+    SensorPrivacyManager spm;
+    spm.removeSensorPrivacyListener(this);
+}
+
+bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+    return mSensorPrivacyEnabled;
+}
+
+binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+    mSensorPrivacyEnabled = enabled;
+    sp<AudioPolicyService> service = mService.promote();
+    if (service != nullptr) {
+        service->updateUidStates();
+    }
+    return binder::Status::ok();
+}
+
 // -----------  AudioPolicyService::AudioCommandThread implementation ----------
 
 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 23c3daa..45d37dc 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -33,6 +33,7 @@
 #include <media/AudioPolicy.h>
 #include "AudioPolicyEffects.h"
 #include "managerdefault/AudioPolicyManager.h"
+#include <android/hardware/BnSensorPrivacyListener.h>
 
 #include <unordered_map>
 
@@ -279,6 +280,8 @@
     void updateUidStates();
     void updateUidStates_l();
 
+    void silenceAllRecordings_l();
+
     static bool isPrivacySensitive(audio_source_t source);
 
     // If recording we need to make sure the UID is allowed to do that. If the UID is idle
@@ -334,6 +337,27 @@
         std::vector<uid_t> mA11yUids;
     };
 
+    // If sensor privacy is enabled then all apps, including those that are active, should be
+    // prevented from recording. This is handled similar to idle UIDs, any app that attempts
+    // to record while sensor privacy is enabled will receive buffers with zeros. As soon as
+    // sensor privacy is disabled active apps will receive the expected data when recording.
+    class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+        public:
+            explicit SensorPrivacyPolicy(wp<AudioPolicyService> service)
+                    : mService(service) {}
+
+            void registerSelf();
+            void unregisterSelf();
+
+            bool isSensorPrivacyEnabled();
+
+            binder::Status onSensorPrivacyChanged(bool enabled);
+
+        private:
+            wp<AudioPolicyService> mService;
+            std::atomic_bool mSensorPrivacyEnabled;
+    };
+
     // Thread used to send audio config commands to audio flinger
     // For audio config commands, it is necessary because audio flinger requires that the calling
     // process (user) has permission to modify audio settings.
@@ -718,6 +742,8 @@
     audio_mode_t mPhoneState;
 
     sp<UidPolicy> mUidPolicy;
+    sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
+
     DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> >   mAudioRecordClients;
     DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> >   mAudioPlaybackClients;
 };
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 789548d..3b6dc80 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -108,6 +108,7 @@
 LOCAL_MODULE := mediaswcodec
 LOCAL_INIT_RC := mediaswcodec.rc
 LOCAL_32_BIT_ONLY := true
+LOCAL_SANITIZE := scudo
 
 sanitizer_runtime_libraries :=
 llndk_libraries :=
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
index 386abb2..79fea25 100644
--- a/services/mediacodec/main_swcodecservice.cpp
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -37,6 +37,12 @@
 static const char kVendorSeccompPolicyPath[] =
         "/vendor/etc/seccomp_policy/mediacodec.policy";
 
+// Disable Scudo's mismatch allocation check, as it is being triggered
+// by some third party code.
+extern "C" const char *__scudo_default_options() {
+  return "DeallocationTypeMismatch=false";
+}
+
 int main(int argc __unused, char** /*argv*/)
 {
     LOG(INFO) << "media swcodec service starting";
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index dddd960..e31eadc 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -38,11 +38,6 @@
 LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediaextractor.policy
 LOCAL_REQUIRED_MODULES_x86_64 := crash_dump.policy mediaextractor.policy
 
-# extractor libraries
-LOCAL_REQUIRED_MODULES += \
-    libmpeg2extractor \
-    liboggextractor \
-
 LOCAL_SRC_FILES := main_extractorservice.cpp
 LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
     liblog libbase libicuuc libavservices_minijail
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 98288e1..37d105b 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -82,8 +82,9 @@
 
             std::lock_guard <std::mutex> lock(mLockStreams);
             for (const auto& clientStream : mRegisteredStreams) {
-                if (clientStream->isRunning()) {
+                if (clientStream->isRunning() && !clientStream->isSuspended()) {
                     int64_t clientFramesWritten = 0;
+
                     sp<AAudioServiceStreamShared> streamShared =
                             static_cast<AAudioServiceStreamShared *>(clientStream.get());
 
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index ac0d61d..1e1c552 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -84,6 +84,10 @@
                 int64_t clientFramesRead = 0;
                 bool allowUnderflow = true;
 
+                if (clientStream->isSuspended()) {
+                    continue; // dead stream
+                }
+
                 aaudio_stream_state_t state = clientStream->getState();
                 if (state == AAUDIO_STREAM_STATE_STOPPING) {
                     allowUnderflow = false; // just read what is already in the FIFO
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 354b36a..defbb7b 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -179,6 +179,7 @@
     }
 
     setFlowing(false);
+    setSuspended(false);
 
     // Start with fresh presentation timestamps.
     mAtomicTimestamp.clear();
@@ -345,7 +346,9 @@
     }
     int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
     if (count != 1) {
-        ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
+        ALOGW("%s(): Queue full. Did client stop? Suspending stream. what = %u, %s",
+              __func__, command->what, getTypeText());
+        setSuspended(true);
         return AAUDIO_ERROR_WOULD_BLOCK;
     } else {
         return AAUDIO_OK;
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index a1815d0..7904b25 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -204,6 +204,20 @@
     }
 
     /**
+     * Set false when the stream should not longer be processed.
+     * This may be caused by a message queue overflow.
+     * Set true when stream is started.
+     * @param suspended
+     */
+    void setSuspended(bool suspended) {
+        mSuspended = suspended;
+    }
+
+    bool isSuspended() const {
+        return mSuspended;
+    }
+
+    /**
      * Atomically increment the number of active references to the stream by AAudioService.
      *
      * This is called under a global lock in AAudioStreamTracker.
@@ -304,7 +318,12 @@
     // This is modified under a global lock in AAudioStreamTracker.
     int32_t                 mCallingCount = 0;
 
+    // This indicates that a stream that is being referenced by a binder call needs to closed.
     std::atomic<bool>       mCloseNeeded{false};
+
+    // This indicate that a running stream should not be processed because of an error,
+    // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
+    std::atomic<bool>       mSuspended{false};
 };
 
 } /* namespace aaudio */