[automerger skipped] Prevent read of uninitialized memory am: f8c7ecf656 am: 559114ac1c -s ours am: cc8061888f

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Icc79e309d09a57783f1cf59578a5ae9ea8c11c35
diff --git a/apex/Android.bp b/apex/Android.bp
index c1ef3d8..2ba6267 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -34,6 +34,9 @@
             ],
         },
     },
+    // JNI
+    native_shared_libs: ["libmediaparser-jni"],
+    compile_multilib: "both",
     prebuilts: [
         "mediaextractor.policy",
         "code_coverage.policy",
diff --git a/apex/manifest.json b/apex/manifest.json
index ddd642e..f1f69f4 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media",
-  "version": 300000000
+  "version": 309999900
 }
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 2320fd7..e20d867 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,7 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 300000000
+  "version": 309999900,
+  "requireNativeLibs": [
+    ":sphal"
+  ]
 }
diff --git a/media/bufferpool/1.0/TEST_MAPPING b/media/bufferpool/1.0/TEST_MAPPING
new file mode 100644
index 0000000..a1e6a58
--- /dev/null
+++ b/media/bufferpool/1.0/TEST_MAPPING
@@ -0,0 +1,8 @@
+// mappings for frameworks/av/media/bufferpool/1.0
+{
+  "presubmit": [
+
+    { "name": "VtsVndkHidlBufferpoolV1_0TargetSingleTest" },
+    { "name": "VtsVndkHidlBufferpoolV1_0TargetMultiTest"}
+  ]
+}
diff --git a/media/bufferpool/1.0/vts/Android.bp b/media/bufferpool/1.0/vts/Android.bp
index ee5a757..691ed40 100644
--- a/media/bufferpool/1.0/vts/Android.bp
+++ b/media/bufferpool/1.0/vts/Android.bp
@@ -16,6 +16,7 @@
 
 cc_test {
     name: "VtsVndkHidlBufferpoolV1_0TargetSingleTest",
+    test_suites: ["device-tests"],
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "allocator.cpp",
@@ -34,6 +35,7 @@
 
 cc_test {
     name: "VtsVndkHidlBufferpoolV1_0TargetMultiTest",
+    test_suites: ["device-tests"],
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "allocator.cpp",
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
index 6111fea..1d2562e 100644
--- a/media/bufferpool/2.0/AccessorImpl.cpp
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
@@ -39,6 +39,8 @@
 
     static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
     static constexpr size_t kMinBufferCountForEviction = 25;
+    static constexpr size_t kMaxUnusedBufferCount = 64;
+    static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
 
     static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
     static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
@@ -724,9 +726,11 @@
 }
 
 void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
-    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) {
+    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs ||
+            mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
         mLastCleanUpUs = mTimestampUs;
-        if (mTimestampUs > mLastLogUs + kLogDurationUs) {
+        if (mTimestampUs > mLastLogUs + kLogDurationUs ||
+                mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
             mLastLogUs = mTimestampUs;
             ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
                   "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
@@ -737,8 +741,9 @@
                   mStats.mTotalFetches, mStats.mTotalTransfers);
         }
         for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
-            if (!clearCache && (mStats.mSizeCached < kMinAllocBytesForEviction
-                    || mBuffers.size() < kMinBufferCountForEviction)) {
+            if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
+                    (mStats.mSizeCached < kMinAllocBytesForEviction ||
+                     mBuffers.size() < kMinBufferCountForEviction)) {
                 break;
             }
             auto it = mBuffers.find(*freeIt);
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
index cd1b4d0..3d39941 100644
--- a/media/bufferpool/2.0/AccessorImpl.h
+++ b/media/bufferpool/2.0/AccessorImpl.h
@@ -193,6 +193,12 @@
                 : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
                   mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
 
+            /// # of currently unused buffers
+            size_t buffersNotInUse() const {
+                ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
+                return mBuffersCached - mBuffersInUse;
+            }
+
             /// A new buffer is allocated on an allocation request.
             void onBufferAllocated(size_t allocSize) {
                 mSizeCached += allocSize;
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/bufferpool/2.0/BufferPoolClient.cpp
index 342fef6..9308b81 100644
--- a/media/bufferpool/2.0/BufferPoolClient.cpp
+++ b/media/bufferpool/2.0/BufferPoolClient.cpp
@@ -32,6 +32,8 @@
 static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
 static constexpr int kPostMaxRetry = 3;
 static constexpr int kCacheTtlUs = 1000000; // TODO: tune
+static constexpr size_t kMaxCachedBufferCount = 64;
+static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
 
 class BufferPoolClient::Impl
         : public std::enable_shared_from_this<BufferPoolClient::Impl> {
@@ -136,6 +138,10 @@
             --mActive;
             mLastChangeUs = getTimestampNow();
         }
+
+        int cachedBufferCount() const {
+            return mBuffers.size() - mActive;
+        }
     } mCache;
 
     // FMQ - release notifier
@@ -668,10 +674,12 @@
 // should have mCache.mLock
 void BufferPoolClient::Impl::evictCaches(bool clearCache) {
     int64_t now = getTimestampNow();
-    if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
+    if (now >= mLastEvictCacheUs + kCacheTtlUs ||
+            clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
         size_t evicted = 0;
         for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
-            if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
+            if (!it->second->hasCache() && (it->second->expire() ||
+                        clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
                 it = mCache.mBuffers.erase(it);
                 ++evicted;
             } else {
diff --git a/media/bufferpool/2.0/TEST_MAPPING b/media/bufferpool/2.0/TEST_MAPPING
new file mode 100644
index 0000000..65dee2c
--- /dev/null
+++ b/media/bufferpool/2.0/TEST_MAPPING
@@ -0,0 +1,7 @@
+// mappings for frameworks/av/media/bufferpool/2.0
+{
+  "presubmit": [
+    { "name": "VtsVndkHidlBufferpoolV2_0TargetSingleTest"},
+    { "name": "VtsVndkHidlBufferpoolV2_0TargetMultiTest"}
+  ]
+}
diff --git a/media/bufferpool/2.0/tests/Android.bp b/media/bufferpool/2.0/tests/Android.bp
index 8b44f61..8492939 100644
--- a/media/bufferpool/2.0/tests/Android.bp
+++ b/media/bufferpool/2.0/tests/Android.bp
@@ -16,6 +16,7 @@
 
 cc_test {
     name: "VtsVndkHidlBufferpoolV2_0TargetSingleTest",
+    test_suites: ["device-tests"],
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "allocator.cpp",
@@ -34,6 +35,7 @@
 
 cc_test {
     name: "VtsVndkHidlBufferpoolV2_0TargetMultiTest",
+    test_suites: ["device-tests"],
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "allocator.cpp",
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index 8afa1a8..fca3477 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -1,5 +1,10 @@
 {
   "presubmit": [
+    // TODO failing 4 of 13
+    // { "name": "codec2_core_param_test"},
+    // TODO(b/155516524)
+    // { "name": "codec2_vndk_interface_test"},
+    { "name": "codec2_vndk_test"},
     {
       "name": "CtsMediaTestCases",
       "options": [
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index d7b9e12..3afd670 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -34,7 +34,11 @@
 constexpr size_t kMinInputBufferSize = 2 * 1024 * 1024;
 constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
 constexpr uint32_t kDefaultOutputDelay = 8;
-constexpr uint32_t kMaxOutputDelay = 16;
+/* avc specification allows for a maximum delay of 16 frames.
+   As soft avc decoder supports interlaced, this delay would be 32 fields.
+   And avc decoder implementation has an additional delay of 2 decode calls.
+   So total maximum output delay is 34 */
+constexpr uint32_t kMaxOutputDelay = 34;
 constexpr uint32_t kMinInputBytes = 4;
 }  // namespace
 
diff --git a/media/codec2/components/gav1/Android.bp b/media/codec2/components/gav1/Android.bp
index 5c4abb7..f374089 100644
--- a/media/codec2/components/gav1/Android.bp
+++ b/media/codec2/components/gav1/Android.bp
@@ -13,8 +13,4 @@
 
     srcs: ["C2SoftGav1Dec.cpp"],
     static_libs: ["libgav1"],
-
-    include_dirs: [
-        "external/libgav1/libgav1/",
-    ],
 }
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index ec5f549..120ba7a 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -288,9 +288,7 @@
 void C2SoftGav1Dec::onRelease() { destroyDecoder(); }
 
 c2_status_t C2SoftGav1Dec::onFlush_sm() {
-  Libgav1StatusCode status =
-      mCodecCtx->EnqueueFrame(/*data=*/nullptr, /*size=*/0,
-                              /*user_private_data=*/0);
+  Libgav1StatusCode status = mCodecCtx->SignalEOS();
   if (status != kLibgav1StatusOk) {
     ALOGE("Failed to flush av1 decoder. status: %d.", status);
     return C2_CORRUPTED;
@@ -299,7 +297,7 @@
   // Dequeue frame (if any) that was enqueued previously.
   const libgav1::DecoderBuffer *buffer;
   status = mCodecCtx->DequeueFrame(&buffer);
-  if (status != kLibgav1StatusOk) {
+  if (status != kLibgav1StatusOk && status != kLibgav1StatusNothingToDequeue) {
     ALOGE("Failed to dequeue frame after flushing the av1 decoder. status: %d",
           status);
     return C2_CORRUPTED;
@@ -433,7 +431,8 @@
     TIME_DIFF(mTimeEnd, mTimeStart, delay);
 
     const Libgav1StatusCode status =
-        mCodecCtx->EnqueueFrame(bitstream, inSize, frameIndex);
+        mCodecCtx->EnqueueFrame(bitstream, inSize, frameIndex,
+                                /*buffer_private_data=*/nullptr);
 
     GETTIME(&mTimeEnd, nullptr);
     TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
@@ -447,17 +446,6 @@
       return;
     }
 
-  } else {
-    const Libgav1StatusCode status =
-        mCodecCtx->EnqueueFrame(/*data=*/nullptr, /*size=*/0,
-                                /*user_private_data=*/0);
-    if (status != kLibgav1StatusOk) {
-      ALOGE("Failed to flush av1 decoder. status: %d.", status);
-      work->result = C2_CORRUPTED;
-      work->workletsProcessed = 1u;
-      mSignalledError = true;
-      return;
-    }
   }
 
   (void)outputBuffer(pool, work);
@@ -470,13 +458,12 @@
   }
 }
 
-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) {
-  const size_t dstYStride = align(width, 16);
-  const size_t dstUVStride = align(dstYStride / 2, 16);
+static void copyOutputBufferToYuvPlanarFrame(uint8_t *dst, const uint8_t *srcY,
+                                             const uint8_t *srcU,
+                                             const uint8_t *srcV, size_t srcYStride,
+                                             size_t srcUStride, size_t srcVStride,
+                                             size_t dstYStride, size_t dstUVStride,
+                                             uint32_t width, uint32_t height) {
   uint8_t *const dstStart = dst;
 
   for (size_t i = 0; i < height; ++i) {
@@ -570,10 +557,10 @@
 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) {
+    size_t srcVStride, size_t dstYStride, size_t dstUVStride,
+    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 dstYSize = dstYStride * height;
   size_t dstUVSize = dstUVStride * height / 2;
   uint8_t *dstV = dstY + dstYSize;
   uint8_t *dstU = dstV + dstUVSize;
@@ -584,7 +571,7 @@
     }
 
     srcY += srcYStride;
-    dstY += dstStride;
+    dstY += dstYStride;
   }
 
   for (size_t y = 0; y < (height + 1) / 2; ++y) {
@@ -607,13 +594,14 @@
   const libgav1::DecoderBuffer *buffer;
   const Libgav1StatusCode status = mCodecCtx->DequeueFrame(&buffer);
 
-  if (status != kLibgav1StatusOk) {
+  if (status != kLibgav1StatusOk && status != kLibgav1StatusNothingToDequeue) {
     ALOGE("av1 decoder DequeueFrame failed. status: %d.", status);
     return false;
   }
 
-  // |buffer| can be NULL if status was equal to kLibgav1StatusOk. This is not
-  // an error. This could mean one of two things:
+  // |buffer| can be NULL if status was equal to kLibgav1StatusOk or
+  // kLibgav1StatusNothingToDequeue. This is not an error. This could mean one
+  // of two things:
   //  - The EnqueueFrame() call was either a flush (called with nullptr).
   //  - The enqueued frame did not have any displayable frames.
   if (!buffer) {
@@ -683,6 +671,9 @@
   size_t srcYStride = buffer->stride[0];
   size_t srcUStride = buffer->stride[1];
   size_t srcVStride = buffer->stride[2];
+  C2PlanarLayout layout = wView.layout();
+  size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+  size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
 
   if (buffer->bitdepth == 10) {
     const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
@@ -692,18 +683,19 @@
     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);
+          srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
     } else {
       convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
                                           srcUStride / 2, srcVStride / 2,
-                                          align(mWidth, 16), mWidth, mHeight);
+                                          dstYStride, dstUVStride, mWidth, mHeight);
     }
   } else {
     const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
     const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
     const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
-    copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV, srcYStride, srcUStride,
-                                srcVStride, mWidth, mHeight);
+    copyOutputBufferToYuvPlanarFrame(dst, srcY, srcU, srcV, srcYStride, srcUStride,
+                                     srcVStride, dstYStride, dstUVStride,
+                                     mWidth, mHeight);
   }
   finishWork(buffer->user_private_data, work, std::move(block));
   block = nullptr;
@@ -722,9 +714,7 @@
     return C2_OMITTED;
   }
 
-  Libgav1StatusCode status =
-      mCodecCtx->EnqueueFrame(/*data=*/nullptr, /*size=*/0,
-                              /*user_private_data=*/0);
+  const Libgav1StatusCode status = mCodecCtx->SignalEOS();
   if (status != kLibgav1StatusOk) {
     ALOGE("Failed to flush av1 decoder. status: %d.", status);
     return C2_CORRUPTED;
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index a7c08bb..555adc9 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -18,8 +18,8 @@
 #define ANDROID_C2_SOFT_GAV1_DEC_H_
 
 #include <SimpleC2Component.h>
-#include "libgav1/src/decoder.h"
-#include "libgav1/src/decoder_settings.h"
+#include "libgav1/src/gav1/decoder.h"
+#include "libgav1/src/gav1/decoder_settings.h"
 
 #define GETTIME(a, b) gettimeofday(a, b);
 #define TIME_DIFF(start, end, diff)     \
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index 15564d9..a8b5377 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -279,6 +279,8 @@
         // skip 7 <type + "vorbis"> bytes
         makeBitReader((const uint8_t *)data + 7, inSize - 7, &buf, &ref, &bits);
         if (data[0] == 1) {
+            // release any memory that vorbis_info_init will blindly overwrite
+            vorbis_info_clear(mVi);
             vorbis_info_init(mVi);
             if (0 != _vorbis_unpack_info(mVi, &bits)) {
                 ALOGE("Encountered error while unpacking info");
@@ -323,6 +325,8 @@
                 work->result = C2_CORRUPTED;
                 return;
             }
+            // release any memory that vorbis_dsp_init will blindly overwrite
+            vorbis_dsp_clear(mState);
             if (0 != vorbis_dsp_init(mState, mVi)) {
                 ALOGE("Encountered error while dsp init");
                 mSignalledError = true;
diff --git a/media/codec2/sfplugin/TEST_MAPPING b/media/codec2/sfplugin/TEST_MAPPING
new file mode 100644
index 0000000..045e5b5
--- /dev/null
+++ b/media/codec2/sfplugin/TEST_MAPPING
@@ -0,0 +1,12 @@
+// mappings for frameworks/av/media/codec2/sfplugin
+{
+  "presubmit": [
+    // failing 1 of 11
+    // TODO(b/156167471)
+    // { "name": "ccodec_unit_test" },
+
+    // failing 4 of 17, around max-input-size defaults & overrides
+    // TODO(b/156167471)
+    //{ "name": "mc_sanity_test"}
+  ]
+}
diff --git a/media/codec2/sfplugin/tests/Android.bp b/media/codec2/sfplugin/tests/Android.bp
index 8d1a9c3..5c774a2 100644
--- a/media/codec2/sfplugin/tests/Android.bp
+++ b/media/codec2/sfplugin/tests/Android.bp
@@ -1,5 +1,6 @@
 cc_test {
     name: "ccodec_unit_test",
+    test_suites: ["device-tests"],
 
     srcs: [
         "CCodecBuffers_test.cpp",
@@ -43,6 +44,7 @@
 
 cc_test {
     name: "mc_sanity_test",
+    test_suites: ["device-tests"],
 
     srcs: [
         "MediaCodec_sanity_test.cpp",
diff --git a/media/codec2/tests/Android.bp b/media/codec2/tests/Android.bp
index fce6e21..c9169a9 100644
--- a/media/codec2/tests/Android.bp
+++ b/media/codec2/tests/Android.bp
@@ -1,5 +1,6 @@
 cc_test {
     name: "codec2_core_param_test",
+    test_suites: ["device-tests"],
 
     srcs: [
         "C2Param_test.cpp",
@@ -28,6 +29,7 @@
 
 cc_test {
     name: "codec2_vndk_test",
+    test_suites: ["device-tests"],
 
     srcs: [
         "C2_test.cpp",
diff --git a/media/extractors/TEST_MAPPING b/media/extractors/TEST_MAPPING
index abefb0f..cf3c30e 100644
--- a/media/extractors/TEST_MAPPING
+++ b/media/extractors/TEST_MAPPING
@@ -13,5 +13,7 @@
     //      }
     //    ]
     //  }
+    // TODO(b/148094059): unit tests not allowed to download content
+    //{ "name": "ExtractorUnitTest" }
   ]
 }
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index 0617e88..ec7cb24 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -561,6 +561,8 @@
         AMediaFormat_setString(mFileMetadata,
                 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
     }
+    mMaxBufferSize = getMaxBlockSize() * getChannels() * getOutputSampleSize();
+    AMediaFormat_setInt32(mTrackMetadata, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, mMaxBufferSize);
     return OK;
 }
 
@@ -568,8 +570,6 @@
 {
     CHECK(mGroup == NULL);
     mGroup = group;
-    mMaxBufferSize = getMaxBlockSize() * getChannels() * getOutputSampleSize();
-    AMediaFormat_setInt32(mTrackMetadata, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, mMaxBufferSize);
     mGroup->add_buffer(mMaxBufferSize);
 }
 
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index b88e4e8..27bd357 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -840,7 +840,7 @@
         }
 
         if (err != OK) {
-            mPendingFrames.clear();
+            clearPendingFrames();
 
             mBlockIter.advance();
             mbuf->release();
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 828bcd6..eb2246d 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -1304,8 +1304,8 @@
                 || audioChannelCount <= 0 || audioChannelCount > FCC_8) {
             ALOGE("Invalid haptic channel count found in metadata: %d", mHapticChannelCount);
         } else {
-            const audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(
-                    audioChannelCount) | hapticChannelMask;
+            const audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(
+                    audio_channel_out_mask_from_count(audioChannelCount) | hapticChannelMask);
             AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK, channelMask);
             AMediaFormat_setInt32(
                     mMeta, AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT, mHapticChannelCount);
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index e71ea2c..12a87d1 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -20,6 +20,8 @@
 
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <unistd.h>
+#include <algorithm>
 
 #include <media/MidiIoWrapper.h>
 #include <media/MediaExtractorPluginApi.h>
@@ -32,6 +34,8 @@
 }
 
 namespace android {
+int MidiIoWrapper::sCacheBufferSize = 0;
+Mutex MidiIoWrapper::mCacheLock;
 
 MidiIoWrapper::MidiIoWrapper(const char *path) {
     ALOGV("MidiIoWrapper(%s)", path);
@@ -39,6 +43,8 @@
     mBase = 0;
     mLength = lseek(mFd, 0, SEEK_END);
     mDataSource = nullptr;
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 MidiIoWrapper::MidiIoWrapper(int fd, off64_t offset, int64_t size) {
@@ -47,6 +53,8 @@
     mBase = offset;
     mLength = size;
     mDataSource = nullptr;
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 class MidiIoWrapper::DataSourceUnwrapper {
@@ -96,6 +104,8 @@
     } else {
         mLength = 0;
     }
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 MidiIoWrapper::~MidiIoWrapper() {
@@ -104,11 +114,80 @@
         close(mFd);
     }
     delete mDataSource;
+
+    if (NULL != mCacheBuffer) {
+        delete [] mCacheBuffer;
+        mCacheBuffer = NULL;
+        {
+            Mutex::Autolock _l(mCacheLock);
+            sCacheBufferSize -= mLength;
+        }
+    }
 }
 
 int MidiIoWrapper::readAt(void *buffer, int offset, int size) {
     ALOGV("readAt(%p, %d, %d)", buffer, offset, size);
 
+    if (offset < 0) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (offset + size > mLength) {
+        size = mLength - offset;
+    }
+
+    if (mCacheBuffer == NULL) {
+        Mutex::Autolock _l(mCacheLock);
+        if (sCacheBufferSize + mLength <= kTotalCacheSize) {
+            mCacheBuffer = new (std::nothrow) unsigned char[mLength];
+            if (NULL != mCacheBuffer) {
+                sCacheBufferSize += mLength;
+                ALOGV("sCacheBufferSize : %d", sCacheBufferSize);
+            } else {
+                ALOGE("failed to allocate memory for mCacheBuffer");
+            }
+        } else {
+            ALOGV("not allocate memory for mCacheBuffer");
+        }
+    }
+
+    if (mCacheBuffer != NULL) {
+        if (mCacheBufRangeLength > 0 && mCacheBufRangeLength >= (offset + size)) {
+            /* Use buffered data */
+            memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+            return size;
+        } else {
+            /* Buffer new data */
+            int64_t beyondCacheBufRangeLength = (offset + size) - mCacheBufRangeLength;
+            int64_t numRequiredBytesToCache =
+                  std::max((int64_t)kSingleCacheSize, beyondCacheBufRangeLength);
+            int64_t availableReadLength = mLength - mCacheBufRangeLength;
+            int64_t readSize = std::min(availableReadLength, numRequiredBytesToCache);
+            int actualNumBytesRead =
+                unbufferedReadAt(mCacheBuffer + mCacheBufRangeLength,
+                        mCacheBufRangeLength, readSize);
+            if(actualNumBytesRead > 0) {
+                mCacheBufRangeLength += actualNumBytesRead;
+                if (offset >= mCacheBufRangeLength) {
+                    return 0;
+                } else if (offset + size >= mCacheBufRangeLength) {
+                    memcpy(buffer, (void*)(mCacheBuffer + offset), mCacheBufRangeLength - offset);
+                    return mCacheBufRangeLength - offset;
+                } else {
+                    memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+                    return size;
+                }
+            } else {
+                return actualNumBytesRead;
+            }
+        }
+    } else {
+        return unbufferedReadAt(buffer, offset, size);
+    }
+}
+
+int MidiIoWrapper::unbufferedReadAt(void *buffer, int offset, int size) {
+    ALOGV("unbufferedReadAt(%p, %d, %d)", buffer, offset, size);
     if (mDataSource != NULL) {
         return mDataSource->readAt(offset, buffer, size);
     }
diff --git a/media/libmedia/TEST_MAPPING b/media/libmedia/TEST_MAPPING
new file mode 100644
index 0000000..65390ed
--- /dev/null
+++ b/media/libmedia/TEST_MAPPING
@@ -0,0 +1,6 @@
+// test_mapping for frameworks/av/media/libmedia
+{
+  "presubmit": [
+    { "name": "CodecListTest" }
+  ]
+}
diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
index 0cdd4ad..5fa745c 100644
--- a/media/libmedia/include/media/MidiIoWrapper.h
+++ b/media/libmedia/include/media/MidiIoWrapper.h
@@ -18,6 +18,7 @@
 #define MIDI_IO_WRAPPER_H_
 
 #include <libsonivox/eas_types.h>
+#include <utils/Mutex.h>
 
 namespace android {
 
@@ -32,17 +33,27 @@
     ~MidiIoWrapper();
 
     int readAt(void *buffer, int offset, int size);
+    int unbufferedReadAt(void *buffer, int offset, int size);
     int size();
 
     EAS_FILE_LOCATOR getLocator();
 
 private:
+    enum {
+        kTotalCacheSize      = 1024 * 1024 + 512 * 1024,
+        kSingleCacheSize     = 65536,
+    };
+
     int mFd;
     off64_t mBase;
     int64_t  mLength;
     class DataSourceUnwrapper;
     DataSourceUnwrapper *mDataSource;
     EAS_FILE mEasFile;
+    unsigned char *mCacheBuffer;
+    int64_t mCacheBufRangeLength;
+    static int sCacheBufferSize;
+    static Mutex mCacheLock;
 };
 
 
diff --git a/media/libmedia/tests/codeclist/Android.bp b/media/libmedia/tests/codeclist/Android.bp
new file mode 100644
index 0000000..a930d6e
--- /dev/null
+++ b/media/libmedia/tests/codeclist/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "CodecListTest",
+    test_suites: ["device-tests"],
+    gtest: true,
+
+    srcs: [
+        "CodecListTest.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libmedia_codeclist",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libstagefright_xmlparser",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libmedia/tests/codeclist/CodecListTest.cpp b/media/libmedia/tests/codeclist/CodecListTest.cpp
new file mode 100644
index 0000000..bd2adf7
--- /dev/null
+++ b/media/libmedia/tests/codeclist/CodecListTest.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecListTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <binder/Parcel.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#define kSwCodecXmlPath "/apex/com.android.media.swcodec/etc/"
+
+using namespace android;
+
+struct CddReq {
+    CddReq(const char *type, bool encoder) {
+        mediaType = type;
+        isEncoder = encoder;
+    }
+
+    const char *mediaType;
+    bool isEncoder;
+};
+
+TEST(CodecListTest, CodecListSanityTest) {
+    sp<IMediaCodecList> list = MediaCodecList::getInstance();
+    ASSERT_NE(list, nullptr) << "Unable to get MediaCodecList instance.";
+    EXPECT_GT(list->countCodecs(), 0) << "No codecs in CodecList";
+    for (size_t i = 0; i < list->countCodecs(); ++i) {
+        sp<MediaCodecInfo> info = list->getCodecInfo(i);
+        ASSERT_NE(info, nullptr) << "CodecInfo is null";
+        ssize_t index = list->findCodecByName(info->getCodecName());
+        EXPECT_GE(index, 0) << "Wasn't able to find existing codec: " << info->getCodecName();
+    }
+}
+
+TEST(CodecListTest, CodecListByTypeTest) {
+    sp<IMediaCodecList> list = MediaCodecList::getInstance();
+    ASSERT_NE(list, nullptr) << "Unable to get MediaCodecList instance.";
+
+    std::vector<CddReq> cddReq{
+            // media type, isEncoder
+            CddReq(MIMETYPE_AUDIO_AAC, false),
+            CddReq(MIMETYPE_AUDIO_AAC, true),
+
+            CddReq(MIMETYPE_VIDEO_AVC, false),
+            CddReq(MIMETYPE_VIDEO_HEVC, false),
+            CddReq(MIMETYPE_VIDEO_MPEG4, false),
+            CddReq(MIMETYPE_VIDEO_VP8, false),
+            CddReq(MIMETYPE_VIDEO_VP9, false),
+
+            CddReq(MIMETYPE_VIDEO_AVC, true),
+            CddReq(MIMETYPE_VIDEO_VP8, true),
+    };
+
+    for (CddReq codecReq : cddReq) {
+        ssize_t index = list->findCodecByType(codecReq.mediaType, codecReq.isEncoder);
+        EXPECT_GE(index, 0) << "Wasn't able to find codec for media type: " << codecReq.mediaType
+                            << (codecReq.isEncoder ? " encoder" : " decoder");
+    }
+}
+
+TEST(CodecInfoTest, ListInfoTest) {
+    ALOGV("Compare CodecInfo with info in XML");
+    MediaCodecsXmlParser parser;
+    status_t status = parser.parseXmlFilesInSearchDirs();
+    ASSERT_EQ(status, OK) << "XML Parsing failed for default paths";
+
+    const std::vector<std::string> &xmlFiles = MediaCodecsXmlParser::getDefaultXmlNames();
+    const std::vector<std::string> &searchDirsApex{std::string(kSwCodecXmlPath)};
+    status = parser.parseXmlFilesInSearchDirs(xmlFiles, searchDirsApex);
+    ASSERT_EQ(status, OK) << "XML Parsing of " << kSwCodecXmlPath << " failed";
+
+    MediaCodecsXmlParser::CodecMap codecMap = parser.getCodecMap();
+
+    sp<IMediaCodecList> list = MediaCodecList::getInstance();
+    ASSERT_NE(list, nullptr) << "Unable to get MediaCodecList instance";
+
+    // Compare CodecMap from XML to CodecList
+    for (auto mapIter : codecMap) {
+        ssize_t index = list->findCodecByName(mapIter.first.c_str());
+        if (index < 0) {
+            std::cout << "[   WARN   ] " << mapIter.first << " not found in CodecList \n";
+            continue;
+        }
+
+        sp<MediaCodecInfo> info = list->getCodecInfo(index);
+        ASSERT_NE(info, nullptr) << "CodecInfo is null";
+
+        MediaCodecsXmlParser::CodecProperties codecProperties = mapIter.second;
+        ASSERT_EQ(codecProperties.isEncoder, info->isEncoder()) << "Encoder property mismatch";
+
+        ALOGV("codec name: %s", info->getCodecName());
+        ALOGV("codec rank: %d", info->getRank());
+        ALOGV("codec ownername: %s", info->getOwnerName());
+        ALOGV("codec isEncoder: %d", info->isEncoder());
+
+        ALOGV("attributeFlags: kFlagIsHardwareAccelerated, kFlagIsSoftwareOnly, kFlagIsVendor, "
+              "kFlagIsEncoder");
+        std::bitset<4> attr(info->getAttributes());
+        ALOGV("codec attributes: %s", attr.to_string().c_str());
+
+        Vector<AString> mediaTypes;
+        info->getSupportedMediaTypes(&mediaTypes);
+        ALOGV("supported media types count: %zu", mediaTypes.size());
+        ASSERT_FALSE(mediaTypes.isEmpty())
+                << "no media type supported by codec: " << info->getCodecName();
+
+        MediaCodecsXmlParser::TypeMap typeMap = codecProperties.typeMap;
+        for (auto mediaType : mediaTypes) {
+            ALOGV("codec mediaTypes: %s", mediaType.c_str());
+            auto searchTypeMap = typeMap.find(mediaType.c_str());
+            ASSERT_NE(searchTypeMap, typeMap.end())
+                    << "CodecList doesn't contain codec media type: " << mediaType.c_str();
+            MediaCodecsXmlParser::AttributeMap attributeMap = searchTypeMap->second;
+
+            const sp<MediaCodecInfo::Capabilities> &capabilities =
+                    info->getCapabilitiesFor(mediaType.c_str());
+
+            Vector<uint32_t> colorFormats;
+            capabilities->getSupportedColorFormats(&colorFormats);
+            for (auto colorFormat : colorFormats) {
+                ALOGV("supported color formats: %d", colorFormat);
+            }
+
+            Vector<MediaCodecInfo::ProfileLevel> profileLevels;
+            capabilities->getSupportedProfileLevels(&profileLevels);
+            if (!profileLevels.empty()) {
+                ALOGV("supported profilelevel for media type: %s", mediaType.c_str());
+            }
+            for (auto profileLevel : profileLevels) {
+                ALOGV("profile: %d, level: %d", profileLevel.mProfile, profileLevel.mLevel);
+            }
+
+            sp<AMessage> details = capabilities->getDetails();
+            ASSERT_NE(details, nullptr) << "Details in codec capabilities is null";
+            ALOGV("no. of entries in details: %zu", details->countEntries());
+
+            for (size_t idxDetail = 0; idxDetail < details->countEntries(); idxDetail++) {
+                AMessage::Type type;
+                const char *name = details->getEntryNameAt(idxDetail, &type);
+                ALOGV("details entry name: %s", name);
+                AMessage::ItemData itemData = details->getEntryAt(idxDetail);
+                switch (type) {
+                    case AMessage::kTypeInt32:
+                        int32_t val32;
+                        if (itemData.find(&val32)) {
+                            ALOGV("entry int val: %d", val32);
+                            auto searchAttr = attributeMap.find(name);
+                            if (searchAttr == attributeMap.end()) {
+                                ALOGW("Parser doesn't have key: %s", name);
+                            } else if (stoi(searchAttr->second) != val32) {
+                                ALOGW("Values didn't match for key: %s", name);
+                                ALOGV("Values act/exp: %d / %d", val32, stoi(searchAttr->second));
+                            }
+                        }
+                        break;
+                    case AMessage::kTypeString:
+                        if (AString valStr; itemData.find(&valStr)) {
+                            ALOGV("entry str val: %s", valStr.c_str());
+                            auto searchAttr = attributeMap.find(name);
+                            if (searchAttr == attributeMap.end()) {
+                                ALOGW("Parser doesn't have key: %s", name);
+                            } else if (searchAttr->second != valStr.c_str()) {
+                                ALOGW("Values didn't match for key: %s", name);
+                                ALOGV("Values act/exp: %s / %s", valStr.c_str(),
+                                      searchAttr->second.c_str());
+                            }
+                        }
+                        break;
+                    default:
+                        ALOGV("data type: %d shouldn't be present in details", type);
+                        break;
+                }
+            }
+        }
+
+        Parcel *codecInfoParcel = new Parcel();
+        ASSERT_NE(codecInfoParcel, nullptr) << "Unable to create parcel";
+
+        status_t status = info->writeToParcel(codecInfoParcel);
+        ASSERT_EQ(status, OK) << "Writing to parcel failed";
+
+        codecInfoParcel->setDataPosition(0);
+        sp<MediaCodecInfo> parcelCodecInfo = info->FromParcel(*codecInfoParcel);
+        ASSERT_NE(parcelCodecInfo, nullptr) << "CodecInfo from parcel is null";
+        delete codecInfoParcel;
+
+        EXPECT_STREQ(info->getCodecName(), parcelCodecInfo->getCodecName())
+                << "Returned codec name in info doesn't match";
+        EXPECT_EQ(info->getRank(), parcelCodecInfo->getRank())
+                << "Returned component rank in info doesn't match";
+    }
+}
+
+TEST(CodecListTest, CodecListGlobalSettingsTest) {
+    sp<IMediaCodecList> list = MediaCodecList::getInstance();
+    ASSERT_NE(list, nullptr) << "Unable to get MediaCodecList instance";
+
+    sp<AMessage> globalSettings = list->getGlobalSettings();
+    ASSERT_NE(globalSettings, nullptr) << "GlobalSettings AMessage is null";
+    ALOGV("global settings: %s", globalSettings->debugString(0).c_str());
+}
diff --git a/media/libmediametrics/Android.bp b/media/libmediametrics/Android.bp
index 03068c7..a63b8b4 100644
--- a/media/libmediametrics/Android.bp
+++ b/media/libmediametrics/Android.bp
@@ -53,6 +53,7 @@
     visibility: [
         "//cts/tests/tests/nativemedia/mediametrics",
         "//frameworks/av:__subpackages__",
+        "//frameworks/base/apex/media/framework",
         "//frameworks/base/core/jni",
         "//frameworks/base/media/jni",
     ],
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index 8b36ea5..3dceef7 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -1,5 +1,12 @@
 {
   "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "HEVCUtilsUnitTest" },
+    //{ "name": "ExtractorFactoryTest" },
+    // writerTest fails about 5 out of 66
+    // in addition to needing the download ability
+    //{ "name": "writerTest" },
+
     {
       "name": "CtsMediaTestCases",
       "options": [
diff --git a/media/libstagefright/bqhelper/TEST_MAPPING b/media/libstagefright/bqhelper/TEST_MAPPING
new file mode 100644
index 0000000..c7f2fd8
--- /dev/null
+++ b/media/libstagefright/bqhelper/TEST_MAPPING
@@ -0,0 +1,6 @@
+// mappings for frameworks/av/media/libstagefright/bqhelper
+{
+  "presubmit": [
+    { "name": "FrameDropper_test"}
+  ]
+}
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
index 4e83059..7e2909a 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
@@ -30,6 +30,8 @@
     FrameDropper();
 
     // maxFrameRate required to be positive.
+    // maxFrameRate negative causes shouldDrop() to always return false
+    // maxFrameRate == 0 is illegal
     status_t setMaxFrameRate(float maxFrameRate);
 
     // Returns false if max frame rate has not been set via setMaxFrameRate.
diff --git a/media/libstagefright/bqhelper/tests/Android.bp b/media/libstagefright/bqhelper/tests/Android.bp
index 2fbc3d6..759ff8c 100644
--- a/media/libstagefright/bqhelper/tests/Android.bp
+++ b/media/libstagefright/bqhelper/tests/Android.bp
@@ -1,15 +1,17 @@
 cc_test {
     name: "FrameDropper_test",
-
+    test_suites: [
+        "device-tests",
+        "mts",
+    ],
     srcs: ["FrameDropper_test.cpp"],
-
     shared_libs: [
         "libstagefright_bufferqueue_helper",
         "libutils",
     ],
-
     cflags: [
         "-Werror",
         "-Wall",
     ],
+    compile_multilib: "first",
 }
diff --git a/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp b/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp
index 55ae77c..b18067f 100644
--- a/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp
+++ b/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp
@@ -110,7 +110,7 @@
 };
 
 TEST_F(FrameDropperTest, TestInvalidMaxFrameRate) {
-    EXPECT_NE(OK, mFrameDropper->setMaxFrameRate(-1.0));
+    EXPECT_EQ(OK, mFrameDropper->setMaxFrameRate(-1.0));
     EXPECT_NE(OK, mFrameDropper->setMaxFrameRate(0));
 }
 
diff --git a/media/libstagefright/codecs/amrnb/TEST_MAPPING b/media/libstagefright/codecs/amrnb/TEST_MAPPING
new file mode 100644
index 0000000..2909099
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/TEST_MAPPING
@@ -0,0 +1,11 @@
+// mappings for frameworks/av/media/libstagefright/codecs/amrnb
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "AmrnbDecoderTest"},
+
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "AmrnbEncoderTest"}
+
+  ]
+}
diff --git a/media/libstagefright/codecs/amrnb/dec/test/Android.bp b/media/libstagefright/codecs/amrnb/dec/test/Android.bp
index 7a95cfa..91c9f86 100644
--- a/media/libstagefright/codecs/amrnb/dec/test/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/test/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "AmrnbDecoderTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs: [
         "AmrnbDecoderTest.cpp",
diff --git a/media/libstagefright/codecs/amrnb/enc/test/Android.bp b/media/libstagefright/codecs/amrnb/enc/test/Android.bp
index e8982fe..7e1b561 100644
--- a/media/libstagefright/codecs/amrnb/enc/test/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/test/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "AmrnbEncoderTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs: [
         "AmrnbEncoderTest.cpp",
diff --git a/media/libstagefright/codecs/amrwb/TEST_MAPPING b/media/libstagefright/codecs/amrwb/TEST_MAPPING
new file mode 100644
index 0000000..3d58ba2
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/TEST_MAPPING
@@ -0,0 +1,8 @@
+// mappings for frameworks/av/media/libstagefright/codecs/amrwb
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "AmrwbDecoderTest"}
+
+  ]
+}
diff --git a/media/libstagefright/codecs/amrwbenc/TEST_MAPPING b/media/libstagefright/codecs/amrwbenc/TEST_MAPPING
new file mode 100644
index 0000000..d53d665
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/TEST_MAPPING
@@ -0,0 +1,8 @@
+// mappings for frameworks/av/media/libstagefright/codecs/amrwbenc
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "AmrwbEncoderTest"}
+
+  ]
+}
diff --git a/media/libstagefright/codecs/m4v_h263/TEST_MAPPING b/media/libstagefright/codecs/m4v_h263/TEST_MAPPING
new file mode 100644
index 0000000..6b42847
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/TEST_MAPPING
@@ -0,0 +1,16 @@
+// mappings for frameworks/av/media/libstagefright/codecs/m4v_h263
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+
+    // the decoder reports something bad about an unexpected newline in the *config file
+    // and the config file looks like the AndroidTest.xml file that we put in there.
+    // I don't get this from the Encoder -- and I don't see any substantive difference
+    // between decode and encode AndroidTest.xml files -- except that encode does NOT
+    // finish with a newline.
+    // strange.
+    // { "name": "Mpeg4H263DecoderTest"},
+    // { "name": "Mpeg4H263EncoderTest"}
+
+  ]
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
index 37250f3..5b19db4 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
@@ -649,8 +649,11 @@
 
 
 
-void PVLocateM4VFrameBoundary(BitstreamDecVideo *stream)
+PV_STATUS PVLocateM4VFrameBoundary(BitstreamDecVideo *stream)
 {
+    PV_STATUS status = BitstreamCheckEndBuffer(stream);
+    if (status == PV_END_OF_VOP) return status;
+
     uint8 *ptr;
     int32 byte_pos = (stream->bitcnt >> 3);
 
@@ -658,10 +661,14 @@
     ptr = stream->bitstreamBuffer + byte_pos;
 
     stream->data_end_pos = PVLocateFrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
+    return PV_SUCCESS;
 }
 
-void PVLocateH263FrameBoundary(BitstreamDecVideo *stream)
+PV_STATUS PVLocateH263FrameBoundary(BitstreamDecVideo *stream)
 {
+    PV_STATUS status = BitstreamCheckEndBuffer(stream);
+    if (status == PV_END_OF_VOP) return status;
+
     uint8 *ptr;
     int32 byte_pos = (stream->bitcnt >> 3);
 
@@ -669,6 +676,7 @@
     ptr = stream->bitstreamBuffer + byte_pos;
 
     stream->data_end_pos = PVLocateH263FrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
+    return PV_SUCCESS;
 }
 
 /* ======================================================================== */
@@ -687,7 +695,8 @@
 
     if (stream->searched_frame_boundary == 0)
     {
-        PVLocateM4VFrameBoundary(stream);
+        status = PVLocateM4VFrameBoundary(stream);
+        if (status != PV_SUCCESS) return status;
     }
 
     do
@@ -711,7 +720,8 @@
 
     if (stream->searched_frame_boundary == 0)
     {
-        PVLocateH263FrameBoundary(stream);
+        status = PVLocateH263FrameBoundary(stream);
+        if (status != PV_SUCCESS) return status;
     }
 
     do
@@ -789,7 +799,8 @@
 
     if (stream->searched_frame_boundary == 0)
     {
-        PVLocateM4VFrameBoundary(stream);
+        status = PVLocateM4VFrameBoundary(stream);
+        if (status != PV_SUCCESS) return status;
     }
 
     while (TRUE)
@@ -880,7 +891,8 @@
 
     if (stream->searched_frame_boundary == 0)
     {
-        PVLocateM4VFrameBoundary(stream);
+        status = PVLocateM4VFrameBoundary(stream);
+        if (status != PV_SUCCESS) return status;
     }
 
     while (TRUE)
@@ -956,7 +968,8 @@
 
     if (stream->searched_frame_boundary == 0)
     {
-        PVLocateH263FrameBoundary(stream);
+        status = PVLocateH263FrameBoundary(stream);
+        if (status != PV_SUCCESS) return status;
     }
 
     while (TRUE)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
index d52fa87..0cf903d 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
@@ -156,8 +156,8 @@
 
 
     /* for error concealment & soft-decoding */
-    void PVLocateM4VFrameBoundary(BitstreamDecVideo *stream);
-    void PVSearchH263FrameBoundary(BitstreamDecVideo *stream);
+    PV_STATUS PVLocateM4VFrameBoundary(BitstreamDecVideo *stream);
+    PV_STATUS PVSearchH263FrameBoundary(BitstreamDecVideo *stream);
 
     PV_STATUS quickSearchMotionMarker(BitstreamDecVideo *stream);
     PV_STATUS quickSearchDCM(BitstreamDecVideo *stream);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
index a11f55e..7b32498 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -24,7 +24,6 @@
 
 #define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
 
-#ifdef PV_SUPPORT_MAIN_PROFILE
 /* INTRA */
 const static int mpeg_iqmat_def[NCOEFF_BLOCK] =
 {
@@ -50,7 +49,6 @@
     22, 23, 24, 26, 27, 28, 30, 31,
     23, 24, 25, 27, 28, 30, 31, 33
 };
-#endif
 
 /* ======================================================================== */
 /*  Function : CalcNumBits()                                                */
@@ -86,9 +84,7 @@
     BitstreamDecVideo *stream;
     uint32 tmpvar, vol_shape;
     uint32 startCode;
-#ifdef PV_SUPPORT_MAIN_PROFILE
     int *qmat, i, j;
-#endif
     int version_id = 1;
 #ifdef PV_TOLERATE_VOL_ERRORS
     uint32 profile = 0x01;
@@ -317,7 +313,8 @@
         }
         else
         {
-            if (tmpvar != 0x01) return PV_FAIL;
+            // Simple and advanced simple (for quant-type 1)
+            if (tmpvar != 0x01 && tmpvar != 0x11) return PV_FAIL;
         }
 
         /* version id specified? */
@@ -486,7 +483,6 @@
         currVol->quantType = BitstreamRead1Bits(stream);
         if (currVol->quantType)
         {
-#ifdef PV_SUPPORT_MAIN_PROFILE
             /* load quantization matrices.   5/22/2000 */
             /* load_intra_quant_mat (1 bit) */
             qmat = currVol->iqmat;
@@ -501,6 +497,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
@@ -524,6 +527,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
@@ -531,9 +541,6 @@
             {
                 oscl_memcpy(qmat, mpeg_nqmat_def, 64*sizeof(int));
             }
-#else
-            return PV_FAIL;
-#endif
         }
 
         if (version_id != 1)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
index 655491a..9c753e6 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "Mpeg4H263DecoderTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs: [
         "Mpeg4H263DecoderTest.cpp",
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml b/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml
index 47e10ca..f572b0c 100755
--- a/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="Mpeg4H263DecoderTest->/data/local/tmp/Mpeg4H263DecoderTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.1.zip?unzip=true"
             value="/data/local/tmp/Mpeg4H263DecoderTestRes/" />
     </target_preparer>
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
index 967c1ea..53d66ea 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
@@ -404,6 +404,9 @@
                           make_tuple("swirl_352x288_h263.h263", "swirl_352x288_h263.info", false),
                           make_tuple("bbb_352x288_h263.h263", "bbb_352x288_h263.info", false),
                           make_tuple("bbb_352x288_mpeg4.m4v", "bbb_352x288_mpeg4.info", true),
+                          make_tuple("qtype0_mpeg4.m4v", "qtype0_mpeg4.info", true),
+                          make_tuple("qtype1_mpeg4.m4v", "qtype1_mpeg4.info", true),
+                          make_tuple("qtype1_qmatrix_mpeg4.m4v", "qtype1_qmatrix_mpeg4.info", true),
                           make_tuple("swirl_128x128_mpeg4.m4v", "swirl_128x128_mpeg4.info", true),
                           make_tuple("swirl_130x132_mpeg4.m4v", "swirl_130x132_mpeg4.info", true),
                           make_tuple("swirl_132x130_mpeg4.m4v", "swirl_132x130_mpeg4.info", true),
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/README.md b/media/libstagefright/codecs/m4v_h263/dec/test/README.md
index 7e4aea1..38ac567 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/README.md
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/README.md
@@ -22,7 +22,8 @@
 adb push ${OUT}/data/nativetest/Mpeg4H263DecoderTest/Mpeg4H263DecoderTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder.zip). Download, unzip and push these files into device for testing.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.1.zip).
+Download, unzip and push these files into device for testing.
 
 ```
 adb push Mpeg4H263Decoder /data/local/tmp/
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/test/Android.bp
index b9a8117..d2982da 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/test/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/test/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "Mpeg4H263EncoderTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs : [ "Mpeg4H263EncoderTest.cpp" ],
 
diff --git a/media/libstagefright/codecs/mp3dec/TEST_MAPPING b/media/libstagefright/codecs/mp3dec/TEST_MAPPING
new file mode 100644
index 0000000..b237d65
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/TEST_MAPPING
@@ -0,0 +1,7 @@
+// mappings for frameworks/av/media/libstagefright/codecs/mp3dec
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    // { "name": "Mp3DecoderTest"}
+  ]
+}
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
index 1f8018a..c306873 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
@@ -111,6 +111,7 @@
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
 
+__attribute__((no_sanitize("integer")))
 void pvmp3_dct_6(int32 vec[])
 {
 
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
index a5c7f5e..15d2feb 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
@@ -219,6 +219,11 @@
 
     if (info->error_protection)
     {
+        if (!bitsAvailable(&pVars->inputStream, 16))
+        {
+            return SIDE_INFO_ERROR;
+        }
+
         /*
          *  Get crc content
          */
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
index d644207..1a3fca5 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
@@ -73,6 +73,7 @@
 
 #include "pvmp3_get_side_info.h"
 #include "pvmp3_crc.h"
+#include "pvmp3_getbits.h"
 
 
 /*----------------------------------------------------------------------------
@@ -125,12 +126,22 @@
     {
         if (stereo == 1)
         {
+            if (!bitsAvailable(inputStream, 14))
+            {
+                return SIDE_INFO_ERROR;
+            }
+
             tmp = getbits_crc(inputStream, 14, crc, info->error_protection);
             si->main_data_begin = (tmp << 18) >> 23;    /* 9 */
             si->private_bits    = (tmp << 27) >> 27;    /* 5 */
         }
         else
         {
+            if (!bitsAvailable(inputStream, 12))
+            {
+                return SIDE_INFO_ERROR;
+            }
+
             tmp = getbits_crc(inputStream, 12, crc, info->error_protection);
             si->main_data_begin = (tmp << 20) >> 23;    /* 9 */
             si->private_bits    = (tmp << 29) >> 29;    /* 3 */
@@ -139,6 +150,11 @@
 
         for (ch = 0; ch < stereo; ch++)
         {
+            if (!bitsAvailable(inputStream, 4))
+            {
+                return SIDE_INFO_ERROR;
+            }
+
             tmp = getbits_crc(inputStream, 4, crc, info->error_protection);
             si->ch[ch].scfsi[0] = (tmp << 28) >> 31;    /* 1 */
             si->ch[ch].scfsi[1] = (tmp << 29) >> 31;    /* 1 */
@@ -150,6 +166,11 @@
         {
             for (ch = 0; ch < stereo; ch++)
             {
+                if (!bitsAvailable(inputStream, 34))
+                {
+                    return SIDE_INFO_ERROR;
+                }
+
                 si->ch[ch].gran[gr].part2_3_length    = getbits_crc(inputStream, 12, crc, info->error_protection);
                 tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
 
@@ -160,6 +181,11 @@
 
                 if (si->ch[ch].gran[gr].window_switching_flag)
                 {
+                    if (!bitsAvailable(inputStream, 22))
+                    {
+                        return SIDE_INFO_ERROR;
+                    }
+
                     tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
 
                     si->ch[ch].gran[gr].block_type       = (tmp << 10) >> 30;   /* 2 */;
@@ -192,6 +218,11 @@
                 }
                 else
                 {
+                    if (!bitsAvailable(inputStream, 22))
+                    {
+                        return SIDE_INFO_ERROR;
+                    }
+
                     tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
 
                     si->ch[ch].gran[gr].table_select[0] = (tmp << 10) >> 27;   /* 5 */;
@@ -204,6 +235,11 @@
                     si->ch[ch].gran[gr].block_type      = 0;
                 }
 
+                if (!bitsAvailable(inputStream, 3))
+                {
+                    return SIDE_INFO_ERROR;
+                }
+
                 tmp = getbits_crc(inputStream, 3, crc, info->error_protection);
                 si->ch[ch].gran[gr].preflag            = (tmp << 29) >> 31;    /* 1 */
                 si->ch[ch].gran[gr].scalefac_scale     = (tmp << 30) >> 31;    /* 1 */
@@ -213,11 +249,21 @@
     }
     else /* Layer 3 LSF */
     {
+        if (!bitsAvailable(inputStream, 8 + stereo))
+        {
+            return SIDE_INFO_ERROR;
+        }
+
         si->main_data_begin = getbits_crc(inputStream,      8, crc, info->error_protection);
         si->private_bits    = getbits_crc(inputStream, stereo, crc, info->error_protection);
 
         for (ch = 0; ch < stereo; ch++)
         {
+            if (!bitsAvailable(inputStream, 39))
+            {
+                return SIDE_INFO_ERROR;
+            }
+
             tmp = getbits_crc(inputStream, 21, crc, info->error_protection);
             si->ch[ch].gran[0].part2_3_length    = (tmp << 11) >> 20;  /* 12 */
             si->ch[ch].gran[0].big_values        = (tmp << 23) >> 23;  /*  9 */
@@ -230,6 +276,11 @@
             if (si->ch[ch].gran[0].window_switching_flag)
             {
 
+                if (!bitsAvailable(inputStream, 22))
+                {
+                    return SIDE_INFO_ERROR;
+                }
+
                 tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
 
                 si->ch[ch].gran[0].block_type       = (tmp << 10) >> 30;   /* 2 */;
@@ -262,6 +313,11 @@
             }
             else
             {
+                if (!bitsAvailable(inputStream, 22))
+                {
+                    return SIDE_INFO_ERROR;
+                }
+
                 tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
 
                 si->ch[ch].gran[0].table_select[0] = (tmp << 10) >> 27;   /* 5 */;
@@ -274,6 +330,11 @@
                 si->ch[ch].gran[0].block_type      = 0;
             }
 
+            if (!bitsAvailable(inputStream, 2))
+            {
+                return SIDE_INFO_ERROR;
+            }
+
             tmp = getbits_crc(inputStream, 2, crc, info->error_protection);
             si->ch[ch].gran[0].scalefac_scale     =  tmp >> 1;  /* 1 */
             si->ch[ch].gran[0].count1table_select =  tmp & 1;  /* 1 */
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
index 8ff7953..4d252ef 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
@@ -113,10 +113,11 @@
 
     uint32    offset;
     uint32    bitIndex;
-    uint8     Elem;         /* Needs to be same type as pInput->pBuffer */
-    uint8     Elem1;
-    uint8     Elem2;
-    uint8     Elem3;
+    uint32    bytesToFetch;
+    uint8     Elem  = 0;         /* Needs to be same type as pInput->pBuffer */
+    uint8     Elem1 = 0;
+    uint8     Elem2 = 0;
+    uint8     Elem3 = 0;
     uint32   returnValue = 0;
 
     if (!neededBits)
@@ -126,10 +127,25 @@
 
     offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
 
-    Elem  = *(ptBitStream->pBuffer + module(offset  , BUFSIZE));
-    Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
-    Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
-    Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE));
+    /* Remove extra high bits by shifting up */
+    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+    bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+    switch (bytesToFetch)
+    {
+    case 4:
+        Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE));
+        [[fallthrough]];
+    case 3:
+        Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+        [[fallthrough]];
+    case 2:
+        Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+        [[fallthrough]];
+    case 1:
+        Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+    }
 
 
     returnValue = (((uint32)(Elem)) << 24) |
@@ -137,9 +153,6 @@
                   (((uint32)(Elem2)) << 8) |
                   ((uint32)(Elem3));
 
-    /* Remove extra high bits by shifting up */
-    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
     /* This line is faster than to mask off the high bits. */
     returnValue <<= bitIndex;
 
@@ -161,22 +174,32 @@
 
     uint32    offset;
     uint32    bitIndex;
-    uint8    Elem;         /* Needs to be same type as pInput->pBuffer */
-    uint8    Elem1;
+    uint32    bytesToFetch;
+    uint8    Elem  = 0;         /* Needs to be same type as pInput->pBuffer */
+    uint8    Elem1 = 0;
     uint16   returnValue;
 
     offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
 
-    Elem  = *(ptBitStream->pBuffer + module(offset  , BUFSIZE));
-    Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+    /* Remove extra high bits by shifting up */
+    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+    bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+    if (bytesToFetch > 1)
+    {
+        Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+        Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+    }
+    else if (bytesToFetch > 0)
+    {
+        Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+    }
 
 
     returnValue = (((uint16)(Elem)) << 8) |
                   ((uint16)(Elem1));
 
-    /* Remove extra high bits by shifting up */
-    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
     ptBitStream->usedBits += neededBits;
     /* This line is faster than to mask off the high bits. */
     returnValue = (returnValue << (bitIndex));
@@ -197,25 +220,40 @@
 
     uint32    offset;
     uint32    bitIndex;
-    uint8     Elem;         /* Needs to be same type as pInput->pBuffer */
-    uint8     Elem1;
-    uint8     Elem2;
+    uint32    bytesToFetch;
+    uint8     Elem  = 0;         /* Needs to be same type as pInput->pBuffer */
+    uint8     Elem1 = 0;
+    uint8     Elem2 = 0;
     uint32   returnValue;
 
     offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
 
-    Elem  = *(ptBitStream->pBuffer + module(offset  , BUFSIZE));
-    Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
-    Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+    /* Remove extra high bits by shifting up */
+    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+    bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+    if (bytesToFetch > 2)
+    {
+        Elem  = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+        Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+        Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+    }
+    else if (bytesToFetch > 1)
+    {
+        Elem  = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+        Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+    }
+    else if (bytesToFetch > 0)
+    {
+        Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+    }
 
 
     returnValue = (((uint32)(Elem)) << 16) |
                   (((uint32)(Elem1)) << 8) |
                   ((uint32)(Elem2));
 
-    /* Remove extra high bits by shifting up */
-    bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
     ptBitStream->usedBits += neededBits;
     /* This line is faster than to mask off the high bits. */
     returnValue = 0xFFFFFF & (returnValue << (bitIndex));
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
index b058b00..b04fe6d 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
@@ -104,6 +104,11 @@
 ; Function Prototype declaration
 ----------------------------------------------------------------------------*/
 
+static inline bool bitsAvailable(tmp3Bits *inputStream, uint32 neededBits)
+{
+    return (inputStream->inputBufferCurrentLength << 3) >= (neededBits + inputStream->usedBits);
+}
+
 /*----------------------------------------------------------------------------
 ; END
 ----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
index 8d80e8f..1ba080d 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
@@ -118,7 +118,7 @@
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
 
-
+__attribute__((no_sanitize("integer")))
 void pvmp3_mdct_6(int32 vec[], int32 *history)
 {
     int32 i;
diff --git a/media/libstagefright/codecs/mp3dec/test/Android.bp b/media/libstagefright/codecs/mp3dec/test/Android.bp
index 0ff8b12..6b92ae9 100644
--- a/media/libstagefright/codecs/mp3dec/test/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/test/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "Mp3DecoderTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs: [
         "mp3reader.cpp",
diff --git a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
index 7ff9732..233f9bb 100644
--- a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
+++ b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="Mp3DecoderTest->/data/local/tmp/Mp3DecoderTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.1.zip?unzip=true"
             value="/data/local/tmp/Mp3DecoderTestRes/" />
     </target_preparer>
 
diff --git a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
index 99553ec..0784c0c 100644
--- a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
+++ b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
@@ -185,6 +185,7 @@
 INSTANTIATE_TEST_SUITE_P(Mp3DecoderTestAll, Mp3DecoderTest,
                          ::testing::Values(("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3"),
                                            ("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3"),
+                                           ("bug_136053885.mp3"),
                                            ("bbb_mp3_stereo_192kbps_48000hz.mp3")));
 
 int main(int argc, char **argv) {
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 6571162..dd2eed3 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -295,12 +295,12 @@
             <Feature name="bitrate-modes" value="VBR,CBR" />
         </MediaCodec>
         <MediaCodec name="c2.android.hevc.encoder" type="video/hevc" variant="!slow-cpu">
-            <!-- profiles and levels:  ProfileMain : MainTierLevel3 -->
-            <Limit name="size" min="2x2" max="960x544" />
+            <!-- profiles and levels:  ProfileMain : MainTierLevel51 -->
+            <Limit name="size" min="2x2" max="512x512" />
             <Limit name="alignment" value="2x2" />
             <Limit name="block-size" value="8x8" />
-            <Limit name="block-count" range="1-8160" /> <!-- max 960x544 -->
-            <Limit name="blocks-per-second" range="1-244880" />
+            <Limit name="block-count" range="1-4096" /> <!-- max 512x512 -->
+            <Limit name="blocks-per-second" range="1-122880" />
             <Limit name="frame-rate" range="1-120" />
             <Limit name="bitrate" range="1-10000000" />
             <Limit name="complexity" range="0-10"  default="0" />
diff --git a/media/libstagefright/foundation/TEST_MAPPING b/media/libstagefright/foundation/TEST_MAPPING
index 3301c4b..80ad9fb 100644
--- a/media/libstagefright/foundation/TEST_MAPPING
+++ b/media/libstagefright/foundation/TEST_MAPPING
@@ -1,5 +1,9 @@
 {
   "presubmit": [
-    { "name": "sf_foundation_test" }
+    // TODO(b/148094059): unit tests not allowed to download content
+    //{ "name": "OpusHeaderTest" },
+
+    { "name": "sf_foundation_test" },
+    { "name": "MetaDataBaseUnitTest"}
   ]
 }
diff --git a/media/libstagefright/id3/TEST_MAPPING b/media/libstagefright/id3/TEST_MAPPING
new file mode 100644
index 0000000..e4454c1
--- /dev/null
+++ b/media/libstagefright/id3/TEST_MAPPING
@@ -0,0 +1,20 @@
+// frameworks/av/media/libstagefright/id3
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    //{ "name": "ID3Test" },
+
+    // this doesn't seem to run any tests.
+    // but: cts-tradefed run -m CtsMediaTestCases -t android.media.cts.MediaMetadataRetrieverTest
+    // does run he 32 and 64 bit tests, but not the instant tests
+    // but all I know is that with 'atest', it's not running
+    {
+      "name": "CtsMediaTestCases",
+      "options": [
+          {
+            "include-filter": "android.media.cts.MediaMetadataRetrieverTest"
+          }
+      ]
+    }
+  ]
+}
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 62e3a4b..27a94fd 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -60,21 +60,23 @@
 
     mIsAudio = false;
     mIsVideo = false;
+    const char *mime;
 
-    if (meta == NULL) {
+    // Do not use meta if no mime.
+    if (meta == NULL || !meta->findCString(kKeyMIMEType, &mime)) {
         return;
     }
 
     mFormat = meta;
-    const char *mime;
-    CHECK(meta->findCString(kKeyMIMEType, &mime));
 
     if (!strncasecmp("audio/", mime, 6)) {
         mIsAudio = true;
-    } else  if (!strncasecmp("video/", mime, 6)) {
+    } else if (!strncasecmp("video/", mime, 6)) {
         mIsVideo = true;
+    } else if (!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12)) {
+        return;
     } else {
-        CHECK(!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12));
+        ALOGW("Unsupported mime type: %s", mime);
     }
 }
 
diff --git a/media/libstagefright/mpeg2ts/TEST_MAPPING b/media/libstagefright/mpeg2ts/TEST_MAPPING
new file mode 100644
index 0000000..b25d732
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/TEST_MAPPING
@@ -0,0 +1,7 @@
+// frameworks/av/media/libstagefright/mpeg2ts
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    //{ "name": "Mpeg2tsUnitTest" }
+  ]
+}
diff --git a/media/libstagefright/mpeg2ts/test/Android.bp b/media/libstagefright/mpeg2ts/test/Android.bp
new file mode 100644
index 0000000..bacf23b
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Android.bp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+    name: "Mpeg2tsUnitTest",
+    gtest: true,
+    test_suites: ["device-tests"],
+
+    srcs: [
+        "Mpeg2tsUnitTest.cpp",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.token@1.0-utils",
+        "android.hidl.allocator@1.0",
+        "libcrypto",
+        "libhidlbase",
+        "libhidlmemory",
+        "liblog",
+        "libmedia",
+        "libbinder",
+        "libbinder_ndk",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libdatasource",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libstagefright_metadatautils",
+        "libstagefright_mpeg2support",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/",
+        "frameworks/av/media/libstagefright/",
+    ],
+
+    header_libs: [
+        "libmedia_headers",
+        "libaudioclient_headers",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/mpeg2ts/test/AndroidTest.xml b/media/libstagefright/mpeg2ts/test/AndroidTest.xml
new file mode 100644
index 0000000..ac1294d
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for Mpeg2ts unit tests">
+    <option name="test-suite-tag" value="Mpeg2tsUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="Mpeg2tsUnitTest->/data/local/tmp/Mpeg2tsUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.zip?unzip=true"
+            value="/data/local/tmp/Mpeg2tsUnitTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="Mpeg2tsUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/Mpeg2tsUnitTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
new file mode 100644
index 0000000..79c233b
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Mpeg2tsUnitTest"
+
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/stat.h>
+
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include "mpeg2ts/ATSParser.h"
+#include "mpeg2ts/AnotherPacketSource.h"
+
+#include "Mpeg2tsUnitTestEnvironment.h"
+
+constexpr size_t kTSPacketSize = 188;
+constexpr uint16_t kPIDMask = 0x1FFF;
+// Max value of PID which is also used for Null packets
+constexpr uint16_t kPIDMaxValue = 8191;
+constexpr uint8_t kTSSyncByte = 0x47;
+constexpr uint8_t kVideoPresent = 0x01;
+constexpr uint8_t kAudioPresent = 0x02;
+constexpr uint8_t kMetaDataPresent = 0x04;
+
+static Mpeg2tsUnitTestEnvironment *gEnv = nullptr;
+
+using namespace android;
+
+class Mpeg2tsUnitTest
+    : public ::testing ::TestWithParam<
+              tuple</*fileName*/ string, /*sourceType*/ char, /*numSource*/ uint16_t>> {
+  public:
+    Mpeg2tsUnitTest()
+        : mInputBuffer(nullptr), mSource(nullptr), mFpInput(nullptr), mParser(nullptr) {}
+
+    ~Mpeg2tsUnitTest() {
+        if (mInputBuffer) free(mInputBuffer);
+        if (mFpInput) fclose(mFpInput);
+        mSource.clear();
+    }
+
+    void SetUp() override {
+        mOffset = 0;
+        mNumDataSource = 0;
+        tuple<string, char, uint16_t> params = GetParam();
+        char sourceType = get<1>(params);
+        /* mSourceType = 0b x x x x x M A V
+                                     /  |  \
+                            metaData  audio  video */
+        mMediaType = (sourceType & 0x07);
+        mNumDataSource = get<2>(params);
+        string inputFile = gEnv->getRes() + get<0>(params);
+        mFpInput = fopen(inputFile.c_str(), "rb");
+        ASSERT_NE(mFpInput, nullptr) << "Failed to open file: " << inputFile;
+
+        struct stat buf;
+        int8_t err = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+        long fileSize = buf.st_size;
+        mTotalPackets = fileSize / kTSPacketSize;
+        int32_t fd = fileno(mFpInput);
+        ASSERT_GE(fd, 0) << "Failed to get the integer file descriptor";
+
+        mSource = new FileSource(dup(fd), 0, buf.st_size);
+        ASSERT_NE(mSource, nullptr) << "Failed to get the data source!";
+
+        mParser = new ATSParser();
+        ASSERT_NE(mParser, nullptr) << "Unable to create ATS parser!";
+        mInputBuffer = (uint8_t *)malloc(kTSPacketSize);
+        ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate memory for TS packet!";
+    }
+
+    uint64_t mOffset;
+    uint64_t mTotalPackets;
+    uint16_t mNumDataSource;
+
+    int8_t mMediaType;
+
+    uint8_t *mInputBuffer;
+    string mInputFile;
+    sp<DataSource> mSource;
+    FILE *mFpInput;
+    ATSParser *mParser;
+};
+
+TEST_P(Mpeg2tsUnitTest, MediaInfoTest) {
+    bool videoFound = false;
+    bool audioFound = false;
+    bool metaDataFound = false;
+    bool syncPointPresent = false;
+
+    int16_t totalDataSource = 0;
+    int32_t val32 = 0;
+    uint8_t numDataSource = 0;
+    uint8_t packet[kTSPacketSize];
+    ssize_t numBytesRead = -1;
+
+    ATSParser::SyncEvent event(mOffset);
+    static const ATSParser::SourceType mediaType[] = {ATSParser::VIDEO, ATSParser::AUDIO,
+                                                      ATSParser::META, ATSParser::NUM_SOURCE_TYPES};
+    const uint32_t nMediaTypes = sizeof(mediaType) / sizeof(mediaType[0]);
+
+    while ((numBytesRead = mSource->readAt(mOffset, packet, kTSPacketSize)) == kTSPacketSize) {
+        ASSERT_TRUE(packet[0] == kTSSyncByte) << "Sync byte error!";
+
+        // pid is 13 bits
+        uint16_t pid = (packet[1] + (packet[2] << 8)) & kPIDMask;
+        ASSERT_TRUE(pid <= kPIDMaxValue) << "Invalid PID: " << pid;
+
+        status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
+        ASSERT_EQ(err, (status_t)OK) << "Unable to feed TS packet!";
+
+        mOffset += numBytesRead;
+        for (int i = 0; i < nMediaTypes; i++) {
+            if (mParser->hasSource(mediaType[i])) {
+                switch (mediaType[i]) {
+                    case ATSParser::VIDEO:
+                        videoFound = true;
+                        break;
+                    case ATSParser::AUDIO:
+                        audioFound = true;
+                        break;
+                    case ATSParser::META:
+                        metaDataFound = true;
+                        break;
+                    case ATSParser::NUM_SOURCE_TYPES:
+                        numDataSource = 3;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        if (videoFound && audioFound && metaDataFound && (numDataSource == 3)) break;
+    }
+
+    for (int i = 0; i < nMediaTypes; i++) {
+        ATSParser::SourceType currentMediaType = mediaType[i];
+        if (mParser->hasSource(currentMediaType)) {
+            if (event.hasReturnedData()) {
+                syncPointPresent = true;
+                sp<AnotherPacketSource> syncPacketSource = event.getMediaSource();
+                ASSERT_NE(syncPacketSource, nullptr)
+                        << "Cannot get sync source for media type: " << currentMediaType;
+
+                status_t err = syncPacketSource->start();
+                ASSERT_EQ(err, (status_t)OK) << "Error returned while starting!";
+
+                sp<MetaData> format = syncPacketSource->getFormat();
+                ASSERT_NE(format, nullptr) << "Unable to get the format of the source packet!";
+
+                MediaBufferBase *buf;
+                syncPacketSource->read(&buf, nullptr);
+                ASSERT_NE(buf, nullptr) << "Failed to read sync packet source data";
+
+                MetaDataBase &inMeta = buf->meta_data();
+                bool status = inMeta.findInt32(kKeyIsSyncFrame, &val32);
+                ASSERT_EQ(status, true) << "Sync frame key is not set";
+
+                status = inMeta.findInt32(kKeyCryptoMode, &val32);
+                ASSERT_EQ(status, false) << "Invalid packet, found scrambled packets!";
+
+                err = syncPacketSource->stop();
+                ASSERT_EQ(err, (status_t)OK) << "Error returned while stopping!";
+            }
+            sp<AnotherPacketSource> packetSource = mParser->getSource(currentMediaType);
+            ASSERT_NE(packetSource, nullptr)
+                    << "Cannot get source for media type: " << currentMediaType;
+
+            status_t err = packetSource->start();
+            ASSERT_EQ(err, (status_t)OK) << "Error returned while starting!";
+            sp<MetaData> format = packetSource->getFormat();
+            ASSERT_NE(format, nullptr) << "Unable to get the format of the packet!";
+
+            err = packetSource->stop();
+            ASSERT_EQ(err, (status_t)OK) << "Error returned while stopping!";
+        }
+    }
+
+    ASSERT_EQ(videoFound, bool(mMediaType & kVideoPresent)) << "No Video packets found!";
+    ASSERT_EQ(audioFound, bool(mMediaType & kAudioPresent)) << "No Audio packets found!";
+    ASSERT_EQ(metaDataFound, bool(mMediaType & kMetaDataPresent)) << "No meta data found!";
+
+    if (videoFound || audioFound) {
+        ASSERT_TRUE(syncPointPresent) << "No sync points found for audio/video";
+    }
+
+    if (videoFound) totalDataSource += 1;
+    if (audioFound) totalDataSource += 1;
+    if (metaDataFound) totalDataSource += 1;
+
+    ASSERT_TRUE(totalDataSource == mNumDataSource)
+            << "Expected " << mNumDataSource << " data sources, found " << totalDataSource;
+    if (numDataSource == 3) {
+        ASSERT_EQ(numDataSource, mNumDataSource)
+                << "Expected " << mNumDataSource << " data sources, found " << totalDataSource;
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        infoTest, Mpeg2tsUnitTest,
+        ::testing::Values(make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", 0x01, 1),
+                          make_tuple("segment000001.ts", 0x03, 2),
+                          make_tuple("bbb_44100hz_2ch_128kbps_mp3_5mins.ts", 0x02, 1)));
+
+int32_t main(int argc, char **argv) {
+    gEnv = new Mpeg2tsUnitTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    uint8_t status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Mpeg2tsUnit Test Result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
new file mode 100644
index 0000000..9e41db7
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
+#define __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class Mpeg2tsUnitTestEnvironment : public::testing::Environment {
+  public:
+    Mpeg2tsUnitTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int Mpeg2tsUnitTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __MPEG2TS_UNIT_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/mpeg2ts/test/README.md b/media/libstagefright/mpeg2ts/test/README.md
new file mode 100644
index 0000000..237ce72
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/test/README.md
@@ -0,0 +1,38 @@
+## Media Testing ##
+---
+#### Mpeg2TS Unit Test :
+The Mpeg2TS Unit Test Suite validates the functionality of the libraries present in Mpeg2TS.
+
+Run the following steps to build the test suite:
+```
+mmm frameworks/av/media/libstagefright/mpeg2ts/test/
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+
+adb push ${OUT}/data/nativetest64/Mpeg2tsUnitTest/Mpeg2tsUnitTest /data/local/tmp/
+
+To test 32-bit binary push binaries from nativetest.
+
+adb push ${OUT}/data/nativetest/Mpeg2tsUnitTest/Mpeg2tsUnitTest /data/local/tmp/
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.zip ).
+Download, unzip and push these files into device for testing.
+
+```
+adb push Mpeg2tsUnitTestRes/. /data/local/tmp/
+```
+
+usage: Mpeg2tsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/Mpeg2tsUnitTest -P /data/local/tmp/Mpeg2tsUnitTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest Mpeg2tsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/tests/extractorFactory/Android.bp b/media/libstagefright/tests/extractorFactory/Android.bp
index e3e61d7..26ec507 100644
--- a/media/libstagefright/tests/extractorFactory/Android.bp
+++ b/media/libstagefright/tests/extractorFactory/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "ExtractorFactoryTest",
     gtest: true,
+    test_suites: ["device-tests"],
 
     srcs: [
         "ExtractorFactoryTest.cpp",
diff --git a/media/libstagefright/timedtext/TEST_MAPPING b/media/libstagefright/timedtext/TEST_MAPPING
new file mode 100644
index 0000000..185f824
--- /dev/null
+++ b/media/libstagefright/timedtext/TEST_MAPPING
@@ -0,0 +1,7 @@
+// mappings for frameworks/av/media/libstagefright/timedtext
+{
+  "presubmit": [
+    // TODO(b/148094059): unit tests not allowed to download content
+    //{ "name": "TimedTextUnitTest" }
+  ]
+}
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 43989bb..439b063 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -172,6 +172,7 @@
 
 cc_test {
     name: "AImageReaderWindowHandleTest",
+    test_suites: ["device-tests"],
     srcs: ["tests/AImageReaderWindowHandleTest.cpp"],
     shared_libs: [
         "libbinder",
diff --git a/media/ndk/TEST_MAPPING b/media/ndk/TEST_MAPPING
new file mode 100644
index 0000000..1a81538
--- /dev/null
+++ b/media/ndk/TEST_MAPPING
@@ -0,0 +1,6 @@
+// mappings for frameworks/av/media/ndk
+{
+  "presubmit": [
+    { "name": "AImageReaderWindowHandleTest" }
+  ]
+}
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index f033d5c..91590e1 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -131,6 +131,7 @@
         "statsd_codec.cpp",
         "statsd_drm.cpp",
         "statsd_extractor.cpp",
+        "statsd_mediaparser.cpp",
         "statsd_nuplayer.cpp",
         "statsd_recorder.cpp",
         "StringUtils.cpp"
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 48e766e..bf6e428 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -468,6 +468,7 @@
                                      "codec",
                                      "extractor",
                                      "mediadrm",
+                                     "mediaparser",
                                      "nuplayer",
                                  }) {
         if (key == allowedKey) {
diff --git a/services/mediametrics/iface_statsd.cpp b/services/mediametrics/iface_statsd.cpp
index 6e51f72..16204de 100644
--- a/services/mediametrics/iface_statsd.cpp
+++ b/services/mediametrics/iface_statsd.cpp
@@ -64,6 +64,7 @@
     { "drmmanager", statsd_drmmanager },
     { "extractor", statsd_extractor },
     { "mediadrm", statsd_mediadrm },
+    { "mediaparser", statsd_mediaparser },
     { "nuplayer", statsd_nuplayer },
     { "nuplayer2", statsd_nuplayer },
     { "recorder", statsd_recorder },
diff --git a/services/mediametrics/iface_statsd.h b/services/mediametrics/iface_statsd.h
index 19505a4..9b49556 100644
--- a/services/mediametrics/iface_statsd.h
+++ b/services/mediametrics/iface_statsd.h
@@ -25,6 +25,7 @@
 extern bool statsd_audiotrack(const mediametrics::Item *);
 extern bool statsd_codec(const mediametrics::Item *);
 extern bool statsd_extractor(const mediametrics::Item *);
+extern bool statsd_mediaparser(const mediametrics::Item *);
 extern bool statsd_nuplayer(const mediametrics::Item *);
 extern bool statsd_recorder(const mediametrics::Item *);
 
diff --git a/services/mediametrics/statsd_audiopolicy.cpp b/services/mediametrics/statsd_audiopolicy.cpp
index 393c6ae..6ef2f2c 100644
--- a/services/mediametrics/statsd_audiopolicy.cpp
+++ b/services/mediametrics/statsd_audiopolicy.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiorecord.cpp b/services/mediametrics/statsd_audiorecord.cpp
index 43feda1..76f4b59 100644
--- a/services/mediametrics/statsd_audiorecord.cpp
+++ b/services/mediametrics/statsd_audiorecord.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiothread.cpp b/services/mediametrics/statsd_audiothread.cpp
index e867f5b..2ad2562 100644
--- a/services/mediametrics/statsd_audiothread.cpp
+++ b/services/mediametrics/statsd_audiothread.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiotrack.cpp b/services/mediametrics/statsd_audiotrack.cpp
index ee5b9b2..6b08a78 100644
--- a/services/mediametrics/statsd_audiotrack.cpp
+++ b/services/mediametrics/statsd_audiotrack.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index ec9354f..d502b30 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -33,7 +33,7 @@
 
 #include "cleaner.h"
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_extractor.cpp b/services/mediametrics/statsd_extractor.cpp
index 3d5739f..16814d9 100644
--- a/services/mediametrics/statsd_extractor.cpp
+++ b/services/mediametrics/statsd_extractor.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_mediaparser.cpp b/services/mediametrics/statsd_mediaparser.cpp
new file mode 100644
index 0000000..262b2ae
--- /dev/null
+++ b/services/mediametrics/statsd_mediaparser.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "statsd_mediaparser"
+#include <utils/Log.h>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <statslog.h>
+
+#include "MediaMetricsService.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
+#include "iface_statsd.h"
+
+namespace android {
+
+bool statsd_mediaparser(const mediametrics::Item *item)
+{
+    if (item == nullptr) {
+        return false;
+    }
+
+    // statsd wrapper data.
+    const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
+    std::string pkgName = item->getPkgName();
+    int64_t pkgVersionCode = item->getPkgVersionCode();
+
+    std::string parserName;
+    item->getString("android.media.mediaparser.parserName", &parserName);
+
+    int32_t createdByName = -1;
+    item->getInt32("android.media.mediaparser.createdByName", &createdByName);
+
+    std::string parserPool;
+    item->getString("android.media.mediaparser.parserPool", &parserPool);
+
+    std::string lastException;
+    item->getString("android.media.mediaparser.lastException", &lastException);
+
+    int64_t resourceByteCount = -1;
+    item->getInt64("android.media.mediaparser.resourceByteCount", &resourceByteCount);
+
+    int64_t durationMillis = -1;
+    item->getInt64("android.media.mediaparser.durationMillis", &durationMillis);
+
+    std::string trackMimeTypes;
+    item->getString("android.media.mediaparser.trackMimeTypes", &trackMimeTypes);
+
+    std::string trackCodecs;
+    item->getString("android.media.mediaparser.trackCodecs", &trackCodecs);
+
+    std::string alteredParameters;
+    item->getString("android.media.mediaparser.alteredParameters", &alteredParameters);
+
+    int32_t videoWidth = -1;
+    item->getInt32("android.media.mediaparser.videoWidth", &videoWidth);
+
+    int32_t videoHeight = -1;
+    item->getInt32("android.media.mediaparser.videoHeight", &videoHeight);
+
+    if (enabled_statsd) {
+        (void) android::util::stats_write(android::util::MEDIAMETRICS_MEDIAPARSER_REPORTED,
+                                   timestamp,
+                                   pkgName.c_str(),
+                                   pkgVersionCode,
+                                   parserName.c_str(),
+                                   createdByName,
+                                   parserPool.c_str(),
+                                   lastException.c_str(),
+                                   resourceByteCount,
+                                   durationMillis,
+                                   trackMimeTypes.c_str(),
+                                   trackCodecs.c_str(),
+                                   alteredParameters.c_str(),
+                                   videoWidth,
+                                   videoHeight);
+    } else {
+        ALOGV("NOT sending MediaParser media metrics.");
+    }
+
+    return true;
+}
+
+} // namespace android
diff --git a/services/mediametrics/statsd_nuplayer.cpp b/services/mediametrics/statsd_nuplayer.cpp
index 488bdcb..a8d0f55 100644
--- a/services/mediametrics/statsd_nuplayer.cpp
+++ b/services/mediametrics/statsd_nuplayer.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_recorder.cpp b/services/mediametrics/statsd_recorder.cpp
index 6d5fca0..2e5ada4 100644
--- a/services/mediametrics/statsd_recorder.cpp
+++ b/services/mediametrics/statsd_recorder.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {