Merge "AImageReader: avoid edit during traversing"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 86e9040..34a9a40 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -224,11 +224,15 @@
         player->setSource(rawSource);
         rawSource.clear();
 
-        player->start(true /* sourceAlreadyStarted */);
+        err = player->start(true /* sourceAlreadyStarted */);
 
-        status_t finalStatus;
-        while (!player->reachedEOS(&finalStatus)) {
-            usleep(100000ll);
+        if (err == OK) {
+            status_t finalStatus;
+            while (!player->reachedEOS(&finalStatus)) {
+                usleep(100000ll);
+            }
+        } else {
+            fprintf(stderr, "unable to start playback err=%d (0x%08x)\n", err, err);
         }
 
         delete player;
@@ -651,7 +655,8 @@
         MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
         MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9,
         MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, MEDIA_MIMETYPE_VIDEO_HEVC,
-        MEDIA_MIMETYPE_AUDIO_EAC3, MEDIA_MIMETYPE_AUDIO_AC4
+        MEDIA_MIMETYPE_AUDIO_EAC3, MEDIA_MIMETYPE_AUDIO_AC4,
+        MEDIA_MIMETYPE_VIDEO_AV1
     };
 
     const char *codecType = queryDecoders? "decoder" : "encoder";
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
index 28a78aa..bb9d7ec 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
@@ -29,8 +29,7 @@
     srcs: ["src/FwdLockEngine.cpp"],
 
     shared_libs: [
-        "libicui18n",
-        "libicuuc",
+        "libandroidicu",
         "libutils",
         "liblog",
         "libdl",
diff --git a/media/codec2/components/aom/Android.bp b/media/codec2/components/aom/Android.bp
new file mode 100644
index 0000000..0fabf5c
--- /dev/null
+++ b/media/codec2/components/aom/Android.bp
@@ -0,0 +1,14 @@
+cc_library_shared {
+    name: "libcodec2_soft_av1dec",
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["C2SoftAomDec.cpp"],
+    static_libs: ["libaom"],
+
+    include_dirs: [
+        "external/libaom/",
+    ],
+}
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
new file mode 100644
index 0000000..6be1807
--- /dev/null
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftAomDec"
+#include <log/log.h>
+
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+
+#include "C2SoftAomDec.h"
+
+namespace android {
+
+constexpr char COMPONENT_NAME[] = "c2.android.av1.decoder";
+
+class C2SoftAomDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+  public:
+    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
+        : SimpleInterface<void>::BaseParams(
+              helper, COMPONENT_NAME, C2Component::KIND_DECODER,
+              C2Component::DOMAIN_VIDEO, MEDIA_MIMETYPE_VIDEO_AV1) {
+        noPrivateBuffers();  // TODO: account for our buffers here
+        noInputReferences();
+        noOutputReferences();
+        noInputLatency();
+        noTimeStretch();
+
+        addParameter(DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+                         .withConstValue(new C2ComponentAttributesSetting(
+                             C2Component::ATTRIB_IS_TEMPORAL))
+                         .build());
+
+        addParameter(
+            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+                .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+                .withFields({
+                    C2F(mSize, width).inRange(2, 2048, 2),
+                    C2F(mSize, height).inRange(2, 2048, 2),
+                })
+                .withSetter(SizeSetter)
+                .build());
+
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                .withDefault(new C2StreamProfileLevelInfo::input(0u,
+                        C2Config::PROFILE_AV1_0, C2Config::LEVEL_AV1_2_1))
+                .withFields({
+                    C2F(mProfileLevel, profile).oneOf({
+                            C2Config::PROFILE_AV1_0,
+                            C2Config::PROFILE_AV1_1}),
+                    C2F(mProfileLevel, level).oneOf({
+                            C2Config::LEVEL_AV1_2,
+                            C2Config::LEVEL_AV1_2_1,
+                            C2Config::LEVEL_AV1_2_2,
+                            C2Config::LEVEL_AV1_3,
+                            C2Config::LEVEL_AV1_3_1,
+                            C2Config::LEVEL_AV1_3_2,
+                    })
+                })
+                .withSetter(ProfileLevelSetter, mSize)
+                .build());
+
+        addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+                         .withDefault(new C2StreamMaxPictureSizeTuning::output(
+                             0u, 320, 240))
+                         .withFields({
+                             C2F(mSize, width).inRange(2, 2048, 2),
+                             C2F(mSize, height).inRange(2, 2048, 2),
+                         })
+                         .withSetter(MaxPictureSizeSetter, mSize)
+                         .build());
+
+        addParameter(
+            DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+                .withDefault(
+                    new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
+                .withFields({
+                    C2F(mMaxInputSize, value).any(),
+                })
+                .calculatedAs(MaxInputSizeSetter, mMaxSize)
+                .build());
+
+        C2ChromaOffsetStruct locations[1] = {
+            C2ChromaOffsetStruct::ITU_YUV_420_0()};
+        std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+            C2StreamColorInfo::output::AllocShared(1u, 0u, 8u /* bitDepth */,
+                                                   C2Color::YUV_420);
+        memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+        defaultColorInfo = C2StreamColorInfo::output::AllocShared(
+            {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */,
+            C2Color::YUV_420);
+        helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+        addParameter(DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+                         .withConstValue(defaultColorInfo)
+                         .build());
+
+        addParameter(
+                DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+                .withDefault(new C2StreamColorAspectsTuning::output(
+                        0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+                        C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+                .withFields({
+                    C2F(mDefaultColorAspects, range).inRange(
+                                C2Color::RANGE_UNSPECIFIED,     C2Color::RANGE_OTHER),
+                    C2F(mDefaultColorAspects, primaries).inRange(
+                                C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+                    C2F(mDefaultColorAspects, transfer).inRange(
+                                C2Color::TRANSFER_UNSPECIFIED,  C2Color::TRANSFER_OTHER),
+                    C2F(mDefaultColorAspects, matrix).inRange(
+                                C2Color::MATRIX_UNSPECIFIED,    C2Color::MATRIX_OTHER)
+                })
+                .withSetter(DefaultColorAspectsSetter)
+                .build());
+
+        // TODO: support more formats?
+        addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+                         .withConstValue(new C2StreamPixelFormatInfo::output(
+                             0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+                         .build());
+    }
+
+    static C2R SizeSetter(bool mayBlock,
+                          const C2P<C2StreamPictureSizeInfo::output>& oldMe,
+                          C2P<C2VideoSizeStreamInfo::output>& me) {
+        (void)mayBlock;
+        C2R res = C2R::Ok();
+        if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+            me.set().width = oldMe.v.width;
+        }
+        if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+            res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+            me.set().height = oldMe.v.height;
+        }
+        return res;
+    }
+
+    static C2R MaxPictureSizeSetter(
+        bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output>& me,
+        const C2P<C2StreamPictureSizeInfo::output>& size) {
+        (void)mayBlock;
+        // TODO: get max width/height from the size's field helpers vs.
+        // hardcoding
+        me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
+        me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
+        return C2R::Ok();
+    }
+
+    static C2R MaxInputSizeSetter(
+        bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& me,
+        const C2P<C2StreamMaxPictureSizeTuning::output>& maxSize) {
+        (void)mayBlock;
+        // assume compression ratio of 2
+        me.set().value = (((maxSize.v.width + 63) / 64) *
+                          ((maxSize.v.height + 63) / 64) * 3072);
+        return C2R::Ok();
+    }
+    static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
+        (void)mayBlock;
+        if (me.v.range > C2Color::RANGE_OTHER) {
+            me.set().range = C2Color::RANGE_OTHER;
+        }
+        if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+            me.set().primaries = C2Color::PRIMARIES_OTHER;
+        }
+        if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+            me.set().transfer = C2Color::TRANSFER_OTHER;
+        }
+        if (me.v.matrix > C2Color::MATRIX_OTHER) {
+            me.set().matrix = C2Color::MATRIX_OTHER;
+        }
+        return C2R::Ok();
+    }
+
+    static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
+                                  const C2P<C2StreamPictureSizeInfo::output> &size) {
+        (void)mayBlock;
+        (void)size;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+    std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
+        return mDefaultColorAspects;
+    }
+
+  private:
+    std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+    std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+    std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+    std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+    std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+    std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+};
+
+C2SoftAomDec::C2SoftAomDec(const char* name, c2_node_id_t id,
+                           const std::shared_ptr<IntfImpl>& intfImpl)
+    : SimpleC2Component(
+          std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+      mIntf(intfImpl),
+      mCodecCtx(nullptr){
+
+    GENERATE_FILE_NAMES();
+    CREATE_DUMP_FILE(mInFile);
+    CREATE_DUMP_FILE(mOutFile);
+
+    gettimeofday(&mTimeStart, nullptr);
+    gettimeofday(&mTimeEnd, nullptr);
+}
+
+C2SoftAomDec::~C2SoftAomDec() {
+    onRelease();
+}
+
+c2_status_t C2SoftAomDec::onInit() {
+    status_t err = initDecoder();
+    return err == OK ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftAomDec::onStop() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    return C2_OK;
+}
+
+void C2SoftAomDec::onReset() {
+    (void)onStop();
+    c2_status_t err = onFlush_sm();
+    if (err != C2_OK) {
+        ALOGW("Failed to flush decoder. Try to hard reset decoder.");
+        destroyDecoder();
+        (void)initDecoder();
+    }
+}
+
+void C2SoftAomDec::onRelease() {
+    destroyDecoder();
+}
+
+c2_status_t C2SoftAomDec::onFlush_sm() {
+    if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+        ALOGE("Failed to flush av1 decoder.");
+        return C2_CORRUPTED;
+    }
+
+    aom_codec_iter_t iter = nullptr;
+    while (aom_codec_get_frame(mCodecCtx, &iter)) {
+    }
+
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+
+    return C2_OK;
+}
+
+static int GetCPUCoreCount() {
+    int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    // _SC_NPROC_ONLN must be defined...
+    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+    CHECK(cpuCoreCount >= 1);
+    ALOGV("Number of CPU cores: %d", cpuCoreCount);
+    return cpuCoreCount;
+}
+
+status_t C2SoftAomDec::initDecoder() {
+    mSignalledError = false;
+    mSignalledOutputEos = false;
+    if (!mCodecCtx) {
+        mCodecCtx = new aom_codec_ctx_t;
+    }
+
+    if (!mCodecCtx) {
+        ALOGE("mCodecCtx is null");
+        return NO_MEMORY;
+    }
+
+    aom_codec_dec_cfg_t cfg;
+    memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
+    cfg.threads = GetCPUCoreCount();
+    cfg.allow_lowbitdepth = 1;
+
+    aom_codec_flags_t flags;
+    memset(&flags, 0, sizeof(aom_codec_flags_t));
+
+    aom_codec_err_t err;
+    if ((err = aom_codec_dec_init(mCodecCtx, aom_codec_av1_dx(), &cfg, 0))) {
+        ALOGE("av1 decoder failed to initialize. (%d)", err);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t C2SoftAomDec::destroyDecoder() {
+    if (mCodecCtx) {
+        aom_codec_destroy(mCodecCtx);
+        delete mCodecCtx;
+        mCodecCtx = nullptr;
+    }
+    return OK;
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
+    uint32_t flags = 0;
+    if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+        flags |= C2FrameData::FLAG_END_OF_STREAM;
+        ALOGV("signalling eos");
+    }
+    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+    work->worklets.front()->output.buffers.clear();
+    work->worklets.front()->output.ordinal = work->input.ordinal;
+    work->workletsProcessed = 1u;
+}
+
+void C2SoftAomDec::finishWork(uint64_t index,
+                              const std::unique_ptr<C2Work>& work,
+                              const std::shared_ptr<C2GraphicBlock>& block) {
+    std::shared_ptr<C2Buffer> buffer =
+        createGraphicBuffer(block, C2Rect(mWidth, mHeight));
+    auto fillWork = [buffer, index](const std::unique_ptr<C2Work>& work) {
+        uint32_t flags = 0;
+        if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
+            (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
+            flags |= C2FrameData::FLAG_END_OF_STREAM;
+            ALOGV("signalling eos");
+        }
+        work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+        work->worklets.front()->output.buffers.clear();
+        work->worklets.front()->output.buffers.push_back(buffer);
+        work->worklets.front()->output.ordinal = work->input.ordinal;
+        work->workletsProcessed = 1u;
+    };
+    if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+        fillWork(work);
+    } else {
+        finish(index, fillWork);
+    }
+}
+
+void C2SoftAomDec::process(const std::unique_ptr<C2Work>& work,
+                           const std::shared_ptr<C2BlockPool>& pool) {
+    work->result = C2_OK;
+    work->workletsProcessed = 0u;
+    work->worklets.front()->output.configUpdate.clear();
+    work->worklets.front()->output.flags = work->input.flags;
+    if (mSignalledError || mSignalledOutputEos) {
+        work->result = C2_BAD_VALUE;
+        return;
+    }
+
+    size_t inOffset = 0u;
+    size_t inSize = 0u;
+    C2ReadView rView = mDummyReadView;
+    if (!work->input.buffers.empty()) {
+        rView =
+            work->input.buffers[0]->data().linearBlocks().front().map().get();
+        inSize = rView.capacity();
+        if (inSize && rView.error()) {
+            ALOGE("read view map failed %d", rView.error());
+            work->result = C2_CORRUPTED;
+            return;
+        }
+    }
+
+    bool codecConfig =
+        ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0);
+    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+
+    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
+          inSize, (int)work->input.ordinal.timestamp.peeku(),
+          (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
+
+    if (codecConfig) {
+        fillEmptyWork(work);
+        return;
+    }
+
+    int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
+    if (inSize) {
+        uint8_t* bitstream = const_cast<uint8_t*>(rView.data() + inOffset);
+        int32_t decodeTime = 0;
+        int32_t delay = 0;
+
+        DUMP_TO_FILE(mOutFile, bitstream, inSize);
+        GETTIME(&mTimeStart, nullptr);
+        TIME_DIFF(mTimeEnd, mTimeStart, delay);
+
+        aom_codec_err_t err =
+            aom_codec_decode(mCodecCtx, bitstream, inSize, &frameIndex);
+
+        GETTIME(&mTimeEnd, nullptr);
+        TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+        ALOGV("decodeTime=%4d delay=%4d\n", decodeTime, delay);
+
+        if (err != AOM_CODEC_OK) {
+            ALOGE("av1 decoder failed to decode frame err: %d", err);
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            mSignalledError = true;
+            return;
+        }
+
+    } else {
+        if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+            ALOGE("Failed to flush av1 decoder.");
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            mSignalledError = true;
+            return;
+        }
+    }
+
+    (void)outputBuffer(pool, work);
+
+    if (eos) {
+        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+        mSignalledOutputEos = true;
+    } else if (!inSize) {
+        fillEmptyWork(work);
+    }
+}
+
+static void copyOutputBufferToYV12Frame(uint8_t *dst,
+        const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        uint32_t width, uint32_t height) {
+    size_t dstYStride = align(width, 16);
+    size_t dstUVStride = align(dstYStride / 2, 16);
+    uint8_t* dstStart = dst;
+
+
+    for (size_t i = 0; i < height; ++i) {
+        memcpy(dst, srcY, width);
+        srcY += srcYStride;
+        dst += dstYStride;
+    }
+
+    dst = dstStart + dstYStride * height;
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcV, width / 2);
+        srcV += srcVStride;
+        dst += dstUVStride;
+    }
+
+    dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
+    for (size_t i = 0; i < height / 2; ++i) {
+         memcpy(dst, srcU, width / 2);
+        srcU += srcUStride;
+        dst += dstUVStride;
+    }
+}
+
+static void convertYUV420Planar16ToY410(uint32_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    // Converting two lines at a time, slightly faster
+    for (size_t y = 0; y < height; y += 2) {
+        uint32_t *dstTop = (uint32_t *) dst;
+        uint32_t *dstBot = (uint32_t *) (dst + dstStride);
+        uint16_t *ySrcTop = (uint16_t*) srcY;
+        uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride);
+        uint16_t *uSrc = (uint16_t*) srcU;
+        uint16_t *vSrc = (uint16_t*) srcV;
+
+        uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
+        size_t x = 0;
+        for (; x < width - 3; x += 4) {
+
+            u01 = *((uint32_t*)uSrc); uSrc += 2;
+            v01 = *((uint32_t*)vSrc); vSrc += 2;
+
+            y01 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y23 = *((uint32_t*)ySrcTop); ySrcTop += 2;
+            y45 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+            y67 = *((uint32_t*)ySrcBot); ySrcBot += 2;
+
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            uv1 = (u01 >> 16) | ((v01 >> 16) << 20);
+
+            *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0;
+            *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1;
+            *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1;
+
+            *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0;
+            *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1;
+            *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1;
+        }
+
+        // There should be at most 2 more pixels to process. Note that we don't
+        // need to consider odd case as the buffer is always aligned to even.
+        if (x < width) {
+            u01 = *uSrc;
+            v01 = *vSrc;
+            y01 = *((uint32_t*)ySrcTop);
+            y45 = *((uint32_t*)ySrcBot);
+            uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20);
+            *dstTop++ = ((y01 & 0x3FF) << 10) | uv0;
+            *dstTop++ = ((y01 >> 16) << 10) | uv0;
+            *dstBot++ = ((y45 & 0x3FF) << 10) | uv0;
+            *dstBot++ = ((y45 >> 16) << 10) | uv0;
+        }
+
+        srcY += srcYStride * 2;
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dst += dstStride * 2;
+    }
+
+    return;
+}
+
+static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+        const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV,
+        size_t srcYStride, size_t srcUStride, size_t srcVStride,
+        size_t dstStride, size_t width, size_t height) {
+
+    uint8_t *dstY = (uint8_t *)dst;
+    size_t dstYSize = dstStride * height;
+    size_t dstUVStride = align(dstStride / 2, 16);
+    size_t dstUVSize = dstUVStride * height / 2;
+    uint8_t *dstV = dstY + dstYSize;
+    uint8_t *dstU = dstV + dstUVSize;
+
+    for (size_t y = 0; y < height; ++y) {
+        for (size_t x = 0; x < width; ++x) {
+            dstY[x] = (uint8_t)(srcY[x] >> 2);
+        }
+
+        srcY += srcYStride;
+        dstY += dstStride;
+    }
+
+    for (size_t y = 0; y < (height + 1) / 2; ++y) {
+        for (size_t x = 0; x < (width + 1) / 2; ++x) {
+            dstU[x] = (uint8_t)(srcU[x] >> 2);
+            dstV[x] = (uint8_t)(srcV[x] >> 2);
+        }
+
+        srcU += srcUStride;
+        srcV += srcVStride;
+        dstU += dstUVStride;
+        dstV += dstUVStride;
+    }
+    return;
+}
+bool C2SoftAomDec::outputBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const std::unique_ptr<C2Work> &work)
+{
+    if (!(work && pool)) return false;
+
+    aom_codec_iter_t iter = nullptr;
+    aom_image_t* img = aom_codec_get_frame(mCodecCtx, &iter);
+
+    if (!img) return false;
+
+    if (img->d_w != mWidth || img->d_h != mHeight) {
+        mWidth = img->d_w;
+        mHeight = img->d_h;
+
+        C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
+        std::vector<std::unique_ptr<C2SettingResult>> failures;
+        c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+        if (err == C2_OK) {
+            work->worklets.front()->output.configUpdate.push_back(
+                C2Param::Copy(size));
+        } else {
+            ALOGE("Config update size failed");
+            mSignalledError = true;
+            work->result = C2_CORRUPTED;
+            work->workletsProcessed = 1u;
+            return false;
+        }
+    }
+
+    CHECK(img->fmt == AOM_IMG_FMT_I420 || img->fmt == AOM_IMG_FMT_I42016);
+
+    std::shared_ptr<C2GraphicBlock> block;
+    uint32_t format = HAL_PIXEL_FORMAT_YV12;
+    if (img->fmt == AOM_IMG_FMT_I42016) {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l();
+
+        if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+            defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+            defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+            format = HAL_PIXEL_FORMAT_RGBA_1010102;
+        }
+    }
+    C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+
+    c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight,
+                                              format, usage, &block);
+
+    if (err != C2_OK) {
+        ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+        work->result = err;
+        return false;
+    }
+
+    C2GraphicView wView = block->map().get();
+
+    if (wView.error()) {
+        ALOGE("graphic view map failed %d", wView.error());
+        work->result = C2_CORRUPTED;
+        return false;
+    }
+
+    ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d",
+          block->width(), block->height(), mWidth, mHeight,
+          (int)*(int64_t*)img->user_priv);
+
+    uint8_t* dst = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+    size_t srcYStride = img->stride[AOM_PLANE_Y];
+    size_t srcUStride = img->stride[AOM_PLANE_U];
+    size_t srcVStride = img->stride[AOM_PLANE_V];
+
+    if (img->fmt == AOM_IMG_FMT_I42016) {
+        const uint16_t *srcY = (const uint16_t *)img->planes[AOM_PLANE_Y];
+        const uint16_t *srcU = (const uint16_t *)img->planes[AOM_PLANE_U];
+        const uint16_t *srcV = (const uint16_t *)img->planes[AOM_PLANE_V];
+
+        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    align(mWidth, 16),
+                                    mWidth, mHeight);
+        } else {
+            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
+                                    srcUStride / 2, srcVStride / 2,
+                                    align(mWidth, 16),
+                                    mWidth, mHeight);
+        }
+    } else {
+        const uint8_t *srcY = (const uint8_t *)img->planes[AOM_PLANE_Y];
+        const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U];
+        const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V];
+        copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV,
+                                srcYStride, srcUStride, srcVStride, mWidth, mHeight);
+    }
+    finishWork(*(int64_t*)img->user_priv, work, std::move(block));
+    block = nullptr;
+    return true;
+}
+
+c2_status_t C2SoftAomDec::drainInternal(
+    uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool,
+    const std::unique_ptr<C2Work>& work) {
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    if (aom_codec_decode(mCodecCtx, nullptr, 0, nullptr)) {
+        ALOGE("Failed to flush av1 decoder.");
+        return C2_CORRUPTED;
+    }
+
+    while ((outputBuffer(pool, work))) {
+    }
+
+    if (drainMode == DRAIN_COMPONENT_WITH_EOS && work &&
+        work->workletsProcessed == 0u) {
+        fillEmptyWork(work);
+    }
+
+    return C2_OK;
+}
+
+c2_status_t C2SoftAomDec::drain(uint32_t drainMode,
+                                const std::shared_ptr<C2BlockPool>& pool) {
+    return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftAomFactory : public C2ComponentFactory {
+   public:
+    C2SoftAomFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+              GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(
+        c2_node_id_t id, std::shared_ptr<C2Component>* const component,
+        std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+            new C2SoftAomDec(COMPONENT_NAME, id,
+                             std::make_shared<C2SoftAomDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+        c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+        std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+            new SimpleInterface<C2SoftAomDec::IntfImpl>(
+                COMPONENT_NAME, id,
+                std::make_shared<C2SoftAomDec::IntfImpl>(mHelper)),
+            deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftAomFactory() override = default;
+
+   private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+}  // namespace android
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftAomFactory();
+}
+
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/aom/C2SoftAomDec.h b/media/codec2/components/aom/C2SoftAomDec.h
new file mode 100644
index 0000000..4c82647
--- /dev/null
+++ b/media/codec2/components/aom/C2SoftAomDec.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_AV1_DEC_H_
+#define ANDROID_C2_SOFT_AV1_DEC_H_
+
+#include <SimpleC2Component.h>
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+
+#define GETTIME(a, b) gettimeofday(a, b);
+#define TIME_DIFF(start, end, diff)     \
+    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
+            ((end).tv_usec - (start).tv_usec);
+
+namespace android {
+
+struct C2SoftAomDec : public SimpleC2Component {
+    class IntfImpl;
+
+    C2SoftAomDec(const char* name, c2_node_id_t id,
+                 const std::shared_ptr<IntfImpl>& intfImpl);
+    virtual ~C2SoftAomDec();
+
+    // From SimpleC2Component
+    c2_status_t onInit() override;
+    c2_status_t onStop() override;
+    void onReset() override;
+    void onRelease() override;
+    c2_status_t onFlush_sm() override;
+    void process(const std::unique_ptr<C2Work>& work,
+                 const std::shared_ptr<C2BlockPool>& pool) override;
+    c2_status_t drain(uint32_t drainMode,
+                      const std::shared_ptr<C2BlockPool>& pool) override;
+
+   private:
+    std::shared_ptr<IntfImpl> mIntf;
+    aom_codec_ctx_t* mCodecCtx;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    bool mSignalledOutputEos;
+    bool mSignalledError;
+
+    #ifdef FILE_DUMP_ENABLE
+    char mInFile[200];
+    char mOutFile[200];
+    #endif /* FILE_DUMP_ENABLE */
+
+    struct timeval mTimeStart;   // Time at the start of decode()
+    struct timeval mTimeEnd;     // Time at the end of decode()
+
+    status_t initDecoder();
+    status_t destroyDecoder();
+    void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
+                    const std::shared_ptr<C2GraphicBlock>& block);
+    bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
+                      const std::unique_ptr<C2Work>& work);
+
+    c2_status_t drainInternal(uint32_t drainMode,
+                              const std::shared_ptr<C2BlockPool>& pool,
+                              const std::unique_ptr<C2Work>& work);
+
+    C2_DO_NOT_COPY(C2SoftAomDec);
+};
+
+#ifdef FILE_DUMP_ENABLE
+
+#define INPUT_DUMP_PATH "/data/local/tmp/temp/av1"
+#define INPUT_DUMP_EXT "webm"
+#define OUTPUT_DUMP_PATH "/data/local/tmp/temp/av1"
+#define OUTPUT_DUMP_EXT "av1"
+#define GENERATE_FILE_NAMES()                                                 \
+    {                                                                         \
+        GETTIME(&mTimeStart, NULL);                                           \
+        strcpy(mInFile, "");                                                  \
+        ALOGD("GENERATE_FILE_NAMES");                                         \
+        sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, mTimeStart.tv_sec, \
+                mTimeStart.tv_usec, INPUT_DUMP_EXT);                          \
+        strcpy(mOutFile, "");                                                 \
+        sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,                  \
+                mTimeStart.tv_sec, mTimeStart.tv_usec, OUTPUT_DUMP_EXT);      \
+    }
+
+#define CREATE_DUMP_FILE(m_filename)                     \
+    {                                                    \
+        FILE* fp = fopen(m_filename, "wb");              \
+        if (fp != NULL) {                                \
+            ALOGD("Opened file %s", m_filename);         \
+            fclose(fp);                                  \
+        } else {                                         \
+            ALOGD("Could not open file %s", m_filename); \
+        }                                                \
+    }
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)              \
+    {                                                        \
+        FILE* fp = fopen(m_filename, "ab");                  \
+        if (fp != NULL && m_buf != NULL) {                   \
+            int i;                                           \
+            ALOGD("Dump to file!");                          \
+            i = fwrite(m_buf, 1, m_size, fp);                \
+            if (i != (int)m_size) {                          \
+                ALOGD("Error in fwrite, returned %d", i);    \
+                perror("Error in write to file");            \
+            }                                                \
+            fclose(fp);                                      \
+        } else {                                             \
+            ALOGD("Could not write to file %s", m_filename); \
+            if (fp != NULL) fclose(fp);                      \
+        }                                                    \
+    }
+#else /* FILE_DUMP_ENABLE */
+#define INPUT_DUMP_PATH
+#define INPUT_DUMP_EXT
+#define OUTPUT_DUMP_PATH
+#define OUTPUT_DUMP_EXT
+#define GENERATE_FILE_NAMES()
+#define CREATE_DUMP_FILE(m_filename)
+#define DUMP_TO_FILE(m_filename, m_buf, m_size)
+#endif /* FILE_DUMP_ENABLE */
+
+}  // namespace android
+
+#endif  // ANDROID_C2_SOFT_AV1_DEC_H_
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 27aa064..cf1f6cf 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -392,6 +392,7 @@
     _C2_PL_HEVC_BASE = 0x6000,
     _C2_PL_VP9_BASE  = 0x7000,
     _C2_PL_DV_BASE   = 0x8000,
+    _C2_PL_AV1_BASE  = 0x9000,
 
     C2_PROFILE_LEVEL_VENDOR_START = 0x70000000,
 };
@@ -539,6 +540,11 @@
     PROFILE_DV_HE_07 = _C2_PL_DV_BASE + 7,      ///< Dolby Vision dvhe.07 profile
     PROFILE_DV_HE_08 = _C2_PL_DV_BASE + 8,      ///< Dolby Vision dvhe.08 profile
     PROFILE_DV_AV_09 = _C2_PL_DV_BASE + 9,      ///< Dolby Vision dvav.09 profile
+
+    // AV1 profiles
+    PROFILE_AV1_0 = _C2_PL_AV1_BASE,            ///< AV1 Profile 0 (4:2:0, 8 to 10 bit)
+    PROFILE_AV1_1,                              ///< AV1 Profile 1 (8 to 10 bit)
+    PROFILE_AV1_2,                              ///< AV1 Profile 2 (8 to 12 bit)
 };
 
 enum C2Config::level_t : uint32_t {
@@ -652,6 +658,31 @@
     LEVEL_DV_HIGH_UHD_30,                       ///< Dolby Vision high tier uhd30
     LEVEL_DV_HIGH_UHD_48,                       ///< Dolby Vision high tier uhd48
     LEVEL_DV_HIGH_UHD_60,                       ///< Dolby Vision high tier uhd60
+
+    LEVEL_AV1_2    = _C2_PL_AV1_BASE ,          ///< AV1 Level 2
+    LEVEL_AV1_2_1,                              ///< AV1 Level 2.1
+    LEVEL_AV1_2_2,                              ///< AV1 Level 2.2
+    LEVEL_AV1_2_3,                              ///< AV1 Level 2.3
+    LEVEL_AV1_3,                                ///< AV1 Level 3
+    LEVEL_AV1_3_1,                              ///< AV1 Level 3.1
+    LEVEL_AV1_3_2,                              ///< AV1 Level 3.2
+    LEVEL_AV1_3_3,                              ///< AV1 Level 3.3
+    LEVEL_AV1_4,                                ///< AV1 Level 4
+    LEVEL_AV1_4_1,                              ///< AV1 Level 4.1
+    LEVEL_AV1_4_2,                              ///< AV1 Level 4.2
+    LEVEL_AV1_4_3,                              ///< AV1 Level 4.3
+    LEVEL_AV1_5,                                ///< AV1 Level 5
+    LEVEL_AV1_5_1,                              ///< AV1 Level 5.1
+    LEVEL_AV1_5_2,                              ///< AV1 Level 5.2
+    LEVEL_AV1_5_3,                              ///< AV1 Level 5.3
+    LEVEL_AV1_6,                                ///< AV1 Level 6
+    LEVEL_AV1_6_1,                              ///< AV1 Level 6.1
+    LEVEL_AV1_6_2,                              ///< AV1 Level 6.2
+    LEVEL_AV1_6_3,                              ///< AV1 Level 6.3
+    LEVEL_AV1_7,                                ///< AV1 Level 7
+    LEVEL_AV1_7_1,                              ///< AV1 Level 7.1
+    LEVEL_AV1_7_2,                              ///< AV1 Level 7.2
+    LEVEL_AV1_7_3,                              ///< AV1 Level 7.3
 };
 
 struct C2ProfileLevelStruct {
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index f36027e..5d0ccd2 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -517,6 +517,13 @@
                         caps->addProfileLevel(VP9Profile2,    VP9Level5);
                         caps->addProfileLevel(VP9Profile2HDR, VP9Level5);
                     }
+                } else if (mediaType == MIMETYPE_VIDEO_AV1 && !encoder) {
+                    caps->addProfileLevel(AV1Profile0,      AV1Level2);
+                    caps->addProfileLevel(AV1Profile0,      AV1Level21);
+                    caps->addProfileLevel(AV1Profile1,      AV1Level22);
+                    caps->addProfileLevel(AV1Profile1,      AV1Level3);
+                    caps->addProfileLevel(AV1Profile2,      AV1Level31);
+                    caps->addProfileLevel(AV1Profile2,      AV1Level32);
                 } else if (mediaType == MIMETYPE_VIDEO_HEVC && !encoder) {
                     caps->addProfileLevel(HEVCProfileMain,      HEVCMainTierLevel51);
                     caps->addProfileLevel(HEVCProfileMainStill, HEVCMainTierLevel51);
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index 97e17e8..b1b33e1 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -326,6 +326,41 @@
     { C2Config::PROFILE_VP9_3, VP9Profile3 },
 };
 
+ALookup<C2Config::level_t, int32_t> sAv1Levels = {
+    { C2Config::LEVEL_AV1_2,    AV1Level2  },
+    { C2Config::LEVEL_AV1_2_1,  AV1Level21 },
+    { C2Config::LEVEL_AV1_2_2,  AV1Level22 },
+    { C2Config::LEVEL_AV1_2_3,  AV1Level23 },
+    { C2Config::LEVEL_AV1_3,    AV1Level3  },
+    { C2Config::LEVEL_AV1_3_1,  AV1Level31 },
+    { C2Config::LEVEL_AV1_3_2,  AV1Level32 },
+    { C2Config::LEVEL_AV1_3_3,  AV1Level33 },
+    { C2Config::LEVEL_AV1_4,    AV1Level4  },
+    { C2Config::LEVEL_AV1_4_1,  AV1Level41 },
+    { C2Config::LEVEL_AV1_4_2,  AV1Level42 },
+    { C2Config::LEVEL_AV1_4_3,  AV1Level43 },
+    { C2Config::LEVEL_AV1_5,    AV1Level5  },
+    { C2Config::LEVEL_AV1_5_1,  AV1Level51 },
+    { C2Config::LEVEL_AV1_5_2,  AV1Level52 },
+    { C2Config::LEVEL_AV1_5_3,  AV1Level53 },
+    { C2Config::LEVEL_AV1_6,    AV1Level6  },
+    { C2Config::LEVEL_AV1_6_1,  AV1Level61 },
+    { C2Config::LEVEL_AV1_6_2,  AV1Level62 },
+    { C2Config::LEVEL_AV1_6_3,  AV1Level63 },
+    { C2Config::LEVEL_AV1_7,    AV1Level7  },
+    { C2Config::LEVEL_AV1_7_1,  AV1Level71 },
+    { C2Config::LEVEL_AV1_7_2,  AV1Level72 },
+    { C2Config::LEVEL_AV1_7_3,  AV1Level73 },
+};
+
+
+ALookup<C2Config::profile_t, int32_t> sAv1Profiles = {
+    { C2Config::PROFILE_AV1_0, AV1Profile0 },
+    { C2Config::PROFILE_AV1_1, AV1Profile1 },
+    { C2Config::PROFILE_AV1_2, AV1Profile2 },
+};
+
+
 /**
  * A helper that passes through vendor extension profile and level values.
  */
diff --git a/media/codec2/vndk/C2Config.cpp b/media/codec2/vndk/C2Config.cpp
index da12903..782bec5 100644
--- a/media/codec2/vndk/C2Config.cpp
+++ b/media/codec2/vndk/C2Config.cpp
@@ -139,6 +139,9 @@
         { "vp9-1", C2Config::PROFILE_VP9_1 },
         { "vp9-2", C2Config::PROFILE_VP9_2 },
         { "vp9-3", C2Config::PROFILE_VP9_3 },
+        { "av1-0", C2Config::PROFILE_AV1_0 },
+        { "av1-1", C2Config::PROFILE_AV1_1 },
+        { "av1-2", C2Config::PROFILE_AV1_2 },
 }))
 
 DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2Config::level_t, ({
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 2d4e19e..a5dd203 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -821,6 +821,7 @@
     emplace("c2.android.vp9.decoder", "libcodec2_soft_vp9dec.so");
     emplace("c2.android.vp8.encoder", "libcodec2_soft_vp8enc.so");
     emplace("c2.android.vp9.encoder", "libcodec2_soft_vp9enc.so");
+    emplace("c2.android.av1.decoder", "libcodec2_soft_av1dec.so");
     emplace("c2.android.raw.decoder", "libcodec2_soft_rawdec.so");
     emplace("c2.android.flac.decoder", "libcodec2_soft_flacdec.so");
     emplace("c2.android.flac.encoder", "libcodec2_soft_flacenc.so");
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index 42a9c42..9f197b0 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -1463,6 +1463,8 @@
                       AMediaFormat_setBuffer(meta,
                              AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
                     }
+                } else if (!strcmp("V_AV1", codecID)) {
+                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
                 } else {
                     ALOGW("%s is not supported.", codecID);
                     continue;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 253f400..524db4e 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -343,6 +343,8 @@
         case FOURCC('a', 'l', 'a', 'c'):
             return MEDIA_MIMETYPE_AUDIO_ALAC;
 
+        case FOURCC('a', 'v', '0', '1'):
+            return MEDIA_MIMETYPE_VIDEO_AV1;
         default:
             ALOGW("Unknown fourcc: %c%c%c%c",
                    (fourcc >> 24) & 0xff,
@@ -1754,6 +1756,7 @@
         case FOURCC('a', 'v', 'c', '1'):
         case FOURCC('h', 'v', 'c', '1'):
         case FOURCC('h', 'e', 'v', '1'):
+        case FOURCC('a', 'v', '0', '1'):
         {
             uint8_t buffer[78];
             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
@@ -6017,6 +6020,7 @@
         FOURCC('a', 'v', 'c', '1'),
         FOURCC('h', 'v', 'c', '1'),
         FOURCC('h', 'e', 'v', '1'),
+        FOURCC('a', 'v', '0', '1'),
         FOURCC('3', 'g', 'p', '4'),
         FOURCC('m', 'p', '4', '1'),
         FOURCC('m', 'p', '4', '2'),
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 6002e95..7d759e0 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -216,8 +216,7 @@
         "libutils",
         "libbinder",
         "libsonivox",
-        "libicuuc",
-        "libicui18n",
+        "libandroidicu",
         "libexpat",
         "libcamera_client",
         "libstagefright_foundation",
@@ -232,8 +231,7 @@
     export_shared_lib_headers: [
         "libaudioclient",
         "libbinder",
-        "libicuuc",
-        "libicui18n",
+        "libandroidicu",
         "libsonivox",
         "libmedia_omx",
     ],
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 54309ee..38f42dc 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -16,6 +16,7 @@
         "libandroid_runtime",
         "libaudioclient",
         "libbinder",
+        "libbinder_ndk",
         "libcutils",
         "libgui",
         "liblog",
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
index 5e98589..0c8d016 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
@@ -30,7 +30,6 @@
 #include <media/AudioSystem.h>
 #include <media/AudioTimestamp.h>
 #include <media/BufferingSettings.h>
-#include <media/Metadata.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
 
@@ -224,18 +223,6 @@
     // @return OK if the call was successful.
     virtual status_t invoke(const PlayerMessage &request, PlayerMessage *reply) = 0;
 
-    // The Client in the MetadataPlayerService calls this method on
-    // the native player to retrieve all or a subset of metadata.
-    //
-    // @param ids SortedList of metadata ID to be fetch. If empty, all
-    //            the known metadata should be returned.
-    // @param[inout] records Parcel where the player appends its metadata.
-    // @return OK if the call was successful.
-    virtual status_t getMetadata(const media::Metadata::Filter& /* ids */,
-                                 Parcel* /* records */) {
-        return INVALID_OPERATION;
-    };
-
     void setListener(const sp<MediaPlayer2InterfaceListener> &listener) {
         Mutex::Autolock autoLock(mListenerLock);
         mListener = listener;
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index a945ffd..b8d034b 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -20,7 +20,6 @@
 #include <media/AVSyncSettings.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/BufferingSettings.h>
-#include <media/Metadata.h>
 #include <media/mediaplayer_common.h>
 #include <mediaplayer2/MediaPlayer2Interface.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index f432059..e088a01 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -18,14 +18,11 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaPlayer2Native"
 
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-
+#include <android/binder_ibinder.h>
 #include <media/AudioSystem.h>
 #include <media/DataSourceDesc.h>
 #include <media/MediaAnalyticsItem.h>
 #include <media/MemoryLeakTrackUtil.h>
-#include <media/Metadata.h>
 #include <media/NdkWrapper.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooperRoster.h>
@@ -103,114 +100,110 @@
     String8 result;
     SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
 
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        snprintf(buffer, SIZE, "Permission Denial: can't dump MediaPlayer2\n");
-        result.append(buffer);
+    {
+        Mutex::Autolock lock(sRecordLock);
+        ensureInit_l();
+        for (int i = 0, n = sPlayers->size(); i < n; ++i) {
+            sp<MediaPlayer2> p = (*sPlayers)[i].promote();
+            if (p != 0) {
+                p->dump(fd, args);
+            }
+            players.add(p);
+        }
+    }
+
+    result.append(" Files opened and/or mapped:\n");
+    snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
+    FILE *f = fopen(buffer, "r");
+    if (f) {
+        while (!feof(f)) {
+            fgets(buffer, SIZE, f);
+            if (strstr(buffer, " /storage/") ||
+                strstr(buffer, " /system/sounds/") ||
+                strstr(buffer, " /data/") ||
+                strstr(buffer, " /system/media/")) {
+                result.append("  ");
+                result.append(buffer);
+            }
+        }
+        fclose(f);
     } else {
-        {
-            Mutex::Autolock lock(sRecordLock);
-            ensureInit_l();
-            for (int i = 0, n = sPlayers->size(); i < n; ++i) {
-                sp<MediaPlayer2> p = (*sPlayers)[i].promote();
-                if (p != 0) {
-                    p->dump(fd, args);
-                }
-                players.add(p);
-            }
-        }
+        result.append("couldn't open ");
+        result.append(buffer);
+        result.append("\n");
+    }
 
-        result.append(" Files opened and/or mapped:\n");
-        snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
-        FILE *f = fopen(buffer, "r");
-        if (f) {
-            while (!feof(f)) {
-                fgets(buffer, SIZE, f);
-                if (strstr(buffer, " /storage/") ||
-                    strstr(buffer, " /system/sounds/") ||
-                    strstr(buffer, " /data/") ||
-                    strstr(buffer, " /system/media/")) {
-                    result.append("  ");
-                    result.append(buffer);
-                }
-            }
-            fclose(f);
-        } else {
-            result.append("couldn't open ");
-            result.append(buffer);
-            result.append("\n");
-        }
-
-        snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
-        DIR *d = opendir(buffer);
-        if (d) {
-            struct dirent *ent;
-            while((ent = readdir(d)) != NULL) {
-                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
-                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
-                    struct stat s;
-                    if (lstat(buffer, &s) == 0) {
-                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
-                            char linkto[256];
-                            int len = readlink(buffer, linkto, sizeof(linkto));
-                            if(len > 0) {
-                                if(len > 255) {
-                                    linkto[252] = '.';
-                                    linkto[253] = '.';
-                                    linkto[254] = '.';
-                                    linkto[255] = 0;
-                                } else {
-                                    linkto[len] = 0;
-                                }
-                                if (strstr(linkto, "/storage/") == linkto ||
-                                    strstr(linkto, "/system/sounds/") == linkto ||
-                                    strstr(linkto, "/data/") == linkto ||
-                                    strstr(linkto, "/system/media/") == linkto) {
-                                    result.append("  ");
-                                    result.append(buffer);
-                                    result.append(" -> ");
-                                    result.append(linkto);
-                                    result.append("\n");
-                                }
+    snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
+    DIR *d = opendir(buffer);
+    if (d) {
+        struct dirent *ent;
+        while((ent = readdir(d)) != NULL) {
+            if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
+                snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
+                struct stat s;
+                if (lstat(buffer, &s) == 0) {
+                    if ((s.st_mode & S_IFMT) == S_IFLNK) {
+                        char linkto[256];
+                        int len = readlink(buffer, linkto, sizeof(linkto));
+                        if(len > 0) {
+                            if(len > 255) {
+                                linkto[252] = '.';
+                                linkto[253] = '.';
+                                linkto[254] = '.';
+                                linkto[255] = 0;
+                            } else {
+                                linkto[len] = 0;
                             }
-                        } else {
-                            result.append("  unexpected type for ");
-                            result.append(buffer);
-                            result.append("\n");
+                            if (strstr(linkto, "/storage/") == linkto ||
+                                strstr(linkto, "/system/sounds/") == linkto ||
+                                strstr(linkto, "/data/") == linkto ||
+                                strstr(linkto, "/system/media/") == linkto) {
+                                result.append("  ");
+                                result.append(buffer);
+                                result.append(" -> ");
+                                result.append(linkto);
+                                result.append("\n");
+                            }
                         }
+                    } else {
+                        result.append("  unexpected type for ");
+                        result.append(buffer);
+                        result.append("\n");
                     }
                 }
             }
-            closedir(d);
-        } else {
-            result.append("couldn't open ");
-            result.append(buffer);
-            result.append("\n");
         }
+        closedir(d);
+    } else {
+        result.append("couldn't open ");
+        result.append(buffer);
+        result.append("\n");
+    }
 
-        gLooperRoster.dump(fd, args);
+    gLooperRoster.dump(fd, args);
 
-        bool dumpMem = false;
-        bool unreachableMemory = false;
-        for (size_t i = 0; i < args.size(); i++) {
-            if (args[i] == String16("-m")) {
-                dumpMem = true;
-            } else if (args[i] == String16("--unreachable")) {
-                unreachableMemory = true;
-            }
-        }
-        if (dumpMem) {
-            result.append("\nDumping memory:\n");
-            std::string s = dumpMemoryAddresses(100 /* limit */);
-            result.append(s.c_str(), s.size());
-        }
-        if (unreachableMemory) {
-            result.append("\nDumping unreachable memory:\n");
-            // TODO - should limit be an argument parameter?
-            // TODO: enable GetUnreachableMemoryString if it's part of stable API
-            //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
-            //result.append(s.c_str(), s.size());
+    bool dumpMem = false;
+    bool unreachableMemory = false;
+    for (size_t i = 0; i < args.size(); i++) {
+        if (args[i] == String16("-m")) {
+            dumpMem = true;
+        } else if (args[i] == String16("--unreachable")) {
+            unreachableMemory = true;
         }
     }
+    if (dumpMem) {
+        result.append("\nDumping memory:\n");
+        std::string s = dumpMemoryAddresses(100 /* limit */);
+        result.append(s.c_str(), s.size());
+    }
+    if (unreachableMemory) {
+        result.append("\nDumping unreachable memory:\n");
+        // TODO - should limit be an argument parameter?
+        // TODO: enable GetUnreachableMemoryString if it's part of stable API
+        //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
+        //result.append(s.c_str(), s.size());
+    }
+
     write(fd, result.string(), result.size());
     return NO_ERROR;
 }
@@ -253,9 +246,8 @@
     mVideoWidth = mVideoHeight = 0;
     mSendLevel = 0;
 
-    // TODO: get pid and uid from JAVA
-    mPid = IPCThreadState::self()->getCallingPid();
-    mUid = IPCThreadState::self()->getCallingUid();
+    mPid = AIBinder_getCallingPid();
+    mUid = AIBinder_getCallingUid();
 
     mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
 }
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index 2dab2dd..3c11b17 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -662,33 +662,6 @@
     return INVALID_OPERATION;
 }
 
-status_t NuPlayer2Driver::getMetadata(
-        const media::Metadata::Filter& /* ids */, Parcel *records) {
-    Mutex::Autolock autoLock(mLock);
-
-    using media::Metadata;
-
-    Metadata meta(records);
-
-    meta.appendBool(
-            Metadata::kPauseAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_PAUSE);
-
-    meta.appendBool(
-            Metadata::kSeekBackwardAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK_BACKWARD);
-
-    meta.appendBool(
-            Metadata::kSeekForwardAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK_FORWARD);
-
-    meta.appendBool(
-            Metadata::kSeekAvailable,
-            mPlayerFlags & NuPlayer2::Source::FLAG_CAN_SEEK);
-
-    return OK;
-}
-
 void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
     ALOGD("notifyResetComplete(%p)", this);
     Mutex::Autolock autoLock(mLock);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
index bb30c76..fe17d03 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
@@ -61,9 +61,6 @@
     virtual status_t setParameter(int key, const Parcel &request) override;
     virtual status_t getParameter(int key, Parcel *reply) override;
 
-    virtual status_t getMetadata(
-            const media::Metadata::Filter& ids, Parcel *records) override;
-
     virtual status_t dump(int fd, const Vector<String16> &args) const override;
 
     virtual void onMessageReceived(const sp<AMessage> &msg) override;
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
index e3c9b4b..2881fd4 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
@@ -26,6 +26,8 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/MediaClock.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
 #include <media/stagefright/VideoFrameScheduler2.h>
@@ -86,6 +88,20 @@
 // static
 const int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000LL;
 
+static audio_format_t constexpr audioFormatFromEncoding(int32_t pcmEncoding) {
+    switch (pcmEncoding) {
+    case kAudioEncodingPcmFloat:
+        return AUDIO_FORMAT_PCM_FLOAT;
+    case kAudioEncodingPcm16bit:
+        return AUDIO_FORMAT_PCM_16_BIT;
+    case kAudioEncodingPcm8bit:
+        return AUDIO_FORMAT_PCM_8_BIT;  // TODO: do we want to support this?
+    default:
+        ALOGE("%s: Invalid encoding: %d", __func__, pcmEncoding);
+        return AUDIO_FORMAT_INVALID;
+    }
+}
+
 NuPlayer2::Renderer::Renderer(
         const sp<MediaPlayer2Interface::AudioSink> &sink,
         const sp<MediaClock> &mediaClock,
@@ -1269,10 +1285,10 @@
             mAnchorTimeMediaUs = mediaTimeUs;
         }
     }
-    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
+    mNextVideoTimeMediaUs = mediaTimeUs;
     if (!mHasAudio) {
         // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+        mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
     }
 
     if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
@@ -1406,9 +1422,15 @@
         mHasAudio = false;
         if (mNextVideoTimeMediaUs >= 0) {
             int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
-            if (mNextVideoTimeMediaUs > mediaUs) {
-                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+            int64_t nowUs = ALooper::GetNowUs();
+            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
+            if (result == OK) {
+                if (mNextVideoTimeMediaUs > mediaUs) {
+                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+                }
+            } else {
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs, mNextVideoTimeMediaUs + 100000);
             }
         }
     }
@@ -1864,8 +1886,13 @@
     int32_t sampleRate;
     CHECK(format->findInt32("sample-rate", &sampleRate));
 
+    // read pcm encoding from MediaCodec output format, if available
+    int32_t pcmEncoding;
+    audio_format_t audioFormat =
+            format->findInt32(KEY_PCM_ENCODING, &pcmEncoding) ?
+                    audioFormatFromEncoding(pcmEncoding) : AUDIO_FORMAT_PCM_16_BIT;
+
     if (offloadingAudio()) {
-        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
         AString mime;
         CHECK(format->findString("mime", &mime));
         status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
@@ -1966,7 +1993,7 @@
         const PcmInfo info = {
                 (audio_channel_mask_t)channelMask,
                 (audio_output_flags_t)pcmFlags,
-                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+                audioFormat,
                 numChannels,
                 sampleRate
         };
@@ -1998,7 +2025,7 @@
                     sampleRate,
                     numChannels,
                     (audio_channel_mask_t)channelMask,
-                    AUDIO_FORMAT_PCM_16_BIT,
+                    audioFormat,
                     mUseAudioCallback ? &NuPlayer2::Renderer::AudioSinkCallback : NULL,
                     mUseAudioCallback ? this : NULL,
                     (audio_output_flags_t)pcmFlags,
@@ -2054,4 +2081,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index c8f6738..c990b2a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1299,10 +1299,10 @@
             mAnchorTimeMediaUs = mediaTimeUs;
         }
     }
-    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
+    mNextVideoTimeMediaUs = mediaTimeUs;
     if (!mHasAudio) {
         // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+        mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
     }
 
     if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
@@ -1436,9 +1436,15 @@
         mHasAudio = false;
         if (mNextVideoTimeMediaUs >= 0) {
             int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
-            if (mNextVideoTimeMediaUs > mediaUs) {
-                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+            int64_t nowUs = ALooper::GetNowUs();
+            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
+            if (result == OK) {
+                if (mNextVideoTimeMediaUs > mediaUs) {
+                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+                }
+            } else {
+                mMediaClock->updateAnchor(
+                        mNextVideoTimeMediaUs, nowUs, mNextVideoTimeMediaUs + 100000);
             }
         }
     }
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index a6f0a0b..199b57b 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -118,6 +118,13 @@
     }
 
     sp<MetaData> format = mSource->getFormat();
+
+    if (format == NULL) {
+        ALOGE("No metadata b/118620871");
+        android_errorWriteLog(0x534e4554, "118620871");
+        return BAD_VALUE;
+    }
+
     const char *mime;
     bool success = format->findCString(kKeyMIMEType, &mime);
     CHECK(success);
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 942f850..c6dc326 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -430,6 +430,15 @@
                 return;
             }
 
+            if (size < sizeof(int64_t)) {
+                // The 2nd and 3rd input buffer are expected to contain
+                //  an int64_t (see below), so make sure we get at least
+                //  that much. The first input buffer must contain 19 bytes,
+                //  but that is checked already.
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
+            }
+
             if (mInputBufferCount == 0) {
                 delete mHeader;
                 mHeader = new OpusHeader();
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
index f352fba..1d792fd 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -110,15 +110,22 @@
 
 {
     initPorts();
-    CHECK_EQ(initDecoder(), (status_t)OK);
+    mMemoryVec.clear();
+    mDrcMemoryVec.clear();
+
+    CHECK_EQ(initDecoder(), IA_NO_ERROR);
 }
 
 SoftXAAC::~SoftXAAC() {
-    int errCode = deInitXAACDecoder();
-    if (0 != errCode) {
-        ALOGE("deInitXAACDecoder() failed %d", errCode);
+    IA_ERRORCODE err_code = deInitXAACDecoder();
+    if (IA_NO_ERROR != err_code) {
+        ALOGE("deInitXAACDecoder() failed %d", err_code);
     }
 
+    err_code = deInitMPEGDDDrc();
+    if (IA_NO_ERROR != err_code) {
+        ALOGE("deInitMPEGDDDrc() failed %d", err_code);
+    }
     mIsCodecInitialized = false;
     mIsCodecConfigFlushRequired = false;
 }
@@ -164,36 +171,16 @@
     addPort(def);
 }
 
-status_t SoftXAAC::initDecoder() {
-    status_t status = UNKNOWN_ERROR;
-
+IA_ERRORCODE SoftXAAC::initDecoder() {
     int ui_drc_val;
     IA_ERRORCODE err_code = IA_NO_ERROR;
     int loop = 0;
 
     err_code = initXAACDecoder();
     if (err_code != IA_NO_ERROR) {
-        if (NULL == mXheaacCodecHandle) {
-            ALOGE("AAC decoder handle is null");
-        }
-        if (NULL == mMpegDDrcHandle) {
-            ALOGE("MPEG-D DRC decoder handle is null");
-        }
-        for (loop = 1; loop < mMallocCount; loop++) {
-            if (mMemoryArray[loop] == NULL) {
-                ALOGE(" memory allocation error %d\n", loop);
-                break;
-            }
-        }
-        ALOGE("initXAACDecoder Failed");
-
-        for (loop = 0; loop < mMallocCount; loop++) {
-            if (mMemoryArray[loop]) free(mMemoryArray[loop]);
-        }
-        mMallocCount = 0;
-        return status;
-    } else {
-        status = OK;
+        ALOGE("initXAACDecoder failed with error %d", err_code);
+        deInitXAACDecoder();
+        return err_code;
     }
 
     mEndOfInput = false;
@@ -274,7 +261,7 @@
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
 
 #endif
-    return status;
+    return IA_NO_ERROR;
 }
 
 OMX_ERRORTYPE SoftXAAC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
@@ -547,9 +534,6 @@
     /* sample currently                                                  */
     if (mIsCodecInitialized) {
         numOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
-        if ((mPcmWdSz / 8) != 2) {
-            ALOGE("XAAC assumes 2 bytes per sample! mPcmWdSz %d", mPcmWdSz);
-        }
     }
 
     while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
@@ -569,8 +553,8 @@
                 inBufferLength = inHeader->nFilledLen;
 
                 /* GA header configuration sent to Decoder! */
-                int err_code = configXAACDecoder(inBuffer, inBufferLength);
-                if (0 != err_code) {
+                IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+                if (IA_NO_ERROR != err_code) {
                     ALOGW("configXAACDecoder err_code = %d", err_code);
                     mSignalledError = true;
                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
@@ -682,8 +666,8 @@
             /* which should initialize the codec. Once this state is reached, call the  */
             /* decodeXAACStream API with same frame to decode!                        */
             if (!mIsCodecInitialized) {
-                int err_code = configXAACDecoder(inBuffer, inBufferLength);
-                if (0 != err_code) {
+                IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
+                if (IA_NO_ERROR != err_code) {
                     ALOGW("configXAACDecoder Failed 2 err_code = %d", err_code);
                     mSignalledError = true;
                     notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
@@ -845,7 +829,7 @@
     }
 }
 
-int SoftXAAC::configflushDecode() {
+IA_ERRORCODE SoftXAAC::configflushDecode() {
     IA_ERRORCODE err_code;
     UWORD32 ui_init_done;
     uint32_t inBufferLength = 8203;
@@ -871,16 +855,13 @@
             "Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz "
             "%d\nchannelMask %d\noutputFrameLength %d",
             mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
-        if (mNumChannels > MAX_CHANNEL_COUNT) {
-            ALOGE(" No of channels are more than max channels\n");
-            mIsCodecInitialized = false;
-        } else
-            mIsCodecInitialized = true;
+
+        mIsCodecInitialized = true;
     }
-    return err_code;
+    return IA_NO_ERROR;
 }
-int SoftXAAC::drainDecoder() {
-    return 0;
+IA_ERRORCODE SoftXAAC::drainDecoder() {
+    return IA_NO_ERROR;
 }
 
 void SoftXAAC::onReset() {
@@ -921,7 +902,7 @@
     }
 }
 
-int SoftXAAC::initXAACDecoder() {
+IA_ERRORCODE SoftXAAC::initXAACDecoder() {
     LOOPIDX i;
 
     /* Error code */
@@ -939,11 +920,11 @@
     UWORD32 ui_proc_mem_tabs_size;
     /* API size */
     UWORD32 pui_api_size;
+    pVOID pv_alloc_ptr;
 
     mInputBufferSize = 0;
     mInputBuffer = 0;
     mOutputBuffer = 0;
-    mMallocCount = 0;
 
     /* Process struct initing end */
     /* ******************************************************************/
@@ -954,20 +935,13 @@
     err_code = ixheaacd_dec_api(NULL, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
     /* Allocate memory for API */
-    mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
-    if (mMemoryArray[mMallocCount] == NULL) {
+    mXheaacCodecHandle = memalign(4, pui_api_size);
+    if (mXheaacCodecHandle == NULL) {
         ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
         return IA_FATAL_ERROR;
     }
-    /* Set API object with the memory allocated */
-    mXheaacCodecHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-    mMallocCount++;
+    mMemoryVec.push(mXheaacCodecHandle);
 
     /* Set the config params to default values */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
@@ -979,23 +953,16 @@
 
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
     /* Allocate memory for API */
-    mMemoryArray[mMallocCount] = memalign(4, pui_api_size);
+    mMpegDDrcHandle = memalign(4, pui_api_size);
 
-    if (mMemoryArray[mMallocCount] == NULL) {
+    if (mMpegDDrcHandle == NULL) {
         ALOGE("malloc for drc api structure Failed");
         return IA_FATAL_ERROR;
     }
-    memset(mMemoryArray[mMallocCount], 0, pui_api_size);
+    mMemoryVec.push(mMpegDDrcHandle);
 
-    /* Set API object with the memory allocated */
-    mMpegDDrcHandle = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-    mMallocCount++;
+    memset(mMpegDDrcHandle, 0, pui_api_size);
 
     /* Set the config params to default values */
     err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
@@ -1021,23 +988,17 @@
                                 &ui_proc_mem_tabs_size);
     RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
 
-    if (mMallocCount == MAX_MEM_ALLOCS) {
-        ALOGE("mMemoryArray is full");
-        return IA_FATAL_ERROR;
-    }
-
-    mMemoryArray[mMallocCount] = memalign(4, ui_proc_mem_tabs_size);
-    if (mMemoryArray[mMallocCount] == NULL) {
+    pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
+    if (pv_alloc_ptr == NULL) {
         ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!",
               ui_proc_mem_tabs_size + 4);
         return IA_FATAL_ERROR;
     }
-    mMallocCount++;
-    /* Set pointer for process memory tables    */
-    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
-                                (pVOID)((WORD8*)mMemoryArray[mMallocCount - 1]));
-    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
+    mMemoryVec.push(pv_alloc_ptr);
 
+    /* Set pointer for process memory tables    */
+    err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0, pv_alloc_ptr);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
 
     /* initialize the API, post config, fill memory tables  */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
@@ -1066,17 +1027,12 @@
         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
         RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
 
-        if (mMallocCount == MAX_MEM_ALLOCS) {
-            ALOGE("mMemoryArray is full");
-            return IA_FATAL_ERROR;
-        }
-        mMemoryArray[mMallocCount] = memalign(ui_alignment, ui_size);
-        if (mMemoryArray[mMallocCount] == NULL) {
+        pv_alloc_ptr = memalign(ui_alignment, ui_size);
+        if (pv_alloc_ptr == NULL) {
             ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!", ui_size + ui_alignment);
             return IA_FATAL_ERROR;
         }
-        pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-        mMallocCount++;
+        mMemoryVec.push(pv_alloc_ptr);
 
         /* Set the buffer pointer */
         err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
@@ -1095,7 +1051,7 @@
     return IA_NO_ERROR;
 }
 
-int SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
+IA_ERRORCODE SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
     UWORD32 ui_init_done;
     int32_t i_bytes_consumed;
 
@@ -1154,13 +1110,73 @@
 
     return IA_NO_ERROR;
 }
-int SoftXAAC::configMPEGDDrc() {
+IA_ERRORCODE SoftXAAC::initMPEGDDDrc() {
+    IA_ERRORCODE err_code = IA_NO_ERROR;
+    int i;
+
+    for (i = 0; i < (WORD32)2; i++) {
+        WORD32 ui_size, ui_alignment, ui_type;
+        pVOID pv_alloc_ptr;
+
+        /* Get memory size */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
+
+        /* Get memory alignment */
+        err_code =
+            ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
+
+        /* Get memory type */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
+
+        pv_alloc_ptr = memalign(4, ui_size);
+        if (pv_alloc_ptr == NULL) {
+            ALOGE(" Cannot create requested memory  %d", ui_size);
+            return IA_FATAL_ERROR;
+        }
+        mDrcMemoryVec.push(pv_alloc_ptr);
+
+        /* Set the buffer pointer */
+        err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
+
+        RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+    }
+
+    WORD32 ui_size;
+    ui_size = 8192 * 2;
+
+    mDrcInBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcInBuf == NULL) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcInBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    mDrcOutBuf = (int8_t*)memalign(4, ui_size);
+    if (mDrcOutBuf == NULL) {
+        ALOGE(" Cannot create requested memory  %d", ui_size);
+        return IA_FATAL_ERROR;
+    }
+    mDrcMemoryVec.push(mDrcOutBuf);
+
+    err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
+    RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+
+    return IA_NO_ERROR;
+}
+IA_ERRORCODE SoftXAAC::configMPEGDDrc() {
     IA_ERRORCODE err_code = IA_NO_ERROR;
     int i_effect_type;
     int i_loud_norm;
     int i_target_loudness;
     unsigned int i_sbr_mode;
-    int n_mems;
     int i;
 
 #ifdef ENABLE_MPEG_D_DRC
@@ -1217,78 +1233,16 @@
 
         RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
 
-        for (i = 0; i < (WORD32)2; i++) {
-            WORD32 ui_size, ui_alignment, ui_type;
-            pVOID pv_alloc_ptr;
+        /* Free any memory that is allocated for MPEG D Drc so far */
+        deInitMPEGDDDrc();
 
-            /* Get memory size */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
-
-            /* Get memory alignment */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i,
-                                      &ui_alignment);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
-
-            /* Get memory type */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
-
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-            pv_alloc_ptr = (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
-            mMallocCount++;
-
-            /* Set the buffer pointer */
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
-
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
+        err_code = initMPEGDDDrc();
+        if (err_code != IA_NO_ERROR) {
+            ALOGE("initMPEGDDDrc failed with error %d", err_code);
+            deInitMPEGDDDrc();
+            return err_code;
         }
-        {
-            WORD32 ui_size;
-            ui_size = 8192 * 2;
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
 
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-
-            mDrcInBuf = (int8_t*)mMemoryArray[mMallocCount];
-            mMallocCount++;
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2,
-                                      /*mOutputBuffer*/ mDrcInBuf);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-
-            if (mMallocCount == MAX_MEM_ALLOCS) {
-                ALOGE("mMemoryArray is full");
-                return IA_FATAL_ERROR;
-            }
-            mMemoryArray[mMallocCount] = memalign(4, ui_size);
-            if (mMemoryArray[mMallocCount] == NULL) {
-                ALOGE(" Cannot create requested memory  %d", ui_size);
-                return IA_FATAL_ERROR;
-            }
-
-            mDrcOutBuf = (int8_t*)mMemoryArray[mMallocCount];
-            mMallocCount++;
-            err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3,
-                                      /*mOutputBuffer*/ mDrcOutBuf);
-            RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-        }
         /* DRC buffers
             buf[0] - contains extension element pay load loudness related
             buf[1] - contains extension element pay load*/
@@ -1423,10 +1377,10 @@
     }
 #endif
 
-    return err_code;
+    return IA_NO_ERROR;
 }
-int SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength, int32_t* bytesConsumed,
-                               int32_t* outBytes) {
+IA_ERRORCODE SoftXAAC::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
+                                        int32_t* bytesConsumed, int32_t* outBytes) {
     if (mInputBufferSize < inBufferLength) {
         ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize,
               inBufferLength);
@@ -1516,24 +1470,33 @@
         memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
     }
 #endif
-    return err_code;
+    return IA_NO_ERROR;
 }
 
-int SoftXAAC::deInitXAACDecoder() {
+IA_ERRORCODE SoftXAAC::deInitXAACDecoder() {
     ALOGI("deInitXAACDecoder");
 
     /* Tell that the input is over in this buffer */
     IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, NULL);
-    RETURN_IF_FATAL(err_code, "IA_API_CMD_INPUT_OVER");
 
-    for (int i = 0; i < mMallocCount; i++) {
-        if (mMemoryArray[i]) free(mMemoryArray[i]);
+    /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
+    for (void* buf : mMemoryVec) {
+        free(buf);
     }
-    mMallocCount = 0;
-
+    mMemoryVec.clear();
     return err_code;
 }
 
+IA_ERRORCODE SoftXAAC::deInitMPEGDDDrc() {
+    ALOGI("deInitMPEGDDDrc");
+
+    for (void* buf : mDrcMemoryVec) {
+        free(buf);
+    }
+    mDrcMemoryVec.clear();
+    return IA_NO_ERROR;
+}
+
 IA_ERRORCODE SoftXAAC::getXAACStreamInfo() {
     IA_ERRORCODE err_code = IA_NO_ERROR;
 
@@ -1546,11 +1509,19 @@
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
+    if (mNumChannels > MAX_CHANNEL_COUNT) {
+        ALOGE(" No of channels are more than max channels\n");
+        return IA_FATAL_ERROR;
+    }
 
     /* PCM word size */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
                                 IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
     RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
+    if ((mPcmWdSz / 8) != 2) {
+        ALOGE("Invalid Number of bytes per sample: %d, Expected is 2", mPcmWdSz);
+        return IA_FATAL_ERROR;
+    }
 
     /* channel mask to tell the arrangement of channels in bit stream */
     err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.h b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
index 6176082..a62a797 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.h
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
@@ -33,8 +33,6 @@
 #include "impd_apicmd_standards.h"
 #include "impd_drc_config_params.h"
 
-#define MAX_MEM_ALLOCS 100
-
 extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd, WORD32 i_idx,
                                          pVOID pv_value);
 extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd, WORD32 i_idx,
@@ -80,18 +78,19 @@
     enum { NONE, AWAITING_DISABLED, AWAITING_ENABLED } mOutputPortSettingsChange;
 
     void initPorts();
-    status_t initDecoder();
+    IA_ERRORCODE initDecoder();
     bool isConfigured() const;
-    int drainDecoder();
-    int initXAACDecoder();
-    int deInitXAACDecoder();
+    IA_ERRORCODE drainDecoder();
+    IA_ERRORCODE initXAACDecoder();
+    IA_ERRORCODE deInitXAACDecoder();
+    IA_ERRORCODE initMPEGDDDrc();
+    IA_ERRORCODE deInitMPEGDDDrc();
+    IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
+    IA_ERRORCODE configMPEGDDrc();
+    IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
+                                  int32_t* bytesConsumed, int32_t* outBytes);
 
-    int configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
-    int configMPEGDDrc();
-    int decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength, int32_t* bytesConsumed,
-                         int32_t* outBytes);
-
-    int configflushDecode();
+    IA_ERRORCODE configflushDecode();
     IA_ERRORCODE getXAACStreamInfo();
     IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost, int32_t drcRefLevel,
                                 int32_t drcHeavyCompression
@@ -120,9 +119,8 @@
     int8_t* mDrcOutBuf;
     int32_t mMpegDDRCPresent;
     int32_t mDRCFlag;
-
-    void* mMemoryArray[MAX_MEM_ALLOCS];
-    int32_t mMallocCount;
+    Vector<void*> mMemoryVec;
+    Vector<void*> mDrcMemoryVec;
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftXAAC);
 };
diff --git a/media/libstagefright/foundation/MediaDefs.cpp b/media/libstagefright/foundation/MediaDefs.cpp
index aba44bb..9d1ec1f 100644
--- a/media/libstagefright/foundation/MediaDefs.cpp
+++ b/media/libstagefright/foundation/MediaDefs.cpp
@@ -23,6 +23,7 @@
 
 const char *MEDIA_MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
 const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+const char *MEDIA_MIMETYPE_VIDEO_AV1 = "video/av01";
 const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
 const char *MEDIA_MIMETYPE_VIDEO_HEVC = "video/hevc";
 const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
index 8edddcc..e68852d 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
@@ -25,6 +25,7 @@
 
 extern const char *MEDIA_MIMETYPE_VIDEO_VP8;
 extern const char *MEDIA_MIMETYPE_VIDEO_VP9;
+extern const char *MEDIA_MIMETYPE_VIDEO_AV1;
 extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
 extern const char *MEDIA_MIMETYPE_VIDEO_HEVC;
 extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 704bfdd..984c23d 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -153,6 +153,35 @@
 constexpr int32_t VP9Level61 = 0x1000;
 constexpr int32_t VP9Level62 = 0x2000;
 
+constexpr int32_t AV1Profile0 = 0x01;
+constexpr int32_t AV1Profile1 = 0x02;
+constexpr int32_t AV1Profile2 = 0x04;
+
+constexpr int32_t AV1Level2  = 0x1;
+constexpr int32_t AV1Level21 = 0x2;
+constexpr int32_t AV1Level22 = 0x4;
+constexpr int32_t AV1Level23 = 0x8;
+constexpr int32_t AV1Level3  = 0x10;
+constexpr int32_t AV1Level31 = 0x20;
+constexpr int32_t AV1Level32 = 0x40;
+constexpr int32_t AV1Level33 = 0x80;
+constexpr int32_t AV1Level4  = 0x100;
+constexpr int32_t AV1Level41 = 0x200;
+constexpr int32_t AV1Level42 = 0x400;
+constexpr int32_t AV1Level43 = 0x800;
+constexpr int32_t AV1Level5  = 0x1000;
+constexpr int32_t AV1Level51 = 0x2000;
+constexpr int32_t AV1Level52 = 0x4000;
+constexpr int32_t AV1Level53 = 0x8000;
+constexpr int32_t AV1Level6  = 0x10000;
+constexpr int32_t AV1Level61 = 0x20000;
+constexpr int32_t AV1Level62 = 0x40000;
+constexpr int32_t AV1Level63 = 0x80000;
+constexpr int32_t AV1Level7  = 0x100000;
+constexpr int32_t AV1Level71 = 0x200000;
+constexpr int32_t AV1Level72 = 0x400000;
+constexpr int32_t AV1Level73 = 0x800000;
+
 constexpr int32_t HEVCProfileMain        = 0x01;
 constexpr int32_t HEVCProfileMain10      = 0x02;
 constexpr int32_t HEVCProfileMainStill   = 0x04;
@@ -273,6 +302,7 @@
 // from MediaFormat.java
 constexpr char MIMETYPE_VIDEO_VP8[] = "video/x-vnd.on2.vp8";
 constexpr char MIMETYPE_VIDEO_VP9[] = "video/x-vnd.on2.vp9";
+constexpr char MIMETYPE_VIDEO_AV1[] = "video/av01";
 constexpr char MIMETYPE_VIDEO_AVC[] = "video/avc";
 constexpr char MIMETYPE_VIDEO_HEVC[] = "video/hevc";
 constexpr char MIMETYPE_VIDEO_MPEG4[] = "video/mp4v-es";
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index e9baa1a..345f85d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -1610,9 +1610,9 @@
                     detailedError = _detailedError;
                 });
 
-        if (!returnVoid.isOk()) {
-            ALOGE("[stream %d] descramble failed, trans=%s",
-                    mElementaryPID, returnVoid.description().c_str());
+        if (!returnVoid.isOk() || status != Status::OK) {
+            ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
+                    mElementaryPID, returnVoid.description().c_str(), status);
             return UNKNOWN_ERROR;
         }
 
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index b187035..1b8493a 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -150,6 +150,8 @@
             "video_decoder.vp8", "video_encoder.vp8" },
         { MEDIA_MIMETYPE_VIDEO_VP9,
             "video_decoder.vp9", "video_encoder.vp9" },
+        { MEDIA_MIMETYPE_VIDEO_AV1,
+            "video_decoder.av1", "video_encoder.av1" },
         { MEDIA_MIMETYPE_AUDIO_RAW,
             "audio_decoder.raw", "audio_encoder.raw" },
         { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index f7597db..1fbb85e 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -20,7 +20,7 @@
         libmediaplayerservice \
         libutils \
         libbinder \
-        libicuuc \
+        libandroidicu \
         android.hardware.media.omx@1.0 \
 
 LOCAL_STATIC_LIBRARIES := \
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
index eaebcfb..65682a8 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
@@ -1142,8 +1142,7 @@
         private boolean mRegistered = false;
 
         public MessageHandler(Looper looper, MediaController.Callback cb) {
-            //TODO:(b/119539849) Uncomment below line and resolve the error.
-            // super(looper, null, true);
+            super(looper);
             mCallback = cb;
         }
 
@@ -1182,6 +1181,7 @@
 
         public void post(int what, Object obj, Bundle data) {
             Message msg = obtainMessage(what, obj);
+            msg.setAsynchronous(true);
             msg.setData(data);
             msg.sendToTarget();
         }
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
index 943843d..73e16a6 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
@@ -1458,8 +1458,7 @@
         private RemoteUserInfo mCurrentControllerInfo;
 
         public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
-            //TODO:(b/119539849) Uncomment below line and resolve the error.
-            //super(looper, null, true);
+            super(looper);
             mCallback = callback;
             mCallback.mHandler = this;
         }
@@ -1467,6 +1466,7 @@
         public void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) {
             Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj);
             Message msg = obtainMessage(what, objWithCaller);
+            msg.setAsynchronous(true);
             msg.setData(data);
             if (delayMs > 0) {
                 sendMessageDelayed(msg, delayMs);
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index d71aa15..ebb4f3b 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -86,7 +86,7 @@
 LOCAL_SHARED_LIBRARIES += libmedia_helper
 LOCAL_SHARED_LIBRARIES += libmediametrics
 
-LOCAL_SHARED_LIBRARIES += libhidlbase libicuuc libxml2
+LOCAL_SHARED_LIBRARIES += libhidlbase libxml2
 
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index baa5eb3..5544821 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4142,9 +4142,9 @@
     for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
         if (mAvailableInputDevices[i]->address().isEmpty()) {
             if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                mAvailableInputDevices[i]->address() = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->setAddress(String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS));
             } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
-                mAvailableInputDevices[i]->address() = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+                mAvailableInputDevices[i]->setAddress(String8(AUDIO_BACK_MICROPHONE_ADDRESS));
             }
         }
     }
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
index 653317b..f119472 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/services/mediacodec/registrant/Android.bp
@@ -39,6 +39,7 @@
         "libcodec2_soft_opusdec",
         "libcodec2_soft_vp8dec",
         "libcodec2_soft_vp9dec",
+        "libcodec2_soft_av1dec",
         "libcodec2_soft_vp8enc",
         "libcodec2_soft_vp9enc",
         "libcodec2_soft_rawdec",
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index e31eadc..6101c8a 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -40,7 +40,7 @@
 
 LOCAL_SRC_FILES := main_extractorservice.cpp
 LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
-    liblog libbase libicuuc libavservices_minijail
+    liblog libbase libandroidicu libavservices_minijail
 LOCAL_STATIC_LIBRARIES := libicuandroid_utils
 LOCAL_MODULE:= mediaextractor
 LOCAL_INIT_RC := mediaextractor.rc